IopWaitAndAcquireFileObjectLock

NTSTATUS __stdcall IopWaitAndAcquireFileObjectLock(VOID *Object, CHAR a2, UINT8 a3, _BYTE *a4, INT64 a5){
  int v9; 
  UINT64 Flags; 
  _KTHREAD *Thread; 
  UINT64 BoostPriority; 

  _InterlockedIncrement((volatile signed __int32 *)Object + 28);
  do
  {
    if( !*((_DWORD *)Object + 29) && !_InterlockedExchange((volatile __int32 *)Object + 29, 1) )
    {
      if( a4 )
        a4[26] |= 1u;
      ObfReferenceObject(Object);
      _InterlockedDecrement((volatile signed __int32 *)Object + 28);
      return 0;
    }
    if( a4 )
      KeAbPreWait(a4);
    v9 = IopWaitForLockAlertable((char *)Object + 128, a2, a3);
    if( a4 )
      a4 = KeAbPreAcquire((char *)Object + 128, a4, 0i64);
  }
  while( v9 >= 0 );
  _InterlockedDecrement((volatile signed __int32 *)Object + 28);
  if( !*((_DWORD *)Object + 29) && *((_DWORD *)Object + 28) )
  {
    LOBYTE(Flags) = 0;
    LODWORD(BoostPriority) = KeGetCurrentThread()->Priority;
    KeSetEventBoostPriorityEx((char *)Object + 128, (_KTHREAD **)&Thread, &BoostPriority, (char *)Object + 128, Flags);
  }
  if( a4 )
    KeAbPostReleaseEx((char *)Object + 128, a4);
  *(_BYTE *)a5 = 1;
  KeLeaveCriticalRegion();
  return v9;
}

Referenced by:

BuildQueryDirectoryIrp
IoSetInformation
IopCloseFile
IopGetSetSecurityObject
IopQueryXxxInformation
IopSetEaOrQuotaInformationFile
IopXxxControlFile
NtFlushBuffersFileEx
NtLockFile
NtNotifyChangeDirectoryFileEx
NtQueryEaFile
NtQueryInformationFile
NtQueryQuotaInformationFile
NtQueryVolumeInformationFile
NtReadFile
NtReadFileScatter
NtSetEaFile
NtSetInformationFile
NtSetVolumeInformationFile
NtUnlockFile
NtWriteFile
NtWriteFileGather