#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 BeginReadingFile ( CCB_Header * h ); static void ContinueReadingFile ( CCB_Header * h ); static void EndReadingFile ( CCB_Header * h ); static void SfsReadFile ( CCB_Header * h ); static void SfsReadFileAsynchronously ( FCB_File * f, CCB_ReadFile * c, FCB_Frame * r ); static void BeginWritingFile ( CCB_Header * h ); static void ContinueWritingFile ( CCB_Header * h ); static void EndWritingFile ( CCB_Header * h ); static void SfsWriteFile ( CCB_Header * h ); static void SfsWriteFileAsynchronously ( FCB_File * f, CCB_WriteFile * c, FCB_Frame * r ); static void ChangeFileLocks ( CCB_Header * h ); static void ChangeFilePointer ( CCB_Header * h ); static void CloseFile ( CCB_Header * h ); static void SfsDeleteFile ( CCB_Header * h ); static void QueryFile ( CCB_Header * h ); static void CloseFiles ( CCB_Header * h ); static void SfsDeleteFiles ( CCB_Header * h ); static void QueryFiles ( CCB_Header * h ); static void NotifyAndActAsProper ( WORD ErrorDescriptor ); static void SplitGenericFileGroup ( CCB_Header * h ); static void SplitGenericFilesGroup ( CCB_Header * h ); static void SplitReadFileGroup ( CCB_Header * h ); static void SplitWriteFileGroup ( CCB_Header * h ); FCB_File * FindFileControlBlock ( BYTE SearchKey ); SCB_Semaphore * FindSemaphoreControlBlock ( BYTE SearchKey ); void QueryCurrentFilePointer ( FCB_File * f ); // new void SplitFileClassRequests ( CCB_Header * s ); void SplitOpenFileGroup ( CCB_Header * h ); void TypeFileStatusInfo ( FCB_File * f, BY_HANDLE_FILE_INFORMATION * s ); /*---------------------------------------------------------------------------------*/ /* Other Definitions */ /*---------------------------------------------------------------------------------*/ extern IEB_Gate * IEB_GatePointer; extern FCB_File * FCB_FileChainEntryPoint; extern FCB_Frame FrameControlBlocks[]; extern FCB_Frame * CreateControlPointer; extern BYTE FrameIndex; extern BYTE CreateFlag; extern HANDLE LastReadHandle; extern ULONG LastReadOffset; extern ULONG LastReadCount; extern BYTE LastReadName[]; extern BYTE DebugBuffer[]; static FCB_File * FCB_FileTrackPointer; static PCB_Process * PCB_ProcessChainEntryPoint; static PCB_Process * PCB_ProcessPointer; static PCB_Prototype * PCB_PrototypeChainEntryPoint; static PCB_Prototype * PCB_PrototypePointer; static SCB_Semaphore * SCB_SemaphoreChainEntryPoint; static SCB_Semaphore * SCB_SemaphorePointer; 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 QUAD Reserved = Zero; static WORD AsynchronousErrors; static WORD BytesRead; static WORD BytesToBeRead; static WORD BytesWritten; static WORD BytesToBeWritten; static DWORD ReturnCode; BY_HANDLE_FILE_INFORMATION FileStatusBuffer; //BYTE FileStatusBuffer[ sizeof ( BY_HANDLE_FILE_INFORMATION ) ]; /*---------------------------------------------------------------------------------*/ void SplitFileClassRequests ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { switch ( h -> RequestGroup ) { case FileLocksGroup: ChangeFileLocks ( h ); break; case FilePointerGroup: ChangeFilePointer ( h ); break; case GenericFileGroup: SplitGenericFileGroup ( h ); break; case GenericFilesGroup: SplitGenericFilesGroup ( h ); break; case OpenFileGroup: SplitOpenFileGroup ( h ); break; case ReadFileGroup: SplitReadFileGroup ( h ); break; case WriteFileGroup: SplitWriteFileGroup ( h ); break; default: NotifyAndActAsProper ( ErrorGroupNotSupported ); break; } return; } /*---------------------------------------------------------------------------------*/ void SplitGenericFileGroup ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { switch ( h -> RequestCode ) { case CloseFileRequest: CloseFile ( h ); break; case DeleteFileRequest: SfsDeleteFile ( h ); break; case QueryFileRequest: QueryFile ( h ); break; default: NotifyAndActAsProper ( ErrorRequestNotSupported ); break; } return; } /*---------------------------------------------------------------------------------*/ void SplitGenericFilesGroup ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { switch ( h -> RequestCode ) { case CloseFilesRequest: CloseFiles ( h ); break; case DeleteFilesRequest: SfsDeleteFiles ( h ); break; case QueryFilesRequest: QueryFiles ( h ); break; default: NotifyAndActAsProper ( ErrorRequestNotSupported ); break; } return; } /*---------------------------------------------------------------------------------*/ void SplitReadFileGroup ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { switch ( h -> RequestCode ) { case BeginReadingFileRequest: BeginReadingFile ( h ); break; case ContinueReadingFileRequest: ContinueReadingFile ( h ); break; case EndReadingFileRequest: EndReadingFile ( h ); break; case ReadFileRequest: SfsReadFile ( h ); break; default: NotifyAndActAsProper ( ErrorRequestNotSupported ); break; } return; } /*---------------------------------------------------------------------------------*/ void SplitWriteFileGroup ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { switch ( h -> RequestCode ) { case BeginWritingFileRequest: BeginWritingFile ( h ); break; case ContinueWritingFileRequest: ContinueWritingFile ( h ); break; case EndWritingFileRequest: EndWritingFile ( h ); break; case WriteFileRequest: SfsWriteFile ( h ); break; default: NotifyAndActAsProper ( ErrorRequestNotSupported ); break; } return; } /*---------------------------------------------------------------------------------*/ void ChangeFileLocks ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { //CCB_ChangeFileLocks * c; CCB_ChangeFilePointer * c; // to be changed completely FCB_File * f; DWORD NewPointer; c = ( CCB_ChangeFilePointer * ) h; if ( f = FindFileControlBlock ( c -> FileExtrinsicKey ) ) { FCB_FileTrackPointer = f; if ( f -> FileStatus & FileOpen ) { f -> FileOldPointer = f -> FileNewPointer; NewPointer = SetFilePointer( f -> FileHandle, c -> FileOffset, NULL, c -> FileOffPoint ); if( NewPointer == 0xFFFFFFFF ) { ReturnCode = GetLastError(); NotifyAndActAsProper ( ErrorSetFilePointer ); } else { f -> FileNewPointer = NewPointer; f -> FileOffset = c -> FileOffset; f -> FileOffPoint = c -> FileOffPoint; } } else NotifyAndActAsProper ( ErrorFileNotOpen ); } else NotifyAndActAsProper ( ErrorFCB_FileNotFound ); return; } /*---------------------------------------------------------------------------------*/ void ChangeFilePointer ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { CCB_ChangeFilePointer * c; FCB_File * f; DWORD NewPointer; c = ( CCB_ChangeFilePointer * ) h; if ( f = FindFileControlBlock ( c -> FileExtrinsicKey ) ) { FCB_FileTrackPointer = f; if ( f -> FileStatus & FileOpen ) { f -> FileOldPointer = f -> FileNewPointer; NewPointer = SetFilePointer( f -> FileHandle, c -> FileOffset, NULL, c -> FileOffPoint ); if ( NewPointer == 0xFFFFFFFF ) { ReturnCode = GetLastError(); NotifyAndActAsProper ( ErrorSetFilePointer ); } else { f -> FileNewPointer = NewPointer; f -> FileOffset = c -> FileOffset; f -> FileOffPoint = c -> FileOffPoint; } } else NotifyAndActAsProper ( ErrorFileNotOpen ); } else NotifyAndActAsProper ( ErrorFCB_FileNotFound ); return; } /*---------------------------------------------------------------------------------*/ void CloseFile ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { CCB_CloseFile * c; FCB_File * f; c = ( CCB_CloseFile * ) h; if ( f = FindFileControlBlock ( c -> FileExtrinsicKey ) ) { FCB_FileTrackPointer = f; if ( f -> FileStatus & FileOpen ) { if( ! CloseHandle( f -> FileHandle ) ) { ReturnCode = GetLastError(); NotifyAndActAsProper ( ErrorCloseHandle ); } else { f -> FileStatus ^= FileOpen; } } else NotifyAndActAsProper ( ErrorFileNotOpen ); } else NotifyAndActAsProper ( ErrorFCB_FileNotFound ); return; } /*---------------------------------------------------------------------------------*/ void CloseFiles ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { FCB_File * f; f = FCB_FileChainEntryPoint; while ( f ) { if ( f -> FileStatus & FileOpen ) { FCB_FileTrackPointer = f; if ( ! CloseHandle( f -> FileHandle ) ) { ReturnCode = GetLastError(); NotifyAndActAsProper ( ErrorCloseHandle ); } else { f -> FileStatus ^= FileOpen; } } f = f -> FCB_FileNextInChain; } return; } /*---------------------------------------------------------------------------------*/ void SfsDeleteFile ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { CCB_DeleteFile * c; FCB_File * f; c = ( CCB_DeleteFile * ) h; if ( f = FindFileControlBlock ( c -> FileExtrinsicKey ) ) { FCB_FileTrackPointer = f; if ( f -> FileStatus & FileDeleted ) NotifyAndActAsProper ( ErrorFileAlreadyDeleted ); else { if ( ! DeleteFile ( f -> FileNamePointer ) ) { ReturnCode = GetLastError(); NotifyAndActAsProper ( ErrorDeleteFile ); } else { f -> FileStatus |= FileDeleted; f -> FileStatus &= ~FileOpen; } } } else NotifyAndActAsProper ( ErrorFCB_FileNotFound ); return; } /*---------------------------------------------------------------------------------*/ void SfsDeleteFiles ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { FCB_File * f; f = FCB_FileChainEntryPoint; while ( f ) { if ( !( f -> FileStatus & FileOpen ) ) if ( !( f -> FileStatus & FileDeleted ) ) { FCB_FileTrackPointer = f; if ( ! DeleteFile ( f -> FileNamePointer ) ) { ReturnCode = GetLastError(); NotifyAndActAsProper ( ErrorDeleteFile ); } else { f -> FileStatus |= FileDeleted; f -> FileStatus &= ~FileOpen; } } f = f -> FCB_FileNextInChain; } return; } /*---------------------------------------------------------------------------------*/ void QueryFile ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { CCB_QueryFile * c; FCB_File * f; c = ( CCB_QueryFile * ) h; if ( f = FindFileControlBlock ( c -> FileExtrinsicKey ) ) { FCB_FileTrackPointer = f; if ( f -> FileStatus & FileOpen ) { //c -> QueryLevel = 1; // FILE_INFO_1 = 1 ??? ??? if( ! GetFileInformationByHandle( f -> FileHandle, &FileStatusBuffer ) ) { ReturnCode = GetLastError(); NotifyAndActAsProper ( ErrorGetFileInfo ); } else TypeFileStatusInfo ( f, &FileStatusBuffer ); } else NotifyAndActAsProper ( ErrorFileNotOpen ); } else NotifyAndActAsProper ( ErrorFCB_FileNotFound ); return; } /*---------------------------------------------------------------------------------*/ void QueryFiles ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { FCB_File * f; f = FCB_FileChainEntryPoint; while ( f ) { if ( f -> FileStatus & FileOpen ) { FCB_FileTrackPointer = f; if( ! GetFileInformationByHandle( f -> FileHandle, &FileStatusBuffer ) ) { ReturnCode = GetLastError(); NotifyAndActAsProper ( ErrorGetFileInfo ); } else TypeFileStatusInfo ( f, &FileStatusBuffer ); } f = f -> FCB_FileNextInChain; } return; } /*---------------------------------------------------------------------------------*/ void BeginReadingFile ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { return; } /*---------------------------------------------------------------------------------*/ void ContinueReadingFile ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { return; } /*---------------------------------------------------------------------------------*/ void EndReadingFile ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { return; } /*---------------------------------------------------------------------------------*/ void SfsReadFile ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { CCB_ReadFile * c; FCB_File * f; FCB_Frame * r; c = ( CCB_ReadFile * ) h; if ( f = FindFileControlBlock ( c -> FileExtrinsicKey ) ) { FCB_FileTrackPointer = f; if ( f -> FileStatus & FileOpen ) { FrameIndex ^= FrameSwitch; r = FrameControlBlocks + FrameIndex; r -> FrameStatus &= ~FlagFrameValid; r -> FrameOwner = f -> FileExtrinsicKey; r -> FrameUser = Zero; QueryCurrentFilePointer ( f ); // new if ( c -> RecordSize ) r -> BytesToBeRead = c -> RecordSize; else r -> BytesToBeRead = f -> RecordSize; if ( c -> RequestModifiers & AsynchronousFlag ) SfsReadFileAsynchronously ( f, c, r ); else { if ( ! ReadFile ( f -> FileHandle, r -> FramePointer, r -> BytesToBeRead, &( r -> RecordSpan ), NULL ) ) { ReturnCode = GetLastError(); NotifyAndActAsProper ( ErrorReadFile ); } LastReadHandle = f -> FileHandle; LastReadOffset = f -> FileNewPointer; LastReadCount = r -> RecordSpan; strcpy( LastReadName, f -> FileNamePointer ); r -> FrameStatus |= FlagFrameValid; if ( r -> RecordSpan < r -> BytesToBeRead ) NotifyAndActAsProper ( ErrorEndOfFile ); // change later so that the error flag is raised only if // r -> RecordSpan is Zero ... } } else NotifyAndActAsProper ( ErrorFileNotOpen ); } else NotifyAndActAsProper ( ErrorFCB_FileNotFound ); return; } /*---------------------------------------------------------------------------------*/ void SfsReadFileAsynchronously ( FCB_File * f, CCB_ReadFile * c, FCB_Frame * r ) /*---------------------------------------------------------------------------------*/ { #if 0 SCB_Semaphore * s; if ( s = FindSemaphoreControlBlock ( c -> SemaphoreExtrinsicKey ) ) { ReturnCode = DosSemSet ( &( s -> Lights ) ); if ( ReturnCode ) NotifyAndActAsProper ( ErrorDosSemSet ); else { // Save Semaphore Extrinsic Key too ... in FCB_Frame * r // Set Asynchronous Flag in Frame Status ... ReturnCode = DosReadAsync ( f -> FileHandle, &( s -> Lights ), &( r -> DelayedReadErrors ), r -> FramePointer, r -> BytesToBeRead, &( r -> RecordSpan ) ); // Mark file status ... as being read or written // asynchronously and verify errors on subsequent operations } } else NotifyAndActAsProper ( ErrorSemaphoreNotFound ); return; #endif printf( "ASYNCHRONOUS READS ARE NOT SUPPORTED.\n" ); } /*---------------------------------------------------------------------------------*/ void BeginWritingFile ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { return; } /*---------------------------------------------------------------------------------*/ void ContinueWritingFile ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { return; } /*---------------------------------------------------------------------------------*/ void EndWritingFile ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { return; } /*---------------------------------------------------------------------------------*/ void SfsWriteFile ( CCB_Header * h ) /*---------------------------------------------------------------------------------*/ { CCB_WriteFile * c; FCB_File * f; FCB_Frame * r; c = ( CCB_WriteFile * ) h; if ( f = FindFileControlBlock ( c -> FileExtrinsicKey ) ) { FCB_FileTrackPointer = f; if ( f -> FileStatus & FileOpen ) { if ( CreateFlag ) r = CreateControlPointer; else r = FrameControlBlocks + FrameIndex; if ( r -> FrameStatus & FlagFrameValid ) { if ( c -> RecordSize ) r -> BytesToBeWritten = c -> RecordSize; else r -> BytesToBeWritten = f -> RecordSize; r -> FrameUser = f -> FileExtrinsicKey; if ( c -> RequestModifiers & AsynchronousFlag ) SfsWriteFileAsynchronously ( f, c, r ); else { if( ! WriteFile ( f -> FileHandle, r -> FramePointer, r -> BytesToBeWritten, &( r -> BytesWritten ), NULL ) ) { ReturnCode = GetLastError(); NotifyAndActAsProper ( ErrorWriteFile ); } if ( r -> BytesWritten < r -> BytesToBeWritten ) NotifyAndActAsProper ( ErrorRecordWrittenPartly ); } } else NotifyAndActAsProper ( ErrorImproperWriteAttempt ); } else NotifyAndActAsProper ( ErrorFileNotOpen ); } else NotifyAndActAsProper ( ErrorFCB_FileNotFound ); return; } /*---------------------------------------------------------------------------------*/ void SfsWriteFileAsynchronously ( FCB_File * f, CCB_WriteFile * c, FCB_Frame * r ) /*---------------------------------------------------------------------------------*/ { #if 0 SCB_Semaphore * s; if ( s = FindSemaphoreControlBlock ( c -> SemaphoreExtrinsicKey ) ) { ReturnCode = DosSemSet ( &( s -> Lights ) ); if ( ReturnCode ) NotifyAndActAsProper ( ErrorDosSemSet ); else { ReturnCode = DosWriteAsync ( f -> FileHandle, &( s -> Lights ), &( r -> DelayedWriteErrors ), r -> FramePointer, r -> BytesToBeWritten, &( r -> BytesWritten ) ); // Mark file status ... as being read or written // asynchronously and verify errors on operations to follow } } else NotifyAndActAsProper ( ErrorSemaphoreNotFound ); return; #endif printf( "ASYNCHRONOUS WRITES ARE NOT SUPPORTED.\n" ); } /*---------------------------------------------------------------------------------*/ void NotifyAndActAsProper ( WORD ErrorDescriptor ) /*---------------------------------------------------------------------------------*/ { FCB_File * f; f = FCB_FileTrackPointer; switch ( ErrorDescriptor ) { // remember lights ... later case ErrorDeleteFile: printf ( "\r\n.. Error executing DeleteFile on file" ); printf ( " %s", f -> FileNamePointer ); printf ( "\r\n.. DeleteFile Return Code is %u.\r\n", ReturnCode ); break; case ErrorReadFile: printf ( "\r\n.. Error reading file %s", f -> FileNamePointer ); printf ( "\r\n.. ReadFile Return Code is %u.\r\n", ReturnCode ); break; case ErrorWriteFile: printf ( "\r\n.. Error writing file %s", f -> FileNamePointer ); printf ( "\r\n.. WriteFile Return Code is %u.\r\n", ReturnCode ); break; case ErrorEndOfFile: printf ( "\r\n.. End of file %s", f -> FileNamePointer ); printf ( " has been reached.\r\n" ); break; case ErrorFileAlreadyDeleted: printf ( "\r\n.. Error deleting file %s", f -> FileNamePointer ); printf ( "\r\n.. File already deleted.\r\n" ); break; default: printf ( "\r\n.. Error on file %s", f -> FileNamePointer ); printf ( "\r\n.. Error Descriptor is %u", ErrorDescriptor ); break; } if ( ErrorDescriptor > DosErrorLowerLimit ) if ( ReturnCode == ERROR_VC_DISCONNECTED ) DebugBreak(); return; }