FsRtlpAcknowledgeOplockBreakByCacheFlags

INT64 __fastcall FsRtlpAcknowledgeOplockBreakByCacheFlags(
        _NONOPAQUE_OPLOCK *Oplock,
        _IO_STACK_LOCATION *AckIrpSp,
        _IRP *AckIrp,
        UINT64 NewOplockLevel,
        _RH_OP_CONTEXT **NewRHOpContext,
        UINT64 LowerOplockLevel){
  unsigned int v6; 
  unsigned int v8; 
  _DELAY_ACK_FO *PoolWithTag; 
  char v10; 
  char v11; 
  unsigned int OplockState; 
  bool v13; 
  int v14; 
  int v15; 
  unsigned int v16; 
  _LIST_ENTRY *v17; 
  _FILE_OBJECT **v18; 
  int v19; 
  int v20; 
  _DELAY_ACK_FO *v21; 
  int v22; 
  _IO_STACK_LOCATION *v23; 
  _FILE_OBJECT *FileObject; 
  _FILE_OBJECT *v25; 
  _LIST_ENTRY *p_DelayAckFileObjectQueue; 
  _LIST_ENTRY *Flink; 
  _FILE_OBJECT *Blink; 
  UINT8 v29; 
  __int64 v30; 
  _LIST_ENTRY *v31; 
  _LIST_ENTRY *v32; 
  _ETHREAD *v33; 
  _FILE_OBJECT *v34; 
  unsigned int v35; 
  __int64 v36; 
  _LIST_ENTRY *v37; 
  _DELAY_ACK_FO **DelayAckFo; 
  UINT8 *ReleaseIrpsWaitingForExclusive; 
  UINT64 v41; 
  char v42; 
  bool RefFileObject; 
  char v44; 
  UINT8 v45; 
  UINT8 DereferenceExclusiveFileObject; 
  char v47; 
  int v48; 
  _DELAY_ACK_FO *v49; 
  char v50; 
  char v51; 
  _LIST_ENTRY *v52; 
  __int64 v53; 
  __int64 v54; 
  _ETHREAD *CurrentThread; 
  _ETHREAD *v56; 
  _NONOPAQUE_OPLOCK *Oplocka; 
  _IO_STACK_LOCATION *AckIrpSpa; 
  AckIrpSpa = AckIrpSp;
  Oplocka = Oplock;
  v6 = NewOplockLevel;
  v8 = 0;
  PoolWithTag = 0i64;
  v49 = 0i64;
  v42 = 0;
  v10 = 0;
  v47 = 0;
  v50 = 0;
  v44 = 0;
  v11 = 0;
  v51 = 0;
  DereferenceExclusiveFileObject = 0;
  v45 = 0;
  if( !Oplock )
  {
    *((_DWORD *)AckIrp + 12) = -1073741597;
    IofCompleteRequest(AckIrp, 1);
    return 3221225699i64;
  }
  ExAcquireFastMutexUnsafe(Oplock->FastMutex);
  OplockState = Oplocka->OplockState;
  if( (OplockState & 0xF00000) == 0 && (((OplockState & 0x1F0FFDF) - 12288) & 0xFFFF7FFF) != 0
    || (((OplockState & 0x1F0FFDF) - 12288) & 0xFFFF7FFF) == 0 && Oplocka->RHBreakQueue.Flink == &Oplocka->RHBreakQueue )
  {
LABEL_32:
    v8 = -1073741597;
    *((_DWORD *)AckIrp + 12) = -1073741597;
    IofCompleteRequest(AckIrp, 1);
    goto LABEL_98;
  }
  v53 = *((_QWORD *)AckIrp + 3);
  v13 = (*(_DWORD *)(v53 + 8) & 4) == 0;
  v14 = *(_DWORD *)(v53 + 8) & 4;
  v48 = v14;
  RefFileObject = !v13;
  v15 = 0;
  if( v14 )
  {
    PoolWithTag = (_DELAY_ACK_FO *)ExAllocatePoolWithTag((_POOL_TYPE)17, 0x18ui64, 0x6F725346ui64);
    v49 = PoolWithTag;
    PoolWithTag->Links = 0i64;
    PoolWithTag->OriginalFileObject = 0i64;
    v14 = v48;
    v15 = 0;
  }
  v16 = Oplocka->OplockState & 0x1F0FFDF;
  if( v16 <= 0x307040 )
  {
    if( v16 != 3174464 )
    {
      if( v16 == 12288 || v16 == 45056 || v16 == 1060864 )
        goto LABEL_8;
      if( v16 != 1069120 && v16 != 1077312 )
        goto LABEL_32;
    }
LABEL_39:
    v23 = AckIrpSpa;
    if( !v14 )
      goto LABEL_44;
    FileObject = Oplocka->FileObject;
    v25 = (_FILE_OBJECT *)*((_QWORD *)AckIrpSpa + 6);
    if( FileObject == v25 || !FsRtlpOplockKeysEqual(v25, FileObject, 0i64) )
      goto LABEL_32;
    v14 = v48;
    if( !v48 )
    {
LABEL_44:
      if( Oplocka->FileObject != (_FILE_OBJECT *)*((_QWORD *)v23 + 6) )
        goto LABEL_32;
      if( !v14 )
        goto LABEL_81;
    }
    if( v6 )
    {
LABEL_81:
      v35 = Oplocka->OplockState & 0x1F0FFDF;
      if( (v35 == 1069120 || v35 == 1077312 || v35 == 3174464 || v35 == 5271616 || v35 == 8409152 || v35 == 8417344)
        && (v6 & 0x7000) > (Oplocka->OplockState & 0x200000 | ((Oplocka->OplockState & 0x100000 | (Oplocka->OplockState >> 1) & 0x200000) >> 1)) >> 7
        && Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
      {
        v11 = 1;
      }
      if( v11 )
      {
        v36 = *((_QWORD *)AckIrp + 3);
        *(_OWORD *)v36 = 0i64;
        *(_QWORD *)(v36 + 16) = 0i64;
        *(_DWORD *)(v36 + 4) = (Oplocka->OplockState >> 12) & 7;
        *(_DWORD *)(v36 + 8) = (Oplocka->OplockState & 0x200000 | ((Oplocka->OplockState & 0x100000 | (Oplocka->OplockState >> 1) & 0x200000) >> 1)) >> 19;
        *(_DWORD *)(v36 + 12) |= 1u;
        *((_QWORD *)AckIrp + 7) = 24i64;
        v8 = -2147483602;
        *((_DWORD *)AckIrp + 12) = -2147483602;
        IofCompleteRequest(AckIrp, 1);
        goto LABEL_98;
      }
      FsRtlpModifyThreadPriorities(Oplocka, 0i64, 0);
      FsRtlpClearOwner((INT64)Oplocka, 0i64);
      Oplocka->WaiterPriority = 0;
      LODWORD(v41) = LowerOplockLevel;
      v8 = FsRtlpGrantAnyOplockFromExclusive(
             Oplocka,
             AckIrp,
             v23,
             v6,
             NewRHOpContext,
             RefFileObject,
             &v49,
             &v45,
             &DereferenceExclusiveFileObject,
             v41);
      PoolWithTag = v49;
      goto LABEL_93;
    }
    FsRtlpModifyThreadPriorities(Oplocka, 0i64, 0);
    FsRtlpClearOwner((INT64)Oplocka, 0i64);
    Oplocka->WaiterPriority = 0;
    Oplocka->OplockState = Oplocka->OplockState & 0x20 | 1;
    PoolWithTag->OriginalFileObject = Oplocka->FileObject;
    p_DelayAckFileObjectQueue = &Oplocka->DelayAckFileObjectQueue;
    Flink = Oplocka->DelayAckFileObjectQueue.Flink;
    if( Flink->Blink == &Oplocka->DelayAckFileObjectQueue )
    {
      PoolWithTag->Links.Flink = Flink;
      PoolWithTag->Links.Blink = p_DelayAckFileObjectQueue;
      Flink->Blink = &PoolWithTag->Links;
      p_DelayAckFileObjectQueue->Flink = &PoolWithTag->Links;
      PoolWithTag = 0i64;
      v49 = 0i64;
      Oplocka->FileObject = 0i64;
      Oplocka->OplockState |= 0x1000000u;
      *((_DWORD *)AckIrp + 12) = 0;
      IofCompleteRequest(AckIrp, 1);
      goto LABEL_93;
    }
LABEL_80:
    __fastfail(3u);
  }
  if( v16 != 8400896 )
  {
    if( v16 != 5271616 && v16 != 8409152 && v16 != 8417344 )
      goto LABEL_32;
    goto LABEL_39;
  }
LABEL_8:
  v17 = Oplocka->RHBreakQueue.Flink;
  while( 1 )
  {
    v52 = v17;
    if( v17 == &Oplocka->RHBreakQueue )
      goto LABEL_24;
    v18 = (_FILE_OBJECT **)((char *)AckIrpSpa + 48);
    if( v14 )
      break;
    if( (_FILE_OBJECT *)v17[1].Blink == *v18 )
      goto LABEL_12;
LABEL_55:
    v17 = v17->Flink;
    v10 = v47;
  }
  Blink = (_FILE_OBJECT *)v17[1].Blink;
  if( Blink == *v18 )
    goto LABEL_55;
  v29 = FsRtlpOplockKeysEqual(*v18, Blink, 0i64);
  v15 = 0;
  v14 = v48;
  if( !v29 )
    goto LABEL_55;
LABEL_12:
  v42 = 1;
  v19 = (__int64)v17[3].Flink & 0xF00000;
  v20 = LowerOplockLevel;
  if( v19 != 0x800000 )
  {
    if( v19 != 0x100000
      || (v6 & 0x7000) <= 0x3000
      || Oplocka->WaitingIrps.Flink == &Oplocka->WaitingIrps
      && FsRtlpOplockUpperLowerCompatible(v6, (unsigned int)LowerOplockLevel) )
    {
      goto LABEL_14;
    }
    v30 = *((_QWORD *)AckIrp + 3);
    *(_OWORD *)v30 = 0i64;
    *(_QWORD *)(v30 + 16) = 0i64;
    *(_DWORD *)(v30 + 4) = 3;
    if( Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
      v20 = 1;
LABEL_63:
    *(_DWORD *)(v30 + 8) = v20;
    *(_DWORD *)(v30 + 12) |= 1u;
    *((_QWORD *)AckIrp + 7) = 24i64;
    v8 = -2147483602;
    *((_DWORD *)AckIrp + 12) = -2147483602;
    IofCompleteRequest(AckIrp, 1);
    goto LABEL_23;
  }
  if( v6
    && (Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps
     || !FsRtlpOplockUpperLowerCompatible(v6, (unsigned int)LowerOplockLevel)) )
  {
    v30 = *((_QWORD *)AckIrp + 3);
    *(_OWORD *)v30 = 0i64;
    *(_QWORD *)(v30 + 16) = 0i64;
    *(_DWORD *)(v30 + 4) = 3;
    if( Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
      v20 = v15;
    goto LABEL_63;
  }
LABEL_14:
  FsRtlpOplockDequeueRH((_RH_OP_CONTEXT *)v17);
  if( !v22 )
  {
    v44 = 1;
    if( !v6 )
    {
      ObfDereferenceObjectWithTag(v17[1].Blink, 0x746C6644ui64);
      goto LABEL_17;
    }
    goto LABEL_71;
  }
  PoolWithTag->OriginalFileObject = (_FILE_OBJECT *)v17[1].Blink;
  v31 = &Oplocka->DelayAckFileObjectQueue;
  v32 = Oplocka->DelayAckFileObjectQueue.Flink;
  if( v32->Blink != &Oplocka->DelayAckFileObjectQueue )
    goto LABEL_80;
  PoolWithTag->Links.Flink = v32;
  PoolWithTag->Links.Blink = v31;
  v32->Blink = &PoolWithTag->Links;
  v31->Flink = &PoolWithTag->Links;
  PoolWithTag = v21;
  v49 = v21;
LABEL_17:
  if( v6 )
  {
LABEL_71:
    if( (v6 & 0x4040) == 0 && (v6 & 0x3010) != 0 )
    {
      LODWORD(ReleaseIrpsWaitingForExclusive) = v20;
      LOBYTE(DelayAckFo) = 1;
      v8 = FsRtlpRequestShareableOplock(
             &Oplocka,
             AckIrpSpa,
             AckIrp,
             v6,
             NewRHOpContext,
             RefFileObject,
             (INT64)DelayAckFo,
             (UINT64)ReleaseIrpsWaitingForExclusive);
    }
    else
    {
      Oplocka->IrpExclusiveOplock = AckIrp;
      v54 = *((_QWORD *)AckIrp + 23);
      *(_BYTE *)(v54 + 3) |= 1u;
      *((_QWORD *)AckIrp + 7) = Oplocka;
      CurrentThread = (_ETHREAD *)KeGetCurrentThread();
      Oplocka->ExclusiveOplockOwner = (_EPROCESS *)*((_QWORD *)CurrentThread + 23);
      v33 = (_ETHREAD *)KeGetCurrentThread();
      v56 = v33;
      Oplocka->ExclusiveOplockOwnerThread = v33;
      ObfReferenceObjectWithTag(v33, 0x746C6644u);
      Oplocka->WaiterPriority = 0;
      if( v48 )
      {
        ObfReferenceObjectWithTag(*v18, 0x746C6644u);
        v34 = *v18;
      }
      else
      {
        v34 = (_FILE_OBJECT *)v17[1].Blink;
      }
      Oplocka->FileObject = v34;
      Oplocka->OplockState = v6 | Oplocka->OplockState & 0x20 | 0x40;
      *((_BYTE *)AckIrp + 69) = KeAcquireQueuedSpinLock(7ui64);
      if( *((_BYTE *)AckIrp + 68) )
      {
        FsRtlpCancelExclusiveIrp(AckIrp, 1u, !RefFileObject);
      }
      else
      {
        _InterlockedExchange64((volatile __int64 *)AckIrp + 13, (__int64)FsRtlpExclusiveIrpCancelRoutine);
        KeReleaseQueuedSpinLock(7ui64, *((_BYTE *)AckIrp + 69));
      }
      v42 = 1;
      v17 = v52;
      PoolWithTag = v49;
      v8 = 259;
    }
  }
  else
  {
    FsRtlpComputeShareableOplockState(Oplocka);
    v8 = 0;
    *((_DWORD *)AckIrp + 12) = 0;
    IofCompleteRequest(AckIrp, 1);
  }
  FsRtlpModifyThreadPriorities(Oplocka, (_RH_OP_CONTEXT *)v17, 0);
  FsRtlpClearOwner((INT64)Oplocka, (INT64)v17);
  if( Oplocka->RHBreakQueue.Flink == &Oplocka->RHBreakQueue )
    Oplocka->WaiterPriority = 0;
  ExFreePoolWithTag(v17, 0);
  if( v48 )
    Oplocka->OplockState |= 0x1000000u;
LABEL_23:
  v10 = 1;
LABEL_24:
  if( !v42 )
    goto LABEL_32;
  if( v44 )
    FsRtlpReleaseIrpsWaitingForRH((INT64)Oplocka);
  if( !v10 )
  {
LABEL_93:
    if( v45 )
    {
      while( 1 )
      {
        v37 = Oplocka->WaitingIrps.Flink;
        if( v37 == &Oplocka->WaitingIrps )
          break;
        FsRtlpRemoveAndCompleteWaitingIrp((_WAITING_IRP *)v37);
      }
    }
    if( DereferenceExclusiveFileObject )
    {
      ObfDereferenceObjectWithTag(Oplocka->FileObject, 0x746C6644ui64);
      Oplocka->FileObject = 0i64;
    }
  }
LABEL_98:
  if( PoolWithTag )
    ExFreePoolWithTag(PoolWithTag, 0);
  ExReleaseFastMutexUnsafe(Oplocka->FastMutex);
  return v8;
}

Referenced by:

FsRtlpOplockFsctrlInternal