#include "brian.h" // // Local constants and procedure declarations. // #define CHAR_POSITION 51 #define COPY_BUFF_SRC_DEFAULT 0 #define COPY_BUFF_DST_DEFAULT 0 #define COPY_BUFF_SRC_OFF_DEFAULT 0 #define COPY_BUFF_DST_OFF_DEFAULT 0 #define COPY_BUFF_LENGTH_DEFAULT 0 #define DISPLAY_INDEX_DEFAULT 0 #define DISPLAY_OFFSET_DEFAULT 0 #define DISPLAY_LENGTH_DEFAULT 0x100 #define ALLOC_ZERO_BITS_DEFAULT 0 #define ALLOC_REGION_SIZE_DEFAULT 0x100 #define ALLOC_VERBOSE_DEFAULT TRUE #define ALLOC_DISPLAY_PARMS_DEFAULT FALSE ULONG PrintDwords ( IN PULONG BufferAddress, IN ULONG CountWords ); ULONG PrintWords ( IN PUSHORT BufferAddress, IN ULONG CountWords ); ULONG PrintBytes ( IN PCHAR BufferAddress, IN ULONG CountChars ); VOID PrintChars( IN PCHAR BufferAddress, IN ULONG CountChars ); VOID ClearBuffer( IN ULONG Index ); VOID DisplayBuffer ( IN ULONG Index, IN ULONG StartOffset, IN ULONG DisplayLength, IN ULONG DisplaySize ); VOID CopyBuffer( IN ULONG SrcIndex, IN ULONG DstIndex, IN ULONG Length, IN ULONG SrcOffset, IN ULONG DstOffset ); VOID FillBuffer ( IN ULONG Index, IN PVOID Structure, IN ULONG Length ); NTSTATUS FullAllocMem( IN ULONG ZeroBits, IN OUT PSIZE_T RegionSize, OUT PULONG BufferIndex, IN BOOLEAN VerboseResults, IN BOOLEAN DisplayParms ); NTSTATUS FullDeallocMem( IN ULONG Index, IN BOOLEAN VerboseResults, IN BOOLEAN DisplayParms ); VOID InitBuffers ( ) { NtCreateEvent( &BufferEvent, SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, NULL, SynchronizationEvent, TRUE ); RtlZeroMemory( Buffers, sizeof( Buffers )); } VOID UninitBuffers ( ) { USHORT Index; // // Deallocate any buffers remaining. // for (Index = 0; Index < MAX_BUFFERS; Index++) { DeallocateBuffer( Index ); } } NTSTATUS AllocateBuffer ( IN ULONG ZeroBits, IN OUT PSIZE_T RegionSize, OUT PULONG BufferIndex ) { NTSTATUS Status; PVOID BufferAddress; ULONG Index; BufferAddress = NULL; // // Wait for the buffer event. // if ((Status = NtWaitForSingleObject( BufferEvent, FALSE, NULL )) != STATUS_SUCCESS) { return Status; } try { // // Find an available index. Return STATUS_INSUFFICIENT_RESOURCES // if not found. // for (Index = 0; Index < MAX_BUFFERS; Index++) { if (!Buffers[Index].Used) { break; } } if (Index >= MAX_BUFFERS) { Status = STATUS_INSUFFICIENT_RESOURCES; // // Otherwise allocate the virtual memory. If no error occurs, then // store the data in the buffer array. // } else if ((Status = NtAllocateVirtualMemory( NtCurrentProcess(), &BufferAddress, ZeroBits, RegionSize, MEM_COMMIT, PAGE_READWRITE )) == STATUS_SUCCESS) { Buffers[Index].Buffer = BufferAddress; Buffers[Index].Length = (ULONG) *RegionSize; Buffers[Index].Used = TRUE; } // // Set the buffer event back to the signalled state. // *BufferIndex = Index; try_return( NOTHING ); try_exit: NOTHING; } finally { if (AbnormalTermination()) { printf( "\nAllocate Buffer: Abnormal termination\n" ); } NtSetEvent( BufferEvent, NULL ); } return Status; } NTSTATUS DeallocateBuffer ( IN ULONG Index ) { NTSTATUS Status; // // Wait for the buffer event. // if ((Status = NtWaitForSingleObject( BufferEvent, FALSE, NULL )) != STATUS_SUCCESS) { return Status; } try { if (Index <= MAX_BUFFERS && Buffers[Index].Used) { SIZE_T RegionSize = Buffers[Index].Length; Status = NtFreeVirtualMemory( NtCurrentProcess(), (PVOID *) &Buffers[Index].Buffer, &RegionSize, MEM_RELEASE ); Buffers[Index].Used = FALSE; } try_return( NOTHING ); try_exit: NOTHING; } finally { if (AbnormalTermination()) { printf( "\nDeallocate Buffer: Abnormal termination\n" ); } NtSetEvent( BufferEvent, NULL ); } return Status; } BOOLEAN BufferInfo ( IN ULONG Index, OUT PVOID *BufferAddress, OUT PULONG RegionSize ) { if (Index >= MAX_BUFFERS || !Buffers[Index].Used) { return FALSE; } *BufferAddress = Buffers[Index].Buffer; *RegionSize = Buffers[Index].Length; return TRUE; } VOID InputClearBuffer( IN PCHAR ParamBuffer ) { ULONG Index; BOOLEAN LastInput; BOOLEAN ParmSpecified; Index = 0; ParmSpecified = FALSE; LastInput = TRUE; // // While there is more input, analyze the parameter and update the // query flags. // while (TRUE) { ULONG DummyCount; // // Swallow leading white spaces. // ParamBuffer = SwallowWhite( ParamBuffer, &DummyCount ); if (*ParamBuffer) { // // If the next parameter is legal then check the paramter value. // Update the parameter value. // if ((*ParamBuffer == '-' || *ParamBuffer == '/') && (ParamBuffer++, *ParamBuffer != '\0')) { // // Switch on the next character. // switch( *ParamBuffer ) { // // Check buffer index. // case 'b' : case 'B' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; Index = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); ParmSpecified = TRUE; break; default : // // Swallow to the next white space and continue the // loop. // ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); } } // // Else the text is invalid, skip the entire block. // // // // Else if there is no input then exit. // } else if ( LastInput ) { break; // // Else try to read another line for open parameters. // } else { } } // // If no parameters were received then display the syntax message. // if (!ParmSpecified) { printf( "\n Usage: clb -b \n" ); printf( "\n -b Buffer index" ); printf( "\n\n" ); // // Else call our copy buffer routine. // } else { ClearBuffer( Index ); } return; } VOID ClearBuffer( IN ULONG Index ) { // // Check for an invalid index. // if (!Buffers[Index].Used) { printf( "\nClearBuffer: Invalid buffer" ); } else { RtlZeroMemory( Buffers[Index].Buffer, Buffers[Index].Length ); } return; } VOID DisplayBuffer ( IN ULONG Index, IN ULONG StartOffset, IN ULONG DisplayLength, IN ULONG DisplaySize ) { // // If the index is unused, display message but take no action. // if (!Buffers[Index].Used) { printf( "\nDisplayBuffer: Index refers to invalid buffer" ); // // Else if the start offset is invalid, then display error // message. // } else if (StartOffset >= Buffers[Index].Length) { printf( "\nDisplayBuffer: Start offset is invalid" ); // // Else compute the legal display length and output to the screen. // } else { ULONG LegalLength; ULONG FullLines; PCHAR BufferAddress; ULONG SpacesFilled; // // The legal display length is the minimum of the remaining // bytes in the buffer and the desired display length. // LegalLength = Buffers[Index].Length - StartOffset; LegalLength = min( LegalLength, DisplayLength ); BufferAddress = Buffers[Index].Buffer; // // Display the display information. // printf( "\nIndex -> %u, Buffer Base -> %p, ", Index, BufferAddress ); printf( "Buffer Offset -> %08lx, Bytes -> %u", StartOffset, LegalLength ); printf( "\n" ); BufferAddress += StartOffset; // // Compute the number and display the full lines. // FullLines = LegalLength / 16; while (FullLines--) { if (DisplaySize == sizeof( UCHAR )) { PrintBytes( BufferAddress, 16 ); } else if (DisplaySize == sizeof( WCHAR )) { PrintWords( (PVOID) BufferAddress, 8 ); } else { PrintDwords( (PVOID) BufferAddress, 4 ); } printf( " " ); PrintChars( BufferAddress, 16 ); BufferAddress += 16; } // // Display the remaining bytes. // if (DisplaySize == sizeof( UCHAR )) { SpacesFilled = PrintBytes( BufferAddress, LegalLength % 16 ); } else if (DisplaySize == sizeof( WCHAR )) { SpacesFilled = PrintWords( (PVOID) BufferAddress, LegalLength % 8 ); } else { SpacesFilled = PrintDwords( (PVOID) BufferAddress, LegalLength % 4 ); } if (SpacesFilled) { SpacesFilled = CHAR_POSITION - SpacesFilled; while ( SpacesFilled-- ) { printf( " " ); } } PrintChars( BufferAddress, LegalLength % 16 ); printf( "\n\n" ); } return; } ULONG PrintBytes ( IN PCHAR BufferAddress, IN ULONG CountChars ) { ULONG CountSpaces; ULONG RemainingChars; // // Initialize the local variables. // CountSpaces = CountChars * 3 + (CountChars ? 1 : 0); RemainingChars = CountChars - min( CountChars, 8 ); CountChars = min( CountChars, 8 ); // // Print the first 8 bytes (if possible). // if (CountChars) { printf( "\n" ); while (CountChars--) { printf( "%02x ", *((PUCHAR) BufferAddress++) ); } // // If more bytes, then add a blank space and print the rest of the // bytes. // printf( " " ); while (RemainingChars--) { printf( "%02x ", *((PUCHAR) BufferAddress++) ); } } // // Return the number of spaces used. // return CountSpaces; } ULONG PrintWords ( IN PWCHAR BufferAddress, IN ULONG CountWords ) { ULONG CountSpaces; ULONG RemainingWords; // // Initialize the local variables. // CountSpaces = CountWords * 5 + (CountWords ? 1 : 0); RemainingWords = CountWords - min( CountWords, 4 ); CountWords = min( CountWords, 4 ); // // Print the first 4 words (if possible). // if (CountWords) { printf( "\n" ); while (CountWords--) { printf( "%04x ", *((PWCHAR) BufferAddress++) ); } // // If more bytes, then add a blank space and print the rest of the // bytes. // printf( " " ); while (RemainingWords--) { printf( "%04x ", *((PWCHAR) BufferAddress++) ); } } // // Return the number of spaces used. // return CountSpaces; } ULONG PrintDwords ( IN PULONG BufferAddress, IN ULONG CountDwords ) { ULONG CountSpaces; ULONG RemainingDwords; // // Initialize the local variables. // CountSpaces = CountDwords * 7 + (CountDwords ? 1 : 0); RemainingDwords = CountDwords - min( CountDwords, 8 ); CountDwords = min( CountDwords, 8 ); // // Print the first 2 Dwords (if possible). // if (CountDwords) { printf( "\n" ); while (CountDwords--) { printf( "%08x ", *((PULONG) BufferAddress++) ); } // // If more bytes, then add a blank space and print the rest of the // bytes. // printf( " " ); while (RemainingDwords--) { printf( "%08x ", *((PULONG) BufferAddress++) ); } } // // Return the number of spaces used. // return CountSpaces; } VOID PrintChars( IN PCHAR BufferAddress, IN ULONG CountChars ) { ULONG RemainingChars; // // Initialize the local variables. // RemainingChars = CountChars - min( CountChars, 8 ); CountChars = min( CountChars, 8 ); // // Print the first 8 bytes (if possible). // if (CountChars) { while (CountChars--) { if (*BufferAddress > 31 && *BufferAddress != 127) { printf( "%c", *BufferAddress ); } else { printf( "." ); } BufferAddress++; } // // If more bytes, then add a blank space and print the rest of the // bytes. // printf( " " ); while (RemainingChars--) { if (*BufferAddress > 31 && *BufferAddress != 127) { printf( "%c", *BufferAddress ); } else { printf( "." ); } BufferAddress++; } } return; } VOID InputDisplayBuffer( IN PCHAR ParamBuffer, IN ULONG DisplaySize ) { ULONG DisplayLength; ULONG DisplayOffset; ULONG BufferIndex; BOOLEAN ParamReceived; BOOLEAN LastInput; // // Set the defaults. // ParamReceived = FALSE; LastInput = TRUE; BufferIndex = DISPLAY_INDEX_DEFAULT; BufferIndex = DISPLAY_INDEX_DEFAULT; DisplayOffset = DISPLAY_OFFSET_DEFAULT; DisplayLength = DISPLAY_LENGTH_DEFAULT; // // While there is more input, analyze the parameter and update the // query flags. // while (TRUE) { ULONG DummyCount; // // Swallow leading white spaces. // ParamBuffer = SwallowWhite( ParamBuffer, &DummyCount ); if (*ParamBuffer) { // // If the next parameter is legal then check the paramter value. // Update the parameter value. // if ((*ParamBuffer == '-' || *ParamBuffer == '/') && (ParamBuffer++, *ParamBuffer != '\0')) { // // Switch on the next character. // switch( *ParamBuffer ) { // // Check the buffer index. // case 'b' : case 'B' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; BufferIndex = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); ParamReceived = TRUE; break; // // Check the display length. // case 'l' : case 'L' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; DisplayLength = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); break; // // Check the display offset. // case 'o' : case 'O' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; DisplayOffset = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); break; default : // // Swallow to the next white space and continue the // loop. // ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); } } // // Else the text is invalid, skip the entire block. // // // // Else if there is no input then exit. // } else if ( LastInput ) { break; // // Else try to read another line for open parameters. // } else { } } // // If no parameters were received then display the syntax message. // if (!ParamReceived) { printf( "\n Usage: db [options]* -i [options]*\n" ); printf( "\n Options:" ); printf( "\n -b Buffer index" ); printf( "\n -l Display length" ); printf( "\n -o Display starting offset" ); printf( "\n\n" ); // // Else call our display buffer routine. // } else { DisplayBuffer( BufferIndex, DisplayOffset, DisplayLength, DisplaySize ); } } VOID InputCopyBuffer( IN PCHAR ParamBuffer ) { ULONG SrcIndex; ULONG DstIndex; ULONG Length; ULONG SrcOffset; ULONG DstOffset; BOOLEAN DstSpecified; BOOLEAN SrcSpecified; BOOLEAN LastInput; // // Set the defaults. // SrcIndex = COPY_BUFF_SRC_DEFAULT; DstIndex = COPY_BUFF_DST_DEFAULT; Length = COPY_BUFF_SRC_OFF_DEFAULT; SrcOffset = COPY_BUFF_DST_OFF_DEFAULT; DstOffset = COPY_BUFF_LENGTH_DEFAULT; DstSpecified = FALSE; SrcSpecified = FALSE; LastInput = TRUE; // // While there is more input, analyze the parameter and update the // query flags. // while(TRUE) { ULONG DummyCount; // // Swallow leading white spaces. // ParamBuffer = SwallowWhite( ParamBuffer, &DummyCount ); if ( *ParamBuffer ) { // // If the next parameter is legal then check the paramter value. // Update the parameter value. // if ((*ParamBuffer == '-' || *ParamBuffer == '/') && (ParamBuffer++, *ParamBuffer != '\0')) { // // Switch on the next character. // switch( *ParamBuffer ) { // // Check the destination index. // case 'd' : case 'D' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; DstIndex = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); DstSpecified = TRUE; break; // // Check source starting offset. // case 'f' : case 'F' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; SrcOffset = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); break; // // Check copy length. // case 'l' : case 'L' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; Length = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); break; // // Check the source index. // case 's' : case 'S' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; SrcIndex = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); SrcSpecified = TRUE; break; // // Check destination offset. // case 't' : case 'T' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; DstOffset = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); break; default : // // Swallow to the next white space and continue the // loop. // ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); } } // // Else the text is invalid, skip the entire block. // // // // Else if there is no input then exit. // } else if ( LastInput ) { break; // // Else try to read another line for open parameters. // } else { } } // // If no parameters were received then display the syntax message. // if (!SrcSpecified || !DstSpecified) { printf( "\n Usage: cb [options]* -d [options]* -s [options]*\n" ); printf( "\n Options:" ); printf( "\n -d Destination index" ); printf( "\n -f Source offset" ); printf( "\n -l Transfer length" ); printf( "\n -s Source index" ); printf( "\n -t Destination offset" ); printf( "\n\n" ); // // Else call our copy buffer routine. // } else { CopyBuffer( SrcIndex, DstIndex, Length, SrcOffset, DstOffset ); } } VOID CopyBuffer( IN ULONG SrcIndex, IN ULONG DstIndex, IN ULONG Length, IN ULONG SrcOffset, IN ULONG DstOffset ) { // // Check for an invalid source index. // if (!Buffers[SrcIndex].Used) { printf( "\nCopyBuffer: Invalid source buffer" ); // // Otherwise check for an invalid destination index. // } else if (!Buffers[DstIndex].Used) { printf( "\nCopyBuffer: Invalid destination buffer" ); // // Test for an invalid source offset. // } else if (SrcOffset >= Buffers[SrcIndex].Length) { printf( "\nCopyBuffer: Source offset is invalid" ); // // Test for an invalid destination offset. // } else if (DstOffset >= Buffers[DstIndex].Length) { printf( "\nCopyBuffer: Destination offset is invalid" ); // // This statement handles the case of two correct indexes and offsets. // } else { ULONG LegalLength; PCHAR SrcAddress; PCHAR DstAddress; // // Adjust the length according to the source buffer size. // LegalLength = Buffers[SrcIndex].Length - SrcOffset; LegalLength = min( LegalLength, Length ); Length = Buffers[DstIndex].Length - DstOffset; LegalLength = min( LegalLength, Length ); SrcAddress = Buffers[SrcIndex].Buffer + SrcOffset; DstAddress = Buffers[DstIndex].Buffer + DstOffset; // // Display the header information. // printf( "\nSource index -> %2u, Source base -> %p, Source offset -> %08lx, ", SrcIndex, Buffers[SrcIndex].Buffer, SrcOffset ); printf( "\n Dest index -> %2u, Dest base -> %p, Dest offset -> %08lx, ", DstIndex, Buffers[DstIndex].Buffer, DstOffset ); printf( "\nLength -> %u", Length ); // // Perform the transfer for non-zero lengths only. // if (Length) { RtlMoveMemory( DstAddress, SrcAddress, Length ); } } return; } VOID InputAllocMem( IN PCHAR ParamBuffer ) { ULONG ZeroBits; SIZE_T RegionSize; ULONG BufferIndex; BOOLEAN VerboseResults; BOOLEAN DisplayParms; BOOLEAN ParamReceived; BOOLEAN LastInput; // // Set the defaults. // ZeroBits = ALLOC_ZERO_BITS_DEFAULT; RegionSize = ALLOC_REGION_SIZE_DEFAULT; VerboseResults = ALLOC_VERBOSE_DEFAULT; DisplayParms = ALLOC_DISPLAY_PARMS_DEFAULT; ParamReceived = FALSE; LastInput = TRUE; // // While there is more input, analyze the parameter and update the // query flags. // while (TRUE) { ULONG DummyCount; // // Swallow leading white spaces. // ParamBuffer = SwallowWhite( ParamBuffer, &DummyCount ); if ( *ParamBuffer ) { // // If the next parameter is legal then check the paramter value. // Update the parameter value. // if ((*ParamBuffer == '-' || *ParamBuffer == '/') && (ParamBuffer++, *ParamBuffer != '\0')) { // // Switch on the next character. // switch (*ParamBuffer) { // // Update zero bits. // case 'b' : case 'B' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; ZeroBits = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); ParamReceived = TRUE; break; // // Update the region size. // case 'r' : case 'R' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; RegionSize = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); ParamReceived = TRUE; break; case 'v' : case 'V' : // // Legal values for params are T/t or F/f. // ParamBuffer++; if (*ParamBuffer == 'T' || *ParamBuffer == 't') { VerboseResults = TRUE; ParamBuffer++; } else if (*ParamBuffer == 'F' || *ParamBuffer == 'f') { VerboseResults = FALSE; ParamBuffer++; } ParamReceived = TRUE; break; case 'y' : case 'Y' : // // Set the display parms flag and jump over this // character. // DisplayParms = TRUE; ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); ParamReceived = TRUE; break; default : // // Swallow to the next white space and continue the // loop. // ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); } } // // Else the text is invalid, skip the entire block. // // // // Else if there is no input then exit. // } else if ( LastInput ) { break; // // Else try to read another line for open parameters. // } else { } } // // If no parameters were received then display the syntax message. // if (!ParamReceived) { printf( "\n Usage: am [options]*\n" ); printf( "\n Options:" ); printf( "\n -b Zero bits" ); printf( "\n -r Region size" ); printf( "\n -v[t|f] Verbose results" ); printf( "\n -y Display parameters to query" ); printf( "\n\n" ); // // Else call our allocation routine. // } else { FullAllocMem( ZeroBits, &RegionSize, &BufferIndex, VerboseResults, DisplayParms ); } } NTSTATUS FullAllocMem( IN ULONG ZeroBits, IN OUT PSIZE_T RegionSize, OUT PULONG BufferIndex, IN BOOLEAN VerboseResults, IN BOOLEAN DisplayParms ) { NTSTATUS Status; Status = STATUS_SUCCESS; if (DisplayParms) { printf( "\nAlloc Memory Parameters" ); printf( "\n Zero Bits -> %ld", ZeroBits ); printf( "\n Region Size -> %ld", *RegionSize ); printf( "\n\n" ); } // // Try to get the next buffer. // Status = AllocateBuffer( ZeroBits, RegionSize, BufferIndex ); // // Print the results if verbose. // if (VerboseResults) { printf( "\nAllocMem: Status -> %08lx", Status ); printf( "\n RegionSize -> %08lx", *RegionSize ); printf( "\n BufferIndex -> %ld", *BufferIndex ); printf( "\n\n" ); } return Status; } VOID InputDeallocMem( IN PCHAR ParamBuffer ) { ULONG BufferIndex; BOOLEAN ParamReceived; BOOLEAN LastInput; BOOLEAN VerboseResults; BOOLEAN DisplayParms; // // Set the defaults. // VerboseResults = ALLOC_VERBOSE_DEFAULT; DisplayParms = ALLOC_DISPLAY_PARMS_DEFAULT; ParamReceived = FALSE; LastInput = TRUE; // // While there is more input, analyze the parameter and update the // query flags. // while (TRUE) { ULONG DummyCount; // // Swallow leading white spaces. // ParamBuffer = SwallowWhite( ParamBuffer, &DummyCount ); if (*ParamBuffer) { // // If the next parameter is legal then check the paramter value. // Update the parameter value. // if ((*ParamBuffer == '-' || *ParamBuffer == '/') && (ParamBuffer++, *ParamBuffer != '\0')) { // // Switch on the next character. // switch (*ParamBuffer) { // // Find the Index value. // case 'b' : case 'B' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; BufferIndex = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); ParamReceived = TRUE; break; case 'v' : case 'V' : // // Legal values for params are T/t or F/f. // ParamBuffer++; if (*ParamBuffer == 'T' || *ParamBuffer == 't') { VerboseResults = TRUE; ParamBuffer++; } else if (*ParamBuffer == 'F' || *ParamBuffer == 'f') { VerboseResults = FALSE; ParamBuffer++; } ParamReceived = TRUE; break; case 'y' : case 'Y' : // // Set the display parms flag and jump over this // character. // DisplayParms = TRUE; ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); ParamReceived = TRUE; break; default : // // Swallow to the next white space and continue the // loop. // ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); } } // // Else the text is invalid, skip the entire block. // // // // Else if there is no input then exit. // } else if ( LastInput ) { break; // // Else try to read another line for open parameters. // } else { } } // // If no parameters were received then display the syntax message. // if (!ParamReceived) { printf( "\n Usage: dm [options]*\n" ); printf( "\n Options:" ); printf( "\n -b Buffer Index number" ); printf( "\n -v[t|f] Verbose results" ); printf( "\n -y Display parameters to query" ); printf( "\n\n" ); // // Else call our allocation routine. // } else { FullDeallocMem( BufferIndex, VerboseResults, DisplayParms ); } } NTSTATUS FullDeallocMem( IN ULONG Index, IN BOOLEAN VerboseResults, IN BOOLEAN DisplayParms ) { NTSTATUS Status; Status = STATUS_SUCCESS; if (DisplayParms) { printf( "\nDealloc Memory Parameters" ); printf( "\n Buffer Index -> %ld", Index ); printf( "\n\n" ); } // // Try to free the desired buffer. // Status = DeallocateBuffer( Index ); // // Print the results if verbose. // if (VerboseResults) { printf( "\nDeallocMem: Status -> %08lx", Status ); printf( "\n\n" ); } return Status; } VOID InputFillBuffer( IN PCHAR ParamBuffer ) { ULONG BufferIndex; BOOLEAN ParamReceived; BOOLEAN LastInput; BOOLEAN HaveStructure = FALSE; MFT_ENUM_DATA EnumUsnData; READ_USN_JOURNAL_DATA ReadUsnJournal; CREATE_USN_JOURNAL_DATA CreateUsnJournal; LARGE_INTEGER LargeIntegerInput; FILE_ALLOCATED_RANGE_BUFFER AllocatedRangeBuffer; PVOID StructurePointer; ULONG StructureSize; ParamReceived = FALSE; LastInput = TRUE; BufferIndex = DISPLAY_INDEX_DEFAULT; RtlZeroMemory( &EnumUsnData, sizeof( MFT_ENUM_DATA )); RtlZeroMemory( &ReadUsnJournal, sizeof( READ_USN_JOURNAL_DATA )); RtlZeroMemory( &CreateUsnJournal, sizeof( CREATE_USN_JOURNAL_DATA )); RtlZeroMemory( &LargeIntegerInput, sizeof( LARGE_INTEGER )); RtlZeroMemory( &AllocatedRangeBuffer, sizeof( FILE_ALLOCATED_RANGE_BUFFER )); // // While there is more input, analyze the parameter and update the // query flags. // while (TRUE) { ULONG DummyCount; // // Swallow leading white spaces. // ParamBuffer = SwallowWhite( ParamBuffer, &DummyCount ); if (*ParamBuffer) { // // If the next parameter is legal then check the paramter value. // Update the parameter value. // if ((*ParamBuffer == '-' || *ParamBuffer == '/') && (ParamBuffer++, *ParamBuffer != '\0')) { // // Switch on the next character. // switch( *ParamBuffer ) { BOOLEAN SwitchBool; // // Check the buffer index. // case 'b' : case 'B' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; BufferIndex = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); ParamReceived = TRUE; break; // // Check the structure to fill. // case 's' : case 'S' : SwitchBool = TRUE; ParamBuffer++; if (*ParamBuffer && *ParamBuffer != ' ' && *ParamBuffer != '\t') { // // Perform switch on character. // switch (*ParamBuffer) { case 'a' : case 'A' : case 'b' : case 'B' : HaveStructure = TRUE; StructurePointer = &LargeIntegerInput; StructureSize = sizeof( LARGE_INTEGER ); ParamBuffer++; if (*ParamBuffer && *ParamBuffer != ' ' && *ParamBuffer != '\t') { switch (*ParamBuffer) { case 'a' : case 'A' : ParamBuffer++; LargeIntegerInput.QuadPart = AsciiToLargeInteger( ParamBuffer ); break; default : NOTHING; } } break; case 'c' : case 'C' : HaveStructure = TRUE; StructurePointer = &AllocatedRangeBuffer; StructureSize = sizeof( FILE_ALLOCATED_RANGE_BUFFER ); ParamBuffer++; if (*ParamBuffer && *ParamBuffer != ' ' && *ParamBuffer != '\t') { switch (*ParamBuffer) { case 'a' : case 'A' : ParamBuffer++; AllocatedRangeBuffer.FileOffset.QuadPart = AsciiToLargeInteger( ParamBuffer ); break; case 'b' : case 'B' : ParamBuffer++; AllocatedRangeBuffer.Length.QuadPart = AsciiToLargeInteger( ParamBuffer ); break; default : NOTHING; } } break; default : NOTHING; } } break; default : NOTHING; } ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); } // // Else the text is invalid, skip the entire block. // // // // Else if there is no input then exit. // } else if ( LastInput ) { break; // // Else try to read another line for open parameters. // } else { } } // // If no parameters were received then display the syntax message. // if (!ParamReceived) { printf( "\n Usage: fb -b -s[options]* \n" ); printf( "\n -sa[options] Get Volume Bitmap" ); printf( "\n a Starting lcn" ); printf( "\n -sb[options] Query Retrieval Pointers" ); printf( "\n a Starting vcn" ); printf( "\n -sc[options] Query Allocated Ranges" ); printf( "\n a FileOffset" ); printf( "\n b Length" ); printf( "\n\n" ); // // Else fill the buffer. // } else if (HaveStructure) { FillBuffer( BufferIndex, StructurePointer, StructureSize ); } } VOID InputFillBufferUsn( IN PCHAR ParamBuffer ) { ULONG BufferIndex; BOOLEAN ParamReceived; BOOLEAN LastInput; BOOLEAN HaveStructure = FALSE; MFT_ENUM_DATA EnumUsnData; READ_USN_JOURNAL_DATA ReadUsnJournal; CREATE_USN_JOURNAL_DATA CreateUsnJournal; DELETE_USN_JOURNAL_DATA DeleteUsnJournal; PVOID StructurePointer; ULONG StructureSize; ParamReceived = FALSE; LastInput = TRUE; BufferIndex = DISPLAY_INDEX_DEFAULT; RtlZeroMemory( &EnumUsnData, sizeof( MFT_ENUM_DATA )); RtlZeroMemory( &ReadUsnJournal, sizeof( READ_USN_JOURNAL_DATA )); RtlZeroMemory( &CreateUsnJournal, sizeof( CREATE_USN_JOURNAL_DATA )); RtlZeroMemory( &DeleteUsnJournal, sizeof( DELETE_USN_JOURNAL_DATA )); // // While there is more input, analyze the parameter and update the // query flags. // while (TRUE) { ULONG DummyCount; // // Swallow leading white spaces. // ParamBuffer = SwallowWhite( ParamBuffer, &DummyCount ); if (*ParamBuffer) { // // If the next parameter is legal then check the paramter value. // Update the parameter value. // if ((*ParamBuffer == '-' || *ParamBuffer == '/') && (ParamBuffer++, *ParamBuffer != '\0')) { // // Switch on the next character. // switch( *ParamBuffer ) { BOOLEAN SwitchBool; // // Check the buffer index. // case 'b' : case 'B' : // // Move to the next character, as long as there // are no white spaces continue analyzing letters. // On the first bad letter, skip to the next // parameter. // ParamBuffer++; BufferIndex = AsciiToInteger( ParamBuffer ); ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); ParamReceived = TRUE; break; // // Check the structure to fill. // case 's' : case 'S' : SwitchBool = TRUE; ParamBuffer++; if (*ParamBuffer && *ParamBuffer != ' ' && *ParamBuffer != '\t') { // // Perform switch on character. // switch (*ParamBuffer) { // // ENUM_USN_DATA // case 'a' : case 'A' : HaveStructure = TRUE; StructurePointer = &EnumUsnData; StructureSize = sizeof( MFT_ENUM_DATA ); ParamBuffer++; if (*ParamBuffer && *ParamBuffer != ' ' && *ParamBuffer != '\t') { switch (*ParamBuffer) { case 'a' : case 'A' : ParamBuffer++; EnumUsnData.LowUsn = AsciiToLargeInteger( ParamBuffer ); break; case 'b' : case 'B' : ParamBuffer++; EnumUsnData.HighUsn = AsciiToLargeInteger( ParamBuffer ); break; case 'c' : case 'C' : ParamBuffer++; EnumUsnData.StartFileReferenceNumber = AsciiToLargeInteger( ParamBuffer ); break; default : NOTHING; } } break; case 'b' : case 'B' : HaveStructure = TRUE; StructurePointer = &ReadUsnJournal; StructureSize = sizeof( READ_USN_JOURNAL_DATA ); ParamBuffer++; if (*ParamBuffer && *ParamBuffer != ' ' && *ParamBuffer != '\t') { switch (*ParamBuffer) { case 'a' : case 'A' : ParamBuffer++; ReadUsnJournal.StartUsn = AsciiToLargeInteger( ParamBuffer ); break; case 'b' : case 'B' : ParamBuffer++; ReadUsnJournal.ReasonMask = AsciiToInteger( ParamBuffer ); break; case 'c' : case 'C' : ParamBuffer++; ReadUsnJournal.ReturnOnlyOnClose = AsciiToInteger( ParamBuffer ); break; case 'd' : case 'D' : ParamBuffer++; ReadUsnJournal.Timeout = AsciiToLargeInteger( ParamBuffer ); break; case 'e' : case 'E' : ParamBuffer++; ReadUsnJournal.BytesToWaitFor = AsciiToLargeInteger( ParamBuffer ); break; case 'f' : case 'F' : ParamBuffer++; ReadUsnJournal.UsnJournalID = AsciiToLargeInteger( ParamBuffer ); break; default : NOTHING; } } break; case 'c' : case 'C' : HaveStructure = TRUE; StructurePointer = &CreateUsnJournal; StructureSize = sizeof( CREATE_USN_JOURNAL_DATA ); ParamBuffer++; if (*ParamBuffer && *ParamBuffer != ' ' && *ParamBuffer != '\t') { switch (*ParamBuffer) { case 'a' : case 'A' : ParamBuffer++; CreateUsnJournal.MaximumSize = AsciiToLargeInteger( ParamBuffer ); break; case 'b' : case 'B' : ParamBuffer++; CreateUsnJournal.AllocationDelta = AsciiToLargeInteger( ParamBuffer ); break; default : NOTHING; } } break; case 'd' : case 'D' : HaveStructure = TRUE; StructurePointer = &DeleteUsnJournal; StructureSize = sizeof( DELETE_USN_JOURNAL_DATA ); ParamBuffer++; if (*ParamBuffer && *ParamBuffer != ' ' && *ParamBuffer != '\t') { switch (*ParamBuffer) { case 'a' : case 'A' : ParamBuffer++; DeleteUsnJournal.UsnJournalID = AsciiToLargeInteger( ParamBuffer ); break; default : NOTHING; } } break; default : NOTHING; } } break; default : NOTHING; } ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount ); } // // Else the text is invalid, skip the entire block. // // // // Else if there is no input then exit. // } else if ( LastInput ) { break; // // Else try to read another line for open parameters. // } else { } } // // If no parameters were received then display the syntax message. // if (!ParamReceived) { printf( "\n Usage: fbusn -b -s[options]* \n" ); printf( "\n -sa[options] Enum Usn Data" ); printf( "\n a Low usn" ); printf( "\n b High usn" ); printf( "\n c File ref" ); printf( "\n -sb[options] Read Usn Data" ); printf( "\n a Start usn" ); printf( "\n b Reason mask" ); printf( "\n c Return only on close" ); printf( "\n d Timeout" ); printf( "\n e Bytes to wait for" ); printf( "\n f Journal id" ); printf( "\n -sc[options] Create Usn Data" ); printf( "\n a Maximum size" ); printf( "\n b Allocation delta" ); printf( "\n -sd[options] Delete Usn Journal Data" ); printf( "\n a Usn journal id" ); printf( "\n\n" ); // // Else fill the buffer. // } else if (HaveStructure) { FillBuffer( BufferIndex, StructurePointer, StructureSize ); } } VOID FillBuffer ( IN ULONG Index, IN PVOID Structure, IN ULONG Length ) { // // If the index is unused, display message but take no action. // if (!Buffers[Index].Used) { printf( "\nFillBuffer: Index refers to invalid buffer" ); // // Else copy as much of the data as will fit into the buffer. // } else { if (Length > Buffers[Index].Length) { Length = Buffers[Index].Length; } RtlCopyMemory( Buffers[Index].Buffer, Structure, Length ); } return; }