ExShareAddressSpaceWithDevice

NTSTATUS __stdcall ExShareAddressSpaceWithDevice(_DEVICE_OBJECT *PhysicalDeviceObject, UINT64 *ReturnedAsid){
  __int64 v2; 
  unsigned int v5; 
  VOID **v6; 
  VOID *v7; 
  _ETHREAD *CurrentThread; 
  _EPROCESS *Process; 
  _ETHREAD *v11; 
  _EX_PUSH_LOCK *p_SvmProcessLock; 
  __int64 v13; 
  __int64 AbOrphanedEntrySummary; 
  char v15; 
  NTSTATUS SessionId; 
  bool v17; 
  unsigned int DeviceAsid; 
  unsigned int Asid; 
  int v20; 
  unsigned __int8 v21; 
  VOID **v22; 
  VOID ***v23; 
  unsigned __int8 CurrentIrql; 
  _ETHREAD *v25; 
  __int64 v26; 
  __int64 v27; 
  char v28; 
  __int64 v29; 
  NTSTATUS v30; 
  _EXP_SVM_DEVICE *v31; 
  _EXP_SVM_DEVICE *v32; 
  _EXP_SVM_DEVICE *v33; 
  _ETHREAD *v34; 
  unsigned int v35; 
  unsigned __int8 v36; 
  int v37; 
  __int64 v38; 
  _KLOCK_ENTRY *v39; 
  int v40; 
  unsigned int v41; 
  unsigned __int8 v42; 
  VOID **PoolWithTag; 
  char v44; 
  unsigned __int8 v45; 
  _LIST_ENTRY *p_SvmProcessDeviceListHead; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *v48; 
  _ETHREAD *v49; 
  unsigned __int8 v50; 
  int v51; 
  _KLOCK_ENTRY *v52; 
  __int64 v53; 
  int v54; 
  unsigned int v55; 
  __int64 v56; 
  VOID *IommuContext; 
  _EXP_SVM_DEVICE *Device; 
  UINT64 v59; 
  UINT64 v60; 
  UINT64 a3; 
  UINT64 v62; 
  _KLOCK_QUEUE_HANDLE LockHandle; 
  _ETHREAD *v64; 
  _EXP_SVM_DEVICE *DeviceOut[18]; 
  int Interface; 

  v2 = 0i64;
  IommuContext = 0i64;
  memset(DeviceOut, 0i64, 0x50u);
  v5 = -1;
  Device = 0i64;
  *(_DWORD *)ReturnedAsid = -1;
  memset(&LockHandle, 0, sizeof(LockHandle));
  v6 = 0i64;
  v7 = 0i64;
  if( !*(&WheapDeferredInternalLogsEventLock + 298) )
    return -1073741637;
  if( !PhysicalDeviceObject )
    return -1073741585;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v64 = CurrentThread;
  Process = CurrentThread->Tcb.ApcState.Process;
  if( !ExAcquireRundownProtection(&Process->RundownProtect) )
    return -1073741558;
  Interface = IoQueryInterface(
                (INT64)PhysicalDeviceObject,
                0,
                (INT64)&GUID_IOMMU_BUS_INTERFACE,
                0x50u,
                1,
                (INT64)PhysicalDeviceObject,
                (INT64)DeviceOut);
  if( Interface >= 0 )
  {
    --CurrentThread->Tcb.SpecialApcDisable;
    v11 = (_ETHREAD *)KeGetCurrentThread();
    p_SvmProcessLock = &Process->SvmProcessLock;
    LODWORD(a3) = 0;
    --v11->Tcb.SpecialApcDisable;
    if( ++v11->Tcb.AbAllocationRegionCount != 1 )
      KeBugCheckEx(0x192u, v11, &Process->SvmProcessLock, (PVOID)KeGetCurrentIrql(), 0i64);
    LOBYTE(v13) = v11->Tcb.AbEntrySummary;
    HIDWORD(v60) = 0;
    if( !(_BYTE)v13 )
    {
      if( !v11->Tcb.AbOrphanedEntrySummary )
        goto LABEL_14;
      AbOrphanedEntrySummary = v11->Tcb.AbOrphanedEntrySummary;
      v11->Tcb.AbOrphanedEntrySummary = 0;
      LOBYTE(v13) = AbOrphanedEntrySummary | v11->Tcb.AbEntrySummary;
    }
    v15 = v13;
    _BitScanForward((unsigned int *)&v13, (unsigned __int8)v13);
    HIDWORD(v60) = v13;
    v11->Tcb.AbEntrySummary = v15 & ~(1 << v13);
    v2 = (__int64)&v11->Tcb.LockEntries[v13];
    if( v2 )
    {
      if( (unsigned __int64)p_SvmProcessLock >= 0xFFFF800000000000ui64
        && *((_BYTE *)&MiState[1537] + (((unsigned __int64)p_SvmProcessLock >> 39) & 0x1FF)) == 1 )
      {
        SessionId = MmGetSessionIdEx(v11->Tcb.ApcState.Process);
      }
      else
      {
        SessionId = -1;
      }
      *(_DWORD *)(v2 + 40) = SessionId;
      *(_QWORD *)(v2 + 32) = (unsigned __int64)p_SvmProcessLock & 0x7FFFFFFFFFFFFFFCi64;
LABEL_21:
      --v11->Tcb.AbAllocationRegionCount;
      KiAbThreadRemoveBoosts(&v11->Tcb, &Process->SvmProcessLock, &a3);
      v17 = v11->Tcb.SpecialApcDisable++ == -1;
      if( v17 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v11->Tcb.ApcState.ApcListHead[0].Flink != &v11->Tcb.152 )
        KiCheckForKernelApcDelivery();
      if( _interlockedbittestandset64((volatile signed __int32 *)p_SvmProcessLock, 0i64) )
        ExfAcquirePushLockExclusiveEx(&Process->SvmProcessLock, (VOID *)v2, &Process->SvmProcessLock);
      if( v2 )
        *(_BYTE *)(v2 + 26) |= 1u;
      DeviceAsid = Process->DeviceAsid;
      if( !DeviceAsid )
      {
        Asid = ExpAllocateAsid();
        DeviceAsid = Asid;
        if( !Asid )
        {
          v20 = -1073741709;
          Interface = -1073741709;
          goto LABEL_31;
        }
        if( !(unsigned int)ExpAssignPasid(Process, Asid) )
          DeviceAsid = Process->DeviceAsid;
      }
      --DeviceAsid;
      IommuContext = Process->SvmData;
      if( !IommuContext )
      {
        Interface = (*((__int64(__fastcall **)(_QWORD, _QWORD, VOID **))HalIommuDispatch + 2))(
                      DeviceAsid,
                      0i64,
                      &IommuContext);
        v20 = Interface;
        if( Interface < 0 )
          goto LABEL_31;
        CurrentIrql = KeGetCurrentIrql();
        __writecr8(0xFui64);
        KeAcquireInStackQueuedSpinLockAtDpcLevel(&Process->SvmLock, &LockHandle);
        if( Process->SvmData )
        {
          v7 = IommuContext;
          IommuContext = Process->SvmData;
        }
        else
        {
          Process->SvmData = IommuContext;
        }
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        __writecr8(CurrentIrql);
        if( v7 )
          (*((void(__fastcall **)(VOID *))HalIommuDispatch + 8))(v7);
      }
      v25 = (_ETHREAD *)KeGetCurrentThread();
      LODWORD(v62) = 0;
      --v25->Tcb.SpecialApcDisable;
      if( ++v25->Tcb.AbAllocationRegionCount != 1 )
        KeBugCheckEx(0x192u, v25, (char *)&WheapDeferredInternalLogsEventLock + 2280, (PVOID)KeGetCurrentIrql(), 0i64);
      HIDWORD(a3) = 0;
      LOBYTE(v26) = v25->Tcb.AbEntrySummary;
      if( !(_BYTE)v26 )
      {
        if( !v25->Tcb.AbOrphanedEntrySummary )
        {
          v29 = 0i64;
          goto LABEL_57;
        }
        v27 = v25->Tcb.AbOrphanedEntrySummary;
        v25->Tcb.AbOrphanedEntrySummary = 0;
        LOBYTE(v26) = v27 | v25->Tcb.AbEntrySummary;
      }
      v28 = v26;
      _BitScanForward((unsigned int *)&v26, (unsigned __int8)v26);
      HIDWORD(a3) = v26;
      v25->Tcb.AbEntrySummary = v28 & ~(1 << v26);
      v29 = (__int64)&v25->Tcb.LockEntries[v26];
      if( v29 )
      {
        if( (unsigned __int64)&WheapDeferredInternalLogsEventLock + 2280 >= 0xFFFF800000000000ui64
          && *((_BYTE *)&MiState[1537] + ((((unsigned __int64)&WheapDeferredInternalLogsEventLock + 2280) >> 39) & 0x1FF)) == 1 )
        {
          v30 = MmGetSessionIdEx(v25->Tcb.ApcState.Process);
        }
        else
        {
          v30 = -1;
        }
        *(_DWORD *)(v29 + 40) = v30;
        *(_QWORD *)(v29 + 32) = ((unsigned __int64)&WheapDeferredInternalLogsEventLock + 2280) & 0x7FFFFFFFFFFFFFFCi64;
        goto LABEL_60;
      }
LABEL_57:
      _interlockedbittestandset((volatile signed __int32 *)&v25->Tcb.116 + 1, 0x10u);
LABEL_60:
      --v25->Tcb.AbAllocationRegionCount;
      KiAbThreadRemoveBoosts(&v25->Tcb, (char *)&WheapDeferredInternalLogsEventLock + 2280, &v62);
      v17 = v25->Tcb.SpecialApcDisable++ == -1;
      if( v17 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v25->Tcb.ApcState.ApcListHead[0].Flink != &v25->Tcb.152 )
        KiCheckForKernelApcDelivery();
      if( _interlockedbittestandset64((volatile signed __int32 *)&WheapDeferredInternalLogsEventLock + 570, 0i64) )
        ExfAcquirePushLockExclusiveEx(
          (_EX_PUSH_LOCK *)&WheapDeferredInternalLogsEventLock + 285,
          (VOID *)v29,
          (char *)&WheapDeferredInternalLogsEventLock + 2280);
      if( v29 )
        *(_BYTE *)(v29 + 26) |= 1u;
      v31 = (_EXP_SVM_DEVICE *)*(&WheapDeferredInternalLogsEventLock + 294);
      if( (_UNKNOWN *)*(&WheapDeferredInternalLogsEventLock + 294) == (_UNKNOWN *)((char *)&WheapDeferredInternalLogsEventLock
                                                                                  + 2352) )
        goto LABEL_74;
      do
      {
        v32 = v31;
        v33 = v31;
        Device = v31;
        if( *((_DEVICE_OBJECT **)v31 + 2) == PhysicalDeviceObject )
          break;
        v31 = *(_EXP_SVM_DEVICE **)v31;
      }
      while( v31 != (_EXP_SVM_DEVICE *)((char *)&WheapDeferredInternalLogsEventLock + 2352) );
      if( *((_DEVICE_OBJECT **)v33 + 2) != PhysicalDeviceObject )
      {
        v33 = 0i64;
        Device = 0i64;
        v32 = 0i64;
      }
      if( !v32 )
LABEL_74:
        Interface = ExpPrepareNewSvmDevice(PhysicalDeviceObject, IommuContext, DeviceOut);
      else
        ++v33[6];
      if( (_InterlockedExchangeAdd64((_QWORD *)&WheapDeferredInternalLogsEventLock + 285, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock((_EX_PUSH_LOCK *)&WheapDeferredInternalLogsEventLock + 285);
      LODWORD(v59) = 0;
      v34 = (_ETHREAD *)KeGetCurrentThread();
      if( MiGetSystemRegionType((UINT64)&WheapDeferredInternalLogsEventLock + 2280) == 1 )
        v35 = MmGetSessionIdEx(v34->Tcb.ApcState.Process);
      else
        v35 = -1;
      --v34->Tcb.SpecialApcDisable;
      v36 = ++v34->Tcb.AbAllocationRegionCount;
      v37 = ((char)v34->Tcb.AbEntrySummary | (char)v34->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
      while( 1 )
      {
        v17 = !_BitScanReverse((unsigned int *)&v38, v37);
        if( v17 )
          break;
        v39 = &v34->Tcb.LockEntries[v38];
        v37 &= ~(1 << v38);
        if( (v39->AcquiredByte & 1) != 0
          && (v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
          && (v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (((unsigned __int64)&WheapDeferredInternalLogsEventLock
                                                                                                  + 2280) & 0x7FFFFFFFFFFFFFFCi64)
          && v39->LockState.SessionId == v35 )
        {
          v39->AcquiredByte &= ~1u;
          if( v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
          {
            if( v39 )
            {
              v39->CrossThreadReleasableAndBusyByte |= 2u;
              if( v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
                KiAbEntryRemoveFromTree(v39);
              v40 = v39->BoostBitmap.AllFields & 0x1FFFF;
              v41 = v39->BoostBitmap.AllFields & 0xFFFE0000;
              v39->ThreadLocalFlags &= ~1u;
              LODWORD(v59) = v40;
              v39->BoostBitmap.AllFields = v41;
              v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
              v42 = 1 << ((char)((_BYTE)v39 - LOBYTE(v34->Tcb.LockEntries)) / 96);
              if( v36 == 1 )
                v34->Tcb.AbEntrySummary |= v42;
              else
                _InterlockedOr8((volatile signed __int8 *)&v34->Tcb.AbOrphanedEntrySummary, v42);
              goto LABEL_93;
            }
            break;
          }
        }
      }
      if( (*(&v34->Tcb.MiscFlags + 1) & 0x10000) == 0 )
        KeBugCheckEx(0x162u, v34, (char *)&WheapDeferredInternalLogsEventLock + 2280, (PVOID)v35, 0i64);
LABEL_93:
      --v34->Tcb.AbAllocationRegionCount;
      KiAbThreadRemoveBoosts(&v34->Tcb, (char *)&WheapDeferredInternalLogsEventLock + 2280, &v59);
      v17 = v34->Tcb.SpecialApcDisable++ == -1;
      if( v17 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v34->Tcb.ApcState.ApcListHead[0].Flink != &v34->Tcb.152 )
        KiCheckForKernelApcDelivery();
      v20 = Interface;
      if( Interface >= 0 )
      {
        PoolWithTag = ExAllocatePoolWithTag(0x200ui64, 0x18ui64, 1682995269i64);
        v6 = PoolWithTag;
        if( PoolWithTag )
        {
          v44 = 0;
          PoolWithTag[2] = Device;
          v45 = KeGetCurrentIrql();
          __writecr8(0xFui64);
          KeAcquireInStackQueuedSpinLockAtDpcLevel(&Process->SvmLock, &LockHandle);
          p_SvmProcessDeviceListHead = &Process->SvmProcessDeviceListHead;
          Flink = Process->SvmProcessDeviceListHead.Flink;
          if( Flink == &Process->SvmProcessDeviceListHead )
          {
LABEL_105:
            v48 = p_SvmProcessDeviceListHead->Flink;
            if( p_SvmProcessDeviceListHead->Flink->Blink != p_SvmProcessDeviceListHead )
              goto LABEL_112;
            *v6 = v48;
            v6[1] = p_SvmProcessDeviceListHead;
            v48->Blink = (_LIST_ENTRY *)v6;
            p_SvmProcessDeviceListHead->Flink = (_LIST_ENTRY *)v6;
          }
          else
          {
            while( (_DEVICE_OBJECT *)Flink[1].Flink[1].Flink != PhysicalDeviceObject )
            {
              Flink = Flink->Flink;
              if( Flink == p_SvmProcessDeviceListHead )
                goto LABEL_105;
            }
            v44 = 1;
          }
          KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
          __writecr8(v45);
          if( v44 )
          {
            ExFreePoolWithTag(v6, 0);
            v20 = Interface;
            v6 = 0i64;
          }
          else
          {
            MmEnableProcessSvm();
            Interface = (*((__int64(__fastcall **)(VOID *, _QWORD))HalIommuDispatch + 4))(
                          IommuContext,
                          *((_QWORD *)Device + 15));
            v20 = Interface;
            if( Interface >= 0 )
            {
              v20 = (*((__int64(__fastcall **)(VOID *, unsigned __int64))HalIommuDispatch + 5))(
                      IommuContext,
                      Process->Pcb.DirectoryTableBase & 0xFFFFFFFFFFFFF000ui64);
              Interface = v20;
            }
          }
        }
        else
        {
          v20 = -1073741670;
          Interface = -1073741670;
        }
      }
LABEL_31:
      ((void(__fastcall *)(_EXP_SVM_DEVICE *))DeviceOut[3])(DeviceOut[1]);
      if( v20 >= 0 )
      {
        *(_DWORD *)ReturnedAsid = DeviceAsid;
        goto LABEL_114;
      }
      if( Device )
        ExpSvmDereferenceDevice(Device);
      if( !v6 )
        goto LABEL_114;
      v21 = KeGetCurrentIrql();
      __writecr8(0xFui64);
      KeAcquireInStackQueuedSpinLockAtDpcLevel(&Process->SvmLock, &LockHandle);
      v22 = (VOID **)*v6;
      v23 = (VOID ***)v6[1];
      if( *((VOID ***)*v6 + 1) == v6 && *v23 == v6 )
      {
        *v23 = v22;
        v22[1] = v23;
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        __writecr8(v21);
        ExFreePoolWithTag(v6, 0);
LABEL_114:
        v5 = -1;
        goto LABEL_115;
      }
LABEL_112:
      __fastfail(3u);
    }
LABEL_14:
    _interlockedbittestandset((volatile signed __int32 *)&v11->Tcb.116 + 1, 0x10u);
    goto LABEL_21;
  }
LABEL_115:
  if( (_InterlockedExchangeAdd64(&Process->SvmProcessLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
    ExfTryToWakePushLock(&Process->SvmProcessLock);
  v49 = (_ETHREAD *)KeGetCurrentThread();
  LODWORD(v60) = 0;
  if( MiGetSystemRegionType((UINT64)&Process->SvmProcessLock) == 1 )
    v5 = MmGetSessionIdEx(v49->Tcb.ApcState.Process);
  --v49->Tcb.SpecialApcDisable;
  v50 = ++v49->Tcb.AbAllocationRegionCount;
  v51 = ((char)v49->Tcb.AbEntrySummary | (char)v49->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
  while( 1 )
  {
    v17 = !_BitScanReverse((unsigned int *)&v53, v51);
    HIDWORD(v59) = v53;
    if( v17 )
      goto LABEL_126;
    v52 = &v49->Tcb.LockEntries[v53];
    v51 &= ~(1 << v53);
    if( (v52->AcquiredByte & 1) != 0
      && (v52->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
      && (v52->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == ((unsigned __int64)&Process->SvmProcessLock & 0x7FFFFFFFFFFFFFFCi64)
      && v52->LockState.SessionId == v5 )
    {
      v52->AcquiredByte &= ~1u;
      if( v52->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
        break;
    }
  }
  if( !v52 )
  {
LABEL_126:
    if( (*(&v49->Tcb.MiscFlags + 1) & 0x10000) == 0 )
      KeBugCheckEx(0x162u, v49, &Process->SvmProcessLock, (PVOID)v5, 0i64);
    goto LABEL_133;
  }
  v52->CrossThreadReleasableAndBusyByte |= 2u;
  if( v52->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
    KiAbEntryRemoveFromTree(v52);
  v54 = v52->BoostBitmap.AllFields & 0x1FFFF;
  v55 = v52->BoostBitmap.AllFields & 0xFFFE0000;
  v52->ThreadLocalFlags &= ~1u;
  LODWORD(v60) = v54;
  v52->BoostBitmap.AllFields = v55;
  v52->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
  v56 = v52 - v49->Tcb.LockEntries;
  if( v50 == 1 )
    v49->Tcb.AbEntrySummary |= 1 << v56;
  else
    _InterlockedOr8((volatile signed __int8 *)&v49->Tcb.AbOrphanedEntrySummary, 1 << v56);
LABEL_133:
  --v49->Tcb.AbAllocationRegionCount;
  KiAbThreadRemoveBoosts(&v49->Tcb, &Process->SvmProcessLock, &v60);
  v17 = v49->Tcb.SpecialApcDisable++ == -1;
  if( v17 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v49->Tcb.ApcState.ApcListHead[0].Flink != &v49->Tcb.152 )
    KiCheckForKernelApcDelivery();
  KiLeaveGuardedRegionUnsafe((__int64)v64);
  ExReleaseRundownProtection(&Process->RundownProtect);
  return Interface;
}

Referenced by:

No references.