IopLegacyResourceAllocation

NTSTATUS __stdcall IopLegacyResourceAllocation(
        ARBITER_REQUEST_SOURCE AllocationType,
        DRIVER_OBJECT *DriverObject,
        DEVICE_OBJECT *DeviceObject,
        IO_RESOURCE_REQUIREMENTS_LIST *ResourceRequirements,
        CM_RESOURCE_LIST **AllocatedResources){
  _ETHREAD *CurrentThread; 
  _ARBITER_REQUEST_SOURCE v6; 
  _DEVICE_OBJECT *v7; 
  size_t v8; 
  NTSTATUS RootEnumeratedDeviceObject; 
  size_t v13; 
  _DEVICE_NODE *v14; 
  NTSTATUS DeviceNode; 
  size_t v17; 
  size_t v18; 
  _DEVICE_OBJECT *v19; 
  void *v20; 
  size_t v21; 
  __int64 v22; 
  _PNP_DEVNODE_STATE *v23; 
  UINT64 v24; 
  UINT8 **v25; 
  _CM_RESOURCE_LIST *ResourceAssignment; 
  UINT8 *PoolWithTag; 
  UINT64 v28; 
  CHAR *v29; 
  _CM_RESOURCE_LIST *v30; 
  unsigned int v31; 
  void *DeviceObjecta[2]; 
  _PNP_RESOURCE_REQUEST result; 
  size_t Size; 
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v6 = AllocationType;
  v7 = 0i64;
  v8 = 0i64;
  --*((_WORD *)CurrentThread + 242);
  KeWaitForSingleObject(&PpRegistrySemaphore, DelayExecution, 0, 0, 0i64);
  RootEnumeratedDeviceObject = -1073741823;
  if( DeviceObject )
  {
    v13 = *(_QWORD *)(*((_QWORD *)DeviceObject + 39) + 40i64);
    Size = v13;
    if( v13 )
    {
      v8 = v13;
LABEL_4:
      v7 = DeviceObject;
LABEL_5:
      RootEnumeratedDeviceObject = 0;
      goto LABEL_6;
    }
    if( (*((_DWORD *)DeviceObject + 12) & 0x1000) == 0 )
    {
      DeviceNode = PipAllocateDeviceNode((__int64)DeviceObject, (void **)&Size);
      v17 = Size;
      RootEnumeratedDeviceObject = DeviceNode;
      if( Size )
      {
        if( DeviceNode == -1073740946 )
        {
          IopDestroyDeviceNode((_DEVICE_NODE *)Size);
          goto LABEL_17;
        }
        PipSetDevNodeFlags(Size, 0x20000);
        v8 = v17;
        goto LABEL_4;
      }
      goto LABEL_35;
    }
  }
  else
  {
    v18 = IopLegacyDeviceNode;
    Size = IopLegacyDeviceNode;
    if( IopLegacyDeviceNode )
    {
      do
      {
        if( *(DRIVER_OBJECT **)(v18 + 432) == DriverObject )
          break;
        v18 = *(_QWORD *)v18;
      }
      while( v18 );
      Size = v18;
      if( v18 )
      {
        v7 = *(_DEVICE_OBJECT **)(v18 + 32);
        v8 = v18;
        goto LABEL_5;
      }
    }
    DeviceObjecta[0] = 0i64;
    RootEnumeratedDeviceObject = IopCreateRootEnumeratedDeviceObject(DeviceObjecta);
    if( RootEnumeratedDeviceObject >= 0 )
    {
      v19 = (_DEVICE_OBJECT *)DeviceObjecta[0];
      v20 = DeviceObjecta[0];
      *((_DWORD *)DeviceObjecta[0] + 12) |= 0x1000u;
      RootEnumeratedDeviceObject = PipAllocateDeviceNode((__int64)v20, (void **)&Size);
      if( RootEnumeratedDeviceObject == -1073740946 || (v21 = Size) == 0 )
      {
        IoDeleteDevice(v19);
        v6 = AllocationType;
LABEL_35:
        RootEnumeratedDeviceObject = -1073741670;
        goto LABEL_36;
      }
      v22 = Size;
      *((_QWORD *)v19 + 1) = DriverObject;
      PipSetDevNodeFlags(v22, 131073);
      PipSetDevNodeState((_DEVICE_NODE *)v21, DeviceNodeInitialized, v23);
      *(_QWORD *)(v21 + 432) = DriverObject;
      *(_QWORD *)v21 = IopLegacyDeviceNode;
      if( IopLegacyDeviceNode )
        *(_QWORD *)(IopLegacyDeviceNode + 8) = v21;
      v7 = v19;
      IopLegacyDeviceNode = v21;
      v6 = AllocationType;
      v8 = v21;
    }
  }
LABEL_36:
  if( RootEnumeratedDeviceObject < 0 )
    goto LABEL_17;
LABEL_6:
  v14 = 0i64;
  if( *(_QWORD *)(v8 + 16) )
    goto LABEL_7;
  if( ResourceRequirements )
  {
    if( *((_DWORD *)ResourceRequirements + 1) == -1 )
      *((_DWORD *)ResourceRequirements + 1) = 1;
    *(_QWORD *)(v8 + 16) = IopRootDeviceNode;
LABEL_7:
    if( ResourceRequirements )
      goto LABEL_42;
  }
  if( *(_QWORD *)(v8 + 16) )
  {
LABEL_9:
    IopReleaseResources((_DEVICE_NODE *)v8);
    goto LABEL_10;
  }
LABEL_42:
  if( *(_QWORD *)(v8 + 416) || *(_QWORD *)(v8 + 544) )
    goto LABEL_9;
LABEL_10:
  if( !ResourceRequirements )
  {
    v14 = *(_DEVICE_NODE **)(v8 + 528);
    goto LABEL_12;
  }
  memset((INT64)&result, 0i64);
  result.PhysicalDevice = v7;
  result.ResourceRequirements = ResourceRequirements;
  result.AllocationType = v6;
  result.Flags = 128;
  LOBYTE(v24) = 1;
  PnpAllocateResources(1ui64, &result, v24, 0i64);
  RootEnumeratedDeviceObject = result.Status;
  if( result.Status < 0 )
    goto LABEL_12;
  v25 = (UINT8 **)AllocatedResources;
  ResourceAssignment = result.ResourceAssignment;
  if( *AllocatedResources )
    ResourceAssignment = *AllocatedResources;
  Size = (unsigned int)PnpDetermineResourceListSize(ResourceAssignment);
  PoolWithTag = (UINT8 *)ExAllocatePoolWithTag(PagedPool, Size, 0x20207050ui64);
  if( PoolWithTag )
  {
    if( *v25 )
      ExFreePoolWithTag(result.ResourceAssignment, 0);
    else
      *v25 = (UINT8 *)result.ResourceAssignment;
    ExAcquireFastMutex(&PiResourceListLock);
    v28 = Size;
    *(_QWORD *)(v8 + 416) = PoolWithTag;
    memmove(PoolWithTag, *v25, v28);
    *(_QWORD *)(v8 + 424) = result.TranslatedResourceAssignment;
    KeReleaseGuardedMutex(&PiResourceListLock);
    v14 = *(_DEVICE_NODE **)(v8 + 528);
  }
  else
  {
    ExAcquireFastMutex(&PiResourceListLock);
    *(_QWORD *)(v8 + 416) = result.ResourceAssignment;
    *(_QWORD *)(v8 + 424) = result.TranslatedResourceAssignment;
    KeReleaseGuardedMutex(&PiResourceListLock);
    IopReleaseResources((_DEVICE_NODE *)v8);
    RootEnumeratedDeviceObject = -1073741670;
  }
  if( RootEnumeratedDeviceObject < 0 )
  {
LABEL_12:
    IopRemoveLegacyDeviceNode(DeviceObject, (_DEVICE_NODE *)v8);
    if( RootEnumeratedDeviceObject < 0 )
      goto LABEL_17;
  }
  if( v14 )
  {
    v29 = IopCombineLegacyResources((INT64)v14);
    v30 = (_CM_RESOURCE_LIST *)v29;
    if( v29 )
    {
      v31 = PnpDetermineResourceListSize((CM_RESOURCE_LIST *)v29);
      IopWriteAllocatedResourcesToRegistry(v14, v30, v31);
      ExFreePoolWithTag(v30, 0);
    }
  }
  if( AllocationType != ArbiterRequestPnpDetected && ResourceRequirements )
    IopSetLegacyResourcesFlag(DriverObject);
LABEL_17:
  KeReleaseSemaphore(&PpRegistrySemaphore, 0i64, 1i64, 0);
  KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
  return RootEnumeratedDeviceObject;
}

Referenced by:

IoAssignResources
IoReportResourceUsageInternal
IopDestroyDeviceNode
IopReleaseDeviceResources