973 lines
24 KiB
C
973 lines
24 KiB
C
#include "brian.h"
|
||
|
||
typedef struct _ASYNC_QVOLUME {
|
||
|
||
USHORT FileIndex;
|
||
PUSHORT BufferIndexPtr;
|
||
USHORT BufferIndex;
|
||
ULONG Length;
|
||
FILE_INFORMATION_CLASS FileInfoClass;
|
||
BOOLEAN DisplayParms;
|
||
BOOLEAN VerboseResults;
|
||
USHORT AsyncIndex;
|
||
|
||
} ASYNC_QVOLUME, *PASYNC_QVOLUME;
|
||
|
||
#define QVOLUME_LENGTH_DEFAULT 100
|
||
#define FILE_INFO_CLASS_DEFAULT FileFsVolumeInformation
|
||
#define DISPLAY_PARMS_DEFAULT FALSE
|
||
#define VERBOSE_DEFAULT FALSE
|
||
|
||
#define DISPLAY_INDEX_DEFAULT 0
|
||
|
||
VOID
|
||
FullQVolume(
|
||
IN OUT PASYNC_QVOLUME AsyncQVolume
|
||
);
|
||
|
||
VOID
|
||
DisplayFsVolumeInformation (
|
||
IN USHORT BufferIndex
|
||
);
|
||
|
||
VOID
|
||
DisplayFsSizeInformation (
|
||
IN USHORT BufferIndex
|
||
);
|
||
|
||
VOID
|
||
DisplayFsDeviceInformation (
|
||
IN USHORT BufferIndex
|
||
);
|
||
|
||
VOID
|
||
DisplayFsAttributeInformation (
|
||
IN USHORT BufferIndex
|
||
);
|
||
|
||
|
||
VOID
|
||
InputQVolume (
|
||
IN PCHAR ParamBuffer
|
||
)
|
||
{
|
||
ULONG FileIndex;
|
||
PUSHORT BufferIndexPtr;
|
||
USHORT BufferIndex;
|
||
ULONG Length;
|
||
FILE_INFORMATION_CLASS FileInfoClass;
|
||
BOOLEAN DisplayParms;
|
||
BOOLEAN VerboseResults;
|
||
USHORT AsyncIndex;
|
||
|
||
BOOLEAN ParamReceived;
|
||
BOOLEAN LastInput;
|
||
|
||
//
|
||
// Set the defaults.
|
||
//
|
||
|
||
BufferIndexPtr = NULL;
|
||
BufferIndex = 0;
|
||
Length = QVOLUME_LENGTH_DEFAULT;
|
||
FileInfoClass = FILE_INFO_CLASS_DEFAULT;
|
||
DisplayParms = DISPLAY_PARMS_DEFAULT;
|
||
VerboseResults = VERBOSE_DEFAULT;
|
||
|
||
AsyncIndex = 0;
|
||
|
||
ParamReceived = FALSE;
|
||
LastInput = TRUE;
|
||
|
||
//
|
||
// While there is more input, analyze the parameter and update the
|
||
// query flags.
|
||
//
|
||
|
||
while (TRUE) {
|
||
|
||
ULONG DummyCount;
|
||
ULONG TempIndex;
|
||
|
||
//
|
||
// 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')) {
|
||
|
||
BOOLEAN SwitchBool;
|
||
|
||
//
|
||
// Switch on the next character.
|
||
//
|
||
|
||
switch (*ParamBuffer) {
|
||
|
||
//
|
||
// Update 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++;
|
||
|
||
TempIndex = AsciiToInteger( ParamBuffer );
|
||
BufferIndex = (USHORT) TempIndex;
|
||
BufferIndexPtr = &BufferIndex;
|
||
|
||
Length = Buffers[BufferIndex].Length;
|
||
|
||
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
|
||
|
||
break;
|
||
|
||
//
|
||
// Update the byte count.
|
||
//
|
||
|
||
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;
|
||
|
||
//
|
||
// Update the file handle index.
|
||
//
|
||
|
||
case 'i' :
|
||
case 'I' :
|
||
|
||
//
|
||
// 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++;
|
||
|
||
FileIndex = AsciiToInteger( ParamBuffer );
|
||
|
||
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
|
||
|
||
ParamReceived = TRUE;
|
||
|
||
break;
|
||
|
||
//
|
||
// Update the information class.
|
||
//
|
||
case 'c' :
|
||
case 'C' :
|
||
|
||
//
|
||
// 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++;
|
||
|
||
SwitchBool = TRUE;
|
||
while (*ParamBuffer
|
||
&& *ParamBuffer != ' '
|
||
&& *ParamBuffer != '\t') {
|
||
|
||
//
|
||
// Perform switch on character.
|
||
//
|
||
switch (*ParamBuffer) {
|
||
|
||
case 'a' :
|
||
case 'A' :
|
||
|
||
FileInfoClass = FileFsVolumeInformation;
|
||
break;
|
||
|
||
case 'b' :
|
||
case 'B' :
|
||
|
||
FileInfoClass = FileFsSizeInformation;
|
||
break;
|
||
|
||
case 'c' :
|
||
case 'C' :
|
||
|
||
FileInfoClass = FileFsDeviceInformation;
|
||
break;
|
||
|
||
case 'd' :
|
||
case 'D' :
|
||
|
||
FileInfoClass = FileFsAttributeInformation;
|
||
break;
|
||
|
||
default :
|
||
|
||
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
|
||
SwitchBool = FALSE;
|
||
}
|
||
|
||
if (!SwitchBool) {
|
||
|
||
break;
|
||
}
|
||
|
||
ParamBuffer++;
|
||
}
|
||
|
||
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++;
|
||
|
||
}
|
||
|
||
break;
|
||
|
||
case 'y' :
|
||
case 'Y' :
|
||
|
||
//
|
||
// Set the display parms flag and jump over this
|
||
// character.
|
||
//
|
||
DisplayParms = TRUE;
|
||
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
|
||
|
||
break;
|
||
|
||
case 'z' :
|
||
case 'Z' :
|
||
|
||
//
|
||
// Set flag for more input and jump over this char.
|
||
//
|
||
LastInput = FALSE;
|
||
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: qv [options]* -i<index> [options]*\n" );
|
||
printf( "\n Options:" );
|
||
printf( "\n -i<digits> File index" );
|
||
printf( "\n -l<digits> Buffer length" );
|
||
printf( "\n -b<digits> Buffer index" );
|
||
printf( "\n -c<char> File information class" );
|
||
printf( "\n -v[t|f] Verbose results" );
|
||
printf( "\n -y Display parameters to query" );
|
||
printf( "\n -z Additional input line" );
|
||
printf( "\n\n" );
|
||
|
||
//
|
||
// Else call our read routine.
|
||
//
|
||
|
||
} else {
|
||
|
||
NTSTATUS Status;
|
||
SIZE_T RegionSize;
|
||
ULONG TempIndex;
|
||
|
||
PASYNC_QVOLUME AsyncQVolume;
|
||
|
||
HANDLE ThreadHandle;
|
||
ULONG ThreadId;
|
||
|
||
RegionSize = sizeof( ASYNC_QVOLUME );
|
||
|
||
Status = AllocateBuffer( 0, &RegionSize, &TempIndex );
|
||
AsyncIndex = (USHORT) TempIndex;
|
||
|
||
if (!NT_SUCCESS( Status )) {
|
||
|
||
printf("\n\tInputQVolume: Unable to allocate async structure" );
|
||
|
||
} else {
|
||
|
||
AsyncQVolume = (PASYNC_QVOLUME) Buffers[AsyncIndex].Buffer;
|
||
|
||
AsyncQVolume->FileIndex = (USHORT) FileIndex;
|
||
|
||
AsyncQVolume->BufferIndex = BufferIndex;
|
||
AsyncQVolume->BufferIndexPtr = BufferIndexPtr
|
||
? &AsyncQVolume->BufferIndex
|
||
: BufferIndexPtr;
|
||
AsyncQVolume->Length = Length;
|
||
AsyncQVolume->FileInfoClass = FileInfoClass;
|
||
AsyncQVolume->DisplayParms = DisplayParms;
|
||
AsyncQVolume->VerboseResults = VerboseResults;
|
||
AsyncQVolume->AsyncIndex = AsyncIndex;
|
||
|
||
if (!SynchronousCmds) {
|
||
|
||
ThreadHandle = CreateThread( NULL,
|
||
0,
|
||
FullQVolume,
|
||
AsyncQVolume,
|
||
0,
|
||
&ThreadId );
|
||
|
||
if (ThreadHandle == 0) {
|
||
|
||
printf( "\nInputQVolume: Spawning thread fails -> %d\n", GetLastError() );
|
||
|
||
DeallocateBuffer( AsyncIndex );
|
||
|
||
return;
|
||
}
|
||
|
||
} else {
|
||
|
||
FullQVolume( AsyncQVolume );
|
||
}
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
FullQVolume(
|
||
IN OUT PASYNC_QVOLUME AsyncQVolume
|
||
)
|
||
{
|
||
NTSTATUS Status;
|
||
IO_STATUS_BLOCK Iosb;
|
||
|
||
USHORT ThisBufferIndex;
|
||
|
||
BOOLEAN UnwindQVolumeBuffer = FALSE;
|
||
|
||
Status = STATUS_SUCCESS;
|
||
|
||
if (AsyncQVolume->DisplayParms) {
|
||
|
||
bprint "\nQVolume Parameters" );
|
||
bprint "\n File Handle Index -> %d", AsyncQVolume->FileIndex );
|
||
bprint "\n Buffer Index Ptr -> %08lx", AsyncQVolume->BufferIndexPtr );
|
||
if (AsyncQVolume->BufferIndexPtr) {
|
||
|
||
bprint "\n BufferIndex value -> %04x", AsyncQVolume->BufferIndex );
|
||
}
|
||
|
||
bprint "\n Length -> %08lx", AsyncQVolume->Length );
|
||
|
||
bprint "\n FileInfoClass -> %08lx", AsyncQVolume->FileInfoClass );
|
||
|
||
bprint "\n\n" );
|
||
}
|
||
|
||
try {
|
||
|
||
SIZE_T ThisLength;
|
||
|
||
//
|
||
// If we need a buffer, allocate it now.
|
||
//
|
||
|
||
if (AsyncQVolume->BufferIndexPtr == NULL) {
|
||
|
||
ULONG TempIndex;
|
||
|
||
ThisLength = 4096;
|
||
|
||
Status = AllocateBuffer( 0L, &ThisLength, &TempIndex );
|
||
|
||
ThisBufferIndex = (USHORT) TempIndex;
|
||
|
||
if (!NT_SUCCESS( Status )) {
|
||
|
||
bprint "\n\tFullQVolume: Unable to allocate a query buffer" );
|
||
try_return( Status );
|
||
}
|
||
|
||
bprint "\n\tFullQVolume: Reading into buffer -> %04x\n", ThisBufferIndex );
|
||
bprint "\n" );
|
||
|
||
UnwindQVolumeBuffer = TRUE;
|
||
|
||
AsyncQVolume->Length = (ULONG) ThisLength;
|
||
|
||
} else {
|
||
|
||
ThisBufferIndex = AsyncQVolume->BufferIndex;
|
||
}
|
||
|
||
//
|
||
// Check that the buffer index is valid.
|
||
//
|
||
|
||
if (ThisBufferIndex >= MAX_BUFFERS) {
|
||
|
||
bprint "\n\tFullQVolume: The read buffer index is invalid" );
|
||
try_return( Status = STATUS_INVALID_HANDLE );
|
||
}
|
||
|
||
//
|
||
// Check that the file index is valid.
|
||
//
|
||
|
||
if (AsyncQVolume->FileIndex >= MAX_HANDLES) {
|
||
|
||
bprint "\n\tFullQVolume: The file index is invalid" );
|
||
try_return( Status = STATUS_INVALID_HANDLE );
|
||
}
|
||
|
||
//
|
||
// Call the query file routine.
|
||
//
|
||
|
||
Status = NtQueryVolumeInformationFile( Handles[AsyncQVolume->FileIndex].Handle,
|
||
&Iosb,
|
||
Buffers[ThisBufferIndex].Buffer,
|
||
AsyncQVolume->Length,
|
||
AsyncQVolume->FileInfoClass );
|
||
|
||
UnwindQVolumeBuffer = FALSE;
|
||
|
||
if (AsyncQVolume->VerboseResults) {
|
||
|
||
bprint "\nQuery File: Status -> %08lx", Status );
|
||
|
||
if (NT_SUCCESS( Status )) {
|
||
|
||
bprint "\n Iosb.Information -> %08lx", Iosb.Information );
|
||
bprint "\n Iosb.Status -> %08lx", Iosb.Status );
|
||
}
|
||
bprint "\n" );
|
||
}
|
||
|
||
try_return( Status );
|
||
|
||
try_exit: NOTHING;
|
||
} finally {
|
||
|
||
if (UnwindQVolumeBuffer) {
|
||
|
||
DeallocateBuffer( ThisBufferIndex );
|
||
}
|
||
|
||
DeallocateBuffer( AsyncQVolume->AsyncIndex );
|
||
}
|
||
|
||
NtTerminateThread( 0, STATUS_SUCCESS );
|
||
}
|
||
|
||
|
||
VOID
|
||
InputDisplayQVolume (
|
||
IN PCHAR ParamBuffer
|
||
)
|
||
{
|
||
FILE_INFORMATION_CLASS FileInfoClass;
|
||
ULONG BufferIndex;
|
||
BOOLEAN ParamReceived;
|
||
BOOLEAN LastInput;
|
||
|
||
//
|
||
// Set the defaults.
|
||
//
|
||
|
||
BufferIndex = DISPLAY_INDEX_DEFAULT;
|
||
FileInfoClass = FILE_INFO_CLASS_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')) {
|
||
|
||
BOOLEAN SwitchBool;
|
||
|
||
//
|
||
// 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;
|
||
|
||
//
|
||
// Update the desired access.
|
||
//
|
||
case 'c' :
|
||
case 'C' :
|
||
|
||
|
||
//
|
||
// 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++;
|
||
|
||
SwitchBool = TRUE;
|
||
while (*ParamBuffer
|
||
&& *ParamBuffer != ' '
|
||
&& *ParamBuffer != '\t') {
|
||
|
||
//
|
||
// Perform switch on character.
|
||
//
|
||
switch (*ParamBuffer) {
|
||
|
||
case 'a' :
|
||
case 'A' :
|
||
|
||
FileInfoClass = FileFsVolumeInformation;
|
||
break;
|
||
|
||
case 'b' :
|
||
case 'B' :
|
||
|
||
FileInfoClass = FileFsSizeInformation;
|
||
break;
|
||
|
||
case 'c' :
|
||
case 'C' :
|
||
|
||
FileInfoClass = FileFsDeviceInformation;
|
||
break;
|
||
|
||
case 'd' :
|
||
case 'D' :
|
||
|
||
FileInfoClass = FileFsAttributeInformation;
|
||
break;
|
||
|
||
default :
|
||
|
||
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
|
||
SwitchBool = FALSE;
|
||
}
|
||
|
||
if (!SwitchBool) {
|
||
|
||
break;
|
||
}
|
||
|
||
ParamBuffer++;
|
||
}
|
||
|
||
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: dqv [options]* -b<digits> [options]*\n" );
|
||
printf( "\n Options:" );
|
||
printf( "\n -b<digits> Buffer index" );
|
||
printf( "\n -c<char> Key to buffer format" );
|
||
printf( "\n\n" );
|
||
|
||
//
|
||
// Else call our display buffer routine.
|
||
//
|
||
} else {
|
||
|
||
switch (FileInfoClass) {
|
||
|
||
case FileFsVolumeInformation :
|
||
|
||
DisplayFsVolumeInformation( (USHORT) BufferIndex );
|
||
break;
|
||
|
||
case FileFsSizeInformation:
|
||
|
||
DisplayFsSizeInformation( (USHORT) BufferIndex );
|
||
break;
|
||
|
||
case FileFsDeviceInformation:
|
||
|
||
DisplayFsDeviceInformation( (USHORT) BufferIndex );
|
||
break;
|
||
|
||
case FileFsAttributeInformation:
|
||
|
||
DisplayFsAttributeInformation( (USHORT) BufferIndex );
|
||
break;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
DisplayFsVolumeInformation (
|
||
IN USHORT BufferIndex
|
||
)
|
||
{
|
||
PFILE_FS_VOLUME_INFORMATION FileInfo;
|
||
NTSTATUS Status;
|
||
ANSI_STRING AnsiString;
|
||
UNICODE_STRING UnicodeString;
|
||
|
||
BOOLEAN UnwindFreeAnsiString = FALSE;
|
||
|
||
if (!Buffers[BufferIndex].Used) {
|
||
|
||
printf( "\nDisplayFsVolumeInformation: Invalid buffer\n" );
|
||
return;
|
||
}
|
||
|
||
try {
|
||
|
||
FileInfo = (PFILE_FS_VOLUME_INFORMATION) Buffers[BufferIndex].Buffer;
|
||
|
||
printf( "\n\nFs Volume Information\n" );
|
||
|
||
printf( "\n\tVolume Creation Time -> " );
|
||
PrintTime( &FileInfo->VolumeCreationTime );
|
||
printf( "\n\tVolume Serial Number -> %08lx", FileInfo->VolumeSerialNumber );
|
||
printf( "\n\tVolume Label Length -> %08d", FileInfo->VolumeLabelLength );
|
||
printf( "\n\tVolume Supports Objects -> %01d", FileInfo->SupportsObjects );
|
||
|
||
UnicodeString.MaximumLength =
|
||
UnicodeString.Length = (USHORT) FileInfo->VolumeLabelLength;
|
||
UnicodeString.Buffer = (PWSTR) &FileInfo->VolumeLabel;
|
||
|
||
UnicodeString.MaximumLength += 2;
|
||
|
||
Status = RtlUnicodeStringToAnsiString( &AnsiString,
|
||
&UnicodeString,
|
||
TRUE );
|
||
|
||
if (!NT_SUCCESS( Status )) {
|
||
|
||
printf( "\nDisplay Volume Information: Unable to allocate Ansi -> %08lx\n", Status );
|
||
try_return( NOTHING );
|
||
}
|
||
|
||
UnwindFreeAnsiString = TRUE;
|
||
|
||
printf( "\n\tVolume Label -> %s", AnsiString.Buffer );
|
||
|
||
printf( "\n" );
|
||
|
||
try_return( NOTHING );
|
||
|
||
try_exit: NOTHING;
|
||
} finally {
|
||
|
||
if (AbnormalTermination()) {
|
||
|
||
printf( "\nDisplayFsVolumeInformation: AbnormalTermination\n" );
|
||
}
|
||
|
||
if (UnwindFreeAnsiString) {
|
||
|
||
RtlFreeAnsiString( &AnsiString );
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
VOID
|
||
DisplayFsSizeInformation (
|
||
IN USHORT BufferIndex
|
||
)
|
||
{
|
||
PFILE_FS_SIZE_INFORMATION FileInfo;
|
||
|
||
if (!Buffers[BufferIndex].Used) {
|
||
|
||
printf( "\nDisplayFsSizeInformation: Invalid buffer\n" );
|
||
return;
|
||
}
|
||
|
||
try {
|
||
|
||
FileInfo = (PFILE_FS_SIZE_INFORMATION) Buffers[BufferIndex].Buffer;
|
||
|
||
printf( "\n\nFs Size Information\n" );
|
||
|
||
printf( "\n\tTotal Allocation Units -> " );
|
||
PrintLargeInteger( &FileInfo->TotalAllocationUnits );
|
||
printf( "\n\tAvail Allocation Units -> " );
|
||
PrintLargeInteger( &FileInfo->AvailableAllocationUnits );
|
||
printf( "\n\tSectors Per Alloc Unit -> %08lx", FileInfo->SectorsPerAllocationUnit );
|
||
printf( "\n\tBytes Per Sector -> %08lx", FileInfo->BytesPerSector );
|
||
|
||
printf( "\n" );
|
||
|
||
try_return( NOTHING );
|
||
|
||
try_exit: NOTHING;
|
||
} finally {
|
||
|
||
if (AbnormalTermination()) {
|
||
|
||
printf( "\nDisplayFsSizeInformation: AbnormalTermination\n" );
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
VOID
|
||
DisplayFsDeviceInformation (
|
||
IN USHORT BufferIndex
|
||
)
|
||
{
|
||
PFILE_FS_DEVICE_INFORMATION FileInfo;
|
||
|
||
if (!Buffers[BufferIndex].Used) {
|
||
|
||
printf( "\nDisplayFsDeviceInformation: Invalid buffer\n" );
|
||
return;
|
||
}
|
||
|
||
try {
|
||
|
||
FileInfo = (PFILE_FS_DEVICE_INFORMATION) Buffers[BufferIndex].Buffer;
|
||
|
||
printf( "\n\nFs Device Information\n" );
|
||
|
||
printf( "\n\tDevice Type -> %08lx", FileInfo->DeviceType );
|
||
printf( "\n\tCharacteristics -> %08lx", FileInfo->Characteristics );
|
||
|
||
printf( "\n" );
|
||
|
||
try_return( NOTHING );
|
||
|
||
try_exit: NOTHING;
|
||
} finally {
|
||
|
||
if (AbnormalTermination()) {
|
||
|
||
printf( "\nDisplayFsDeviceInformation: AbnormalTermination\n" );
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
VOID
|
||
DisplayFsAttributeInformation (
|
||
IN USHORT BufferIndex
|
||
)
|
||
{
|
||
PFILE_FS_ATTRIBUTE_INFORMATION FileInfo;
|
||
NTSTATUS Status;
|
||
ANSI_STRING AnsiString;
|
||
UNICODE_STRING UnicodeString;
|
||
|
||
BOOLEAN UnwindFreeAnsiString = FALSE;
|
||
|
||
if (!Buffers[BufferIndex].Used) {
|
||
|
||
printf( "\nDisplayFsAttributeInformation: Invalid buffer\n" );
|
||
return;
|
||
}
|
||
|
||
try {
|
||
|
||
FileInfo = (PFILE_FS_ATTRIBUTE_INFORMATION) Buffers[BufferIndex].Buffer;
|
||
|
||
printf( "\n\nFs Attribute Information\n" );
|
||
|
||
printf( "\n\tFile System Attributes -> %08lx", FileInfo->FileSystemAttributes );
|
||
printf( "\n\tMax Component Name Length -> %08d", FileInfo->MaximumComponentNameLength );
|
||
printf( "\n\tFile System Name Length -> %08d", FileInfo->FileSystemNameLength );
|
||
|
||
UnicodeString.MaximumLength =
|
||
UnicodeString.Length = (USHORT) FileInfo->FileSystemNameLength;
|
||
UnicodeString.Buffer = (PWSTR) &FileInfo->FileSystemName;
|
||
|
||
UnicodeString.MaximumLength += 2;
|
||
|
||
Status = RtlUnicodeStringToAnsiString( &AnsiString,
|
||
&UnicodeString,
|
||
TRUE );
|
||
|
||
if (!NT_SUCCESS( Status )) {
|
||
|
||
printf( "\nDisplay Fs Attribute Information: Unable to allocate Ansi -> %08lx\n", Status );
|
||
try_return( NOTHING );
|
||
}
|
||
|
||
UnwindFreeAnsiString = TRUE;
|
||
|
||
printf( "\n\tFile System Name -> %s", AnsiString.Buffer );
|
||
|
||
printf( "\n" );
|
||
|
||
try_return( NOTHING );
|
||
|
||
try_exit: NOTHING;
|
||
} finally {
|
||
|
||
if (AbnormalTermination()) {
|
||
|
||
printf( "\nDisplayFsAttributeInformation: AbnormalTermination\n" );
|
||
}
|
||
|
||
if (UnwindFreeAnsiString) {
|
||
|
||
RtlFreeAnsiString( &AnsiString );
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|
||
|