#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 | -i[l|h] [options]*\n" ); printf( " Options:\n" ); printf( " -f Name of file to open\n" ); printf( " -il Low 32 bits of file id\n" ); printf( " -ih 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 Buffer index for Ea's\n" ); printf( " -l Stated length of Ea buffer\n" ); printf( " -d Modify Desired Access value\n" ); printf( " -r Relative directory handle index\n" ); printf( " -o Object Attributes\n" ); printf( " -s Allocation size\n" ); printf( " -a File Attribute values\n" ); printf( " -h Share Access values\n" ); printf( " -p Create Disposition values\n" ); printf( " -n 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 ); }