IopFreeBandwidthContract

__int64 __fastcall IopFreeBandwidthContract(PVOID Object, _QWORD *a2){
  __int64 result; 
  int v4; 
  _DEVICE_OBJECT *v5; 
  UINT64 v6; 
  _IRP *IrpMustSucceed; 
  _IRP *v8; 
  __int128 *p_Objecta; 
  _IO_STACK_LOCATION *CurrentStackLocation; 
  __int128 *v11; 
  _LARGE_INTEGER Interval; 
  __int128 Objecta; 
  __int64 v14; 
  __int128 v15; 
  __int128 v16; 
  int v17; 

  result = 0i64;
  Objecta = 0i64;
  v14 = 0i64;
  v15 = 0i64;
  v17 = 0;
  v16 = 0i64;
  if( (_QWORD *)*a2 != a2 )
  {
    v4 = *((_DWORD *)Object + 20) & 2;
    while( 1 )
    {
      KeInitializeEvent((INT64)&Objecta, 1, 0);
      if( (*((_DWORD *)Object + 20) & 0x4000000) == 0 )
        KeResetEvent((_KEVENT *)((char *)Object + 152));
      v17 = 0;
      v16 = 0i64;
      LODWORD(v5) = IoGetRelatedDeviceObject((INT64)Object);
      v6 = (UINT64)v5;
      IrpMustSucceed = IopAllocateIrpMustSucceed(v5, v5->StackSize);
      v8 = IrpMustSucceed;
      IrpMustSucceed->Tail.OriginalFileObject = (_FILE_OBJECT *)Object;
      IrpMustSucceed->Tail.Thread = (_ETHREAD *)KeGetCurrentThread();
      IrpMustSucceed->RequestorMode = 0;
      if( v4 )
      {
        p_Objecta = 0i64;
      }
      else
      {
        IrpMustSucceed->Flags = 4;
        p_Objecta = &Objecta;
      }
      IrpMustSucceed->UserEvent = (_KEVENT *)p_Objecta;
      IrpMustSucceed->UserIosb = (_IO_STATUS_BLOCK *)&v15;
      CurrentStackLocation = IrpMustSucceed->Tail.CurrentStackLocation;
      v8->Overlay.UserApcRoutine = 0i64;
      CurrentStackLocation[-1].MajorFunction = 6;
      CurrentStackLocation[-1].FileObject = (_FILE_OBJECT *)Object;
      LODWORD(CurrentStackLocation[-1].Parameters.SecurityContext) = 20;
      CurrentStackLocation[-1].Parameters.Options = 44;
      v8->UserBuffer = 0i64;
      v8->MdlAddress = 0i64;
      v8->AssociatedIrp.MasterIrp = (_IRP *)&v16;
      ObfReferenceObject(Object);
      IopQueueThreadIrp(v8);
      if( IofCallDriver(v6, (UINT64)v8) == 259 )
      {
        v11 = (__int128 *)((char *)Object + 152);
        if( !v4 )
          v11 = &Objecta;
        KeWaitForSingleObject((UINT64)v11, 0, 0, 0, 0i64);
      }
      result = (unsigned int)v15;
      if( (_DWORD)v15 != -1073741670 && (_DWORD)v15 != -1073741801 )
        break;
      Interval.QuadPart = -1000000i64;
      KeDelayExecutionThread(0, 0, &Interval);
    }
  }
  return result;
}

Referenced by:

IopCloseFile