FsRtlpAcknowledgeOplockBreakByCacheFlags

NTSTATUS __stdcall FsRtlpAcknowledgeOplockBreakByCacheFlags(
        _NONOPAQUE_OPLOCK *Oplock,
        _IO_STACK_LOCATION *AckIrpSp,
        _IRP *AckIrp,
        UINT64 NewOplockLevel,
        _RH_OP_CONTEXT **NewRHOpContext,
        UINT64 LowerOplockLevel){
  unsigned int v6; 
  NTSTATUS v8; 
  _DELAY_ACK_FO *PoolWithTag; 
  char v10; 
  char v11; 
  _FILE_OBJECT *FileObject; 
  unsigned int OplockState; 
  bool v14; 
  int v15; 
  int v16; 
  unsigned int v17; 
  _LIST_ENTRY *v18; 
  _FILE_OBJECT **p_FileObject; 
  int v20; 
  int v21; 
  _DELAY_ACK_FO *v22; 
  int v23; 
  _CCHAR v24; 
  _IO_STACK_LOCATION *v25; 
  _FILE_OBJECT *v26; 
  char v27; 
  _CCHAR v28; 
  _LIST_ENTRY *p_DelayAckFileObjectQueue; 
  _LIST_ENTRY *Flink; 
  char v31; 
  union {_IRP *MasterIrp;int IrpCount;void *SystemBuffer;} v32; 
  _LIST_ENTRY *v33; 
  _LIST_ENTRY *v34; 
  _ETHREAD *v35; 
  INT64 v36; 
  INT64 v37; 
  _FILE_OBJECT *Blink; 
  unsigned int v39; 
  union {_IRP *MasterIrp;int IrpCount;void *SystemBuffer;} v40; 
  unsigned int v41; 
  _LIST_ENTRY *v42; 
  UINT64 v44; 
  UINT64 v45; 
  char v46; 
  bool CompleteAckOnClose; 
  char v48; 
  UINT8 ReleaseIrpsWaitingForExclusive; 
  UINT8 DereferenceExclusiveFileObject; 
  char v51; 
  int v52; 
  _DELAY_ACK_FO *DelayAckFo; 
  char v54; 
  char v55; 
  _LIST_ENTRY *v56; 
  union {_IRP *MasterIrp;int IrpCount;void *SystemBuffer;} v57; 
  _IO_STACK_LOCATION *CurrentStackLocation; 
  _ETHREAD *CurrentThread; 
  _ETHREAD *v60; 
  _NONOPAQUE_OPLOCK *Oplocka; 
  _IO_STACK_LOCATION *IrpSp; 

  IrpSp = AckIrpSp;
  Oplocka = Oplock;
  v6 = NewOplockLevel;
  v8 = 0;
  PoolWithTag = 0i64;
  DelayAckFo = 0i64;
  v46 = 0;
  v10 = 0;
  v51 = 0;
  v54 = 0;
  v48 = 0;
  v11 = 0;
  v55 = 0;
  DereferenceExclusiveFileObject = 0;
  ReleaseIrpsWaitingForExclusive = 0;
  if( !Oplock )
  {
    AckIrp->IoStatus.Status = -1073741597;
    IofCompleteRequest(AckIrp, 1);
    return -1073741597;
  }
  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;
    AckIrp->IoStatus.Status = -1073741597;
    LOBYTE(FileObject) = 1;
    IofCompleteRequest(AckIrp, (_CCHAR)FileObject);
    goto LABEL_98;
  }
  v57.MasterIrp = (_IRP *)AckIrp->AssociatedIrp;
  v14 = ((__int64)v57.MasterIrp->MdlAddress & 4) == 0;
  v15 = (__int64)v57.MasterIrp->MdlAddress & 4;
  v52 = v15;
  CompleteAckOnClose = !v14;
  v16 = 0;
  if( v15 )
  {
    PoolWithTag = (_DELAY_ACK_FO *)ExAllocatePoolWithTag(0x11ui64, 0x18ui64, 1869763398i64);
    DelayAckFo = PoolWithTag;
    PoolWithTag->Links = 0i64;
    PoolWithTag->OriginalFileObject = 0i64;
    v15 = v52;
    v16 = 0;
  }
  v17 = Oplocka->OplockState & 0x1F0FFDF;
  if( v17 <= 0x307040 )
  {
    if( v17 != 3174464 )
    {
      if( v17 == 12288 || v17 == 45056 || v17 == 1060864 )
        goto LABEL_8;
      if( v17 != 1069120 && v17 != 1077312 )
        goto LABEL_32;
    }
LABEL_39:
    v25 = IrpSp;
    if( !v15 )
      goto LABEL_44;
    FileObject = Oplocka->FileObject;
    v26 = IrpSp->FileObject;
    if( FileObject == v26 )
      goto LABEL_32;
    FsRtlpOplockKeysEqual(v26, FileObject, 0i64);
    if( !v27 )
      goto LABEL_32;
    v15 = v52;
    if( !v52 )
    {
LABEL_44:
      if( Oplocka->FileObject != v25->FileObject )
        goto LABEL_32;
      if( !v15 )
        goto LABEL_81;
    }
    if( v6 )
    {
LABEL_81:
      v39 = Oplocka->OplockState & 0x1F0FFDF;
      if( (v39 == 1069120 || v39 == 1077312 || v39 == 3174464 || v39 == 5271616 || v39 == 8409152 || v39 == 8417344)
        && (v6 & 0x7000) > (Oplocka->OplockState & 0x200000 | ((Oplocka->OplockState & 0x100000 | (Oplocka->OplockState >> 1) & 0x200000) >> 1)) >> 7
        && Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
      {
        v11 = 1;
      }
      if( v11 )
      {
        v40.MasterIrp = (_IRP *)AckIrp->AssociatedIrp;
        *(_OWORD *)&v40.MasterIrp->Type = 0i64;
        *(_QWORD *)&v40.MasterIrp->Flags = 0i64;
        *(_DWORD *)&v40.MasterIrp->AllocationProcessorNumber = (Oplocka->OplockState >> 12) & 7;
        v41 = (Oplocka->OplockState & 0x200000 | ((Oplocka->OplockState & 0x100000 | (Oplocka->OplockState >> 1) & 0x200000) >> 1)) >> 19;
        LODWORD(v40.MasterIrp->MdlAddress) = v41;
        HIDWORD(v40.MasterIrp->MdlAddress) |= 1u;
        AckIrp->IoStatus.Information = 24i64;
        v8 = -2147483602;
        AckIrp->IoStatus.Status = -2147483602;
        LOBYTE(v41) = 1;
        IofCompleteRequest(AckIrp, v41);
        goto LABEL_98;
      }
      FsRtlpModifyThreadPriorities(Oplocka, 0i64, 0);
      FsRtlpClearOwner(Oplocka, 0i64);
      Oplocka->WaiterPriority = 0;
      LODWORD(v45) = LowerOplockLevel;
      v8 = FsRtlpGrantAnyOplockFromExclusive(
             Oplocka,
             AckIrp,
             v25,
             v6,
             NewRHOpContext,
             CompleteAckOnClose,
             &DelayAckFo,
             &ReleaseIrpsWaitingForExclusive,
             &DereferenceExclusiveFileObject,
             v45);
      PoolWithTag = DelayAckFo;
      goto LABEL_93;
    }
    FsRtlpModifyThreadPriorities(Oplocka, 0i64, 0);
    FsRtlpClearOwner(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;
      DelayAckFo = 0i64;
      Oplocka->FileObject = 0i64;
      Oplocka->OplockState |= 0x1000000u;
      AckIrp->IoStatus.Status = 0;
      LOBYTE(v28) = 1;
      IofCompleteRequest(AckIrp, v28);
      goto LABEL_93;
    }
LABEL_80:
    __fastfail(3u);
  }
  if( v17 != 8400896 )
  {
    if( v17 != 5271616 && v17 != 8409152 && v17 != 8417344 )
      goto LABEL_32;
    goto LABEL_39;
  }
LABEL_8:
  v18 = Oplocka->RHBreakQueue.Flink;
  while( 1 )
  {
    v56 = v18;
    if( v18 == &Oplocka->RHBreakQueue )
      goto LABEL_24;
    p_FileObject = &IrpSp->FileObject;
    if( v15 )
      break;
    if( (_FILE_OBJECT *)v18[1].Blink == *p_FileObject )
      goto LABEL_12;
LABEL_55:
    v18 = v18->Flink;
    v10 = v51;
  }
  FileObject = (_FILE_OBJECT *)v18[1].Blink;
  if( FileObject == *p_FileObject )
    goto LABEL_55;
  FsRtlpOplockKeysEqual(*p_FileObject, FileObject, 0i64);
  v16 = 0;
  v15 = v52;
  if( !v31 )
    goto LABEL_55;
LABEL_12:
  v46 = 1;
  v20 = (__int64)v18[3].Flink & 0xF00000;
  v21 = LowerOplockLevel;
  if( v20 != 0x800000 )
  {
    if( v20 != 0x100000
      || (v6 & 0x7000) <= 0x3000
      || Oplocka->WaitingIrps.Flink == &Oplocka->WaitingIrps
      && FsRtlpOplockUpperLowerCompatible(v6, (unsigned int)LowerOplockLevel) )
    {
      goto LABEL_14;
    }
    v32.MasterIrp = (_IRP *)AckIrp->AssociatedIrp;
    *(_OWORD *)&v32.MasterIrp->Type = 0i64;
    *(_QWORD *)&v32.MasterIrp->Flags = 0i64;
    *(_DWORD *)&v32.MasterIrp->AllocationProcessorNumber = 3;
    if( Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
      v21 = 1;
LABEL_63:
    LODWORD(v32.MasterIrp->MdlAddress) = v21;
    HIDWORD(v32.MasterIrp->MdlAddress) |= 1u;
    AckIrp->IoStatus.Information = 24i64;
    v8 = -2147483602;
    AckIrp->IoStatus.Status = -2147483602;
    LOBYTE(FileObject) = 1;
    IofCompleteRequest(AckIrp, (_CCHAR)FileObject);
    goto LABEL_23;
  }
  if( v6
    && (Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps
     || !FsRtlpOplockUpperLowerCompatible(v6, (unsigned int)LowerOplockLevel)) )
  {
    v32.MasterIrp = (_IRP *)AckIrp->AssociatedIrp;
    *(_OWORD *)&v32.MasterIrp->Type = 0i64;
    *(_QWORD *)&v32.MasterIrp->Flags = 0i64;
    *(_DWORD *)&v32.MasterIrp->AllocationProcessorNumber = 3;
    if( Oplocka->WaitingIrps.Flink != &Oplocka->WaitingIrps )
      v21 = v16;
    goto LABEL_63;
  }
LABEL_14:
  FsRtlpOplockDequeueRH((_RH_OP_CONTEXT *)v18);
  if( !v23 )
  {
    v48 = 1;
    if( !v6 )
    {
      ObfDereferenceObjectWithTag(v18[1].Blink, 0x746C6644ui64);
      goto LABEL_17;
    }
    goto LABEL_71;
  }
  PoolWithTag->OriginalFileObject = (_FILE_OBJECT *)v18[1].Blink;
  v33 = &Oplocka->DelayAckFileObjectQueue;
  v34 = Oplocka->DelayAckFileObjectQueue.Flink;
  if( v34->Blink != &Oplocka->DelayAckFileObjectQueue )
    goto LABEL_80;
  PoolWithTag->Links.Flink = v34;
  PoolWithTag->Links.Blink = v33;
  v34->Blink = &PoolWithTag->Links;
  v33->Flink = &PoolWithTag->Links;
  PoolWithTag = v22;
  DelayAckFo = v22;
LABEL_17:
  if( v6 )
  {
LABEL_71:
    if( (v6 & 0x4040) == 0 && (v6 & 0x3010) != 0 )
    {
      LODWORD(v44) = v21;
      v8 = FsRtlpRequestShareableOplock(&Oplocka, IrpSp, AckIrp, v6, NewRHOpContext, CompleteAckOnClose, 1u, v44);
    }
    else
    {
      Oplocka->IrpExclusiveOplock = AckIrp;
      CurrentStackLocation = AckIrp->Tail.CurrentStackLocation;
      CurrentStackLocation->Control |= 1u;
      AckIrp->IoStatus.Information = (unsigned __int64)Oplocka;
      CurrentThread = (_ETHREAD *)KeGetCurrentThread();
      Oplocka->ExclusiveOplockOwner = CurrentThread->Tcb.ApcState.Process;
      v35 = (_ETHREAD *)KeGetCurrentThread();
      v60 = v35;
      Oplocka->ExclusiveOplockOwnerThread = v35;
      ObfReferenceObjectWithTag(v35, 0x746C6644ui64);
      Oplocka->WaiterPriority = 0;
      if( v52 )
      {
        ObfReferenceObjectWithTag(*p_FileObject, 0x746C6644ui64);
        Blink = *p_FileObject;
      }
      else
      {
        Blink = (_FILE_OBJECT *)v18[1].Blink;
      }
      Oplocka->FileObject = Blink;
      Oplocka->OplockState = v6 | Oplocka->OplockState & 0x20 | 0x40;
      AckIrp->CancelIrql = KeAcquireQueuedSpinLock(7i64, v36, v37);
      if( AckIrp->Cancel )
      {
        FsRtlpCancelExclusiveIrp(AckIrp, 1u, !CompleteAckOnClose);
      }
      else
      {
        _InterlockedExchange64((volatile __int64 *)&AckIrp->CancelRoutine, (__int64)FsRtlpExclusiveIrpCancelRoutine);
        KeReleaseQueuedSpinLock(LockQueueIoCancelLock, AckIrp->CancelIrql);
      }
      v46 = 1;
      v18 = v56;
      PoolWithTag = DelayAckFo;
      v8 = 259;
    }
  }
  else
  {
    FsRtlpComputeShareableOplockState(Oplocka);
    v8 = 0;
    AckIrp->IoStatus.Status = 0;
    LOBYTE(v24) = 1;
    IofCompleteRequest(AckIrp, v24);
  }
  FsRtlpModifyThreadPriorities(Oplocka, (_RH_OP_CONTEXT *)v18, 0);
  FsRtlpClearOwner(Oplocka, (_RH_OP_CONTEXT *)v18);
  if( Oplocka->RHBreakQueue.Flink == &Oplocka->RHBreakQueue )
    Oplocka->WaiterPriority = 0;
  ExFreePoolWithTag(v18, 0);
  if( v52 )
    Oplocka->OplockState |= 0x1000000u;
LABEL_23:
  v10 = 1;
LABEL_24:
  if( !v46 )
    goto LABEL_32;
  if( v48 )
    FsRtlpReleaseIrpsWaitingForRH(Oplocka);
  if( !v10 )
  {
LABEL_93:
    if( ReleaseIrpsWaitingForExclusive )
    {
      while( 1 )
      {
        v42 = Oplocka->WaitingIrps.Flink;
        if( v42 == &Oplocka->WaitingIrps )
          break;
        FsRtlpRemoveAndCompleteWaitingIrp((_WAITING_IRP *)v42);
      }
    }
    if( DereferenceExclusiveFileObject )
    {
      ObfDereferenceObjectWithTag(Oplocka->FileObject, 0x746C6644ui64);
      Oplocka->FileObject = 0i64;
    }
  }
LABEL_98:
  if( PoolWithTag )
    ExFreePoolWithTag(PoolWithTag, 0);
  ExReleaseFastMutexUnsafe(Oplocka->FastMutex);
  return v8;
}

Referenced by:

FsRtlpOplockFsctrlInternal