IopCloseFile

VOID __fastcall IopCloseFile(_EPROCESS *Process, PVOID Object, UINT64 a3, UINT8 *a4){
  UINT8 *v4; 
  _IOP_FOEXT_IOSB_RANGE *FileObjectExtension; 
  _QWORD *v8; 
  int v9; 
  int v10; 
  _DEVICE_OBJECT *v11; 
  int v12; 
  _DEVICE_OBJECT *v13; 
  _ETHREAD *CurrentThread; 
  _BYTE *v15; 
  _IRP *IrpMustSucceed; 
  _IO_STACK_LOCATION *CurrentStackLocation; 
  _ETHREAD *v18; 
  VOID **v19; 
  _FILE_OBJECT *v20; 
  int v21; 
  _DEVICE_OBJECT *v22; 
  _DEVICE_OBJECT *v23; 
  _FAST_IO_DISPATCH *FastIoDispatch; 
  _ETHREAD *v25; 
  _BYTE *v26; 
  unsigned __int8(__fastcall *FastIoUnlockAll)(_FILE_OBJECT *, _EPROCESS *, _IO_STATUS_BLOCK *, _DEVICE_OBJECT *); 
  VOID *v28; 
  unsigned __int8 v29; 
  _IRP *v30; 
  _IO_STACK_LOCATION *v31; 
  PLARGE_INTEGER Timeout; 
  UINT64 v33; 
  INT64 v34; 
  __int128 v35; 
  __int128 Objecta; 
  __int64 v37; 
  INT64 v38; 

  v37 = 0i64;
  v4 = a4;
  FileObjectExtension = 0i64;
  v8 = 0i64;
  v9 = 0;
  Objecta = 0i64;
  if( a3 == 1 )
  {
    if( *((_QWORD *)Object + 26) )
    {
      FileObjectExtension = (_IOP_FOEXT_IOSB_RANGE *)IopGetFileObjectExtension(
                                                       (_FILE_OBJECT *)Object,
                                                       FoExtTypeIosbRange,
                                                       0i64);
      v8 = IopGetFileObjectExtension(v20, (_FILE_OBJECT_EXTENSION_TYPE)((_DWORD)v19 + 4), v19);
    }
    if( v4 == (UINT8 *)1 )
    {
      v10 = *((_DWORD *)Object + 20);
      if( (v10 & 0x800) != 0 )
      {
        LODWORD(v11) = IoGetAttachedDevice(*((_QWORD *)Object + 1));
      }
      else
      {
        LODWORD(v11) = IoGetRelatedDeviceObject((INT64)Object);
        v10 = *((_DWORD *)Object + 20);
      }
      v12 = v10 | 0x40000;
      v13 = v11;
      *((_DWORD *)Object + 20) = v12;
      if( Process && (v12 & 2) != 0 )
      {
        v9 = 1;
        while( 1 )
        {
          CurrentThread = (_ETHREAD *)KeGetCurrentThread();
          --CurrentThread->Tcb.KernelApcDisable;
          v15 = KeAbPreAcquire((char *)Object + 128, 0i64, 0i64);
          if( !_InterlockedExchange((volatile __int32 *)Object + 29, 1) )
            break;
          if( !IopWaitAndAcquireFileObjectLock(Object, 0, 0, v15, (INT64)&v34) )
            goto LABEL_14;
        }
        if( v15 )
          v15[26] |= 1u;
        ObfReferenceObject(Object);
      }
LABEL_14:
      if( v8 )
        IopFreeBandwidthContract(Object, v8);
      KeInitializeEvent((INT64)&Objecta, 1, 0);
      IopResetEvent((_FILE_OBJECT *)Object);
      IrpMustSucceed = IopAllocateIrpMustSucceed(v13, v13->StackSize);
      IrpMustSucceed->Tail.OriginalFileObject = (_FILE_OBJECT *)Object;
      IrpMustSucceed->Tail.Thread = (_ETHREAD *)KeGetCurrentThread();
      IrpMustSucceed->UserIosb = &IrpMustSucceed->IoStatus;
      CurrentStackLocation = IrpMustSucceed->Tail.CurrentStackLocation;
      IrpMustSucceed->RequestorMode = 0;
      IrpMustSucceed->UserEvent = (_KEVENT *)&Objecta;
      IrpMustSucceed->Overlay.UserApcRoutine = 0i64;
      IrpMustSucceed->Flags = 1028;
      CurrentStackLocation[-1].MajorFunction = 18;
      CurrentStackLocation[-1].FileObject = (_FILE_OBJECT *)Object;
      IopQueueThreadIrp(IrpMustSucceed);
      v18 = (_ETHREAD *)KeGetCurrentThread();
      ++v18->Tcb.OtherOperationCount;
      __incgsdword(0x2EE4u);
      if( IofCallDriver((UINT64)v13, (UINT64)IrpMustSucceed) == 259 )
        KeWaitForSingleObject((UINT64)&Objecta, 6, 0, 0, 0i64);
      IrpMustSucceed->Tail.Thread = (_ETHREAD *)KeGetCurrentThread();
      IopDequeueIrpFromThread(IrpMustSucceed);
      IoFreeIrp(IrpMustSucceed);
      if( v9 )
        IopReleaseFileObjectLock((PADAPTER_OBJECT)Object);
      if( *((_QWORD *)Object + 22) || FileObjectExtension )
        IopCleanupProcessResources((_FILE_OBJECT *)Object, Process, FileObjectExtension);
      if( *((_QWORD *)Object + 26) )
        IopCloseFileObjectExtension((_FILE_OBJECT *)Object);
    }
    else
    {
      if( *((_QWORD *)Object + 22) || FileObjectExtension )
        IopCleanupProcessResources((_FILE_OBJECT *)Object, Process, FileObjectExtension);
      LOBYTE(a3) = 1;
      if( IopSetLockOperationProcess(
             (UINT16)Object,
             Process->Pcb.gap0,
             a3,
             a4,
             (UINT64)Timeout,
             v33,
             v34,
             (UINT64 *)v35,
             *((PVOID *)&v35 + 1)) >= 0 )
      {
        v21 = *((_DWORD *)Object + 20);
        v35 = 0i64;
        if( (v21 & 0x800) != 0 )
        {
          LODWORD(v22) = IoGetAttachedDevice(*((_QWORD *)Object + 1));
        }
        else
        {
          LODWORD(v22) = IoGetRelatedDeviceObject((INT64)Object);
          v21 = *((_DWORD *)Object + 20);
        }
        v23 = v22;
        FastIoDispatch = v22->DriverObject->FastIoDispatch;
        if( (v21 & 2) != 0 && (*(_DWORD *)&KeGetCurrentThread()[1].gapD8[8] & 1) == 0 )
        {
          v9 = 1;
          while( 1 )
          {
            v25 = (_ETHREAD *)KeGetCurrentThread();
            --v25->Tcb.KernelApcDisable;
            v26 = KeAbPreAcquire((char *)Object + 128, 0i64, 0i64);
            if( !_InterlockedExchange((volatile __int32 *)Object + 29, 1) )
              break;
            if( !IopWaitAndAcquireFileObjectLock(Object, 0, 0, v26, (INT64)&v38) )
              goto LABEL_46;
          }
          if( v26 )
            v26[26] |= 1u;
          ObfReferenceObject(Object);
        }
LABEL_46:
        if( !FastIoDispatch )
          goto LABEL_54;
        FastIoUnlockAll = FastIoDispatch->FastIoUnlockAll;
        if( !FastIoUnlockAll )
          goto LABEL_54;
        if( (MmVerifierData & 0x10) != 0 )
          v28 = VfFastIoSnapState();
        else
          v28 = 0i64;
        v29 = FastIoUnlockAll(
                (_FILE_OBJECT *)Object,
                KeGetCurrentThread()->ApcState.Process,
                (_IO_STATUS_BLOCK *)&v35,
                v23);
        if( v28 )
          VfFastIoCheckState(v28, FastIoUnlockAll);
        if( !v29 )
        {
LABEL_54:
          KeInitializeEvent((INT64)&Objecta, 1, 0);
          IopResetEvent((_FILE_OBJECT *)Object);
          v30 = IopAllocateIrpMustSucceed(v23, v23->StackSize);
          v30->Tail.OriginalFileObject = (_FILE_OBJECT *)Object;
          v30->Tail.Thread = (_ETHREAD *)KeGetCurrentThread();
          v30->UserIosb = &v30->IoStatus;
          v31 = v30->Tail.CurrentStackLocation;
          v30->RequestorMode = 0;
          v30->UserEvent = (_KEVENT *)&Objecta;
          v30->Flags = 4;
          v30->Overlay.UserApcRoutine = 0i64;
          *(_WORD *)&v31[-1].MajorFunction = 785;
          v31[-1].FileObject = (_FILE_OBJECT *)Object;
          ObfReferenceObject(Object);
          IopQueueThreadIrp(v30);
          if( IofCallDriver((UINT64)v23, (UINT64)v30) == 259 )
            KeWaitForSingleObject((UINT64)&Objecta, 6, 0, 0, 0i64);
        }
        if( v9 == 1 )
          IopReleaseFileObjectLock((PADAPTER_OBJECT)Object);
      }
    }
  }
}

Referenced by:

IopCreateFile
IopDeleteFile
IopParseDevice