FsRtlpOplockFsctrlInternal

NTSTATUS __stdcall FsRtlpOplockFsctrlInternal(
        PVOID *Oplock,
        _IRP *Irp,
        UINT64 OpenCount,
        UINT64 Flags,
        UINT64 LowerOplockLevel){
  unsigned int v5; 
  NTSTATUS v8; 
  PVOID v9; 
  INT64 v10; 
  int v11; 
  int v12; 
  __int64 v13; 
  int v14; 
  int v15; 
  int v16; 
  int v17; 
  int v18; 
  int v19; 
  char v20; 
  int v21; 
  __int16 v22; 
  __int16 v23; 
  __int16 v24; 
  _RH_OP_CONTEXT **v25; 
  int v26; 
  int v28; 
  PFAST_MUTEX *v29; 
  char v30; 
  int v31; 
  int v32; 
  NTSTATUS v33; 
  int v34; 
  int v35; 
  int v36; 
  int v37; 
  int v38; 
  int v39; 
  int v40; 
  char v41; 
  int v42; 
  __int16 v43; 
  __int16 v44; 
  __int16 v45; 
  int v46; 
  _RH_OP_CONTEXT **v47; 
  int v48; 
  char v49; 
  NTSTATUS v50; 
  char v51; 
  UINT8 v52; 
  _NONOPAQUE_OPLOCK *v53; 
  char v54; 
  _QWORD *v55; 
  __int64 v56; 
  _QWORD *v57; 
  _RH_OP_CONTEXT **CompletionRoutine; 
  POPLOCK_FS_PREPOST_IRP PostIrpRoutine; 
  INT64 GrantingInAck; 
  UINT64 v61; 
  int v62; 
  int v63; 
  __int64 v64; 
  char v65; 
  PVOID P[8]; 
  PVOID v67; 
  UINT64 FsctrlFlags; 
  LODWORD(FsctrlFlags) = Flags;
  v5 = OpenCount;
  v8 = 0;
  v9 = 0i64;
  P[0] = 0i64;
  v10 = *((_QWORD *)Irp + 23);
  if( *(_BYTE *)v10 )
  {
    v11 = 2;
    v12 = *(_DWORD *)(v10 + 24);
    if( v12 == 590400 )
    {
      v13 = *((_QWORD *)Irp + 3);
      v64 = v13;
      if( *(_DWORD *)(v10 + 16) < 0xCu || *(_DWORD *)(v10 + 8) < 0x18u )
      {
        v8 = -1073741789;
      }
      else
      {
        if( *(_WORD *)v13 <= 1u )
        {
          v14 = *(_DWORD *)(v13 + 8);
          if( (v14 & 1) != 0 )
          {
            v15 = *(_DWORD *)(v13 + 4);
            LODWORD(v67) = v15 & 1;
            if( (v15 & 1) != 0 )
              v16 = 4096;
            else
              v16 = 0;
            v17 = 0x2000;
            if( (v15 & 2) != 0 )
              v18 = 0x2000;
            else
              v18 = 0;
            v19 = ((v15 & 4) != 0 ? 0x4000 : 0) | v16 | v18;
            if( v19 == 12288 )
            {
LABEL_12:
              if( !v5 )
              {
                IoIsOperationSynchronous(Irp);
                if( !v20 )
                {
                  v21 = 0x4000;
                  if( (*(_DWORD *)(*(_QWORD *)(v10 + 48) + 80i64) & 0x4000) == 0 )
                  {
                    if( (_DWORD)v67 )
                      v22 = 4096;
                    else
                      v22 = 0;
                    if( (v15 & 4) != 0 )
                      v23 = 0x4000;
                    else
                      v23 = 0;
                    if( (v15 & 2) != 0 )
                      v24 = 0x2000;
                    else
                      v24 = 0;
                    if( (((unsigned __int16)v22 | (unsigned __int16)(v23 | v24)) & 0x2000) != 0 )
                    {
                      P[0] = ExAllocatePoolWithTag((_POOL_TYPE)17, 0x48ui64, 0x6F725346ui64);
                      memset((INT64)P[0], 0i64);
                      v15 = *(_DWORD *)(v64 + 4);
                      v9 = P[0];
                      v21 = 0x4000;
                    }
                    if( v9 )
                      v25 = (_RH_OP_CONTEXT **)P;
                    else
                      v25 = 0i64;
                    if( (v15 & 1) != 0 )
                      v26 = 4096;
                    else
                      v26 = 0;
                    if( (v15 & 4) == 0 )
                      v21 = 0;
                    if( (v15 & 2) == 0 )
                      v17 = 0;
                    LODWORD(v61) = LowerOplockLevel;
                    LOBYTE(GrantingInAck) = 0;
                    v8 = FsRtlpRequestShareableOplock(
                           (_NONOPAQUE_OPLOCK **)Oplock,
                           (_IO_STACK_LOCATION *)v10,
                           Irp,
                           v26 | v21 | (unsigned int)v17,
                           v25,
                           1u,
                           GrantingInAck,
                           v61);
LABEL_37:
                    if( P[0] )
                    {
                      FsRtlpClearOwner((INT64)*Oplock, (INT64)P[0]);
                      ExFreePoolWithTag(P[0], 0);
                    }
                    return v8;
                  }
                }
              }
              goto LABEL_102;
            }
            if( v19 )
            {
              if( v19 == 4096 )
                goto LABEL_12;
              if( v19 != 28672 && v19 != 20480 )
              {
LABEL_124:
                v8 = -1073741811;
                *((_DWORD *)Irp + 12) = -1073741811;
                goto LABEL_149;
              }
              IoIsOperationSynchronous(Irp);
              if( v30 || (v31 = 0x4000, (*(_DWORD *)(*(_QWORD *)(v10 + 48) + 80i64) & 0x4000) != 0) )
              {
LABEL_102:
                v8 = -1073741598;
                *((_DWORD *)Irp + 12) = -1073741598;
LABEL_149:
                IofCompleteRequest(Irp, 1);
                return v8;
              }
              if( (_DWORD)v67 )
                v32 = 4160;
              else
                v32 = 64;
              if( (v15 & 4) == 0 )
                v31 = 0;
              if( (v15 & 2) == 0 )
                v17 = 0;
              LODWORD(GrantingInAck) = LowerOplockLevel;
              LODWORD(PostIrpRoutine) = v32 | v31 | v17;
              LODWORD(CompletionRoutine) = FsctrlFlags;
              FsRtlpRequestExclusiveOplock(
                (_NONOPAQUE_OPLOCK **)Oplock,
                (_IO_STACK_LOCATION *)v10,
                Irp,
                v5,
                (UINT64)CompletionRoutine,
                (UINT64)PostIrpRoutine,
                GrantingInAck);
              return v33;
            }
            v53 = (_NONOPAQUE_OPLOCK *)*Oplock;
            if( *Oplock )
            {
              v67 = 0i64;
              if( (v53->OplockState & 0x10000) != 0 )
              {
                FsRtlpCallerIsAtomicRequestor(
                  (INT64)v53,
                  *(_FILE_OBJECT **)(v10 + 48),
                  (INT64)&v67,
                  Flags,
                  CompletionRoutine);
                if( v54 )
                {
                  v55 = v67;
                  FsRtlpOplockDequeueRH((_RH_OP_CONTEXT *)v67);
                  v56 = v55[7];
                  v57 = (_QWORD *)v55[8];
                  if( *(_QWORD **)(v56 + 8) != v55 + 7 || (_QWORD *)*v57 != v55 + 7 )
                    __fastfail(3u);
                  *v57 = v56;
                  *(_QWORD *)(v56 + 8) = v57;
                  if( v53->AtomicQueue.Flink == &v53->AtomicQueue )
                    v53->OplockState &= 0xFFFCFFFF;
                  if( v55[5] )
                    FsRtlpClearOwner((INT64)v53, (INT64)v55);
                  ExFreePoolWithTag(v55, 0);
                  FsRtlpComputeShareableOplockState(v53);
                  FsRtlpReleaseIrpsWaitingForRH((INT64)v53);
                }
              }
            }
LABEL_146:
            *((_DWORD *)Irp + 12) = 0;
            IofCompleteRequest(Irp, 1);
            return 0;
          }
          if( (v14 & 2) != 0 )
          {
            v34 = *(_DWORD *)(v13 + 4);
            v65 = v34;
            LODWORD(v67) = v34 & 1;
            if( (v34 & 1) != 0 )
              v35 = 4096;
            else
              v35 = 0;
            v63 = v34 & 4;
            v36 = 0x4000;
            if( (v34 & 4) != 0 )
              v37 = 0x4000;
            else
              v37 = 0;
            v62 = v34 & 2;
            v38 = 0x2000;
            if( (v34 & 2) != 0 )
              v39 = 0x2000;
            else
              v39 = 0;
            v40 = v35 | v37 | v39;
            if( v40 && v40 != 4096 && v40 != 12288 && v40 != 20480 && v40 != 28672 )
              goto LABEL_124;
            IoIsOperationSynchronous(Irp);
            if( v41 )
              goto LABEL_124;
            if( (*(_DWORD *)(*(_QWORD *)(v10 + 48) + 80i64) & 0x4000) == 0 )
            {
              v42 = 4096;
              if( (_DWORD)v67 )
                v43 = 4096;
              else
                v43 = 0;
              if( v63 )
                v44 = 0x4000;
              else
                v44 = 0;
              if( v62 )
                v45 = 0x2000;
              else
                v45 = 0;
              if( (((unsigned __int16)v43 | (unsigned __int16)(v44 | v45)) & 0x2000) != 0 )
              {
                P[0] = ExAllocatePoolWithTag((_POOL_TYPE)17, 0x48ui64, 0x6F725346ui64);
                memset((INT64)P[0], 0i64);
                v46 = *(_DWORD *)(v13 + 4);
                v9 = P[0];
                v42 = 4096;
              }
              else
              {
                LOBYTE(v46) = v65;
              }
              if( v9 )
                v47 = (_RH_OP_CONTEXT **)P;
              else
                v47 = 0i64;
              if( (v46 & 1) == 0 )
                v42 = 0;
              if( (v46 & 4) == 0 )
                v36 = 0;
              if( (v46 & 2) == 0 )
                v38 = 0;
              LODWORD(PostIrpRoutine) = LowerOplockLevel;
              v8 = FsRtlpAcknowledgeOplockBreakByCacheFlags(
                     (_NONOPAQUE_OPLOCK *)*Oplock,
                     (_IO_STACK_LOCATION *)v10,
                     Irp,
                     v42 | v36 | (unsigned int)v38,
                     v47,
                     (UINT64)PostIrpRoutine);
              goto LABEL_37;
            }
            *(_OWORD *)v13 = 0i64;
            *(_QWORD *)(v13 + 16) = 0i64;
            *(_DWORD *)v13 = 1572865;
            *((_QWORD *)Irp + 7) = 24i64;
            goto LABEL_146;
          }
        }
        v8 = -1073741811;
      }
      *((_DWORD *)Irp + 12) = v8;
      goto LABEL_149;
    }
    switch( v12 )
    {
      case 589824:
        goto LABEL_97;
      case 589828:
        if( (_DWORD)OpenCount )
          goto LABEL_102;
        IoIsOperationSynchronous(Irp);
        if( v51 || (*((_DWORD *)Irp + 4) & 0x40) != 0 || (*(_DWORD *)(*(_QWORD *)(v10 + 48) + 80i64) & 0x4000) != 0 )
          goto LABEL_102;
        LODWORD(v61) = LowerOplockLevel;
        LOBYTE(GrantingInAck) = 0;
        return FsRtlpRequestShareableOplock(
                 (_NONOPAQUE_OPLOCK **)Oplock,
                 (_IO_STACK_LOCATION *)v10,
                 Irp,
                 0x10ui64,
                 0i64,
                 1u,
                 GrantingInAck,
                 v61);
      case 589832:
        goto LABEL_96;
      case 589836:
        v52 = 1;
        goto LABEL_117;
      case 589840:
        return FsRtlpOpBatchBreakClosePending((INT64)*Oplock, v10, Irp);
      case 589844:
        return FsRtlpOplockBreakNotify((_NONOPAQUE_OPLOCK *)*Oplock, (_IO_STACK_LOCATION *)0x140000000i64, Irp);
      case 589904:
        v52 = 0;
LABEL_117:
        LODWORD(CompletionRoutine) = LowerOplockLevel;
        return FsRtlpAcknowledgeOplockBreak(
                 (_NONOPAQUE_OPLOCK *)*Oplock,
                 (_IO_STACK_LOCATION *)v10,
                 Irp,
                 v52,
                 (UINT64)CompletionRoutine);
      case 589916:
        v11 = 4;
LABEL_96:
        v11 *= 2;
LABEL_97:
        v48 = v11 | 0x40;
        if( (_DWORD)OpenCount != 1 )
          goto LABEL_102;
        IoIsOperationSynchronous(Irp);
        if( v49 || (*((_DWORD *)Irp + 4) & 0x40) != 0 || (*(_DWORD *)(*(_QWORD *)(v10 + 48) + 80i64) & 0x4000) != 0 )
          goto LABEL_102;
        LODWORD(GrantingInAck) = LowerOplockLevel;
        LODWORD(PostIrpRoutine) = v48;
        LODWORD(CompletionRoutine) = 0;
        FsRtlpRequestExclusiveOplock(
          (_NONOPAQUE_OPLOCK **)Oplock,
          (_IO_STACK_LOCATION *)v10,
          Irp,
          1ui64,
          (UINT64)CompletionRoutine,
          (UINT64)PostIrpRoutine,
          GrantingInAck);
        v8 = v50;
        break;
      default:
        goto LABEL_124;
    }
  }
  else
  {
    v28 = *(_DWORD *)(v10 + 16);
    if( (v28 & 0x100000) != 0 )
    {
      if( (_DWORD)OpenCount != 1
        || (*(_DWORD *)(*(_QWORD *)(v10 + 8) + 16i64) & 0xFFFFFF7F) != 0
        || (*(_BYTE *)(v10 + 26) & 7) != 7 )
      {
        return -1073741598;
      }
      v8 = FsRtlpAttachOplockKey(Irp);
      if( !v8 )
      {
        LODWORD(GrantingInAck) = LowerOplockLevel;
        LODWORD(PostIrpRoutine) = 200;
        LODWORD(CompletionRoutine) = 0;
        FsRtlpRequestExclusiveOplock(
          (_NONOPAQUE_OPLOCK **)Oplock,
          (_IO_STACK_LOCATION *)v10,
          0i64,
          1ui64,
          (UINT64)CompletionRoutine,
          (UINT64)PostIrpRoutine,
          GrantingInAck);
        return v33;
      }
    }
    else if( (v28 & 0x10000) != 0 )
    {
      v8 = FsRtlpAttachOplockKey(Irp);
      if( !v8 )
      {
        v29 = (PFAST_MUTEX *)*Oplock;
        if( !*Oplock )
        {
          v29 = (PFAST_MUTEX *)FsRtlpAllocateOplock();
          *Oplock = v29;
        }
        v67 = v29;
        ExAcquireFastMutexUnsafe(v29[19]);
        v8 = FsRtlCheckOplockEx(Oplock, Irp, 0x30000000u, 0i64, 0i64, 0i64);
        if( !v8 )
        {
          P[0] = ExAllocatePoolWithTag((_POOL_TYPE)17, 0x48ui64, 0x6F725346ui64);
          memset((INT64)P[0], 0i64);
          LODWORD(v61) = LowerOplockLevel;
          LOBYTE(GrantingInAck) = 0;
          v8 = FsRtlpRequestShareableOplock(
                 (_NONOPAQUE_OPLOCK **)Oplock,
                 (_IO_STACK_LOCATION *)v10,
                 0i64,
                 0x10000ui64,
                 (_RH_OP_CONTEXT **)P,
                 0,
                 GrantingInAck,
                 v61);
        }
        if( P[0] )
        {
          FsRtlpClearOwner((INT64)v29, (INT64)P[0]);
          ExFreePoolWithTag(P[0], 0);
        }
        ExReleaseFastMutexUnsafe(v29[19]);
      }
    }
  }
  return v8;
}

Referenced by:

FsRtlOplockFsctrl
FsRtlOplockFsctrlEx
FsRtlUpperOplockFsctrl