IopCreateFile

NTSTATUS __stdcall IopCreateFile(
        PVOID *FileHandle,
        UINT64 DesiredAccess,
        _OBJECT_ATTRIBUTES *ObjectAttributes,
        _IO_STATUS_BLOCK *IoStatusBlock,
        _LARGE_INTEGER *AllocationSize,
        UINT64 FileAttributes,
        UINT64 ShareAccess,
        UINT64 Disposition,
        UINT64 CreateOptions,
        PVOID EaBuffer,
        UINT64 EaLength,
        _CREATE_FILE_TYPE CreateFileType,
        PVOID InternalParameters,
        UINT64 Options,
        UINT64 InternalFlags,
        _IO_DRIVER_CREATE_CONTEXT *DriverContext){
  int v16; 
  int v17; 
  int v18; 
  char v19; 
  char PreviousMode; 
  struct _KPRCB *CurrentPrcb; 
  _GENERAL_LOOKASIDE *P; 
  PSLIST_ENTRY ParseContext; 
  struct _KPRCB *v24; 
  _GENERAL_LOOKASIDE *v25; 
  _CREATE_FILE_TYPE v27; 
  __int64 v28; 
  __int64 v29; 
  void *QuadPart; 
  INT8 v31; 
  size_t Size; 
  _ETHREAD *CurrentThread; 
  NTSTATUS v34; 
  void *v35; 
  __int64 v36; 
  int v37; 
  __int64 **v38; 
  __int64 *v39; 
  __int64 v40; 
  _QWORD *v41; 
  __int64 v42; 
  void(__fastcall *v43)(_QWORD *, _QWORD *); 
  __int64 v44; 
  int Next; 
  _ADAPTER_OBJECT *v46; 
  struct _KPRCB *v47; 
  _GENERAL_LOOKASIDE *v48; 
  int v49; 
  unsigned __int64 v50; 
  __int64 v51; 
  __int64 *v52; 
  __int64 *v53; 
  __int64 *v54; 
  __int64 **v55; 
  __int64 v56; 
  VOID *PoolWithQuotaTag; 
  int v58; 
  _GENERAL_LOOKASIDE *L; 
  VOID **PoolWithTag; 
  int v61; 
  struct _KPRCB *v62; 
  _GENERAL_LOOKASIDE *v63; 
  struct _KPRCB *v64; 
  struct _KPRCB *v65; 
  _GENERAL_LOOKASIDE *v66; 
  UINT64 DesiredAccessa; 
  NTSTATUS v68; 
  INT8 v69; 
  PVOID Handle; 
  PSLIST_ENTRY ListEntry; 

  v16 = DesiredAccess;
  v17 = CreateOptions;
  Handle = 0i64;
  v18 = Options;
  v19 = 0;
  PreviousMode = KeGetCurrentThread()->PreviousMode;
  if( (Options & 0x100) == 0 )
    v19 = PreviousMode;
  v69 = v19;
  CurrentPrcb = KeGetCurrentPrcb();
  P = CurrentPrcb->PPLookasideList[8].P;
  ++P->TotalAllocates;
  ParseContext = RtlpInterlockedPopEntrySList(&P->ListHead);
  ListEntry = ParseContext;
  if( !ParseContext )
  {
    ++P->AllocateMisses;
    L = CurrentPrcb->PPLookasideList[8].L;
    ++L->TotalAllocates;
    ParseContext = RtlpInterlockedPopEntrySList(&L->ListHead);
    ListEntry = ParseContext;
    if( !ParseContext )
    {
      ++L->AllocateMisses;
      ParseContext = (PSLIST_ENTRY)((__int64(__fastcall *)(_QWORD, _QWORD, _QWORD))L->AllocateEx)(
                                     (unsigned int)L->Type,
                                     L->Size,
                                     L->Tag);
      ListEntry = ParseContext;
    }
  }
  if( !ParseContext )
    return -1073741670;
  LODWORD(ParseContext->Next) = CurrentPrcb->Number;
  if( !v19 && (Options & 0x200) == 0 )
  {
    v27 = CreateFileType;
    goto LABEL_24;
  }
  if( (ShareAccess & 0xFFFFFFF8) != 0
    || (FileAttributes & 0xFFA50048) != 0
    || (unsigned int)Disposition > 5
    || (CreateOptions & 0xFF000000) != 0
    || (CreateOptions & 0x30) != 0 && (v16 & 0x100000) == 0
    || (v16 & 0x10000) == 0 && (CreateOptions & 0x1000) != 0
    || (CreateOptions & 0x30) == 48
    || (CreateOptions & 0x41) == 1 && ((CreateOptions & 0xFF5E0ACC) != 0 || (unsigned int)(Disposition - 1) > 2)
    || (CreateOptions & 0x100100) == 1048832
    || (CreateOptions & 0x10100) == 65792
    || (CreateOptions & 0x110000) == 1114112
    || (v16 & 4) != 0 && (CreateOptions & 8) != 0 )
  {
    v24 = KeGetCurrentPrcb();
    v25 = v24->PPLookasideList[8].P;
    ++v25->TotalFrees;
    if( LOWORD(v25->ListHead.Alignment) >= v25->Depth )
    {
      ++v25->FreeMisses;
      v25 = v24->PPLookasideList[8].L;
      ++v25->TotalFrees;
      if( LOWORD(v25->ListHead.Alignment) >= v25->Depth )
      {
LABEL_166:
        ++v25->FreeMisses;
        ((void(__fastcall *)(PSLIST_ENTRY))v25->FreeEx)(ParseContext);
        return -1073741811;
      }
    }
LABEL_11:
    RtlpInterlockedPushEntrySList(&v25->ListHead, ParseContext);
    return -1073741811;
  }
  if( !IopFailZeroAccessCreate || v16 )
  {
    v27 = CreateFileType;
    switch( CreateFileType )
    {
      case CreateFileTypeNone:
LABEL_23:
        v18 = Options;
LABEL_24:
        if( v69 )
        {
          *((_QWORD *)&ParseContext[4].Next + 1) = 0i64;
          v28 = (__int64)FileHandle;
          if( (unsigned __int64)FileHandle >= 0x7FFFFFFF0000i64 )
            v28 = 0x7FFFFFFF0000i64;
          *(_QWORD *)v28 = *(_QWORD *)v28;
          v29 = (__int64)IoStatusBlock;
          if( (unsigned __int64)IoStatusBlock >= 0x7FFFFFFF0000i64 )
            v29 = 0x7FFFFFFF0000i64;
          *(_DWORD *)v29 = *(_DWORD *)v29;
          if( AllocationSize )
          {
            if( ((unsigned __int8)AllocationSize & 3) != 0 )
              ExRaiseDatatypeMisalignment();
            QuadPart = (void *)AllocationSize->QuadPart;
            Handle = QuadPart;
            if( (__int64)QuadPart < 0 )
              RtlRaiseStatus(-1073741811);
          }
          else
          {
            QuadPart = 0i64;
            Handle = 0i64;
          }
          if( EaBuffer && (_DWORD)EaLength )
          {
            if( ((unsigned __int8)EaBuffer & 3) != 0 )
              ExRaiseDatatypeMisalignment();
            if( (unsigned __int64)EaBuffer + (unsigned int)EaLength > 0x7FFFFFFF0000i64
              || (char *)EaBuffer + (unsigned int)EaLength < EaBuffer )
            {
              MEMORY[0x7FFFFFFF0000] = 0;
            }
            PoolWithQuotaTag = ExAllocatePoolWithQuotaTag(NonPagedPoolNx, (unsigned int)EaLength, 0x61456F49ui64);
            *((_QWORD *)&ParseContext[4].Next + 1) = PoolWithQuotaTag;
            LODWORD(ParseContext[5].Next) = EaLength;
            memmove(PoolWithQuotaTag, EaBuffer, EaLength);
            v58 = IoCheckEaBufferValidity(
                    *((PFILE_FULL_EA_INFORMATION *)&ParseContext[4].Next + 1),
                    (unsigned int)EaLength,
                    (PULONG)&IoStatusBlock->Information);
            if( v58 < 0 )
            {
              IoStatusBlock->Status = v58;
              RtlRaiseStatus(v58);
            }
            goto LABEL_39;
          }
LABEL_38:
          *((_QWORD *)&ParseContext[4].Next + 1) = 0i64;
          LODWORD(ParseContext[5].Next) = 0;
          goto LABEL_39;
        }
        if( (CreateOptions & 0x80000000) != 0i64 )
        {
          LODWORD(Options) = v18 | 0x400;
          v17 = CreateOptions & 0x7FFFFFFF;
        }
        if( !AllocationSize )
        {
          QuadPart = Handle;
          goto LABEL_79;
        }
        QuadPart = (void *)AllocationSize->QuadPart;
        if( AllocationSize->QuadPart >= 0 )
        {
          Handle = (PVOID)AllocationSize->QuadPart;
LABEL_79:
          if( !EaBuffer || !(_DWORD)EaLength )
            goto LABEL_38;
          PoolWithTag = ExAllocatePoolWithTag(0x200ui64, (unsigned int)EaLength, 1631940425i64);
          *((_QWORD *)&ParseContext[4].Next + 1) = PoolWithTag;
          if( PoolWithTag )
          {
            LODWORD(ParseContext[5].Next) = EaLength;
            memmove(PoolWithTag, EaBuffer, EaLength);
            v61 = IoCheckEaBufferValidity(
                    *((PFILE_FULL_EA_INFORMATION *)&ParseContext[4].Next + 1),
                    (unsigned int)EaLength,
                    (PULONG)&IoStatusBlock->Information);
            v68 = v61;
            if( v61 < 0 )
            {
              ExFreePoolWithTag(*((PVOID *)&ParseContext[4].Next + 1), 0);
              IoStatusBlock->Status = v61;
LABEL_70:
              v47 = KeGetCurrentPrcb();
              v48 = v47->PPLookasideList[8].P;
              ++v48->TotalFrees;
              if( LOWORD(v48->ListHead.Alignment) < v48->Depth
                || (++v48->FreeMisses,
                    v48 = v47->PPLookasideList[8].L,
                    ++v48->TotalFrees,
                    LOWORD(v48->ListHead.Alignment) < v48->Depth) )
              {
                RtlpInterlockedPushEntrySList(&v48->ListHead, ParseContext);
              }
              else
              {
                ++v48->FreeMisses;
                ((void(__fastcall *)(PSLIST_ENTRY))v48->FreeEx)(ParseContext);
              }
              return v68;
            }
LABEL_39:
            LODWORD(ParseContext->Next) = 14155784;
            LODWORD(ParseContext[2].Next) = 0;
            *((_QWORD *)&ParseContext[1].Next + 1) = 0i64;
            *((_QWORD *)&ParseContext[3].Next + 1) = QuadPart;
            LODWORD(ParseContext[4].Next) = v17;
            WORD2(ParseContext[4].Next) = FileAttributes;
            HIWORD(ParseContext[4].Next) = ShareAccess;
            *((_DWORD *)&ParseContext[5].Next + 2) = Disposition;
            *((_WORD *)&ParseContext[8].Next + 4) = 0;
            *((_BYTE *)&ParseContext[8].Next + 10) = 0;
            HIDWORD(ParseContext[5].Next) = Options;
            *((_QWORD *)&ParseContext[2].Next + 1) = 0i64;
            ParseContext[3].Next = (_SLIST_ENTRY *)ObjectAttributes;
            *((_DWORD *)&ParseContext[7].Next + 2) = v27;
            ParseContext[8].Next = (_SLIST_ENTRY *)InternalParameters;
            *((_DWORD *)&ParseContext[9].Next + 2) = InternalFlags;
            v31 = v69;
            *((_BYTE *)&ParseContext[9].Next + 12) = v69;
            ParseContext[10] = 0i64;
            ParseContext[11] = 0i64;
            Size = 40;
            LOWORD(ParseContext[10].Next) = 40;
            ParseContext[12].Next = (_SLIST_ENTRY *)1;
            if( DriverContext )
            {
              if( (unsigned __int64)DriverContext->Size <= 0x28 )
                Size = DriverContext->Size;
              memmove(&ParseContext[10], DriverContext, Size);
            }
            if( ParseContext[12].Next == (_SLIST_ENTRY *)1 )
              ParseContext[12].Next = (_SLIST_ENTRY *)PsGetCurrentSilo();
            LODWORD(ParseContext[1].Next) = 0;
            *((_QWORD *)&ParseContext->Next + 1) = 0i64;
            CurrentThread = (_ETHREAD *)KeGetCurrentThread();
            ++CurrentThread->Tcb.OtherOperationCount;
            __incgsdword(0x2EE4u);
            LODWORD(DesiredAccessa) = v16;
            v34 = ObOpenObjectByNameEx(
                    ObjectAttributes,
                    (_OBJECT_TYPE *)IoFileObjectType,
                    v69,
                    0i64,
                    DesiredAccessa,
                    ParseContext,
                    (_EJOB *)ParseContext[12].Next,
                    &Handle);
            v68 = v34;
            v35 = (void *)*((_QWORD *)&ParseContext[4].Next + 1);
            if( v35 )
              ExFreePoolWithTag(v35, 0);
            v36 = *((_QWORD *)&ParseContext[10].Next + 1);
            if( v36 )
            {
              v37 = *(_DWORD *)(v36 + 4);
              if( (v37 & 0x3F0) != 0 )
              {
                *(_DWORD *)(v36 + 4) = v37 - 16;
LABEL_63:
                *((_QWORD *)&ParseContext[10].Next + 1) = 0i64;
                goto LABEL_64;
              }
              v38 = (__int64 **)(v36 + 8);
              if( (v37 & 1) == 0 )
              {
                while( 1 )
                {
                  v39 = *v38;
                  if( *v38 == (__int64 *)v38 )
                    break;
                  v40 = *v39;
                  if( (__int64 **)v39[1] != v38 || *(__int64 **)(v40 + 8) != v39 )
                    goto LABEL_156;
                  *v38 = (__int64 *)v40;
                  *(_QWORD *)(v40 + 8) = v38;
                  v39[1] = 0i64;
                  *v39 = 0i64;
                  v41 = v39 + 8;
                  v42 = 0i64;
                  v43 = (void(__fastcall *)(_QWORD, _QWORD))v39[4];
                  if( v43 )
                    v43(v41, v41 - 6);
                  if( (*(_DWORD *)(v41 - 3) & 0x20) != 0 && *(&stru_140CF2E80 + 599) )
                  {
                    v42 = *(v41 - 1);
                    ((void(__fastcall *)(__int64, _QWORD *))**(&stru_140CF2E80 + 599))(v42, v41);
                  }
                  v44 = *(v41 - 2);
                  if( v44 )
                  {
                    if( (*(_DWORD *)(v41 - 3) & 0x40) != 0 )
                    {
                      ExFreeToNPagedLookasideList((_NPAGED_LOOKASIDE_LIST *)v44, v41 - 9);
                    }
                    else
                    {
                      ++*(_DWORD *)(v44 + 28);
                      if( *(_WORD *)v44 >= *(_WORD *)(v44 + 16) )
                      {
                        ++*(_DWORD *)(v44 + 32);
                        (*(void(__fastcall **)(_QWORD *))(v44 + 56))(v41 - 9);
                      }
                      else
                      {
                        RtlpInterlockedPushEntrySList((PSLIST_HEADER)v44, (PSLIST_ENTRY)(v41 - 9));
                      }
                    }
                  }
                  else
                  {
                    ExFreePoolWithTag(v41 - 9, 0);
                  }
                  if( v42 )
                    (*(void(__fastcall **)(__int64))(*(&stru_140CF2E80 + 599) + 8i64))(v42);
                }
                if( (*(_DWORD *)(v36 + 4) & 4) != 0 )
                {
                  ++*(&WheapErrorSourceTable + 145);
                  if( *(&WheapErrorSourceTable + 276) >= *(&WheapErrorSourceTable + 284) )
                  {
                    ++*(&WheapErrorSourceTable + 146);
                    (*(&WheapErrorSourceTable + 76))(v36);
                  }
                  else
                  {
                    RtlpInterlockedPushEntrySList(
                      (PSLIST_HEADER)((char *)&WheapErrorSourceTable + 552),
                      (PSLIST_ENTRY)v36);
                  }
                }
                else
                {
                  ExFreePoolWithTag((PVOID)v36, 0);
                }
                v31 = v69;
                goto LABEL_63;
              }
              v52 = *v38;
              while( v52 != (__int64 *)v38 )
              {
                v53 = v52;
                v52 = (__int64 *)*v52;
                if( (v53[5] & 1) == 0 )
                {
                  v54 = (__int64 *)*v53;
                  v55 = (__int64 **)v53[1];
                  if( *(__int64 **)(*v53 + 8) != v53 || *v55 != v53 )
LABEL_156:
                    __fastfail(3u);
                  *v55 = v54;
                  v54[1] = (__int64)v55;
                  v53[1] = 0i64;
                  *v53 = 0i64;
                  FsRtlFreeExtraCreateParameter(v53 + 8);
                }
              }
              v31 = v69;
            }
LABEL_64:
            Next = (int)ParseContext[2].Next;
            if( v34 >= 0 )
            {
              if( Next == -1096154543 )
              {
                *(_DWORD *)(*((_QWORD *)&ParseContext->Next + 1) + 80i64) |= 0x40000u;
                *(_DWORD *)(*((_QWORD *)&ParseContext->Next + 1) + 80i64) &= ~0x2000000u;
                *FileHandle = Handle;
                IoStatusBlock->Information = *((_QWORD *)&ParseContext[1].Next + 1);
                IoStatusBlock->Status = (int)ParseContext[1].Next;
                v68 = (NTSTATUS)ParseContext[1].Next;
LABEL_67:
                if( Next == -1096154543 )
                {
                  v46 = (_ADAPTER_OBJECT *)*((_QWORD *)&ParseContext->Next + 1);
                  if( v46 )
                    HalPutDmaAdapter(v46);
                }
                goto LABEL_70;
              }
              ObCloseHandle(Handle, v31);
              v34 = -1073741788;
              v68 = -1073741788;
            }
            v49 = (int)ParseContext[1].Next;
            if( v49 >= 0 )
            {
              v56 = *((_QWORD *)&ParseContext->Next + 1);
              if( v56 )
              {
                if( Next == -1096154543 )
                {
                  if( (*(_DWORD *)(v56 + 80) & 0x40000) == 0 )
                    IopCloseFile(0i64, *((PVOID *)&ParseContext->Next + 1), 1ui64, (UINT8 *)1);
                }
                else
                {
                  if( *(_WORD *)(v56 + 88) )
                  {
                    ExFreePoolWithTag(*(PVOID *)(v56 + 96), 0);
                    v56 = *((_QWORD *)&ParseContext->Next + 1);
                  }
                  *(_QWORD *)(v56 + 8) = 0i64;
                  HalPutDmaAdapter(*((PADAPTER_OBJECT *)&ParseContext->Next + 1));
                }
              }
            }
            else
            {
              v34 = (NTSTATUS)ParseContext[1].Next;
              v68 = v34;
              if( (v49 & 0xC0000000) == 0x80000000 || v49 == -1073741191 )
              {
                IoStatusBlock->Status = v49;
                IoStatusBlock->Information = *((_QWORD *)&ParseContext[1].Next + 1);
              }
            }
            if( v34 == -1073741772 )
            {
              v50 = *((_QWORD *)&ParseContext[1].Next + 1) - 2684354563i64;
              if( v50 <= 0x16 )
              {
                v51 = 4194817i64;
                if( _bittest64(&v51, v50) )
                  v68 = -1073741184;
              }
            }
            goto LABEL_67;
          }
          v65 = KeGetCurrentPrcb();
          v66 = v65->PPLookasideList[8].P;
          ++v66->TotalFrees;
          if( LOWORD(v66->ListHead.Alignment) < v66->Depth
            || (++v66->FreeMisses,
                v66 = v65->PPLookasideList[8].L,
                ++v66->TotalFrees,
                LOWORD(v66->ListHead.Alignment) < v66->Depth) )
          {
            RtlpInterlockedPushEntrySList(&v66->ListHead, ParseContext);
          }
          else
          {
            ++v66->FreeMisses;
            ((void(__fastcall *)(PSLIST_ENTRY))v66->FreeEx)(ParseContext);
          }
          return -1073741670;
        }
LABEL_145:
        v64 = KeGetCurrentPrcb();
        v25 = v64->PPLookasideList[8].P;
        ++v25->TotalFrees;
        if( LOWORD(v25->ListHead.Alignment) >= v25->Depth )
        {
          ++v25->FreeMisses;
          v25 = v64->PPLookasideList[8].L;
          ++v25->TotalFrees;
          if( LOWORD(v25->ListHead.Alignment) >= v25->Depth )
            goto LABEL_166;
        }
        goto LABEL_11;
      case CreateFileTypeNamedPipe:
        if( !InternalParameters
          || (*(_DWORD *)InternalParameters & 0xFFFFFFFC) != 0
          || *((_DWORD *)InternalParameters + 1) > 1u
          || *((_DWORD *)InternalParameters + 2) > 1u
          || (ShareAccess & 4) != 0
          || (unsigned int)(Disposition - 1) > 2 )
        {
          goto LABEL_145;
        }
        break;
      case CreateFileTypeMailslot:
        if( !InternalParameters
          || (ShareAccess & 0xFFFFFFFD) == 0
          || (ShareAccess & 4) != 0
          || (_DWORD)Disposition != 2 )
        {
          goto LABEL_145;
        }
        break;
      default:
        goto LABEL_23;
    }
    if( (CreateOptions & 0xFFFFFFCD) != 0 )
      goto LABEL_145;
    goto LABEL_23;
  }
  v62 = KeGetCurrentPrcb();
  v63 = v62->PPLookasideList[8].P;
  ++v63->TotalFrees;
  if( LOWORD(v63->ListHead.Alignment) < v63->Depth
    || (++v63->FreeMisses,
        v63 = v62->PPLookasideList[8].L,
        ++v63->TotalFrees,
        LOWORD(v63->ListHead.Alignment) < v63->Depth) )
  {
    RtlpInterlockedPushEntrySList(&v63->ListHead, ParseContext);
  }
  else
  {
    ++v63->FreeMisses;
    ((void(__fastcall *)(PSLIST_ENTRY))v63->FreeEx)(ParseContext);
  }
  return -1073741790;
}

Referenced by:

IoCreateFile
IoCreateFileEx
NtCreateFile
NtOpenFile