IopCloseFile

VOID __fastcall IopCloseFile(INT64 *a1){
  _FILE_OBJECT *v1; 
  __int64 v2; 
  __int64 v3; 
  __int64 v4; 
  FILE_OBJECT *v5; 
  VOID *FileObjectExtension; 
  _QWORD *v8; 
  int v9; 
  unsigned int Flags; 
  _DEVICE_OBJECT *RelatedDeviceObject; 
  int v12; 
  _DEVICE_OBJECT *v13; 
  _ETHREAD *CurrentThread; 
  __int64 v15; 
  _IRP *IrpMustSucceed; 
  __int64 v17; 
  _ETHREAD *v18; 
  VOID **v19; 
  _FILE_OBJECT *v20; 
  int v21; 
  unsigned int v22; 
  _DEVICE_OBJECT *v23; 
  _DEVICE_OBJECT *v24; 
  __int64 v25; 
  _ETHREAD *v26; 
  __int64 v27; 
  __int64(__fastcall *v28)(FILE_OBJECT *, _QWORD, __int128 *, _DEVICE_OBJECT *, PLARGE_INTEGER); 
  void *v29; 
  char v30; 
  _IRP *v31; 
  __int64 v32; 
  PLARGE_INTEGER Timeout; 
  __int128 v34; 
  struct _KEVENT Event; 
  __int64 v36; 
  v4 = v3;
  v5 = v1;
  FileObjectExtension = 0i64;
  v8 = 0i64;
  v9 = 0;
  memset(&Event, 0, sizeof(Event));
  if( v2 == 1 )
  {
    if( v1->FileObjectExtension )
    {
      FileObjectExtension = IopGetFileObjectExtension(v1, FoExtTypeIosbRange, 0i64);
      v8 = IopGetFileObjectExtension(v20, (_FILE_OBJECT_EXTENSION_TYPE)((_DWORD)v19 + 4), v19);
    }
    if( v4 == 1 )
    {
      Flags = v5->Flags;
      if( (Flags & 0x800) != 0 )
      {
        IoGetAttachedDevice(v5->DeviceObject);
      }
      else
      {
        RelatedDeviceObject = IoGetRelatedDeviceObject(v5);
        Flags = v5->Flags;
      }
      v12 = Flags | 0x40000;
      v13 = RelatedDeviceObject;
      v5->Flags = v12;
      if( a1 && (v12 & 2) != 0 )
      {
        v9 = 1;
        while( 1 )
        {
          CurrentThread = (_ETHREAD *)KeGetCurrentThread();
          --*((_WORD *)CurrentThread + 242);
          LODWORD(v15) = KeAbPreAcquire(&v5->Lock, 0i64, 0i64);
          if( !_InterlockedExchange((volatile __int32 *)&v5->Busy, 1) )
            break;
          if( !(unsigned int)IopWaitAndAcquireFileObjectLock(v5, 0i64) )
            goto LABEL_14;
        }
        if( v15 )
          *(_BYTE *)(v15 + 26) |= 1u;
        ObfReferenceObject(v5);
      }
LABEL_14:
      if( v8 )
        IopFreeBandwidthContract(v5, v8);
      KeInitializeEvent(&Event, SynchronizationEvent, 0);
      IopResetEvent(v5);
      IrpMustSucceed = IopAllocateIrpMustSucceed(v13, *((_BYTE *)v13 + 76));
      *((_QWORD *)IrpMustSucceed + 24) = v5;
      *((_QWORD *)IrpMustSucceed + 19) = KeGetCurrentThread();
      *((_QWORD *)IrpMustSucceed + 9) = (char *)IrpMustSucceed + 48;
      v17 = *((_QWORD *)IrpMustSucceed + 23);
      *((_BYTE *)IrpMustSucceed + 64) = 0;
      *((_QWORD *)IrpMustSucceed + 10) = &Event;
      *((_QWORD *)IrpMustSucceed + 11) = 0i64;
      *((_DWORD *)IrpMustSucceed + 4) = 1028;
      *(_BYTE *)(v17 - 72) = 18;
      *(_QWORD *)(v17 - 24) = v5;
      IopQueueThreadIrp(IrpMustSucceed);
      v18 = (_ETHREAD *)KeGetCurrentThread();
      ++*((_QWORD *)v18 + 114);
      __incgsdword(0x2EE4u);
      if( IofCallDriver(v13, IrpMustSucceed) == 259 )
        KeWaitForSingleObject(&Event, UserRequest, 0, 0, 0i64);
      *((_QWORD *)IrpMustSucceed + 19) = KeGetCurrentThread();
      IopDequeueIrpFromThread(IrpMustSucceed);
      IoFreeIrp(IrpMustSucceed);
      if( v9 )
        IopReleaseFileObjectLock((PADAPTER_OBJECT)v5);
      if( v5->CompletionContext || FileObjectExtension )
        IopCleanupProcessResources((INT64)v5, (INT64)a1, (INT64)FileObjectExtension);
      if( v5->FileObjectExtension )
        IopCloseFileObjectExtension(v5);
    }
    else
    {
      if( v5->CompletionContext || FileObjectExtension )
        IopCleanupProcessResources((INT64)v5, (INT64)a1, (INT64)FileObjectExtension);
      IopSetLockOperationProcess((__int64)v5, (__int64)a1, 1);
      if( v21 >= 0 )
      {
        v22 = v5->Flags;
        v34 = 0i64;
        if( (v22 & 0x800) != 0 )
        {
          IoGetAttachedDevice(v5->DeviceObject);
        }
        else
        {
          v23 = IoGetRelatedDeviceObject(v5);
          v22 = v5->Flags;
        }
        v24 = v23;
        v25 = *(_QWORD *)(*((_QWORD *)v23 + 1) + 80i64);
        if( (v22 & 2) != 0 && (*((_DWORD *)KeGetCurrentThread() + 324) & 1) == 0 )
        {
          v9 = 1;
          while( 1 )
          {
            v26 = (_ETHREAD *)KeGetCurrentThread();
            --*((_WORD *)v26 + 242);
            LODWORD(v27) = KeAbPreAcquire(&v5->Lock, 0i64, 0i64);
            if( !_InterlockedExchange((volatile __int32 *)&v5->Busy, 1) )
              break;
            Timeout = (PLARGE_INTEGER)&v36;
            if( !(unsigned int)IopWaitAndAcquireFileObjectLock(v5, 0i64) )
              goto LABEL_46;
          }
          if( v27 )
            *(_BYTE *)(v27 + 26) |= 1u;
          ObfReferenceObject(v5);
        }
LABEL_46:
        if( !v25 )
          goto LABEL_54;
        v28 = *(__int64(__fastcall **)(FILE_OBJECT *, _QWORD, __int128 *, _DEVICE_OBJECT *, PLARGE_INTEGER))(v25 + 64);
        if( !v28 )
          goto LABEL_54;
        if( (MmVerifierData & 0x10) != 0 )
          v29 = VfFastIoSnapState();
        else
          v29 = 0i64;
        v30 = v28(v5, *((_QWORD *)KeGetCurrentThread() + 23), &v34, v24, Timeout);
        if( v29 )
          VfFastIoCheckState(v29, v28);
        if( !v30 )
        {
LABEL_54:
          KeInitializeEvent(&Event, SynchronizationEvent, 0);
          IopResetEvent(v5);
          v31 = IopAllocateIrpMustSucceed(v24, *((_BYTE *)v24 + 76));
          *((_QWORD *)v31 + 24) = v5;
          *((_QWORD *)v31 + 19) = KeGetCurrentThread();
          *((_QWORD *)v31 + 9) = (char *)v31 + 48;
          v32 = *((_QWORD *)v31 + 23);
          *((_BYTE *)v31 + 64) = 0;
          *((_QWORD *)v31 + 10) = &Event;
          *((_DWORD *)v31 + 4) = 4;
          *((_QWORD *)v31 + 11) = 0i64;
          *(_WORD *)(v32 - 72) = 785;
          *(_QWORD *)(v32 - 24) = v5;
          ObfReferenceObject(v5);
          IopQueueThreadIrp(v31);
          if( IofCallDriver(v24, v31) == 259 )
            KeWaitForSingleObject(&Event, UserRequest, 0, 0, 0i64);
        }
        if( v9 == 1 )
          IopReleaseFileObjectLock((PADAPTER_OBJECT)v5);
      }
    }
  }
}

Referenced by:

IopCreateFile
IopDeleteFile
IopParseDevice