NtSetInformationFile

NTSTATUS __stdcall NtSetInformationFile(
        VOID *FileHandle,
        IO_STATUS_BLOCK *IoStatusBlock,
        VOID *FileInformation,
        UINT64 Length,
        FILE_INFORMATION_CLASS FileInformationClass){
  UINT64 v5; 
  _ETHREAD *CurrentThread; 
  CHAR v9; 
  FILE_INFORMATION_CLASS v10; 
  unsigned int v11; 
  __int64 v12; 
  __int64 v13; 
  __int16 v14; 
  __int64 v15; 
  unsigned int v16; 
  NTSTATUS result; 
  NTSTATUS Status; 
  struct _DMA_ADAPTER *v19; 
  unsigned int *p_Flags; 
  unsigned int Flags; 
  _DEVICE_OBJECT *RelatedDeviceObject; 
  _ETHREAD *v23; 
  PFILE_OBJECT v24; 
  __int64 v25; 
  __int64 v26; 
  _ETHREAD *v27; 
  struct _DMA_ADAPTER *v28; 
  char v29; 
  IRP *v30; 
  IRP *v31; 
  IO_STATUS_BLOCK *p_IoStatusBlocka; 
  KEVENT *p_Event; 
  __int64 v34; 
  UINT8 *PoolWithQuota; 
  PIRP v36; 
  __int64 v37; 
  _ETHREAD *v38; 
  unsigned __int64 v39; 
  __int64 v40; 
  UINT8 v41; 
  KPROCESSOR_MODE v42; 
  unsigned __int8 CurrentIrql; 
  UINT8 v44; 
  int v45; 
  _DWORD *v46; 
  bool v47; 
  void **v48; 
  PFILE_OBJECT v49; 
  void *v50; 
  UINT64 v51; 
  _IO_COMPLETION_CONTEXT *PoolWithTag; 
  UINT8 v53; 
  UINT64 *p_IrpListLock; 
  int *v55; 
  unsigned int v56; 
  int v57; 
  _DWORD *v58; 
  unsigned int v59; 
  char v60; 
  NTSTATUS v61; 
  char IsSandboxedToken; 
  NTSTATUS v63; 
  __int64 v64; 
  _KEVENT *p_DmaOperations; 
  int v66; 
  NTSTATUS v67; 
  NTSTATUS v68; 
  _DWORD *v69; 
  __int64 v70; 
  struct _DMA_ADAPTER *v71; 
  void *v72; 
  int *v73; 
  int v74; 
  unsigned int v75; 
  unsigned int v76; 
  unsigned int v77; 
  unsigned __int8 v78; 
  char v79; 
  UINT8 v80; 
  char v81; 
  PFILE_OBJECT FileObject; 
  char v83; 
  char v84; 
  PDEVICE_OBJECT DeviceObject; 
  PIRP Irp; 
  PVOID Object; 
  KEVENT Event; 
  UINT8 *v89; 
  __int64 v90; 
  PVOID v91; 
  PVOID FoExt; 
  __int64 v93; 
  HANDLE Handle; 
  _IO_STATUS_BLOCK IoStatusBlocka; 
  PVOID v96; 
  __int64 v97; 
  struct _SECURITY_SUBJECT_CONTEXT SubjectContext; 
  __int64 v99; 
  VOID *retaddr; 
  v5 = (unsigned int)Length;
  FileObject = 0i64;
  memset(&Event, 0, sizeof(Event));
  IoStatusBlocka = 0i64;
  Handle = 0i64;
  v80 = 0;
  v81 = 0;
  v84 = 0;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v89 = (UINT8 *)CurrentThread;
  v9 = *((_BYTE *)CurrentThread + 562);
  v78 = v9;
  if( v9 )
  {
    v10 = FileInformationClass;
    if( (unsigned int)FileInformationClass >= FileMaximumInformation )
      return -1073741821;
    v11 = *((unsigned __int8 *)IopSetOperationLength + (int)FileInformationClass);
    if( !(_BYTE)v11 )
      return -1073741821;
    if( (unsigned int)Length < v11 )
      return -1073741820;
    v12 = (__int64)IoStatusBlock;
    if( (unsigned __int64)IoStatusBlock >= 0x7FFFFFFF0000i64 )
      v12 = 0x7FFFFFFF0000i64;
    *(_DWORD *)v12 = *(_DWORD *)v12;
    v13 = *(_QWORD *)(*((_QWORD *)CurrentThread + 23) + 1408i64);
    if( v13 && ((v14 = *(_WORD *)(v13 + 8), v14 == 332) || v14 == 452) )
    {
      if( !(_DWORD)Length )
        goto LABEL_26;
      if( (_DWORD)Length == 1 )
        v15 = 0i64;
      else
        v15 = 3i64;
      if( (v15 & (unsigned __int64)FileInformation) != 0 )
        ExRaiseDatatypeMisalignment();
      if( (unsigned __int64)FileInformation + (unsigned int)Length <= 0x7FFFFFFF0000i64
        && (char *)FileInformation + (unsigned int)Length >= FileInformation )
      {
        goto LABEL_26;
      }
    }
    else
    {
      if( !(_DWORD)Length )
        goto LABEL_26;
      if( ((*((unsigned __int8 *)IopQuerySetAlignmentRequirement + (int)FileInformationClass) - 1i64) & (unsigned __int64)FileInformation) != 0 )
        ExRaiseDatatypeMisalignment();
      if( (unsigned __int64)FileInformation + (unsigned int)Length <= 0x7FFFFFFF0000i64
        && (char *)FileInformation + (unsigned int)Length >= FileInformation )
      {
        goto LABEL_26;
      }
    }
    MEMORY[0x7FFFFFFF0000] = 0;
LABEL_26:
    v16 = IopSetOperationAccess[FileInformationClass];
    if( FileInformationClass == FileLinkInformation || FileInformationClass == FileLinkInformationEx )
    {
      memset(&SubjectContext, 0, sizeof(SubjectContext));
      SeCaptureSubjectContextEx(CurrentThread, *((_EPROCESS **)CurrentThread + 68), &SubjectContext);
      IsSandboxedToken = RtlIsSandboxedToken(&SubjectContext, v9);
      SeReleaseSubjectContext(&SubjectContext);
      if( IsSandboxedToken )
        v16 |= 0x100u;
    }
    goto LABEL_28;
  }
  v10 = FileInformationClass;
  switch( FileInformationClass )
  {
    case FileRenameInformationBypassAccessCheck:
      v10 = FileRenameInformation;
      v81 = 1;
      break;
    case FileRenameInformationExBypassAccessCheck:
      v10 = FileRenameInformationEx;
      v81 = 1;
      break;
    case FileLinkInformationBypassAccessCheck:
      v10 = FileLinkInformation;
      v81 = 1;
      break;
    case FileLinkInformationExBypassAccessCheck:
      v10 = FileLinkInformationEx;
      v81 = 1;
      break;
    case FileCaseSensitiveInformationForceAccessCheck:
      v10 = FileCaseSensitiveInformation;
      v84 = 1;
      break;
  }
  v16 = IopSetOperationAccess[v10];
LABEL_28:
  result = IopReferenceFileObject(FileHandle, v16, v9, &FileObject, 0i64);
  Status = result;
  if( result < 0 )
    return result;
  v19 = (struct _DMA_ADAPTER *)FileObject;
  p_Flags = &FileObject->Flags;
  Flags = FileObject->Flags;
  if( (Flags & 0x800) != 0 )
  {
    IoGetAttachedDevice(FileObject->DeviceObject);
  }
  else
  {
    RelatedDeviceObject = IoGetRelatedDeviceObject(FileObject);
    Flags = *p_Flags;
  }
  DeviceObject = RelatedDeviceObject;
  if( (Flags & 2) != 0 )
  {
    v23 = (_ETHREAD *)KeGetCurrentThread();
    --*((_WORD *)v23 + 242);
    v24 = FileObject;
    LODWORD(v25) = KeAbPreAcquire(&FileObject->Lock, 0i64, 0i64);
    v83 = 0;
    if( _InterlockedExchange((volatile __int32 *)&v24->Busy, 1) )
    {
      v19 = (struct _DMA_ADAPTER *)FileObject;
      Status = IopWaitAndAcquireFileObjectLock(FileObject, v78);
    }
    else
    {
      if( v25 )
        *(_BYTE *)(v25 + 26) |= 1u;
      v19 = (struct _DMA_ADAPTER *)FileObject;
      ObfReferenceObject(FileObject);
      Status = 0;
    }
    LODWORD(Irp) = Status;
    if( v83 )
    {
      v28 = v19;
LABEL_43:
      HalPutDmaAdapter(v28);
      return Status;
    }
    if( v10 == FilePositionInformation )
    {
      if( (unsigned int)v5 >= 8 )
      {
        v26 = *(_QWORD *)FileInformation;
        v99 = *(_QWORD *)FileInformation;
        if( (*p_Flags & 8) != 0
          && (v45 = *((unsigned __int16 *)DeviceObject + 152), (_WORD)v45)
          && ((v45 - 1) & (unsigned int)v26) != 0
          || v26 < 0 )
        {
          Status = -1073741811;
        }
        else
        {
          v19[6].DmaOperations = (_DMA_OPERATIONS *)v26;
          IoStatusBlock->Status = 0;
          IoStatusBlock->Information = 0i64;
        }
        v27 = (_ETHREAD *)KeGetCurrentThread();
        *((_QWORD *)v27 + 117) += (unsigned int)v5;
        __addgsqword(0x2EF8u, (unsigned int)v5);
        IopReleaseFileObjectLock((PADAPTER_OBJECT)FileObject);
        v28 = (struct _DMA_ADAPTER *)FileObject;
        goto LABEL_43;
      }
      IopReleaseFileObjectLock(v19);
      HalPutDmaAdapter(v19);
      return -1073741820;
    }
    v29 = 1;
  }
  else
  {
    LOWORD(Event.Header.Lock) = 1;
    Event.Header.Size = 6;
    Event.Header.SignalState = 0;
    Event.Header.WaitListHead.Blink = &Event.Header.WaitListHead;
    Event.Header.WaitListHead.Flink = &Event.Header.WaitListHead;
    v29 = 0;
  }
  v79 = v29;
  IopResetEvent((FILE_OBJECT *)v19);
  if( v10 != FileTrackingInformation )
  {
    v30 = IopAllocateIrpExReturn(DeviceObject, *((_BYTE *)DeviceObject + 76), v29 ^ 1u, retaddr);
    v31 = v30;
    Irp = v30;
    if( !v30 )
    {
      IopAllocateIrpCleanup((PUNICODE_STRING)v19);
      return -1073741670;
    }
    *((_QWORD *)v30 + 24) = v19;
    *((_QWORD *)v30 + 19) = v89;
    *((_BYTE *)v30 + 64) = v78;
    if( v79 )
    {
      *((_BYTE *)v30 + 71) |= 2u;
      p_IoStatusBlocka = IoStatusBlock;
      p_Event = 0i64;
    }
    else
    {
      if( v78 == 1 )
        v80 = KeSetKernelStackSwapEnable(0);
      *((_DWORD *)v31 + 4) = 4;
      p_IoStatusBlocka = &IoStatusBlocka;
      p_Event = &Event;
    }
    *((_QWORD *)v31 + 10) = p_Event;
    *((_QWORD *)v31 + 9) = p_IoStatusBlocka;
    *((_QWORD *)v31 + 11) = 0i64;
    v34 = *((_QWORD *)v31 + 23) - 72i64;
    v90 = v34;
    *(_BYTE *)v34 = 6;
    *(_QWORD *)(v34 + 48) = v19;
    *((_QWORD *)v31 + 3) = 0i64;
    *((_QWORD *)v31 + 1) = 0i64;
    PoolWithQuota = (UINT8 *)IopVerifierExAllocatePoolWithQuota(NonPagedPool, v5);
    v89 = PoolWithQuota;
    v36 = Irp;
    *((_QWORD *)Irp + 3) = PoolWithQuota;
    memmove(PoolWithQuota, (UINT8 *)FileInformation, v5);
    if( ((unsigned int)(v10 - 19) <= 1 || v10 == FilePositionInformation) && *((int *)v89 + 1) < 0 )
      RtlRaiseStatus(-1073741811);
    *((_DWORD *)v36 + 4) |= 0x830u;
    v37 = v90;
    *(_DWORD *)(v90 + 8) = v5;
    *(_DWORD *)(v37 + 16) = v10;
    if( v81 || v84 )
      *(_BYTE *)(v37 + 2) |= 1u;
    IopQueueThreadIrp(v36);
    v38 = (_ETHREAD *)KeGetCurrentThread();
    ++*((_QWORD *)v38 + 114);
    __incgsdword(0x2EE4u);
    if( v10 == FileModeInformation )
    {
      v73 = (int *)*((_QWORD *)v36 + 3);
      v74 = *v73;
      if( (*v73 & 0xFFFFFFC9) != 0
        || (v74 & 0x30) != 0 && (*p_Flags & 2) == 0
        || (v74 & 0x30) == 0 && (*p_Flags & 2) != 0
        || (*v73 & 0x30) == 48 )
      {
        Status = -1073741811;
      }
      else
      {
        v75 = *p_Flags;
        if( (*p_Flags & 8) == 0 )
        {
          if( (v74 & 2) != 0 )
            v75 |= 0x10u;
          else
            v75 &= ~0x10u;
          *p_Flags = v75;
        }
        if( (*v73 & 4) != 0 )
          v76 = v75 | 0x20;
        else
          v76 = v75 & 0xFFFFFFDF;
        *p_Flags = v76;
        if( (v76 & 2) != 0 )
        {
          if( (*v73 & 0x10) != 0 )
            v77 = v76 | 4;
          else
            v77 = v76 & 0xFFFFFFFB;
          *p_Flags = v77;
        }
        Status = 0;
      }
      *((_DWORD *)v36 + 12) = Status;
      *((_QWORD *)v36 + 7) = 0i64;
      v41 = v79;
      goto LABEL_71;
    }
    v39 = (unsigned int)(v10 - 10);
    if( (unsigned int)v39 <= 0x3E && (v40 = 0x4080000000200003i64, _bittest64(&v40, v39)) )
    {
      v58 = (_DWORD *)*((_QWORD *)v36 + 3);
      v59 = v58[4];
      if( !v59 || (v59 & 1) != 0 || (int)v5 - 20 < v59 )
      {
        Status = -1073741811;
        *((_DWORD *)v36 + 12) = -1073741811;
        v41 = v79;
        goto LABEL_71;
      }
      if( v10 == FileMoveClusterInformation )
      {
        *(_DWORD *)(v37 + 32) = *v58;
      }
      else
      {
        if( v10 == FileRenameInformationEx || v10 == FileLinkInformationEx )
          v60 = *(_BYTE *)v58 & 1;
        else
          v60 = *(_BYTE *)v58;
        *(_BYTE *)(v37 + 32) = v60;
      }
      if( *((_WORD *)v58 + 10) == 92 || *((_QWORD *)v58 + 1) )
      {
        v61 = IopOpenLinkOrRenameTarget(&Handle, v36, v58, FileObject);
        Status = v61;
        v41 = v79;
        if( v61 < 0 )
        {
          *((_DWORD *)v36 + 12) = v61;
          goto LABEL_71;
        }
LABEL_70:
        Status = IopCallDriverReference(DeviceObject, v36, v41, FileObject, OtherTransfer);
LABEL_71:
        v42 = v78;
        goto LABEL_72;
      }
    }
    else
    {
      if( v10 == FileShortNameInformation )
      {
        v64 = *((_QWORD *)v36 + 3);
        v41 = v79;
        if( (unsigned int)(v5 - 4) < *(_DWORD *)v64 )
        {
          Status = -1073741811;
          *((_DWORD *)v36 + 12) = -1073741811;
          goto LABEL_71;
        }
        if( *(_WORD *)(v64 + 4) == 92 )
        {
          Status = -1073741811;
          *((_DWORD *)v36 + 12) = -1073741811;
          goto LABEL_71;
        }
        goto LABEL_70;
      }
      if( v10 != FileDispositionInformationEx && v10 != FileDispositionInformation )
      {
        switch( v10 )
        {
          case FileCompletionInformation:
            v48 = (void **)*((_QWORD *)v36 + 3);
            v90 = (__int64)v48;
            v49 = FileObject;
            if( FileObject->CompletionContext || (*p_Flags & 2) != 0 )
            {
              Status = -1073741811;
            }
            else
            {
              v50 = *v48;
              Object = 0i64;
              Status = ObReferenceObjectByHandle(v50, 2u, IoCompletionObjectType, v78, &Object, 0i64);
              if( Status >= 0 )
              {
                PoolWithTag = (_IO_COMPLETION_CONTEXT *)ExAllocatePoolWithTag(NonPagedPoolNx, 0x18ui64, 0x63436F49ui64);
                if( PoolWithTag )
                {
                  KeAcquireSpinLockRaiseToDpc(&v49->IrpListLock, v51);
                  p_IrpListLock = &v49->IrpListLock;
                  if( v49->CompletionContext )
                  {
                    KeReleaseSpinLock(p_IrpListLock, v53);
                    ExFreePoolWithTag(PoolWithTag, 0);
                    HalPutDmaAdapter((PADAPTER_OBJECT)Object);
                    Status = -1073741752;
                  }
                  else
                  {
                    *p_Flags &= ~0x400u;
                    PoolWithTag->Port = Object;
                    PoolWithTag->Key = *(void **)(v90 + 8);
                    PoolWithTag->UsageCount = 0i64;
                    v49->CompletionContext = PoolWithTag;
                    Status = 0;
                    KeReleaseSpinLock(p_IrpListLock, v53);
                  }
                }
                else
                {
                  HalPutDmaAdapter((PADAPTER_OBJECT)Object);
                  Status = -1073741670;
                }
              }
            }
            *((_DWORD *)v36 + 12) = Status;
            *((_QWORD *)v36 + 7) = 0i64;
            v41 = v79;
            goto LABEL_71;
          case FileReplaceCompletionInformation:
            v70 = *((_QWORD *)v36 + 3);
            v71 = 0i64;
            v96 = 0i64;
            if( FileObject->CompletionContext )
            {
              v72 = *(void **)v70;
              if( *(_QWORD *)v70 )
              {
                v91 = 0i64;
                Status = ObReferenceObjectByHandle(v72, 2u, IoCompletionObjectType, v78, &v91, 0i64);
                v71 = (struct _DMA_ADAPTER *)v91;
                v96 = v91;
              }
              if( Status >= 0 )
              {
                Status = IopReplaceCompletionPort((__int64)FileObject, v71, *(_QWORD *)(v70 + 8));
                if( v71 )
                  HalPutDmaAdapter(v71);
              }
              goto LABEL_152;
            }
            break;
          case FileIoCompletionNotificationInformation:
            v55 = (int *)*((_QWORD *)v36 + 3);
            v56 = *p_Flags;
            if( (*p_Flags & 2) != 0 )
            {
              Status = -1073741811;
            }
            else
            {
              Status = 0;
              v57 = *v55;
              if( (*v55 & 1) != 0 )
              {
                v56 |= 0x2000000u;
                *p_Flags = v56;
                v57 = *v55;
              }
              if( (v57 & 2) != 0 )
              {
                v56 |= 0x4000000u;
                *p_Flags = v56;
                v57 = *v55;
              }
              if( (v57 & 4) != 0 )
                *p_Flags = v56 | 0x8000000;
            }
            *((_DWORD *)v36 + 12) = Status;
            *((_QWORD *)v36 + 7) = 0i64;
            v41 = v79;
            goto LABEL_71;
          case FileIoStatusBlockRangeInformation:
            if( SeSinglePrivilegeCheck(*(_QWORD *)&SeLockMemoryPrivilege, v78) )
            {
              if( (*p_Flags & 2) != 0 )
                Status = -1073741811;
              else
                Status = IopSetFileObjectIosbRange(FileObject, v36);
            }
            else
            {
              Status = -1073741727;
            }
            *((_DWORD *)v36 + 12) = Status;
            *((_QWORD *)v36 + 7) = 0i64;
            v41 = v79;
            goto LABEL_71;
          case FileIoPriorityHintInformation:
            FoExt = 0i64;
            v69 = (_DWORD *)*((_QWORD *)v36 + 3);
            if( *v69 <= 2u )
            {
              Status = IopAllocateFileObjectExtension(FileObject, &FoExt);
              if( Status >= 0 )
                *((_DWORD *)FoExt + 20) = *v69 + 1;
              goto LABEL_152;
            }
            break;
          case FileMemoryPartitionInformation:
            v42 = v78;
            if( v78 )
            {
              Status = -1073741790;
            }
            else
            {
              Status = IopSetFileMemoryPartitionInformation(FileObject, *((_QWORD *)v36 + 3), (unsigned int)v5);
              v42 = 0;
            }
            *((_DWORD *)v36 + 12) = Status;
            *((_QWORD *)v36 + 7) = 0i64;
            v41 = v79;
LABEL_72:
            if( Status == 259 )
            {
              if( !v41 )
              {
                v63 = KeWaitForSingleObject(&Event, Executive, v42, 0, 0i64);
                if( v63 == 257 || v63 == 192 )
                  IopCancelAlertedRequest(&Event, v36);
                Status = IoStatusBlocka.Status;
                *IoStatusBlock = IoStatusBlocka;
                v44 = v80;
                goto LABEL_78;
              }
              IopWaitForSynchronousIo(v36, FileObject, v42);
              Status = v68;
            }
            else
            {
              v97 = 0i64;
              v93 = 0i64;
              if( !v41 )
                *((_QWORD *)v36 + 10) = 0i64;
              *((_QWORD *)v36 + 9) = IoStatusBlock;
              CurrentIrql = KeGetCurrentIrql();
              __writecr8(1ui64);
              IopCompleteRequest((__int64)v36 + 120, (__int64)&v97, &v93, (ULONG_PTR *)&FileObject, &v93);
              __writecr8(CurrentIrql);
              if( !v41 )
                goto LABEL_77;
            }
            IopReleaseFileObjectLock((PADAPTER_OBJECT)FileObject);
LABEL_77:
            v44 = v80;
LABEL_78:
            if( v44 )
              KeSetKernelStackSwapEnable(1u);
            if( Handle )
              ObCloseHandle(Handle, 0);
            return Status;
          default:
            goto LABEL_69;
        }
        Status = -1073741811;
LABEL_152:
        *((_DWORD *)v36 + 12) = Status;
        *((_QWORD *)v36 + 7) = 0i64;
        v41 = v79;
        goto LABEL_71;
      }
      v46 = (_DWORD *)*((_QWORD *)v36 + 3);
      if( v10 == FileDispositionInformationEx )
        v47 = (*v46 & 1) == 0;
      else
        v47 = *(_BYTE *)v46 == 0;
      if( !v47 )
        *(_QWORD *)(v37 + 32) = FileHandle;
    }
LABEL_69:
    v41 = v79;
    goto LABEL_70;
  }
  if( (unsigned int)v5 < 0x10 )
  {
    v67 = -1073741820;
  }
  else
  {
    if( v29 )
      p_DmaOperations = (_KEVENT *)&v19[9].DmaOperations;
    else
      p_DmaOperations = &Event;
    v66 = IopTrackLink(
            (_FILE_OBJECT *)v19,
            &IoStatusBlocka,
            (_FILE_TRACKING_INFORMATION *)FileInformation,
            (unsigned int)v5,
            p_DmaOperations,
            v78);
    v67 = v66;
    LODWORD(Irp) = v66;
    if( v66 >= 0 )
    {
      IoStatusBlock->Information = 0i64;
      IoStatusBlock->Status = v66;
    }
  }
  if( v29 )
    IopReleaseFileObjectLock(v19);
  HalPutDmaAdapter(v19);
  return v67;
}

Referenced by:

No references.