FsRtlpOplockCleanup

VOID __stdcall FsRtlpOplockCleanup(_NONOPAQUE_OPLOCK *Oplock, _IO_STACK_LOCATION *IrpSp){
  char v3; 
  char v4; 
  _IO_STACK_LOCATION *v5; 
  char v6; 
  INT64 OplockFullFoExt; 
  _NONOPAQUE_OPLOCK *i; 
  _LIST_ENTRY *Flink; 
  _QWORD *v10; 
  __int64 v11; 
  _QWORD *v12; 
  _NONOPAQUE_OPLOCK *v13; 
  int v14; 
  _EPROCESS *ExclusiveOplockOwner; 
  INT64 v16; 
  _RH_OP_CONTEXT *v17; 
  char v18; 
  _QWORD *v19; 
  __int64 v20; 
  _QWORD *v21; 
  unsigned int OplockState; 
  _IRP *IrpExclusiveOplock; 
  __int64 v24; 
  __int64 v25; 
  _LIST_ENTRY *v26; 
  INT64 v27; 
  INT64 v28; 
  UINT64 v29; 
  char v30; 
  v3 = 0;
  v4 = 0;
  v30 = 0;
  if( Oplock->OplockState == 1 )
    goto LABEL_61;
  OplockFullFoExt = IoGetOplockFullFoExt(*((_QWORD *)IrpSp + 6));
  if( (Oplock->OplockState & 0x1000000) != 0 )
  {
    for( i = (_NONOPAQUE_OPLOCK *)Oplock->DelayAckFileObjectQueue.Flink;
          i != (_NONOPAQUE_OPLOCK *)&Oplock->DelayAckFileObjectQueue;
          i = (_NONOPAQUE_OPLOCK *)i->IrpExclusiveOplock )
    {
      if( (_EPROCESS *)*((_QWORD *)v5 + 6) == i->ExclusiveOplockOwner )
      {
        while( 1 )
        {
          Flink = Oplock->WaitingIrps.Flink;
          if( Flink == &Oplock->WaitingIrps )
            break;
          FsRtlpRemoveAndCompleteWaitingIrp((_WAITING_IRP *)Flink);
        }
        v10 = *(_QWORD **)i->FileObject;
        v11 = *v10;
        v12 = (_QWORD *)v10[1];
        if( *(_QWORD **)(*v10 + 8i64) != v10 || (_QWORD *)*v12 != v10 )
          __fastfail(3u);
        *v12 = v11;
        *(_QWORD *)(v11 + 8) = v12;
        ObfDereferenceObjectWithTag(i->ExclusiveOplockOwner, 0x746C6644ui64);
        ExFreePoolWithTag(i, 0);
        v5 = IrpSp;
        v6 = 1;
        break;
      }
    }
    Oplock->OplockState &= ~0x1000000u;
    if( Oplock->DelayAckFileObjectQueue.Flink != &Oplock->DelayAckFileObjectQueue )
      v4 = v6;
    v30 = v4;
  }
  v13 = (_NONOPAQUE_OPLOCK *)Oplock->IrpOplocksR.Flink;
  v14 = 534;
  if( v13 != (_NONOPAQUE_OPLOCK *)&Oplock->IrpOplocksR )
  {
    while( v13 != (_NONOPAQUE_OPLOCK *)&Oplock->IrpOplocksR )
    {
      ExclusiveOplockOwner = v13->ExclusiveOplockOwner;
      if( *((_QWORD *)v5 + 6) == *((_QWORD *)ExclusiveOplockOwner + 6) )
      {
        v13 = (_NONOPAQUE_OPLOCK *)v13->FileObject;
        if( *((_DWORD *)ExclusiveOplockOwner + 6) == 590400 )
          v3 = v6;
        v16 = 534i64;
        if( *((_DWORD *)ExclusiveOplockOwner + 6) != 590400 )
          v16 = 0i64;
        FsRtlpRemoveAndCompleteReadOnlyIrp((LIST_ENTRY *)v13->IrpExclusiveOplock, v16, 0i64);
        if( v3 )
          break;
        v5 = IrpSp;
        v6 = 1;
      }
      v13 = (_NONOPAQUE_OPLOCK *)v13->IrpExclusiveOplock;
    }
    FsRtlpComputeShareableOplockState(Oplock);
  }
  if( OplockFullFoExt )
  {
    v17 = *(_RH_OP_CONTEXT **)(OplockFullFoExt + 40);
    if( v17 )
    {
      v18 = 0;
      if( (v17->Flags & 0xF00000) != 0 )
      {
        FsRtlpOplockDequeueRH(v17);
        FsRtlpModifyThreadPriorities(Oplock, v17, 0);
        FsRtlpClearOwner((INT64)Oplock, (INT64)v17);
        if( Oplock->RHBreakQueue.Flink == &Oplock->RHBreakQueue )
          Oplock->WaiterPriority = 0;
        ObfDereferenceObjectWithTag(v17->OplockRequestFileObject, 0x746C6644ui64);
      }
      else
      {
        if( (Oplock->OplockState & 0x10000) == 0 || !v17->AtomicLinks.Flink )
        {
          if( (unsigned int)Feature_Servicing_39887415__private_IsEnabled() )
          {
            LODWORD(v28) = 0;
            LODWORD(v27) = 0;
            FsRtlpRemoveAndCompleteRHIrp((INT64)v17, (INT64)Oplock, 534i64, 0i64, v27, v28, 0);
          }
          else
          {
            LODWORD(v29) = 0;
            LODWORD(v28) = 0;
            LODWORD(v27) = 0;
            FsRtlpRemoveAndBreakRHIrp(&v17->Links, Oplock, 1u, 534i64, v27, v28, v29, 0);
          }
LABEL_46:
          FsRtlpComputeShareableOplockState(Oplock);
          if( v18 )
            FsRtlpReleaseIrpsWaitingForRH((INT64)Oplock);
          goto LABEL_48;
        }
        FsRtlpOplockDequeueRH(v17);
        v20 = *v19;
        v21 = (_QWORD *)v19[1];
        if( *(_QWORD **)(*v19 + 8i64) != v19 || (_QWORD *)*v21 != v19 )
          __fastfail(3u);
        *v21 = v20;
        *(_QWORD *)(v20 + 8) = v21;
        if( Oplock->AtomicQueue.Flink == &Oplock->AtomicQueue )
          Oplock->OplockState &= 0xFFFCFFFF;
        if( v17->OplockOwnerThread )
          FsRtlpClearOwner((INT64)Oplock, (INT64)v17);
      }
      ExFreePoolWithTag(v17, 0);
      v18 = 1;
      goto LABEL_46;
    }
  }
LABEL_48:
  if( (_FILE_OBJECT *)*((_QWORD *)IrpSp + 6) == Oplock->FileObject )
  {
    OplockState = Oplock->OplockState;
    if( (OplockState & 0x1F00F80) == 0 )
    {
      IrpExclusiveOplock = Oplock->IrpExclusiveOplock;
      v24 = *((_QWORD *)Oplock->IrpExclusiveOplock + 23);
      *((_BYTE *)IrpExclusiveOplock + 69) = KeAcquireQueuedSpinLock(7ui64);
      _InterlockedExchange64((volatile __int64 *)IrpExclusiveOplock + 13, 0i64);
      KeReleaseQueuedSpinLock(7ui64, *((_BYTE *)IrpExclusiveOplock + 69));
      if( *(_DWORD *)(v24 + 24) == 590400 )
      {
        v25 = *((_QWORD *)IrpExclusiveOplock + 3);
        *(_OWORD *)v25 = 0i64;
        *(_QWORD *)(v25 + 16) = 0i64;
        *(_DWORD *)v25 = 1572865;
        *(_DWORD *)(v25 + 4) = (Oplock->OplockState >> 12) & 7;
        *((_QWORD *)IrpExclusiveOplock + 7) = 24i64;
      }
      else
      {
        *((_QWORD *)IrpExclusiveOplock + 7) = 8i64;
        v14 = 0;
      }
      *((_DWORD *)Oplock->IrpExclusiveOplock + 12) = v14;
      IofCompleteRequest(Oplock->IrpExclusiveOplock, 1);
      OplockState = Oplock->OplockState;
      v4 = v30;
    }
    if( (OplockState & 0x80u) == 0 )
      ObfDereferenceObjectWithTag(Oplock->FileObject, 0x746C6644ui64);
    Oplock->FileObject = 0i64;
    Oplock->IrpExclusiveOplock = 0i64;
    if( Oplock->ExclusiveOplockOwnerThread )
    {
      FsRtlpModifyThreadPriorities(Oplock, 0i64, 0);
      FsRtlpClearOwner((INT64)Oplock, 0i64);
      Oplock->WaiterPriority = 0;
    }
    Oplock->OplockState = Oplock->OplockState & 0x20 | 1;
    while( 1 )
    {
      v26 = Oplock->WaitingIrps.Flink;
      if( v26 == &Oplock->WaitingIrps )
        break;
      FsRtlpRemoveAndCompleteWaitingIrp((_WAITING_IRP *)v26);
    }
  }
LABEL_61:
  if( v4 )
    Oplock->OplockState |= 0x1000000u;
}

Referenced by:

FsRtlCheckOplockEx2