windows-nt/Source/XPSP1/NT/base/fs/ntfs/tests/bshell/topen.c
2020-09-26 16:20:57 +08:00

1402 lines
42 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "brian.h"
typedef struct _ASYNC_OPEN {
ACCESS_MASK DesiredAccess;
PLARGE_INTEGER AllocationSizePtr;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG ShareAccess;
ULONG CreateDisposition;
ULONG CreateOptions;
PVOID EaBuffer;
ULONG EaLength;
STRING ObjectName;
PUSHORT RootDirIndexPtr;
USHORT RootDirIndex;
ULONG Attributes;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
BOOLEAN DisplayParameters;
BOOLEAN VerboseResults;
BOOLEAN AnsiName;
USHORT AsyncIndex;
USHORT NameIndex;
} ASYNC_OPEN, *PASYNC_OPEN;
#define DESIRED_ACCESS_DEFAULT (SYNCHRONIZE | GENERIC_READ)
#define ALLOCATION_SIZE_DEFAULT 0L
#define FILE_ATTRIBUTES_DEFAULT FILE_ATTRIBUTE_NORMAL
#define SHARE_ACCESS_DEFAULT FILE_SHARE_READ
#define CREATE_DISP_DEFAULT FILE_OPEN
#define CREATE_OPTIONS_DEFAULT FILE_SYNCHRONOUS_IO_ALERT
#define EA_LENGTH_DEFAULT 0L
#define ATTRIBUTES_DEFAULT OBJ_CASE_INSENSITIVE
#define DISPLAY_PARMS_DEFAULT FALSE
#define VERBOSE_RESULTS_DEFAULT TRUE
#define ANSI_NAME_DEFAULT FALSE
#define EXACT_NAME_DEFAULT FALSE
VOID
FullOpen (
IN PASYNC_OPEN AsyncOpen
);
VOID
InputOpenFile (
IN PCHAR ParamBuffer
)
{
ACCESS_MASK DesiredAccess;
LARGE_INTEGER AllocationSize;
PLARGE_INTEGER AllocationSizePtr;
ULONG FileAttributes;
ULONG ShareAccess;
ULONG CreateDisposition;
ULONG CreateOptions;
PVOID EaBuffer;
USHORT BufferIndex;
ULONG EaLength;
STRING ObjectName;
USHORT NameIndex;
PUSHORT RootDirIndexPtr;
USHORT RootDirIndex;
ULONG Attributes;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
BOOLEAN DisplayParameters;
BOOLEAN VerboseResults;
BOOLEAN AnsiName;
BOOLEAN ExactName;
BOOLEAN FileNameFound;
BOOLEAN LastInput;
BOOLEAN NameIndexAllocated;
PUCHAR FileName;
USHORT AsyncIndex;
//
// Set the defaults for the open and the return values.
//
DesiredAccess = DESIRED_ACCESS_DEFAULT;
AllocationSize = RtlConvertUlongToLargeInteger( ALLOCATION_SIZE_DEFAULT );
AllocationSizePtr = NULL;
FileAttributes = FILE_ATTRIBUTES_DEFAULT;
ShareAccess = SHARE_ACCESS_DEFAULT;
CreateDisposition = CREATE_DISP_DEFAULT;
CreateOptions = CREATE_OPTIONS_DEFAULT;
EaBuffer = NULL;
EaLength = EA_LENGTH_DEFAULT;
ObjectName.MaximumLength = 256;
ObjectName.Length = 256;
RootDirIndexPtr = NULL;
RootDirIndex = 0;
Attributes = ATTRIBUTES_DEFAULT;
SecurityDescriptor = NULL;
SecurityQualityOfService = NULL;
DisplayParameters = DISPLAY_PARMS_DEFAULT;
VerboseResults = VERBOSE_RESULTS_DEFAULT;
AnsiName = ANSI_NAME_DEFAULT;
ExactName = EXACT_NAME_DEFAULT;
NameIndexAllocated = FALSE;
FileNameFound = FALSE;
LastInput = TRUE;
{
NTSTATUS Status;
SIZE_T RegionSize;
ULONG TempIndex;
RegionSize = 1024;
Status = AllocateBuffer( 0, &RegionSize, &TempIndex );
if (!NT_SUCCESS( Status )) {
printf("InputOpenFile: Can't allocate name index buffer\n" );
return;
}
NameIndexAllocated = TRUE;
NameIndex = (USHORT) TempIndex;
ObjectName.Buffer = Buffers[NameIndex].Buffer;
}
//
// While there is more input, analyze the parameter and update the
// open 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) {
//
// Update the file attributes.
//
case 'a' :
case 'A' :
//
// 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' :
FileAttributes |= FILE_ATTRIBUTE_READONLY;
break;
case 'b' :
case 'B' :
FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
break;
case 'c' :
case 'C' :
FileAttributes |= FILE_ATTRIBUTE_SYSTEM;
break;
case 'e' :
case 'E' :
FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
break;
case 'f' :
case 'F' :
FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
break;
case 'g' :
case 'G' :
FileAttributes |= FILE_ATTRIBUTE_ENCRYPTED;
break;
case 'h' :
case 'H' :
FileAttributes |= FILE_ATTRIBUTE_NORMAL;
break;
case 'i' :
case 'I' :
FileAttributes |= FILE_ATTRIBUTE_TEMPORARY;
break;
case 'j' :
case 'J' :
FileAttributes |= FILE_ATTRIBUTE_SPARSE_FILE;
break;
case 'k' :
case 'K' :
FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
break;
case 'l' :
case 'L' :
FileAttributes |= FILE_ATTRIBUTE_COMPRESSED;
break;
case 'm' :
case 'M' :
FileAttributes |= FILE_ATTRIBUTE_OFFLINE;
break;
case 'n' :
case 'N' :
FileAttributes |= FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
break;
case 'z' :
case 'Z' :
FileAttributes = 0;
break;
default :
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
SwitchBool = FALSE;
}
if (!SwitchBool) {
break;
}
ParamBuffer++;
}
break;
//
// Update buffer to use.
//
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 = (USHORT) AsciiToInteger( ParamBuffer );
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
if (BufferIndex <= MAX_BUFFERS) {
EaBuffer = Buffers[BufferIndex].Buffer;
EaLength = Buffers[BufferIndex].Length;
}
break;
//
// Update buffer length to pass.
//
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++;
EaLength = AsciiToInteger( ParamBuffer );
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
break;
//
// Update the desired access.
//
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++;
SwitchBool = TRUE;
while (*ParamBuffer
&& *ParamBuffer != ' '
&& *ParamBuffer != '\t') {
//
// Perform switch on character.
//
switch (*ParamBuffer) {
case 'a' :
case 'A' :
DesiredAccess |= FILE_READ_DATA;
break;
case 'b' :
case 'B' :
DesiredAccess |= FILE_WRITE_DATA;
break;
case 'c' :
case 'C' :
DesiredAccess |= FILE_APPEND_DATA;
break;
case 'd' :
case 'D' :
DesiredAccess |= FILE_READ_EA;
break;
case 'e' :
case 'E' :
DesiredAccess |= FILE_WRITE_EA;
break;
case 'f' :
case 'F' :
DesiredAccess |= FILE_EXECUTE;
break;
case 'g' :
case 'G' :
DesiredAccess |= FILE_DELETE_CHILD;
break;
case 'h' :
case 'H' :
DesiredAccess |= FILE_READ_ATTRIBUTES;
break;
case 'i' :
case 'I' :
DesiredAccess |= FILE_WRITE_ATTRIBUTES;
break;
case 'j' :
case 'J' :
DesiredAccess |= FILE_ALL_ACCESS;
break;
case 'k' :
case 'K' :
DesiredAccess |= SYNCHRONIZE;
break;
case 'l' :
case 'L' :
DesiredAccess |= DELETE;
break;
case 'm' :
case 'M' :
DesiredAccess |= READ_CONTROL;
break;
case 'n' :
case 'N' :
DesiredAccess |= WRITE_DAC;
break;
case 'o' :
case 'O' :
DesiredAccess |= WRITE_OWNER;
break;
case 'p' :
case 'P' :
DesiredAccess |= GENERIC_READ;
break;
case 'q' :
case 'Q' :
DesiredAccess |= GENERIC_WRITE;
break;
case 'r' :
case 'R' :
DesiredAccess |= GENERIC_EXECUTE;
break;
case 's' :
case 'S' :
DesiredAccess |= GENERIC_ALL;
break;
case 't' :
DesiredAccess |= MAXIMUM_ALLOWED;
break;
case 'z' :
case 'Z' :
DesiredAccess = 0;
break;
default :
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
SwitchBool = FALSE;
}
if (!SwitchBool) {
break;
}
ParamBuffer++;
}
break;
//
// Get the filename.
//
case 'f' :
case 'F' :
//
// Remember the buffer offset and get the filename.
//
ParamBuffer++;
FileName = ParamBuffer;
DummyCount = 0;
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
//
// If the name length is 0, then ignore this entry.
//
if (DummyCount) {
ULONG ObjectNameIncrement = 0;
//
// If the first character is a backslash then
// we add the full 'dosdevices' prefix.
//
FileNameFound = TRUE;
if (!ExactName) {
if (*FileName == '\\') {
ObjectNameIncrement = sizeof( "DosDevices" );
RtlMoveMemory( ObjectName.Buffer,
"\\DosDevices",
sizeof( "\\DosDevices" ));
}
}
ObjectName.Length = (SHORT) (DummyCount + ObjectNameIncrement);
RtlMoveMemory( &ObjectName.Buffer[ObjectNameIncrement],
FileName,
DummyCount );
} else {
ULONG ObjectNameIncrement = 0;
FileNameFound = TRUE;
ObjectName.Length = (SHORT) (DummyCount + ObjectNameIncrement);
}
break;
//
// Update the file Id.
//
case 'i' :
case 'I' :
{
PLARGE_INTEGER FileId;
FileId = (PLARGE_INTEGER) ObjectName.Buffer;
//
// 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++;
if (*ParamBuffer == '\0') {
break;
}
switch (*ParamBuffer) {
case 'l':
case 'L':
FileId->LowPart = AsciiToInteger( ++ParamBuffer );
ObjectName.Length = sizeof( LARGE_INTEGER );
break;
case 'h':
case 'H':
FileId->HighPart = AsciiToInteger( ++ParamBuffer );
ObjectName.Length = sizeof( LARGE_INTEGER );
break;
}
FileNameFound = TRUE;
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
break;
}
//
// Update the share access field.
//
case 'h' :
case 'H' :
//
// 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' :
ShareAccess |= FILE_SHARE_READ;
break;
case 'b' :
case 'B' :
ShareAccess |= FILE_SHARE_WRITE;
break;
case 'c' :
case 'C' :
ShareAccess |= FILE_SHARE_DELETE;
break;
case 'z' :
case 'Z' :
ShareAccess = 0;
break;
default :
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
SwitchBool = FALSE;
}
if (!SwitchBool) {
break;
}
ParamBuffer++;
}
break;
//
// Update the create options.
//
case 'n' :
case 'N' :
//
// 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' :
CreateOptions |= FILE_DIRECTORY_FILE;
break;
case 'b' :
case 'B' :
CreateOptions |= FILE_WRITE_THROUGH;
break;
case 'c' :
case 'C' :
CreateOptions |= FILE_SEQUENTIAL_ONLY;
break;
case 'd' :
case 'D' :
CreateOptions |= FILE_NO_INTERMEDIATE_BUFFERING;
break;
case 'e' :
case 'E' :
CreateOptions |= FILE_SYNCHRONOUS_IO_ALERT;
break;
case 'f' :
case 'F' :
CreateOptions |= FILE_SYNCHRONOUS_IO_NONALERT;
break;
case 'g' :
case 'G' :
CreateOptions |= FILE_NON_DIRECTORY_FILE;
break;
case 'h' :
case 'H' :
CreateOptions |= FILE_CREATE_TREE_CONNECTION;
break;
case 'i' :
case 'I' :
CreateOptions |= FILE_COMPLETE_IF_OPLOCKED;
break;
case 'j' :
case 'J' :
CreateOptions |= FILE_OPEN_BY_FILE_ID;
break;
case 'k' :
case 'K' :
CreateOptions |= FILE_NO_EA_KNOWLEDGE;
break;
case 'l' :
case 'L' :
CreateOptions |= FILE_DELETE_ON_CLOSE;
break;
case 'm' :
case 'M' :
CreateOptions |= FILE_RESERVE_OPFILTER;
break;
case 'n' :
case 'N' :
CreateOptions |= FILE_OPEN_REPARSE_POINT;
break;
case 'o' :
case 'O' :
CreateOptions |= FILE_NO_COMPRESSION;
break;
case 'p' :
case 'P' :
CreateOptions |= FILE_OPEN_FOR_BACKUP_INTENT;
break;
case 'z' :
case 'Z' :
CreateOptions = 0;
break;
default :
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
SwitchBool = FALSE;
}
if (!SwitchBool) {
break;
}
ParamBuffer++;
}
break;
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++;
SwitchBool = TRUE;
while (*ParamBuffer
&& *ParamBuffer != ' '
&& *ParamBuffer != '\t') {
//
// Perform switch on character.
//
switch (*ParamBuffer) {
case 'a' :
case 'A' :
Attributes |= OBJ_INHERIT;
break;
case 'b' :
case 'B' :
Attributes |= OBJ_PERMANENT;
break;
case 'c' :
case 'C' :
Attributes |= OBJ_EXCLUSIVE;
break;
case 'd' :
case 'D' :
Attributes |= OBJ_CASE_INSENSITIVE;
break;
case 'e' :
case 'E' :
Attributes |= OBJ_OPENIF;
break;
case 'z' :
case 'Z' :
Attributes = 0;
break;
default :
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
SwitchBool = FALSE;
}
if (!SwitchBool) {
break;
}
ParamBuffer++;
}
break;
//
// Update the create disposition.
//
case 'p' :
case 'P' :
//
// 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' :
CreateDisposition |= FILE_SUPERSEDE;
break;
case 'b' :
case 'B' :
CreateDisposition |= FILE_OPEN;
break;
case 'c' :
case 'C' :
CreateDisposition |= FILE_CREATE;
break;
case 'd' :
case 'D' :
CreateDisposition |= FILE_OPEN_IF;
break;
case 'e' :
case 'E' :
CreateDisposition |= FILE_OVERWRITE;
break;
case 'f' :
case 'F' :
CreateDisposition |= FILE_OVERWRITE_IF;
break;
case 'z' :
case 'Z' :
CreateDisposition = 0;
break;
default :
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
SwitchBool = FALSE;
}
if( !SwitchBool ) {
break;
}
ParamBuffer++;
}
break;
//
// Get a root directory handle.
//
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++;
RootDirIndex = (USHORT) AsciiToInteger( ParamBuffer );
if( RootDirIndex <= MAX_HANDLES ) {
RootDirIndexPtr = &RootDirIndex;
}
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
break;
//
// Update the allocation size.
//
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++;
AllocationSize.QuadPart = AsciiToLargeInteger( ParamBuffer );
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
AllocationSizePtr = &AllocationSize;
break;
case 'v' :
case 'V' :
//
// Legal values for params are T/t or F/f.
//
ParamBuffer++;
if (*ParamBuffer == 'T'
|| *ParamBuffer == 't') {
VerboseResults = TRUE;
} else if (*ParamBuffer == 'F'
|| *ParamBuffer == 'f') {
VerboseResults = FALSE;
}
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
break;
//
// Check for using name exactly as given.
//
case 'x' :
case 'X' :
//
// Legal values for params are T/t or F/f.
//
ParamBuffer++;
if (*ParamBuffer == 'T'
|| *ParamBuffer == 't') {
ExactName = TRUE;
} else if (*ParamBuffer == 'F'
|| *ParamBuffer == 'f') {
ExactName = FALSE;
}
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
break;
//
// Check for unicode or ansi file names.
//
case 'u' :
case 'U' :
//
// Legal values for params are T/t or F/f.
//
ParamBuffer++;
if (*ParamBuffer == 'T'
|| *ParamBuffer == 't') {
AnsiName = FALSE;
} else if (*ParamBuffer == 'F'
|| *ParamBuffer == 'f') {
AnsiName = TRUE;
}
ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
break;
case 'y' :
case 'Y' :
//
// Set the display parms flag and jump over this
// character.
//
DisplayParameters = 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 the file name wasn't found, then display the syntax message
// and set verbose to FALSE.
//
if( !FileNameFound ) {
printf( "\n Usage: op [options]* -f<filename> | -i[l|h]<fileId> [options]*\n" );
printf( " Options:\n" );
printf( " -f<filename> Name of file to open\n" );
printf( " -il<digits> Low 32 bits of file id\n" );
printf( " -ih<digits> High 32 bits of file id\n" );
printf( " -x[t|f] Use name exactly (don't add \\DosDevices)\n" );
printf( " -u[t|f] Use unicode names \n" );
printf( " -v[t|f] Print out results\n" );
printf( " -z Get additional input\n" );
printf( " -y Display create parameters\n" );
printf( " -b<digits> Buffer index for Ea's\n" );
printf( " -l<digits> Stated length of Ea buffer\n" );
printf( " -d<chars> Modify Desired Access value\n" );
printf( " -r<digits> Relative directory handle index\n" );
printf( " -o<chars> Object Attributes\n" );
printf( " -s<digits> Allocation size\n" );
printf( " -a<chars> File Attribute values\n" );
printf( " -h<chars> Share Access values\n" );
printf( " -p<chars> Create Disposition values\n" );
printf( " -n<chars> Create Options values\n" );
printf( "\n\n" );
DeallocateBuffer( NameIndex );
//
// Else return the status of opening the file.
//
} else {
NTSTATUS Status;
SIZE_T RegionSize;
ULONG TempIndex;
PASYNC_OPEN AsyncOpen;
HANDLE ThreadHandle;
ULONG ThreadId;
RegionSize = sizeof( ASYNC_OPEN );
Status = AllocateBuffer( 0, &RegionSize, &TempIndex );
AsyncIndex = (USHORT) TempIndex;
if (!NT_SUCCESS( Status )) {
printf("\tInputOpen: Unable to allocate async structure\n" );
DeallocateBuffer( NameIndex );
} else {
AsyncOpen = (PASYNC_OPEN) Buffers[AsyncIndex].Buffer;
AsyncOpen->DesiredAccess = DesiredAccess;
AsyncOpen->AllocationSize = AllocationSize;
AsyncOpen->AllocationSizePtr = AllocationSizePtr
? &AsyncOpen->AllocationSize
: NULL;
AsyncOpen->FileAttributes = FileAttributes;
AsyncOpen->ShareAccess = ShareAccess;
AsyncOpen->CreateDisposition = CreateDisposition;
AsyncOpen->CreateOptions = CreateOptions;
AsyncOpen->EaBuffer = EaBuffer;
AsyncOpen->EaLength = EaLength;
AsyncOpen->ObjectName = ObjectName;
AsyncOpen->RootDirIndex = RootDirIndex;
AsyncOpen->RootDirIndexPtr = RootDirIndexPtr
? &AsyncOpen->RootDirIndex
: NULL;
AsyncOpen->Attributes = Attributes;
AsyncOpen->SecurityDescriptor = SecurityDescriptor;
AsyncOpen->SecurityQualityOfService = SecurityQualityOfService;
AsyncOpen->DisplayParameters = DisplayParameters;
AsyncOpen->VerboseResults = VerboseResults;
AsyncOpen->AnsiName = AnsiName;
AsyncOpen->AsyncIndex = AsyncIndex;
AsyncOpen->NameIndex = NameIndex;
if (!SynchronousCmds) {
ThreadHandle = CreateThread( NULL,
0,
FullOpen,
AsyncOpen,
0,
&ThreadId );
if (ThreadHandle == 0) {
printf( "\nInputOpen: Spawning thread fails -> %d\n", GetLastError() );
DeallocateBuffer( NameIndex );
DeallocateBuffer( AsyncIndex );
return;
}
} else {
FullOpen( AsyncOpen );
}
}
}
return;
}
VOID
FullOpen (
IN PASYNC_OPEN AsyncOpen
)
{
NTSTATUS Status;
IO_STATUS_BLOCK Iosb;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING UnicodeName;
PUNICODE_STRING NameString;
USHORT ThisIndex;
Iosb.Status = STATUS_SUCCESS;
Iosb.Information = 0;
//
// Check that the relative index is a valid value.
//
if (AsyncOpen->RootDirIndexPtr != NULL) {
if (AsyncOpen->RootDirIndex >= MAX_HANDLES) {
bprint "\n" );
bprint "Relative index is invalid\n" );
DeallocateBuffer( AsyncOpen->AsyncIndex );
DeallocateBuffer( AsyncOpen->NameIndex );
return;
}
ObjectAttributes.RootDirectory = Handles[AsyncOpen->RootDirIndex].Handle;
} else {
ObjectAttributes.RootDirectory = 0;
}
//
// Find a free index.
//
if (ObtainIndex( &ThisIndex ) != STATUS_SUCCESS) {
bprint "\n" );
bprint "Unable to get a new handle index \n" );
return;
}
if (AsyncOpen->AnsiName
|| FlagOn( AsyncOpen->CreateOptions, FILE_OPEN_BY_FILE_ID )) {
NameString = (PUNICODE_STRING) &AsyncOpen->ObjectName;
} else {
RtlAnsiStringToUnicodeString( &UnicodeName,
&AsyncOpen->ObjectName,
TRUE );
NameString = &UnicodeName;
}
ObjectAttributes.Length = sizeof( OBJECT_ATTRIBUTES );
ObjectAttributes.ObjectName = NameString;
ObjectAttributes.SecurityDescriptor = AsyncOpen->SecurityDescriptor;
ObjectAttributes.SecurityQualityOfService = AsyncOpen->SecurityQualityOfService;
ObjectAttributes.Attributes = AsyncOpen->Attributes;
if (AsyncOpen->DisplayParameters) {
bprint "\n" );
bprint " CallOpenFile Parameters\n" );
bprint "\n" );
bprint " DesiredAccess -> %08lx\n", AsyncOpen->DesiredAccess );
if (FlagOn( AsyncOpen->CreateOptions, FILE_OPEN_BY_FILE_ID )) {
PLARGE_INTEGER FileId;
FileId = (PLARGE_INTEGER) AsyncOpen->ObjectName.Buffer;
bprint " FileId.LowPart -> %08lx\n", FileId->LowPart );
bprint " FileId.HighPart -> %08lx\n", FileId->HighPart );
} else {
bprint " Filename -> %s\n", AsyncOpen->ObjectName.Buffer );
bprint " FileNameLen -> %ld\n", AsyncOpen->ObjectName.Length );
}
bprint " RootDirectoryIndexPtr -> %ld\n", AsyncOpen->RootDirIndexPtr );
if (AsyncOpen->RootDirIndexPtr != NULL) {
bprint " RootDirectoryIndex -> %ld\n", AsyncOpen->RootDirIndex );
}
bprint " SecurityDescriptor -> %lx\n", AsyncOpen->SecurityDescriptor );
bprint " SecurityQualityOfService -> %lx\n", AsyncOpen->SecurityQualityOfService );
bprint " Attributes -> %08lx\n", AsyncOpen->Attributes );
bprint " AllocationSizePtr -> %lx\n", AsyncOpen->AllocationSizePtr );
if (AsyncOpen->AllocationSizePtr) {
bprint " AllocationSize.LowPart -> %lx\n", AsyncOpen->AllocationSize.LowPart );
bprint " AllocationSize.HighPart -> %lx\n", AsyncOpen->AllocationSize.HighPart );
}
bprint " FileAttributes -> %08lx\n", AsyncOpen->FileAttributes );
bprint " ShareAccess -> %08lx\n", AsyncOpen->ShareAccess );
bprint " CreateDisposition -> %08lx\n", AsyncOpen->CreateDisposition );
bprint " CreateOptions -> %08lx\n", AsyncOpen->CreateOptions );
bprint " EaBuffer -> %lx\n", AsyncOpen->EaBuffer );
bprint " EaLength -> %ld\n", AsyncOpen->EaLength );
bprint " AnsiName -> %04x\n", AsyncOpen->AnsiName );
bprint "\n" );
}
Status = NtCreateFile( &Handles[ThisIndex].Handle,
AsyncOpen->DesiredAccess,
&ObjectAttributes,
&Iosb,
AsyncOpen->AllocationSizePtr,
AsyncOpen->FileAttributes,
AsyncOpen->ShareAccess,
AsyncOpen->CreateDisposition,
AsyncOpen->CreateOptions,
AsyncOpen->EaBuffer,
AsyncOpen->EaLength );
if (AsyncOpen->VerboseResults) {
bprint "\n" );
bprint " OpenFile: Status -> %08lx\n", Status );
bprint "\n" );
bprint " File Handle -> 0x%lx\n", Handles[ThisIndex].Handle );
bprint " File HandleIndex -> %ld\n", ThisIndex );
if (NT_SUCCESS( Status )) {
bprint " Io.Status -> %08lx\n", Iosb.Status );
bprint " Io.Info -> %08lx\n", Iosb.Information );
}
bprint "\n" );
}
if (!NT_SUCCESS( Status )) {
FreeIndex( ThisIndex );
}
DeallocateBuffer( AsyncOpen->NameIndex );
if (!AsyncOpen->AnsiName) {
RtlFreeUnicodeString( &UnicodeName );
}
DeallocateBuffer( AsyncOpen->AsyncIndex );
NtTerminateThread( 0, STATUS_SUCCESS );
}