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.
559 lines
17 KiB
559 lines
17 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"
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
/* Prototype Definitions */
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
static void AnnounceThisProcess ( void );
|
|
static void Epilogue ( void );
|
|
static void InitializeControlBlocks ( void );
|
|
static void NotifyAndActAsProper ( WORD ErrorDescriptor );
|
|
static void Prologue ( int argc, char * argv[] );
|
|
static void ProvideBufferSpace ( void );
|
|
static void WakeUpToExecuteRequests ( void );
|
|
|
|
void DisplayScreenBuffer ( int length );
|
|
|
|
FCB_File * FindFileControlBlock ( BYTE Key );
|
|
PCB_Process * FindProcessControlBlock ( BYTE Key );
|
|
PCB_Prototype * FindPrototypeControlBlock ( BYTE Key );
|
|
SCB_Semaphore * FindSemaphoreControlBlock ( BYTE Key );
|
|
TCB_Timer * FindTimerControlBlock ( BYTE Key );
|
|
|
|
void SplitAuxiliaryClassRequests ( CCB_Header * h );
|
|
void SplitFileClassRequests ( CCB_Header * h );
|
|
CCB_Header * SplitFlowClassRequests ( CCB_Header * h );
|
|
void SplitSemaphoreClassRequests ( CCB_Header * h );
|
|
void SplitTimerClassRequests ( CCB_Header * h );
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
/* Other Definitions */
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
BYTE *FramesBuffer;
|
|
FCB_Frame FrameControlBlocks[ Frames ];
|
|
QUAD OneFrameSize;
|
|
BYTE FrameIndex = Frames - 2;
|
|
|
|
HANDLE LastReadHandle;
|
|
ULONG LastReadOffset;
|
|
ULONG LastReadCount;
|
|
BYTE LastReadName[512];
|
|
BYTE DebugBuffer[160];
|
|
|
|
static CCB_Header * CCB_CommandChainEntryPoint;
|
|
static CCB_Header * CCB_HeaderPointer;
|
|
|
|
FCB_File * FCB_FileChainEntryPoint;
|
|
static FCB_File * FCB_FilePointer;
|
|
|
|
static OCB_OnError * OCB_OnErrorChainEntryPoint;
|
|
static OCB_OnError * OCB_OnErrorPointer;
|
|
|
|
static OCB_OnTimeout * OCB_OnTimeoutChainEntryPoint;
|
|
static OCB_OnTimeout * OCB_OnTimeoutPointer;
|
|
|
|
static PCB_Process * PCB_ProcessChainEntryPoint;
|
|
static PCB_Process * PCB_ProcessTrackPointer;
|
|
|
|
static PCB_Prototype * PCB_PrototypeChainEntryPoint;
|
|
static PCB_Prototype * PCB_PrototypePointer;
|
|
|
|
static SCB_Segment * SCB_SegmentChainEntryPoint;
|
|
|
|
// many of these may now be omitted ...
|
|
|
|
static SCB_Semaphore * SCB_SemaphoreChainEntryPoint;
|
|
static SCB_Semaphore * SCB_SemaphorePointer;
|
|
|
|
static TCB_Timer * TCB_TimerChainEntryPoint;
|
|
static TCB_Timer * TCB_TimerPointer;
|
|
static TCB_TimerReadings TCB_Time;
|
|
|
|
static BYTE FileExtrinsicKey;
|
|
static BYTE FileIntrinsicKey;
|
|
|
|
static BYTE ProcessExtrinsicKey;
|
|
static BYTE ProcessIntrinsicKey;
|
|
|
|
static BYTE PrototypeExtrinsicKey;
|
|
static BYTE PrototypeIntrinsicKey;
|
|
|
|
static BYTE SemaphoreExtrinsicKey;
|
|
static BYTE SemaphoreIntrinsicKey;
|
|
|
|
static BYTE TimerExtrinsicKey;
|
|
static BYTE TimerIntrinsicKey;
|
|
|
|
IEB_Gate * IEB_GatePointer;
|
|
|
|
static QUAD BufferSpace;
|
|
|
|
static WORD NumberOfSegments;
|
|
static WORD PartialSegmentSize;
|
|
|
|
static DWORD PageErrorLevel;
|
|
|
|
static DWORD ReturnCode;
|
|
|
|
static BYTE TracingFlag;
|
|
|
|
BYTE TracingLevel;
|
|
|
|
static TEXT GateLatchKey[16];
|
|
static TEXT SegmentDeclaredName[32];
|
|
static TEXT SegmentIntrinsicName[16];
|
|
static TEXT SegmentNamePrefix[] = "";
|
|
|
|
TEXT ScreenBuffer[401];
|
|
|
|
// This is the base address at which shared memory will be allocated;
|
|
// since the shared memory has pointers in it, it must be mapped at
|
|
// the same address in every process. This initial value must agree
|
|
// with the variable in sfs-gate.c.
|
|
//
|
|
PBYTE BaseAddress = (PBYTE) 0x09800000;
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void _CRTAPI1 main ( int argc, char * argv[] )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
Prologue ( argc, argv );
|
|
|
|
InitializeControlBlocks ();
|
|
ProvideBufferSpace ();
|
|
AnnounceThisProcess ();
|
|
WakeUpToExecuteRequests ();
|
|
|
|
Epilogue ();
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void Prologue ( int argc, char * argv[] )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
int count;
|
|
|
|
for ( count = 0; count < argc; count ++ )
|
|
if ( ( * argv[ count ] == '-' ) || ( * argv[ count ] == '/' ) )
|
|
switch ( tolower ( * ( argv[ count ] + 1 ) ) )
|
|
{
|
|
case 'k':
|
|
strcpy ( GateLatchKey, argv[ ++ count ] );
|
|
break;
|
|
|
|
default:
|
|
NotifyAndActAsProper ( ErrorImproperCall );
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void InitializeControlBlocks ( void )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
IEB_Gate * g;
|
|
PCB_Process * p;
|
|
SCB_Segment * s;
|
|
SECURITY_ATTRIBUTES SecurityAttributes = { sizeof ( SECURITY_ATTRIBUTES ),
|
|
NULL,
|
|
TRUE };
|
|
HANDLE MappingHandle;
|
|
PVOID ptr;
|
|
|
|
strcpy ( SegmentIntrinsicName, GateLatchKey );
|
|
strcpy ( SegmentDeclaredName, SegmentNamePrefix );
|
|
strcat ( SegmentDeclaredName, SegmentIntrinsicName );
|
|
|
|
MappingHandle = OpenFileMapping ( FILE_MAP_WRITE,
|
|
TRUE,
|
|
SegmentDeclaredName );
|
|
|
|
if ( MappingHandle == INVALID_HANDLE_VALUE )
|
|
{
|
|
ReturnCode = GetLastError();
|
|
NotifyAndActAsProper ( ErrorCreateFileMapping );
|
|
}
|
|
|
|
ptr = MapViewOfFileEx ( MappingHandle,
|
|
FILE_MAP_WRITE,
|
|
0,
|
|
0,
|
|
OneSegmentSpan,
|
|
BaseAddress );
|
|
|
|
if ( ptr == NULL )
|
|
{
|
|
ReturnCode = GetLastError();
|
|
NotifyAndActAsProper ( ErrorMapViewOfFile );
|
|
}
|
|
|
|
BaseAddress += OneSegmentSpan;
|
|
|
|
s = ( SCB_Segment * ) ptr;
|
|
SCB_SegmentChainEntryPoint = s;
|
|
|
|
while ( s -> SCB_SegmentNextInChain )
|
|
{
|
|
strcpy ( SegmentDeclaredName, SegmentNamePrefix );
|
|
strcat ( SegmentDeclaredName, s -> NextSegmentIntrinsicName );
|
|
|
|
MappingHandle = OpenFileMapping ( FILE_MAP_WRITE,
|
|
TRUE,
|
|
SegmentDeclaredName );
|
|
|
|
if ( MappingHandle == INVALID_HANDLE_VALUE )
|
|
{
|
|
ReturnCode = GetLastError();
|
|
NotifyAndActAsProper ( ErrorCreateFileMapping );
|
|
}
|
|
|
|
ptr = MapViewOfFileEx ( MappingHandle,
|
|
FILE_MAP_WRITE,
|
|
0,
|
|
0,
|
|
OneSegmentSpan,
|
|
BaseAddress );
|
|
|
|
if ( ptr == NULL ||
|
|
(PVOID)(s -> SCB_SegmentNextInChain) != ptr )
|
|
{
|
|
ReturnCode = GetLastError();
|
|
NotifyAndActAsProper ( ErrorMapViewOfFile );
|
|
}
|
|
|
|
BaseAddress += OneSegmentSpan;
|
|
s = s -> SCB_SegmentNextInChain;
|
|
}
|
|
|
|
|
|
IEB_GatePointer = ( IEB_Gate * ) SCB_SegmentChainEntryPoint;
|
|
g = IEB_GatePointer;
|
|
|
|
if ( p = FindProcessControlBlock ( g -> ProcessToWakeUp ) )
|
|
PCB_ProcessTrackPointer = p;
|
|
else
|
|
NotifyAndActAsProper ( ErrorProcessNotFound );
|
|
|
|
if ( !SetEvent ( g -> GateCheckInLights ) )
|
|
{
|
|
ReturnCode = GetLastError();
|
|
NotifyAndActAsProper ( ErrorSetEvent );
|
|
}
|
|
|
|
PCB_ProcessChainEntryPoint = g -> PCB_ProcessChainEntryPoint;
|
|
PCB_PrototypeChainEntryPoint = g -> PCB_PrototypeChainEntryPoint;
|
|
SCB_SemaphoreChainEntryPoint = g -> SCB_SemaphoreChainEntryPoint;
|
|
|
|
CCB_CommandChainEntryPoint = p -> CCB_CommandChainEntryPoint;
|
|
FCB_FileChainEntryPoint = p -> FCB_FileChainEntryPoint;
|
|
OCB_OnErrorChainEntryPoint = p -> OCB_OnErrorChainEntryPoint;
|
|
OCB_OnTimeoutChainEntryPoint = p -> OCB_OnTimeoutChainEntryPoint;
|
|
TCB_TimerChainEntryPoint = p -> TCB_TimerChainEntryPoint;
|
|
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void AnnounceThisProcess ( void )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
int l;
|
|
CCB_Header * h;
|
|
|
|
h = CCB_CommandChainEntryPoint;
|
|
|
|
l = Zero;
|
|
l += sprintf ( ScreenBuffer + l, "\r\nProcess %d", h -> ProcessExtrinsicKey );
|
|
l += sprintf ( ScreenBuffer + l, " is now starting ..." );
|
|
DisplayScreenBuffer ( l );
|
|
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void WakeUpToExecuteRequests ( void )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
CCB_Header * h;
|
|
|
|
|
|
h = CCB_CommandChainEntryPoint;
|
|
|
|
while ( h )
|
|
{
|
|
switch ( h -> RequestClass )
|
|
{
|
|
case AuxiliaryClass:
|
|
SplitAuxiliaryClassRequests ( h );
|
|
break;
|
|
|
|
case FileClass:
|
|
SplitFileClassRequests ( h );
|
|
break;
|
|
|
|
case FlowClass:
|
|
h = SplitFlowClassRequests ( h );
|
|
continue;
|
|
|
|
case SemaphoreClass:
|
|
SplitSemaphoreClassRequests ( h );
|
|
break;
|
|
|
|
case TimerClass:
|
|
SplitTimerClassRequests ( h );
|
|
break;
|
|
|
|
default:
|
|
NotifyAndActAsProper ( ErrorClassNotSupported );
|
|
break;
|
|
}
|
|
h = h -> CCB_HeaderNextInChain;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void ProvideBufferSpace ( void )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
BYTE * CurrentFrame;
|
|
FCB_Frame * f;
|
|
int count;
|
|
|
|
BufferSpace = PCB_ProcessTrackPointer -> BufferSpace;
|
|
|
|
// Round BufferSpace up to a multiple of 1K and to a
|
|
// multiple of Frames.
|
|
//
|
|
BufferSpace += K - 1;
|
|
BufferSpace &= ~(K - 1);
|
|
|
|
BufferSpace += Frames - 1;
|
|
BufferSpace /= Frames;
|
|
BufferSpace *= Frames;
|
|
|
|
if ( BufferSpace < SpaceLowerLimit )
|
|
BufferSpace = SpaceLowerLimit;
|
|
else
|
|
if ( BufferSpace > SpaceUpperLimit )
|
|
BufferSpace = SpaceUpperLimit;
|
|
|
|
OneFrameSize = BufferSpace / Frames;
|
|
f = FrameControlBlocks;
|
|
count = Frames;
|
|
|
|
// Allocate the buffer for the frames. Since we want the frames
|
|
// to be 1K aligned, allocate 1K - 1 extra bytes. The first
|
|
// frame will be allocated the first 1K-aligned chunk of memory
|
|
// in the buffer, and frames will thereafter be contiguous.
|
|
// (This of course assumes that OneFrameSize comes out to a
|
|
// multiple of 1K.)
|
|
//
|
|
FramesBuffer = (BYTE *) GlobalAlloc ( 0, BufferSpace + K - 1);
|
|
|
|
if ( FramesBuffer == NULL )
|
|
NotifyAndActAsProper ( ErrorGlobalAlloc );
|
|
|
|
CurrentFrame = (BYTE *)((ULONG)(FramesBuffer + K - 1) & ~(K - 1));
|
|
|
|
while( count-- )
|
|
{
|
|
f -> FramePointer = CurrentFrame;
|
|
f -> FrameStatus = Zero;
|
|
|
|
CurrentFrame += OneFrameSize;
|
|
f ++;
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void Epilogue ( void )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
IEB_Gate * g;
|
|
|
|
g = IEB_GatePointer;
|
|
|
|
GlobalFree ( FramesBuffer );
|
|
|
|
ReturnCode = WaitForSingleObject ( g -> GateCheckOutLights, INFINITE );
|
|
|
|
if ( ReturnCode != WAIT_OBJECT_0 )
|
|
NotifyAndActAsProper ( ErrorWaitForSingleObject );
|
|
|
|
if ( -- g -> GateCheckOutCount == Zero )
|
|
SetEvent ( g -> GateClosureLights );
|
|
|
|
SetEvent ( g -> GateCheckOutLights );
|
|
ExitProcess ( PageErrorLevel );
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
FCB_File * FindFileControlBlock ( BYTE SearchKey )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
FCB_File * f;
|
|
|
|
f = PCB_ProcessTrackPointer -> FCB_FileChainEntryPoint;
|
|
|
|
while ( f )
|
|
{
|
|
if ( f -> FileExtrinsicKey == SearchKey )
|
|
break;
|
|
f = f -> FCB_FileNextInChain;
|
|
}
|
|
return FCB_FilePointer = f;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
PCB_Process * FindProcessControlBlock ( BYTE SearchKey )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
IEB_Gate * g;
|
|
PCB_Process * p;
|
|
|
|
g = IEB_GatePointer;
|
|
p = g -> PCB_ProcessChainEntryPoint;
|
|
|
|
while ( p )
|
|
{
|
|
if ( p -> ProcessIntrinsicKey == SearchKey )
|
|
break;
|
|
p = p -> PCB_ProcessNextInChain;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
PCB_Prototype * FindPrototypeControlBlock ( BYTE SearchKey )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
IEB_Gate * g;
|
|
PCB_Prototype * p;
|
|
|
|
g = IEB_GatePointer;
|
|
p = g -> PCB_PrototypeChainEntryPoint;
|
|
|
|
while ( p )
|
|
{
|
|
if ( p -> PrototypeExtrinsicKey == SearchKey )
|
|
break;
|
|
p = p -> PCB_PrototypeNextInChain;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
SCB_Semaphore * FindSemaphoreControlBlock ( BYTE SearchKey )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
IEB_Gate * g;
|
|
SCB_Semaphore * s;
|
|
|
|
g = IEB_GatePointer;
|
|
s = g -> SCB_SemaphoreChainEntryPoint;
|
|
|
|
while ( s )
|
|
{
|
|
if ( s -> SemaphoreExtrinsicKey == SearchKey )
|
|
break;
|
|
s = s -> SCB_SemaphoreNextInChain;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
TCB_Timer * FindTimerControlBlock ( BYTE SearchKey )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
TCB_Timer * t;
|
|
|
|
t = TCB_TimerChainEntryPoint;
|
|
|
|
while ( t )
|
|
{
|
|
if ( t -> TimerExtrinsicKey == SearchKey )
|
|
break;
|
|
t = t -> TCB_TimerNextInChain;
|
|
}
|
|
return t;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void NotifyAndActAsProper ( WORD ErrorDescriptor )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
TEXT * p;
|
|
int l;
|
|
|
|
p = ScreenBuffer;
|
|
l = Zero;
|
|
|
|
l += sprintf ( p + l,"\r\nsfs-page: " );
|
|
if ( ErrorDescriptor > DosErrorLowerLimit )
|
|
l += sprintf ( p + l, "Error %hu executing ", ReturnCode );
|
|
|
|
switch ( ErrorDescriptor )
|
|
{
|
|
case ErrorGlobalAlloc:
|
|
l += sprintf ( p + l, "GlobalAlloc" );
|
|
break;
|
|
|
|
case ErrorCreateFileMapping:
|
|
l += sprintf ( ScreenBuffer + l, "CreateFileMapping" );
|
|
break;
|
|
|
|
case ErrorMapViewOfFile:
|
|
l += sprintf ( ScreenBuffer + l, "MapViewOfFile" );
|
|
break;
|
|
|
|
case ErrorImproperCall:
|
|
l += sprintf ( p + l, "Improper call" );
|
|
break;
|
|
|
|
case ErrorProcessNotFound:
|
|
l += sprintf ( p + l, "Process not found" );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
DisplayScreenBuffer ( l );
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
void DisplayScreenBuffer ( int length )
|
|
/*---------------------------------------------------------------------------------*/
|
|
{
|
|
IEB_Gate * g;
|
|
DWORD done;
|
|
|
|
g = IEB_GatePointer;
|
|
|
|
ReturnCode = WaitForSingleObject ( g -> GateScreenLights, INFINITE );
|
|
|
|
if( ReturnCode != WAIT_OBJECT_0 )
|
|
NotifyAndActAsProper ( ErrorWaitForSingleObject );
|
|
|
|
WriteFile ( GetStdHandle ( STD_OUTPUT_HANDLE ),
|
|
ScreenBuffer,
|
|
length,
|
|
&done,
|
|
NULL );
|
|
|
|
ReleaseMutex ( g -> GateScreenLights );
|
|
|
|
return;
|
|
}
|