FsRtlCheckOplockEx2

INT64 __fastcall FsRtlCheckOplockEx2(
        PVOID *Oplock,
        IRP *Irp,
        UINT64 Flags,
        INT64 a4,
        INT64 a5,
        INT64 a6,
        INT64 a7,
        INT64 a8,
        INT64 a9,
        INT64 a10){
  unsigned int v10; 
  unsigned int v13; 
  _NONOPAQUE_OPLOCK *v14; 
  FAST_MUTEX *v15; 
  NTSTATUS v16; 
  int v17; 
  __int64 v19; 
  struct _ECP_LIST *v20; 
  int v21; 
  __int64 FileObject; 
  char Count; 
  ULONG_PTR v24; 
  ULONG_PTR v25; 
  unsigned __int8 v26; 
  __int64 v27; 
  __int64 v28; 
  int SessionId; 
  FAST_MUTEX *v30; 
  unsigned int v31; 
  char v32; 
  int v33; 
  int Count_low; 
  __int64 v35; 
  char Contention_high; 
  unsigned int Contention; 
  bool v38; 
  int v39; 
  char v40; 
  unsigned int Lock; 
  FAST_MUTEX *FastMutex; 
  unsigned __int32 v43; 
  __int64 v44; 
  int v45; 
  INT64 v46; 
  char v47; 
  _QWORD *v48; 
  __int64 v49; 
  _QWORD *v50; 
  _RH_OP_CONTEXT **BugCheckParameter4; 
  bool v52; 
  char v53; 
  bool v54; 
  char v55[4]; 
  int v56; 
  int v57; 
  unsigned int v58; 
  FAST_MUTEX *Mutex; 
  int OplockState; 
  unsigned int v61; 
  PVOID EcpContext; 
  __int64 v63; 
  int v64; 
  int v65; 
  int v66; 
  int v67; 
  void(__fastcall *v68)(__int128 *); 
  __int64 v69; 
  void(__fastcall *v70)(__int64, __int64); 
  __int64 v71; 
  PVOID P; 
  struct _ECP_LIST *ExtraCreateParameter; 
  __int64 v74; 
  __int64 v75; 
  PVOID v76; 
  _ETHREAD *CurrentThread; 
  __int64 v78; 
  GUID EcpType; 
  v66 = a4;
  v10 = Flags;
  v67 = Flags;
  v63 = a5;
  v71 = a6;
  v70 = (void(__fastcall *)(__int64, __int64))a7;
  v69 = a9;
  v68 = (void(__fastcall *)(__int128 *))a10;
  v13 = 0;
  v58 = 0;
  v14 = (_NONOPAQUE_OPLOCK *)*Oplock;
  v76 = *Oplock;
  if( (_DWORD)a4 )
    return 3221225485i64;
  v15 = (FAST_MUTEX *)*((_QWORD *)Irp + 23);
  Mutex = v15;
  if( (Flags & 4) != 0 )
  {
    P = 0i64;
    if( !v14 )
      return 0i64;
    ExAcquireFastMutexUnsafe(v14->FastMutex);
    if( LOBYTE(v15->Count) )
    {
      v13 = -1073741811;
    }
    else if( (v14->OplockState & 0x10000) != 0 )
    {
      FsRtlpCallerIsAtomicRequestor((INT64)v14, *(_FILE_OBJECT **)&v15->OldIrql, (INT64)&P, v46, BugCheckParameter4);
      if( v47 )
      {
        v48 = P;
        FsRtlpOplockDequeueRH((_RH_OP_CONTEXT *)P);
        v49 = v48[7];
        v50 = (_QWORD *)v48[8];
        if( *(_QWORD **)(v49 + 8) != v48 + 7 || (_QWORD *)*v50 != v48 + 7 )
          __fastfail(3u);
        *v50 = v49;
        *(_QWORD *)(v49 + 8) = v50;
        if( v14->AtomicQueue.Flink == &v14->AtomicQueue )
          v14->OplockState &= 0xFFFCFFFF;
        if( v48[5] )
          FsRtlpClearOwner((INT64)v14, (INT64)v48);
        ExFreePoolWithTag(v48, 0);
        FsRtlpComputeShareableOplockState(v14);
        FsRtlpReleaseIrpsWaitingForRH((INT64)v14);
      }
    }
    ExReleaseFastMutexUnsafe(v14->FastMutex);
    return v13;
  }
  if( (Flags & 0x10000000) == 0 )
  {
    v16 = 0;
    if( LOBYTE(v15->Count) )
      goto LABEL_5;
    v19 = *(_QWORD *)(*(_QWORD *)&v15->OldIrql + 208i64);
    if( v19 )
    {
      if( v19 != IopRevocationExtension )
      {
        v44 = *(_QWORD *)(v19 + 56);
        if( v44 )
        {
          if( (*(_BYTE *)(v44 + 2) & 3) != 0 )
            goto LABEL_5;
        }
      }
    }
    EcpContext = 0i64;
    ExtraCreateParameter = 0i64;
    EcpType = 0i64;
    IoGetIrpExtraCreateParameter(Irp, &ExtraCreateParameter);
    v20 = ExtraCreateParameter;
    if( ExtraCreateParameter )
    {
      EcpType = GUID_ECP_DUAL_OPLOCK_KEY;
      if( FsRtlFindExtraCreateParameter(ExtraCreateParameter, &EcpType, &EcpContext, 0i64) )
      {
        EcpType = GUID_ECP_OPLOCK_KEY;
        if( FsRtlRemoveExtraCreateParameter(v20, &EcpType, &EcpContext, 0i64) )
          goto LABEL_15;
        v45 = 1;
      }
      else
      {
        v45 = 2;
      }
      v57 = v45;
      v15 = Mutex;
      v16 = IoSetOplockKeyContext(*(_FILE_OBJECT **)&Mutex->OldIrql, EcpContext, v45);
      if( (_WORD)v57 == 1 )
        FsRtlFreeExtraCreateParameter(EcpContext);
      else
        FsRtlAcknowledgeEcp(EcpContext);
      if( v16 == -1073741823 )
        v16 = 0;
      goto LABEL_5;
    }
LABEL_15:
    v15 = Mutex;
LABEL_5:
    v58 = v16;
  }
  FsRtlpOplockStoreKeyForDeleteOperation(Oplock, Irp, v10);
  if( v14 != *Oplock )
  {
    v14 = (_NONOPAQUE_OPLOCK *)*Oplock;
    v76 = *Oplock;
  }
  if( (v10 & 2) == 0 && v14 && (*((_DWORD *)Irp + 4) & 2) == 0 && !v58 )
  {
    v52 = (v10 & 0x20000000) != 0;
    v53 = 1;
    while( 1 )
    {
      v55[0] = 0;
      v21 = v10 & 0x10;
      v57 = v21;
      if( (v10 & 0x10) == 0 && !v52 )
      {
        OplockState = v14->OplockState;
        FileObject = (__int64)v14->FileObject;
        v78 = FileObject;
        Count = v15->Count;
        v17 = OplockState;
        if( LOBYTE(v15->Count) == 3 && (OplockState & 0xFFFF4FFE) == 0 )
          v53 = 0;
        if( Count == 4 && (OplockState & 0xFFFFDFFE) == 0 )
          v53 = 0;
        if( (v10 & 8) == 0 && Count != 18 && FileObject && FileObject == *(_QWORD *)&v15->OldIrql )
        {
          v53 = 0;
          goto LABEL_132;
        }
      }
      if( !v53 )
        goto LABEL_132;
      if( !v52 )
        break;
LABEL_46:
      v52 = 1;
      v31 = v14->OplockState;
      if( v31 != 1 )
      {
        LOBYTE(v17) = 0;
        v57 = v17;
        v54 = 0;
        v32 = 0;
        v33 = 0;
        v56 = 0;
        if( v21 )
          goto LABEL_64;
        Count_low = LOBYTE(v15->Count);
        if( Count_low == 3 )
        {
          if( (v31 & 8) != 0 )
          {
LABEL_82:
            v33 = 0x4000;
            v56 = 0x4000;
          }
          else
          {
            LOBYTE(v17) = 1;
            v54 = 1;
            v33 = 0x4000;
            v56 = 0x4000;
          }
          goto LABEL_51;
        }
        if( Count_low == 4 )
        {
LABEL_63:
          v32 = 1;
LABEL_64:
          v33 = 20480;
          v56 = 20480;
        }
        else
        {
          switch( LOBYTE(v15->Count) )
          {
            case 0:
              if( ((v31 & 0x7000) == 0 || (*((_DWORD *)v15->Owner + 4) & 0xFFEDFE7F) == 0)
                && ((v31 & 0x1E) == 0 || (*((_DWORD *)v15->Owner + 4) & 0xFFEFFE7F) == 0)
                && (v15->Contention & 0x100000) == 0
                || (v31 & 8) != 0
                && (*((_DWORD *)v15->Owner + 4) & 0xFFEDFE56) == 0
                && (v15->Event.Header.Size & 1) != 0 )
              {
                break;
              }
              Contention_high = HIBYTE(v15->Contention);
              if( ((Contention_high & 0xFA) != 0 || Contention_high == 1) && (v15->Contention & 0x100000) == 0 )
                goto LABEL_81;
              goto LABEL_63;
            case 2:
              if( (*(_DWORD *)(*(_QWORD *)&v15->OldIrql + 80i64) & 0x4000) != 0 )
                break;
              goto LABEL_72;
            case 6:
              Contention = v15->Contention;
              if( Contention == 20 )
              {
                v38 = BYTE1(v15->Event.Header.WaitListHead.Flink) == 0;
                goto LABEL_92;
              }
              if( Contention == 19 )
                goto LABEL_63;
              switch( Contention )
              {
                case 0xAu:
                case 0xBu:
                case 0x28u:
                case 0x41u:
                  v33 = 0x2000;
                  v56 = 0x2000;
                  if( (v31 & 0xC) == 0 )
                    goto LABEL_51;
                  v32 = 1;
                  break;
                case 0xDu:
                  if( **((_BYTE **)Irp + 3) )
                    goto LABEL_97;
                  goto LABEL_51;
                case 0x27u:
                  goto LABEL_63;
                case 0x40u:
                  if( (**((_DWORD **)Irp + 3) & 1) != 0 )
                  {
                    v33 = 0x2000;
                    v56 = 0x2000;
                  }
                  goto LABEL_51;
                default:
                  goto LABEL_51;
              }
              goto LABEL_52;
            case 9:
LABEL_81:
              LOBYTE(v17) = 1;
              v54 = 1;
              goto LABEL_82;
            case 0xD:
              Lock = v15->Event.Header.Lock;
              if( Lock > 0x98268 )
              {
                if( Lock == 623428 || Lock == 623592 )
                  goto LABEL_63;
                v38 = Lock == 639668;
LABEL_92:
                if( v38 )
                  goto LABEL_63;
              }
              else
              {
                switch( Lock )
                {
                  case 0x98268u:
                    goto LABEL_63;
                  case 0x900FCu:
                    if( (FsRtlGetMarkHandleInfo(Irp) & 0x4000) == 0 )
                    {
LABEL_75:
                      v17 = v57;
                      goto LABEL_51;
                    }
                    v33 = 0x2000;
                    v56 = 0x2000;
                    v17 = v57;
                    if( (v31 & 0xC) != 0 )
                    {
                      v32 = 1;
                      goto LABEL_52;
                    }
                    break;
                  case 0x94264u:
                    v17 = (v31 & 8) == 0;
                    v54 = (v31 & 8) == 0;
                    v33 = 0x4000;
                    v56 = 0x4000;
                    goto LABEL_51;
                  case 0x980C8u:
                  case 0x98208u:
                    goto LABEL_63;
                }
              }
              break;
            case 0x11:
              if( (v31 & 8) != 0 )
                break;
              goto LABEL_63;
            case 0x12:
LABEL_72:
              FsRtlpOplockCleanup(v14, (_IO_STACK_LOCATION *)v15);
              if( LOBYTE(v15->Count) == 18 && (v10 & 0x20) != 0 )
              {
                v33 = 0x2000;
                v56 = 0x2000;
              }
              goto LABEL_75;
            case 0x15:
LABEL_97:
              v33 = 0x2000;
              v56 = 0x2000;
              break;
            default:
              break;
          }
LABEL_51:
          v32 = 0;
        }
LABEL_52:
        if( (_BYTE)v17 )
        {
          if( (v14->OplockState & 0x1F0FFDF) == 16
            || FsRtlpOplockKeysEqual(*(_FILE_OBJECT **)&v15->OldIrql, v14->FileObject, 0i64) )
          {
            goto LABEL_55;
          }
          v35 = v63;
          v58 = FsRtlpOplockBreakToII(
                  (__int64)v14,
                  (__int64)v15,
                  (__int64)Irp,
                  v10,
                  (int)BugCheckParameter4,
                  v63,
                  v71,
                  v70,
                  a8,
                  v69,
                  v68,
                  &v52,
                  v55);
        }
        else if( v32
               && ((v14->OplockState & 0x1F0FFDF) == 16
                || !FsRtlpOplockKeysEqual(*(_FILE_OBJECT **)&v15->OldIrql, v14->FileObject, 0i64)) )
        {
          v35 = v63;
          v58 = FsRtlpOplockBreakToNone(
                  (__int64)v14,
                  (__int64)v15,
                  (__int64)Irp,
                  v10,
                  (int)BugCheckParameter4,
                  v63,
                  v71,
                  v70,
                  a8,
                  v69,
                  v68,
                  &v52,
                  v55);
        }
        else
        {
LABEL_55:
          v35 = v63;
        }
        if( !v58 && (v14->OplockState & v33) != 0 )
        {
          LODWORD(BugCheckParameter4) = v66;
          v58 = FsRtlpOplockBreakByCacheFlags(
                  (__int64)v14,
                  (__int64)v15,
                  (__int64)Irp,
                  v10,
                  (__int64)BugCheckParameter4,
                  v33,
                  v35,
                  v71,
                  v70,
                  a8,
                  v69,
                  v68,
                  &v52,
                  v55);
        }
      }
LABEL_132:
      if( v52 && (v10 & 0x20000000) == 0 )
      {
        FastMutex = v14->FastMutex;
        FastMutex->Owner = 0i64;
        v43 = _InterlockedCompareExchange(&FastMutex->Count, 1, 0);
        if( v43 )
          ExpReleaseFastMutexContended(FastMutex, v43);
        KeAbPostRelease(FastMutex);
      }
      if( !v55[0] )
        return v58;
    }
    v24 = (ULONG_PTR)v14->FastMutex;
    Mutex = (FAST_MUTEX *)v24;
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    v75 = 0i64;
    v61 = 0;
    v25 = (ULONG_PTR)CurrentThread;
    --*((_WORD *)CurrentThread + 243);
    if( ++*(_BYTE *)(v25 + 794) != 1 )
      KeBugCheckEx(0x192u, v25, v24, KeGetCurrentIrql(), 0i64);
    v75 = 0i64;
    v74 = 0i64;
    v65 = 0;
    v26 = *(_BYTE *)(v25 + 792);
    if( v26
      || ((v39 = 0, *(_BYTE *)(v25 + 870)) ? (v40 = *(_BYTE *)(v25 + 870),
                                              *(_BYTE *)(v25 + 870) = 0,
                                              *(_BYTE *)(v25 + 792) |= v40,
                                              v26 = *(_BYTE *)(v25 + 792),
                                              v39 = 1) : (v26 = 0),
          (v64 = v39) != 0) )
    {
      _BitScanForward((unsigned int *)&v27, v26);
      v65 = v27;
      *(_BYTE *)(v25 + 792) = v26 & ~(1 << v27);
      v28 = *(_QWORD *)(v25 + 800) + 96 * v27;
      v74 = v28;
      v24 = (ULONG_PTR)Mutex;
    }
    else
    {
      v28 = 0i64;
      v74 = 0i64;
    }
    v75 = v28;
    if( !v28 )
    {
      _interlockedbittestandset((volatile signed __int32 *)(v25 + 120), 0x10u);
LABEL_38:
      --*(_BYTE *)(v25 + 794);
      KiAbThreadRemoveBoosts(v25, v24, &v61);
      v38 = (*(_WORD *)(v25 + 486))++ == 0xFFFF;
      if( v38 && *(_QWORD *)(v25 + 152) != v25 + 152 )
        KiCheckForKernelApcDelivery();
      v30 = Mutex;
      if( !_interlockedbittestandreset(&Mutex->Count, 0) )
        ExpAcquireFastMutexContended(v30, (PVOID)v28);
      if( v28 )
        *(_BYTE *)(v28 + 26) |= 1u;
      v30->Owner = CurrentThread;
      v21 = v57;
      goto LABEL_46;
    }
    if( v24 >= 0xFFFF800000000000ui64 )
    {
      if( *((_BYTE *)&antNameB + ((v24 >> 39) & 0x1FF) - 256) == 1 )
      {
        SessionId = MmGetSessionIdEx(*(_QWORD *)(v25 + 184));
        v24 = (ULONG_PTR)Mutex;
        goto LABEL_37;
      }
      v24 = (ULONG_PTR)Mutex;
    }
    SessionId = -1;
LABEL_37:
    *(_DWORD *)(v28 + 40) = SessionId;
    *(_QWORD *)(v28 + 32) = v24 & 0x7FFFFFFFFFFFFFFCi64;
    goto LABEL_38;
  }
  return v58;
}

Referenced by:

FsRtlCheckOplock
FsRtlCheckOplockEx