text: #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 'q' :
                          case 'Q' :
  
                              CreateOptions |= FILE_OPEN_NO_RECALL;
                              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 );
  
      if (!SynchronousCmds) {
  
          NtTerminateThread( 0, STATUS_SUCCESS );
      }
  }
  