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.
2296 lines
57 KiB
2296 lines
57 KiB
#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<digits> \n" );
|
|
printf( "\n -b<digits> 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<digits> [options]*\n" );
|
|
printf( "\n Options:" );
|
|
printf( "\n -b<digits> Buffer index" );
|
|
printf( "\n -l<digits> Display length" );
|
|
printf( "\n -o<digits> 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<digits> [options]* -s<digits> [options]*\n" );
|
|
printf( "\n Options:" );
|
|
printf( "\n -d<digits> Destination index" );
|
|
printf( "\n -f<digits> Source offset" );
|
|
printf( "\n -l<digits> Transfer length" );
|
|
printf( "\n -s<digits> Source index" );
|
|
printf( "\n -t<digits> 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<digits> Zero bits" );
|
|
printf( "\n -r<digits> 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<digits> 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<digits> -s<struct>[options]* \n" );
|
|
printf( "\n -sa[options] Get Volume Bitmap" );
|
|
printf( "\n a<digits> Starting lcn" );
|
|
printf( "\n -sb[options] Query Retrieval Pointers" );
|
|
printf( "\n a<digits> Starting vcn" );
|
|
printf( "\n -sc[options] Query Allocated Ranges" );
|
|
printf( "\n a<digits> FileOffset" );
|
|
printf( "\n b<digits> 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<digits> -s<struct>[options]* \n" );
|
|
printf( "\n -sa[options] Enum Usn Data" );
|
|
printf( "\n a<digits> Low usn" );
|
|
printf( "\n b<digits> High usn" );
|
|
printf( "\n c<digits> File ref" );
|
|
printf( "\n -sb[options] Read Usn Data" );
|
|
printf( "\n a<digits> Start usn" );
|
|
printf( "\n b<digits> Reason mask" );
|
|
printf( "\n c<digits> Return only on close" );
|
|
printf( "\n d<digits> Timeout" );
|
|
printf( "\n e<digits> Bytes to wait for" );
|
|
printf( "\n f<digits> Journal id" );
|
|
printf( "\n -sc[options] Create Usn Data" );
|
|
printf( "\n a<digits> Maximum size" );
|
|
printf( "\n b<digits> Allocation delta" );
|
|
printf( "\n -sd[options] Delete Usn Journal Data" );
|
|
printf( "\n a<digits> 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;
|
|
}
|