NtAssociateWaitCompletionPacket

NTSTATUS __stdcall NtAssociateWaitCompletionPacket(
        PVOID WaitCompletionPacketHandle,
        PVOID IoCompletionHandle,
        PVOID TargetObjectHandle,
        PVOID KeyContext,
        PVOID ApcContext,
        INT64 IoStatus,
        UINT64 IoStatusInformation,
        UINT8 *AlreadySignaled){
  KPROCESSOR_MODE v10; 
  NTSTATUS result; 
  int v12; 
  int v13; 
  PVOID v14; 
  KMUTANT *WaitObject; 
  UINT64 *v16; 
  unsigned __int8 CurrentIrql; 
  _QWORD *v18; 
  PVOID v19; 
  UINT8 v20; 
  _LIST_ENTRY *Blink; 
  _LIST_ENTRY *v22; 
  UINT8 v23; 
  __int64 v24; 
  __int64 v25; 
  unsigned __int64 v26; 
  _KQUEUE *v27; 
  UINT8 v28; 
  int SignalState; 
  _LIST_ENTRY *v30; 
  _LIST_ENTRY *v31; 
  volatile unsigned int CurrentCount; 
  PVOID v33; 
  PVOID Object; 
  PVOID v35; 
  PVOID v36; 
  UINT64 SpinCount; 
  _QWORD *v38; 
  _KPRCB *Prcb; 
  __int64 v40; 
  v10 = *((_BYTE *)KeGetCurrentThread() + 562);
  Object = 0i64;
  result = ObReferenceObjectByHandle(
             WaitCompletionPacketHandle,
             1u,
             IopWaitCompletionPacketObjectType,
             v10,
             &Object,
             0i64);
  if( result >= 0 )
  {
    v35 = 0i64;
    v12 = ObReferenceObjectByHandle(IoCompletionHandle, 2u, IoCompletionObjectType, v10, &v35, 0i64);
    if( v12 < 0 )
    {
      ObfDereferenceObjectWithTag(Object, 0x746C6644ui64);
      return v12;
    }
    v36 = 0i64;
    v13 = ObReferenceObjectByHandle(TargetObjectHandle, 0x100000u, 0i64, v10, &v36, 0i64);
    HIDWORD(SpinCount) = v13;
    if( v13 < 0 )
    {
      ObfDereferenceObjectWithTag(Object, 0x746C6644ui64);
      v33 = v35;
    }
    else
    {
      v14 = v36;
      WaitObject = (KMUTANT *)ObpGetWaitObject((INT64)v36 - 48);
      if( WaitObject != (KMUTANT *)&ObpDefaultObject
        && WaitObject
        && (((WaitObject->Header.Type & 0x7F) - 2) & 0xFD) != 0 )
      {
        v16 = (UINT64 *)((char *)Object + 96);
        CurrentIrql = KeGetCurrentIrql();
        __writecr8(2ui64);
        if( _interlockedbittestandset64((volatile signed __int32 *)v16, 0i64) )
          KxWaitForSpinLockAndAcquire(v16);
        if( !*((_BYTE *)Object + 104) )
        {
          *((_BYTE *)Object + 104) = 1;
          v18 = Object;
          *((_QWORD *)Object + 6) = KeyContext;
          v18[7] = ApcContext;
          *((_DWORD *)v18 + 18) = IoStatus;
          v18[8] = IoStatusInformation;
          v18[10] = v36;
          v19 = v35;
          v18[11] = v35;
          *((_WORD *)v18 + 8) = 1026;
          v18[3] = v19;
          v18[4] = WaitObject;
          v20 = KeGetCurrentIrql();
          __writecr8(2ui64);
          LODWORD(SpinCount) = 0;
          while( _interlockedbittestandset(&WaitObject->Header.Lock, 7u) )
          {
            do
              KeYieldProcessorEx(&SpinCount);
            while( (WaitObject->Header.LockNV & 0x80u) != 0 );
          }
          if( WaitObject->Header.SignalState <= 0 )
          {
            Blink = WaitObject->Header.WaitListHead.Blink;
            if( Blink->Flink == &WaitObject->Header.WaitListHead )
            {
              v22 = (_LIST_ENTRY *)Object;
              *(_QWORD *)Object = &WaitObject->Header.WaitListHead;
              v22->Blink = Blink;
              Blink->Flink = v22;
              WaitObject->Header.WaitListHead.Blink = v22;
              _InterlockedAnd(&WaitObject->Header.Lock, 0xFFFFFF7F);
              __writecr8(v20);
              v23 = 0;
              goto LABEL_14;
            }
LABEL_34:
            __fastfail(3u);
          }
          KiWaitSatisfyOther(WaitObject);
          *((_BYTE *)v18 + 17) = 5;
          *(_QWORD *)Object = v25;
          v38 = (char *)v35 + 8;
          KeGetCurrentIrql();
          __writecr8(v26);
          Prcb = KeGetCurrentPrcb();
          v40 = *((_QWORD *)Prcb + 1);
          v27 = (_KQUEUE *)v35;
          KiAcquireKobjectLockSafe(v35);
          if( (_QWORD *)*v38 == v38
            || (CurrentCount = v27->CurrentCount, v27 = (_KQUEUE *)v35, CurrentCount >= *((_DWORD *)v35 + 11))
            || (v27 = (_KQUEUE *)v35, *(PVOID *)(v40 + 232) == v35) && *(_BYTE *)(v40 + 643) == 15 )
          {
            v28 = 0;
          }
          else
          {
            v28 = KiWakeQueueWaiter(Prcb, (_KQUEUE *)v35, (INT64)Object);
          }
          if( !v28 )
          {
            SignalState = v27->Header.SignalState;
            v27->Header.SignalState = SignalState + 1;
            v30 = v27->EntryListHead.Blink;
            if( v30->Flink != &v27->EntryListHead )
              goto LABEL_34;
            v31 = (_LIST_ENTRY *)Object;
            *(_QWORD *)Object = &v27->EntryListHead;
            v31->Blink = v30;
            v30->Flink = v31;
            v27->EntryListHead.Blink = v31;
            if( !SignalState && (_QWORD *)*v38 != v38 )
              KiWakeOtherQueueWaiters(Prcb, v27);
          }
          _InterlockedAnd(&v27->Header.Lock, 0xFFFFFF7F);
          _InterlockedAnd(&WaitObject->Header.Lock, 0xFFFFFF7F);
          KiExitDispatcher(KeGetCurrentPrcb(), 0i64, AdjustUnwait, 0i64, v20);
          v23 = 1;
LABEL_14:
          _InterlockedAnd64((volatile signed __int64 *)v16, 0i64);
          __writecr8(CurrentIrql);
          if( AlreadySignaled )
          {
            if( v10 )
            {
              v24 = (__int64)AlreadySignaled;
              if( (unsigned __int64)AlreadySignaled >= 0x7FFFFFFF0000i64 )
                v24 = 0x7FFFFFFF0000i64;
              *(_BYTE *)v24 = *(_BYTE *)v24;
            }
            *AlreadySignaled = v23;
          }
          return v13;
        }
        KxReleaseSpinLock(v16);
        __writecr8(CurrentIrql);
        v13 = -1073741585;
        v14 = v36;
      }
      else
      {
        v13 = -1073741583;
      }
      ObfDereferenceObjectWithTag(v35, 0x746C6644ui64);
      ObfDereferenceObjectWithTag(v14, 0x746C6644ui64);
      v33 = Object;
    }
    ObfDereferenceObjectWithTag(v33, 0x746C6644ui64);
    return v13;
  }
  return result;
}

Referenced by:

No references.