mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
451 lines
14 KiB
451 lines
14 KiB
|
|
#include "sfs-hide.h"
|
|
#include "sfs-main.h"
|
|
#include "sfs-file.h"
|
|
#include "sfs-pack.h"
|
|
|
|
#include "sfs-scan.h"
|
|
#include "sfs-page.h"
|
|
#include "sfs-gate.h"
|
|
#include "sfs-tree.h"
|
|
|
|
#define MismatchThreshold 2
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
/* Prototype Definitions */
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
static void DisplayMismatchDetails ( BYTE SourceOfRecord );
|
|
static void NotifyAndActAsProper ( WORD ErrorDescriptor );
|
|
static void SplitAuxiliaryGroupRequests ( CCB_Header * h );
|
|
static void TypeComment ( CCB_Header * h );
|
|
|
|
void CollateRecords ( void );
|
|
void CreateNextRecord ( void );
|
|
void CreateRecord ( QUAD RecordIndex );
|
|
void CreateRecords ( BYTE PatternIndex, WORD RecordSize );
|
|
|
|
FCB_File * FindFileControlBlock ( BYTE SearchKey );
|
|
|
|
void SplitAuxiliaryClassRequests ( CCB_Header * h );
|
|
void SplitUtilityGroupRequests ( CCB_Header * h );
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
/* Other Definitions */
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
FCB_Frame * CreateControlPointer = NULL;
|
|
BYTE CreateFlag = Zero;
|
|
|
|
extern BYTE FrameIndex;
|
|
extern QUAD OneFrameSize;
|
|
extern FCB_Frame FrameControlBlocks[];
|
|
extern HANDLE LastReadHandle;
|
|
extern ULONG LastReadOffset;
|
|
extern ULONG LastReadCount;
|
|
extern BYTE LastReadName[];
|
|
|
|
static QUAD BaseQuads[] = {
|
|
|
|
0x03FB05F1, 0x07EF0BE9, 0x0DE511E3, 0x13DF17D3,
|
|
0x1DC71FC5, 0x25C129BF, 0x2BB52FB3, 0x35AD3BA7,
|
|
0x3DA3439D, 0x00000000, 0x01010101, 0x02020202,
|
|
0x03030303, 0x04040404, 0x05050505, 0x06060606,
|
|
0x37373737, 0x08080808, 0x09090909, 0x0A0A0A0A,
|
|
0x0B0B0B0B, 0x0C0C0C0C, 0x0D0D0D0D, 0x0E0E0E0E,
|
|
0x0F0F0F0F, 0x10101010, 0x11111111, 0x12121212,
|
|
0xFAFAFAFA, 0xCDCDCDCD, 0xEEEEEEEE, 0x000000DB };
|
|
|
|
static QUAD StepQuads[] = {
|
|
|
|
0x0D111317, 0x1D1F2529, 0x2B2F353B, 0x3D434749,
|
|
0x4F535961, 0x65676B6D, 0x717F8389, 0x8B95979D,
|
|
0xA3A7ADB3, 0x00000000, 0x00000000, 0x00000000,
|
|
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
|
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
|
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
|
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
|
0x00000000, 0x00000000, 0x00000000, 0x00000004 };
|
|
|
|
static QUAD BaseQuadInUse;
|
|
static QUAD StepQuadInUse;
|
|
|
|
static QUAD CurrentQuad;
|
|
|
|
static QUAD SequenceAlignedPointer;
|
|
static QUAD SequenceCurrentPointer;
|
|
static QUAD SequenceEndPointer;
|
|
|
|
static QUAD RecordIndex;
|
|
static WORD RecordSize;
|
|
|
|
static WORD BytesToBeCollated;
|
|
static WORD NumberOfMismatches;
|
|
static WORD OffsetOfMismatch;
|
|
|
|
static WORD SourceRecordSpan;
|
|
static WORD TargetRecordSpan;
|
|
|
|
static BYTE * SourceStartPointer;
|
|
|
|
static BYTE SourceOfSourceRecord;
|
|
static BYTE SourceOfTargetRecord;
|
|
|
|
static BYTE OffsetInQuad;
|
|
|
|
static BYTE PatternIndex;
|
|
static BYTE PatternIndexLimit = sizeof ( BaseQuads ) / sizeof ( QUAD );
|
|
|
|
BYTE DebugOutputBuffer[512];
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void SplitAuxiliaryClassRequests ( CCB_Header * h )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
switch ( h -> RequestGroup )
|
|
{
|
|
case CollateGroup:
|
|
SplitAuxiliaryGroupRequests ( h );
|
|
break;
|
|
|
|
case CreateGroup:
|
|
SplitAuxiliaryGroupRequests ( h );
|
|
break;
|
|
|
|
case RecordGroup:
|
|
SplitRecordGroupRequests ( h );
|
|
break;
|
|
|
|
case UtilityGroup:
|
|
SplitUtilityGroupRequests ( h );
|
|
break;
|
|
|
|
case TypeGroup:
|
|
SplitAuxiliaryGroupRequests ( h );
|
|
break;
|
|
|
|
default:
|
|
NotifyAndActAsProper ( ErrorGroupNotSupported );
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void SplitAuxiliaryGroupRequests ( CCB_Header * h )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
CCB_CreateRecord * r;
|
|
CCB_CreateRecords * c;
|
|
|
|
switch ( h -> RequestCode )
|
|
{
|
|
case ClearCreateFlagRequest:
|
|
CreateFlag = Reset;
|
|
break;
|
|
|
|
case CollateRecordsRequest:
|
|
CollateRecords ();
|
|
break;
|
|
|
|
case CreateNextRecordRequest:
|
|
CreateNextRecord ();
|
|
break;
|
|
|
|
case CreateRecordRequest:
|
|
r = ( CCB_CreateRecord * ) h;
|
|
CreateRecord ( r -> RecordIndex );
|
|
break;
|
|
|
|
case CreateRecordsRequest:
|
|
c = ( CCB_CreateRecords * ) h;
|
|
CreateRecords ( c -> PatternIndex, c -> RecordSize );
|
|
break;
|
|
|
|
case SetCreateFlagRequest:
|
|
CreateFlag = Set;
|
|
break;
|
|
|
|
case TypeCommentRequest:
|
|
TypeComment ( h );
|
|
break;
|
|
|
|
default:
|
|
NotifyAndActAsProper ( ErrorRequestNotSupported );
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void CollateRecords ( void )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
BYTE * s, * t, * TargetStartPointer;
|
|
FCB_Frame * f;
|
|
WORD count;
|
|
|
|
if ( CreateFlag )
|
|
if ( f = CreateControlPointer )
|
|
if ( f -> FrameStatus & FlagFrameValid )
|
|
{
|
|
s = f -> FramePointer;
|
|
SourceRecordSpan = f -> RecordSpan;
|
|
SourceOfSourceRecord = Zero;
|
|
}
|
|
else
|
|
NotifyAndActAsProper ( ErrorImproperSource );
|
|
else
|
|
NotifyAndActAsProper ( ErrorImproperCollateAttempt );
|
|
else
|
|
{
|
|
f = FrameControlBlocks + ( FrameIndex ^ FrameSwitch );
|
|
if ( f -> FrameStatus & FlagFrameValid )
|
|
{
|
|
s = f -> FramePointer;
|
|
SourceRecordSpan = f -> RecordSpan;
|
|
SourceOfSourceRecord = f -> FrameOwner;
|
|
}
|
|
else
|
|
NotifyAndActAsProper ( ErrorImproperSource );
|
|
}
|
|
f = FrameControlBlocks + FrameIndex;
|
|
if ( f -> FrameStatus & FlagFrameValid )
|
|
{
|
|
t = f -> FramePointer;
|
|
TargetRecordSpan = f -> RecordSpan;
|
|
SourceOfTargetRecord = f -> FrameOwner;
|
|
}
|
|
else
|
|
NotifyAndActAsProper ( ErrorImproperTarget );
|
|
|
|
BytesToBeCollated = SourceRecordSpan;
|
|
if ( SourceRecordSpan > TargetRecordSpan )
|
|
BytesToBeCollated = TargetRecordSpan;
|
|
if ( SourceRecordSpan - TargetRecordSpan )
|
|
NotifyAndActAsProper ( ErrorRecordSpansDiffer );
|
|
|
|
if ( count = BytesToBeCollated )
|
|
{
|
|
SourceStartPointer = s;
|
|
TargetStartPointer = t;
|
|
|
|
while ( count -- )
|
|
{
|
|
if ( * s - * t )
|
|
{
|
|
OffsetOfMismatch = s - SourceStartPointer;
|
|
NotifyAndActAsProper ( ErrorRecordBytesDiffer );
|
|
NumberOfMismatches ++ ;
|
|
sprintf ( DebugOutputBuffer,
|
|
"Mismatch at offset 0x%x\n"
|
|
" Source Buffer: 0x%x\n"
|
|
" Target Buffer: 0x%x\n",
|
|
OffsetOfMismatch,
|
|
SourceStartPointer,
|
|
TargetStartPointer );
|
|
OutputDebugString ( DebugOutputBuffer );
|
|
sprintf ( DebugOutputBuffer,
|
|
"Last read handle: 0x%x\n", LastReadHandle );
|
|
OutputDebugString ( DebugOutputBuffer );
|
|
sprintf ( DebugOutputBuffer,
|
|
" name: %s\n", LastReadName );
|
|
OutputDebugString ( DebugOutputBuffer );
|
|
sprintf ( DebugOutputBuffer,
|
|
" read 0x%x bytes at file offset 0x%x\n",
|
|
LastReadCount, LastReadOffset );
|
|
OutputDebugString ( DebugOutputBuffer );
|
|
DebugBreak();
|
|
if ( NumberOfMismatches > MismatchThreshold )
|
|
{
|
|
NotifyAndActAsProper ( ErrorMismatchThreshold );
|
|
NumberOfMismatches = Zero;
|
|
break;
|
|
}
|
|
}
|
|
s ++ ;
|
|
t ++ ;
|
|
}
|
|
}
|
|
else
|
|
NotifyAndActAsProper ( ErrorNothingToCollate );
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void CreateNextRecord ( void )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
BYTE * r, * q;
|
|
FCB_Frame * f;
|
|
|
|
if ( f = CreateControlPointer )
|
|
{
|
|
r = f -> FramePointer;
|
|
q = ( BYTE * ) &CurrentQuad;
|
|
|
|
while ( SequenceCurrentPointer < SequenceEndPointer )
|
|
{
|
|
|
|
if ( OffsetInQuad == sizeof ( QUAD ) )
|
|
{
|
|
CurrentQuad += StepQuadInUse;
|
|
OffsetInQuad = Zero;
|
|
}
|
|
* r ++ = * ( q + OffsetInQuad );
|
|
SequenceCurrentPointer ++ ;
|
|
OffsetInQuad ++ ;
|
|
}
|
|
|
|
SequenceEndPointer += RecordSize;
|
|
CreateFlag = Set;
|
|
RecordIndex ++ ;
|
|
f -> FrameStatus |= FlagFrameValid;
|
|
}
|
|
else
|
|
NotifyAndActAsProper ( ErrorImproperCall );
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void CreateRecord ( QUAD RecordNumber )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
if ( CreateControlPointer )
|
|
{
|
|
RecordIndex = RecordNumber - 1;
|
|
|
|
SequenceCurrentPointer = Zero;
|
|
SequenceCurrentPointer += RecordSize * RecordIndex;
|
|
SequenceEndPointer = SequenceCurrentPointer + RecordSize;
|
|
|
|
SequenceAlignedPointer = SequenceCurrentPointer >> 2;
|
|
CurrentQuad = BaseQuadInUse;
|
|
CurrentQuad += StepQuadInUse * SequenceAlignedPointer;
|
|
|
|
SequenceAlignedPointer <<= 2;
|
|
OffsetInQuad = SequenceCurrentPointer - SequenceAlignedPointer;
|
|
|
|
CreateNextRecord ();
|
|
}
|
|
else
|
|
NotifyAndActAsProper ( ErrorImproperCall );
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void CreateRecords ( BYTE PatternNumber, WORD Size )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
FCB_Frame * f;
|
|
|
|
PatternIndex = PatternNumber;
|
|
RecordSize = Size;
|
|
RecordIndex = Zero;
|
|
|
|
if ( RecordSize > OneFrameSize )
|
|
NotifyAndActAsProper ( ErrorImproperRecordSpan );
|
|
|
|
if ( PatternIndex > PatternIndexLimit )
|
|
{
|
|
NotifyAndActAsProper ( ErrorPatternUndefined );
|
|
PatternIndex = 1;
|
|
}
|
|
BaseQuadInUse = BaseQuads[ PatternIndex - 1 ];
|
|
StepQuadInUse = StepQuads[ PatternIndex - 1 ];
|
|
|
|
CurrentQuad = BaseQuadInUse;
|
|
SequenceCurrentPointer = Zero;
|
|
SequenceEndPointer = RecordSize;
|
|
OffsetInQuad = Zero;
|
|
|
|
f = FrameControlBlocks + Frames - 1;
|
|
CreateControlPointer = f;
|
|
f -> RecordSpan = RecordSize;
|
|
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void TypeComment ( CCB_Header * h )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
CCB_Comment * c;
|
|
|
|
c = ( CCB_Comment * ) h;
|
|
|
|
printf ( "\r\n... Comment: %s\r\n", c -> CommentTextPointer );
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void NotifyAndActAsProper ( WORD ErrorDescriptor )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
switch ( ErrorDescriptor )
|
|
{
|
|
case ErrorImproperCall:
|
|
printf ( "\r\n.. Improper call" );
|
|
break;
|
|
|
|
case ErrorImproperCollateAttempt:
|
|
printf ( "\r\n.. Improper collate attempt" );
|
|
break;
|
|
|
|
case ErrorImproperSource:
|
|
printf ( "\r\n.. Improper source" );
|
|
break;
|
|
|
|
case ErrorImproperTarget:
|
|
printf ( "\r\n.. Improper target" );
|
|
break;
|
|
|
|
case ErrorMismatchThreshold:
|
|
printf ( "\r\n.. MismatchThreshold of %d ", MismatchThreshold );
|
|
printf ( "has been reached" );
|
|
break;
|
|
|
|
case ErrorPatternUndefined:
|
|
printf ( "\r\n.. Pattern %d undefined", PatternIndex );
|
|
printf ( "\r\n.. Pattern 1 will be used instead" );
|
|
break;
|
|
|
|
case ErrorRecordBytesDiffer:
|
|
printf ( "\r\n\nData mismatch found while collating records:" );
|
|
DisplayMismatchDetails ( SourceOfSourceRecord );
|
|
DisplayMismatchDetails ( SourceOfTargetRecord );
|
|
break;
|
|
|
|
case ErrorRecordSpansDiffer:
|
|
printf ( "\r\n.. Spans of record %lu differ:", RecordIndex );
|
|
printf ( " %u for source,", SourceRecordSpan );
|
|
printf ( " %u for target", TargetRecordSpan );
|
|
break;
|
|
|
|
case ErrorRequestNotSupported:
|
|
printf ( "\r\n.. Request not supported, it will be ignored." );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void DisplayMismatchDetails ( BYTE SourceOfRecord )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
FCB_File * f;
|
|
|
|
if ( SourceOfRecord )
|
|
{
|
|
f = FindFileControlBlock ( SourceOfRecord );
|
|
printf ( "\r\n p = %d", f -> ProcessExtrinsicKey );
|
|
printf ( ", file[ %d ] %s", f -> FileExtrinsicKey, f -> FileNamePointer );
|
|
printf ( "\r\n p = %d", f -> ProcessExtrinsicKey );
|
|
printf ( ", offset of record in file: %lu", f -> FileNewPointer );
|
|
printf ( ", offset of mismatch in record: %u", OffsetOfMismatch );
|
|
}
|
|
return;
|
|
}
|