ReactOS 0.4.15-dev-7907-g95bf896
pnpres.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for pnpres.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

FORCEINLINE PIO_RESOURCE_LIST IopGetNextResourceList (_In_ const IO_RESOURCE_LIST *ResourceList)
 
static BOOLEAN IopCheckDescriptorForConflict (PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
 
static BOOLEAN IopFindBusNumberResource (IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
 
static BOOLEAN IopFindMemoryResource (IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
 
static BOOLEAN IopFindPortResource (IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
 
static BOOLEAN IopFindDmaResource (IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
 
static BOOLEAN IopFindInterruptResource (IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
 
NTSTATUS NTAPI IopFixupResourceListWithRequirements (IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList, OUT PCM_RESOURCE_LIST *ResourceList)
 
static BOOLEAN IopCheckResourceDescriptor (IN PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc, IN PCM_RESOURCE_LIST ResourceList, IN BOOLEAN Silent, OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
 
static NTSTATUS IopUpdateControlKeyWithResources (IN PDEVICE_NODE DeviceNode)
 
static NTSTATUS IopFilterResourceRequirements (IN PDEVICE_NODE DeviceNode)
 
NTSTATUS IopUpdateResourceMap (IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2Key)
 
NTSTATUS IopUpdateResourceMapForPnPDevice (IN PDEVICE_NODE DeviceNode)
 
static NTSTATUS IopTranslateDeviceResources (IN PDEVICE_NODE DeviceNode)
 
NTSTATUS NTAPI IopAssignDeviceResources (IN PDEVICE_NODE DeviceNode)
 
static BOOLEAN IopCheckForResourceConflict (IN PCM_RESOURCE_LIST ResourceList1, IN PCM_RESOURCE_LIST ResourceList2, IN BOOLEAN Silent, OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
 
NTSTATUS NTAPI IopDetectResourceConflict (IN PCM_RESOURCE_LIST ResourceList, IN BOOLEAN Silent, OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file pnpres.c.

Function Documentation

◆ IopAssignDeviceResources()

NTSTATUS NTAPI IopAssignDeviceResources ( IN PDEVICE_NODE  DeviceNode)

Definition at line 1116 of file pnpres.c.

1118{
1120 ULONG ListSize;
1121
1123 if (!NT_SUCCESS(Status))
1124 goto ByeBye;
1125
1126 if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements)
1127 {
1128 /* No resource needed for this device */
1129 DeviceNode->ResourceList = NULL;
1130 DeviceNode->ResourceListTranslated = NULL;
1133
1134 return STATUS_SUCCESS;
1135 }
1136
1137 if (DeviceNode->BootResources)
1138 {
1139 ListSize = PnpDetermineResourceListSize(DeviceNode->BootResources);
1140
1141 DeviceNode->ResourceList = ExAllocatePool(PagedPool, ListSize);
1142 if (!DeviceNode->ResourceList)
1143 {
1145 goto ByeBye;
1146 }
1147
1148 RtlCopyMemory(DeviceNode->ResourceList, DeviceNode->BootResources, ListSize);
1149
1151 if (!NT_SUCCESS(Status))
1152 {
1153 DPRINT1("Boot resources for %wZ cause a resource conflict!\n", &DeviceNode->InstancePath);
1154 ExFreePool(DeviceNode->ResourceList);
1155 DeviceNode->ResourceList = NULL;
1156 }
1157 }
1158 else
1159 {
1160 /* We'll make this from the requirements */
1161 DeviceNode->ResourceList = NULL;
1162 }
1163
1164 /* No resources requirements */
1165 if (!DeviceNode->ResourceRequirements)
1166 goto Finish;
1167
1168 /* Call HAL to fixup our resource requirements list */
1169 HalAdjustResourceList(&DeviceNode->ResourceRequirements);
1170
1171 /* Add resource requirements that aren't in the list we already got */
1173 &DeviceNode->ResourceList);
1174 if (!NT_SUCCESS(Status))
1175 {
1176 DPRINT1("Failed to fixup a resource list from supplied resources for %wZ\n", &DeviceNode->InstancePath);
1178 goto ByeBye;
1179 }
1180
1181 /* IopFixupResourceListWithRequirements should NEVER give us a conflicting list */
1183
1184Finish:
1186 if (!NT_SUCCESS(Status))
1187 {
1189 DPRINT1("Failed to translate resources for %wZ\n", &DeviceNode->InstancePath);
1190 goto ByeBye;
1191 }
1192
1194 if (!NT_SUCCESS(Status))
1195 goto ByeBye;
1196
1198 if (!NT_SUCCESS(Status))
1199 goto ByeBye;
1200
1202
1203 return STATUS_SUCCESS;
1204
1205ByeBye:
1206 if (DeviceNode->ResourceList)
1207 {
1208 ExFreePool(DeviceNode->ResourceList);
1209 DeviceNode->ResourceList = NULL;
1210 }
1211
1212 DeviceNode->ResourceListTranslated = NULL;
1213
1214 return Status;
1215}
@ DeviceNode
Definition: Node.h:9
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define CM_PROB_TRANSLATION_FAILED
Definition: cfg.h:63
#define CM_PROB_NORMAL_CONFLICT
Definition: cfg.h:42
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PagedPool
Definition: env_spec_w32.h:308
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI HalAdjustResourceList(IN PIO_RESOURCE_REQUIREMENTS_LIST *ResourceList)
Definition: bus.c:26
#define ASSERT(a)
Definition: mode.c:44
@ DeviceNodeResourcesAssigned
Definition: iotypes.h:425
#define DNF_NO_RESOURCE_REQUIRED
Definition: iotypes.h:178
ULONG NTAPI PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList)
Definition: pnpmgr.c:1237
PNP_DEVNODE_STATE PiSetDevNodeState(_In_ PDEVICE_NODE DeviceNode, _In_ PNP_DEVNODE_STATE NewState)
Definition: devnode.c:108
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
NTSTATUS IopUpdateResourceMapForPnPDevice(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:961
NTSTATUS NTAPI IopFixupResourceListWithRequirements(IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList, OUT PCM_RESOURCE_LIST *ResourceList)
Definition: pnpres.c:219
static NTSTATUS IopTranslateDeviceResources(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:969
static NTSTATUS IopUpdateControlKeyWithResources(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:716
static NTSTATUS IopFilterResourceRequirements(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:773
NTSTATUS NTAPI IopDetectResourceConflict(IN PCM_RESOURCE_LIST ResourceList, IN BOOLEAN Silent, OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
Definition: pnpres.c:1255
#define STATUS_SUCCESS
Definition: shellext.h:65
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59

Referenced by IoReportDetectedDevice(), and PiDevNodeStateMachine().

◆ IopCheckDescriptorForConflict()

static BOOLEAN IopCheckDescriptorForConflict ( PCM_PARTIAL_RESOURCE_DESCRIPTOR  CmDesc,
OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR  ConflictingDescriptor 
)
static

Definition at line 27 of file pnpres.c.

30{
31 CM_RESOURCE_LIST CmList;
33
34 CmList.Count = 1;
36 CmList.List[0].BusNumber = 0;
37 CmList.List[0].PartialResourceList.Version = 1;
38 CmList.List[0].PartialResourceList.Revision = 1;
39 CmList.List[0].PartialResourceList.Count = 1;
40 CmList.List[0].PartialResourceList.PartialDescriptors[0] = *CmDesc;
41
42 Status = IopDetectResourceConflict(&CmList, TRUE, ConflictingDescriptor);
44 return TRUE;
45
46 return FALSE;
47}
#define TRUE
Definition: types.h:120
@ InterfaceTypeUndefined
Definition: hwresource.cpp:136
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
CM_FULL_RESOURCE_DESCRIPTOR List[1]
Definition: hwresource.cpp:165

Referenced by IopFindBusNumberResource(), IopFindDmaResource(), IopFindInterruptResource(), IopFindMemoryResource(), and IopFindPortResource().

◆ IopCheckForResourceConflict()

static BOOLEAN IopCheckForResourceConflict ( IN PCM_RESOURCE_LIST  ResourceList1,
IN PCM_RESOURCE_LIST  ResourceList2,
IN BOOLEAN  Silent,
OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR  ConflictingDescriptor 
)
static

Definition at line 1219 of file pnpres.c.

1224{
1225 ULONG i, ii;
1227 PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
1228
1229 FullDescriptor = &ResourceList1->List[0];
1230 for (i = 0; i < ResourceList1->Count; i++)
1231 {
1232 PCM_PARTIAL_RESOURCE_LIST ResList = &FullDescriptor->PartialResourceList;
1233 FullDescriptor = CmiGetNextResourceDescriptor(FullDescriptor);
1234
1235 for (ii = 0; ii < ResList->Count; ii++)
1236 {
1237 /* Partial resource descriptors can be of variable size (CmResourceTypeDeviceSpecific),
1238 but only one is allowed and it must be the last one in the list! */
1240
1242 ResourceList2,
1243 Silent,
1244 ConflictingDescriptor);
1245 if (Result) goto ByeBye;
1246 }
1247 }
1248
1249ByeBye:
1250
1251 return Result;
1252}
unsigned char BOOLEAN
FORCEINLINE PCM_FULL_RESOURCE_DESCRIPTOR CmiGetNextResourceDescriptor(_In_ const CM_FULL_RESOURCE_DESCRIPTOR *ResourceDescriptor)
Definition: cmreslist.h:54
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static BOOLEAN IopCheckResourceDescriptor(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc, IN PCM_RESOURCE_LIST ResourceList, IN BOOLEAN Silent, OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
Definition: pnpres.c:559
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by IopDetectResourceConflict().

◆ IopCheckResourceDescriptor()

static BOOLEAN IopCheckResourceDescriptor ( IN PCM_PARTIAL_RESOURCE_DESCRIPTOR  ResDesc,
IN PCM_RESOURCE_LIST  ResourceList,
IN BOOLEAN  Silent,
OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR  ConflictingDescriptor 
)
static

Definition at line 559 of file pnpres.c.

564{
565 ULONG i, ii;
567 PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
568
569 FullDescriptor = &ResourceList->List[0];
570 for (i = 0; i < ResourceList->Count; i++)
571 {
572 PCM_PARTIAL_RESOURCE_LIST ResList = &FullDescriptor->PartialResourceList;
573 FullDescriptor = CmiGetNextResourceDescriptor(FullDescriptor);
574
575 for (ii = 0; ii < ResList->Count; ii++)
576 {
577 /* Partial resource descriptors can be of variable size (CmResourceTypeDeviceSpecific),
578 but only one is allowed and it must be the last one in the list! */
580
581 /* We don't care about shared resources */
582 if (ResDesc->ShareDisposition == CmResourceShareShared &&
584 continue;
585
586 /* Make sure we're comparing the same types */
587 if (ResDesc->Type != ResDesc2->Type)
588 continue;
589
590 switch (ResDesc->Type)
591 {
593 {
594 /* NOTE: ranges are in a form [x1;x2) */
595 UINT64 rStart = (UINT64)ResDesc->u.Memory.Start.QuadPart;
596 UINT64 rEnd = (UINT64)ResDesc->u.Memory.Start.QuadPart
597 + ResDesc->u.Memory.Length;
598 UINT64 r2Start = (UINT64)ResDesc2->u.Memory.Start.QuadPart;
599 UINT64 r2End = (UINT64)ResDesc2->u.Memory.Start.QuadPart
600 + ResDesc2->u.Memory.Length;
601
602 if (rStart < r2End && r2Start < rEnd)
603 {
604 if (!Silent)
605 {
606 DPRINT1("Resource conflict: Memory (0x%I64x to 0x%I64x vs. 0x%I64x to 0x%I64x)\n",
607 rStart, rEnd, r2Start, r2End);
608 }
609
610 Result = TRUE;
611
612 goto ByeBye;
613 }
614 break;
615 }
617 {
618 /* NOTE: ranges are in a form [x1;x2) */
619 UINT64 rStart = (UINT64)ResDesc->u.Port.Start.QuadPart;
620 UINT64 rEnd = (UINT64)ResDesc->u.Port.Start.QuadPart
621 + ResDesc->u.Port.Length;
622 UINT64 r2Start = (UINT64)ResDesc2->u.Port.Start.QuadPart;
623 UINT64 r2End = (UINT64)ResDesc2->u.Port.Start.QuadPart
624 + ResDesc2->u.Port.Length;
625
626 if (rStart < r2End && r2Start < rEnd)
627 {
628 if (!Silent)
629 {
630 DPRINT1("Resource conflict: Port (0x%I64x to 0x%I64x vs. 0x%I64x to 0x%I64x)\n",
631 rStart, rEnd, r2Start, r2End);
632 }
633
634 Result = TRUE;
635
636 goto ByeBye;
637 }
638 break;
639 }
641 {
642 if (ResDesc->u.Interrupt.Vector == ResDesc2->u.Interrupt.Vector)
643 {
644 if (!Silent)
645 {
646 DPRINT1("Resource conflict: IRQ (0x%x 0x%x vs. 0x%x 0x%x)\n",
647 ResDesc->u.Interrupt.Vector, ResDesc->u.Interrupt.Level,
648 ResDesc2->u.Interrupt.Vector, ResDesc2->u.Interrupt.Level);
649 }
650
651 Result = TRUE;
652
653 goto ByeBye;
654 }
655 break;
656 }
658 {
659 /* NOTE: ranges are in a form [x1;x2) */
660 UINT32 rStart = ResDesc->u.BusNumber.Start;
661 UINT32 rEnd = ResDesc->u.BusNumber.Start + ResDesc->u.BusNumber.Length;
662 UINT32 r2Start = ResDesc2->u.BusNumber.Start;
663 UINT32 r2End = ResDesc2->u.BusNumber.Start + ResDesc2->u.BusNumber.Length;
664
665 if (rStart < r2End && r2Start < rEnd)
666 {
667 if (!Silent)
668 {
669 DPRINT1("Resource conflict: Bus number (0x%x to 0x%x vs. 0x%x to 0x%x)\n",
670 rStart, rEnd, r2Start, r2End);
671 }
672
673 Result = TRUE;
674
675 goto ByeBye;
676 }
677 break;
678 }
680 {
681 if (ResDesc->u.Dma.Channel == ResDesc2->u.Dma.Channel)
682 {
683 if (!Silent)
684 {
685 DPRINT1("Resource conflict: Dma (0x%x 0x%x vs. 0x%x 0x%x)\n",
686 ResDesc->u.Dma.Channel, ResDesc->u.Dma.Port,
687 ResDesc2->u.Dma.Channel, ResDesc2->u.Dma.Port);
688 }
689
690 Result = TRUE;
691
692 goto ByeBye;
693 }
694 break;
695 }
696 }
697 }
698 }
699
700ByeBye:
701
702 if (Result && ConflictingDescriptor)
703 {
704 RtlCopyMemory(ConflictingDescriptor,
705 ResDesc,
707 }
708
709 // Hacked, because after fixing resource list parsing
710 // we actually detect resource conflicts
711 return Silent ? Result : FALSE; // Result;
712}
unsigned long long UINT64
unsigned int UINT32
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
#define CmResourceTypeDma
Definition: hwresource.cpp:126
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define CmResourceTypeBusNumber
Definition: hwresource.cpp:128
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393::@396 Interrupt
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393::@398 Memory
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393::@401 BusNumber
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393::@395 Port
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393::@399 Dma
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:309
@ CmResourceShareShared
Definition: cmtypes.h:243

Referenced by IopCheckForResourceConflict().

◆ IopDetectResourceConflict()

NTSTATUS NTAPI IopDetectResourceConflict ( IN PCM_RESOURCE_LIST  ResourceList,
IN BOOLEAN  Silent,
OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR  ConflictingDescriptor 
)

Definition at line 1255 of file pnpres.c.

1259{
1262 HANDLE ResourceMapKey = NULL, ChildKey2 = NULL, ChildKey3 = NULL;
1263 ULONG KeyInformationLength, RequiredLength, KeyValueInformationLength, KeyNameInformationLength;
1264 PKEY_BASIC_INFORMATION KeyInformation;
1265 PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
1267 ULONG ChildKeyIndex1 = 0, ChildKeyIndex2, ChildKeyIndex3;
1269
1270 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
1272 &KeyName,
1274 NULL,
1275 NULL);
1276 Status = ZwOpenKey(&ResourceMapKey, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &ObjectAttributes);
1277 if (!NT_SUCCESS(Status))
1278 {
1279 /* The key is missing which means we are the first device */
1280 return STATUS_SUCCESS;
1281 }
1282
1283 while (TRUE)
1284 {
1285 Status = ZwEnumerateKey(ResourceMapKey,
1286 ChildKeyIndex1,
1288 NULL,
1289 0,
1292 break;
1294 {
1295 KeyInformationLength = RequiredLength;
1296 KeyInformation = ExAllocatePoolWithTag(PagedPool,
1297 KeyInformationLength,
1298 TAG_IO);
1299 if (!KeyInformation)
1300 {
1302 goto cleanup;
1303 }
1304
1305 Status = ZwEnumerateKey(ResourceMapKey,
1306 ChildKeyIndex1,
1308 KeyInformation,
1309 KeyInformationLength,
1311 }
1312 else
1313 goto cleanup;
1314 ChildKeyIndex1++;
1315 if (!NT_SUCCESS(Status))
1316 {
1317 ExFreePoolWithTag(KeyInformation, TAG_IO);
1318 goto cleanup;
1319 }
1320
1321 KeyName.Buffer = KeyInformation->Name;
1322 KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength;
1324 &KeyName,
1326 ResourceMapKey,
1327 NULL);
1328 Status = ZwOpenKey(&ChildKey2,
1331 ExFreePoolWithTag(KeyInformation, TAG_IO);
1332 if (!NT_SUCCESS(Status))
1333 goto cleanup;
1334
1335 ChildKeyIndex2 = 0;
1336 while (TRUE)
1337 {
1338 Status = ZwEnumerateKey(ChildKey2,
1339 ChildKeyIndex2,
1341 NULL,
1342 0,
1345 break;
1346 else if (Status == STATUS_BUFFER_TOO_SMALL)
1347 {
1348 KeyInformationLength = RequiredLength;
1349 KeyInformation = ExAllocatePoolWithTag(PagedPool,
1350 KeyInformationLength,
1351 TAG_IO);
1352 if (!KeyInformation)
1353 {
1355 goto cleanup;
1356 }
1357
1358 Status = ZwEnumerateKey(ChildKey2,
1359 ChildKeyIndex2,
1361 KeyInformation,
1362 KeyInformationLength,
1364 }
1365 else
1366 goto cleanup;
1367 ChildKeyIndex2++;
1368 if (!NT_SUCCESS(Status))
1369 {
1370 ExFreePoolWithTag(KeyInformation, TAG_IO);
1371 goto cleanup;
1372 }
1373
1374 KeyName.Buffer = KeyInformation->Name;
1375 KeyName.MaximumLength = KeyName.Length = (USHORT)KeyInformation->NameLength;
1377 &KeyName,
1379 ChildKey2,
1380 NULL);
1381 Status = ZwOpenKey(&ChildKey3, KEY_QUERY_VALUE, &ObjectAttributes);
1382 ExFreePoolWithTag(KeyInformation, TAG_IO);
1383 if (!NT_SUCCESS(Status))
1384 goto cleanup;
1385
1386 ChildKeyIndex3 = 0;
1387 while (TRUE)
1388 {
1389 Status = ZwEnumerateValueKey(ChildKey3,
1390 ChildKeyIndex3,
1392 NULL,
1393 0,
1396 break;
1397 else if (Status == STATUS_BUFFER_TOO_SMALL)
1398 {
1399 KeyValueInformationLength = RequiredLength;
1400 KeyValueInformation = ExAllocatePoolWithTag(PagedPool,
1401 KeyValueInformationLength,
1402 TAG_IO);
1403 if (!KeyValueInformation)
1404 {
1406 goto cleanup;
1407 }
1408
1409 Status = ZwEnumerateValueKey(ChildKey3,
1410 ChildKeyIndex3,
1412 KeyValueInformation,
1413 KeyValueInformationLength,
1415 }
1416 else
1417 goto cleanup;
1418 if (!NT_SUCCESS(Status))
1419 {
1420 ExFreePoolWithTag(KeyValueInformation, TAG_IO);
1421 goto cleanup;
1422 }
1423
1424 Status = ZwEnumerateValueKey(ChildKey3,
1425 ChildKeyIndex3,
1427 NULL,
1428 0,
1431 {
1432 KeyNameInformationLength = RequiredLength;
1434 KeyNameInformationLength + sizeof(WCHAR),
1435 TAG_IO);
1436 if (!KeyNameInformation)
1437 {
1439 goto cleanup;
1440 }
1441
1442 Status = ZwEnumerateValueKey(ChildKey3,
1443 ChildKeyIndex3,
1446 KeyNameInformationLength,
1448 }
1449 else
1450 goto cleanup;
1451 ChildKeyIndex3++;
1452 if (!NT_SUCCESS(Status))
1453 {
1455 goto cleanup;
1456 }
1457
1458 KeyNameInformation->Name[KeyNameInformation->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
1459
1460 /* Skip translated entries */
1461 if (wcsstr(KeyNameInformation->Name, L".Translated"))
1462 {
1464 ExFreePoolWithTag(KeyValueInformation, TAG_IO);
1465 continue;
1466 }
1467
1469
1471 (PCM_RESOURCE_LIST)KeyValueInformation->Data,
1472 Silent,
1473 ConflictingDescriptor))
1474 {
1475 ExFreePoolWithTag(KeyValueInformation, TAG_IO);
1477 goto cleanup;
1478 }
1479
1480 ExFreePoolWithTag(KeyValueInformation, TAG_IO);
1481 }
1482 }
1483 }
1484
1485cleanup:
1486 if (ResourceMapKey != NULL)
1487 ObCloseHandle(ResourceMapKey, KernelMode);
1488 if (ChildKey2 != NULL)
1489 ObCloseHandle(ChildKey2, KernelMode);
1490 if (ChildKey3 != NULL)
1491 ObCloseHandle(ChildKey3, KernelMode);
1492
1495
1496 return Status;
1497}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
static void cleanup(void)
Definition: main.c:1335
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
@ KeyNameInformation
Definition: winternl.h:831
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KernelMode
Definition: asm.h:34
@ KeyBasicInformation
Definition: nt_native.h:1131
@ KeyValueBasicInformation
Definition: nt_native.h:1180
@ KeyValuePartialInformation
Definition: nt_native.h:1182
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define UNICODE_NULL
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
unsigned short USHORT
Definition: pedump.c:61
static BOOLEAN IopCheckForResourceConflict(IN PCM_RESOURCE_LIST ResourceList1, IN PCM_RESOURCE_LIST ResourceList2, IN BOOLEAN Silent, OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
Definition: pnpres.c:1219
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define TAG_IO
Definition: tag.h:80
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:30
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by IopAssignDeviceResources(), IopCheckDescriptorForConflict(), IoReportResourceForDetection(), and IoReportResourceUsage().

◆ IopFilterResourceRequirements()

static NTSTATUS IopFilterResourceRequirements ( IN PDEVICE_NODE  DeviceNode)
static

Definition at line 773 of file pnpres.c.

775{
779
780 DPRINT("Sending IRP_MN_FILTER_RESOURCE_REQUIREMENTS to device stack\n");
781
782 Stack.Parameters.FilterResourceRequirements.IoResourceRequirementList = DeviceNode->ResourceRequirements;
783 Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
786 &Stack);
788 {
789 DPRINT1("IopInitiatePnpIrp(IRP_MN_FILTER_RESOURCE_REQUIREMENTS) failed\n");
790 return Status;
791 }
793 {
795 }
796
797 return STATUS_SUCCESS;
798}
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define DPRINT
Definition: sndvol32.h:71
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS

Referenced by IopAssignDeviceResources().

◆ IopFindBusNumberResource()

static BOOLEAN IopFindBusNumberResource ( IN PIO_RESOURCE_DESCRIPTOR  IoDesc,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR  CmDesc 
)
static

Definition at line 51 of file pnpres.c.

54{
56 CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc;
57
58 ASSERT(IoDesc->Type == CmDesc->Type);
59 ASSERT(IoDesc->Type == CmResourceTypeBusNumber);
60
61 for (Start = IoDesc->u.BusNumber.MinBusNumber;
62 Start <= IoDesc->u.BusNumber.MaxBusNumber - IoDesc->u.BusNumber.Length + 1;
63 Start++)
64 {
65 CmDesc->u.BusNumber.Length = IoDesc->u.BusNumber.Length;
66 CmDesc->u.BusNumber.Start = Start;
67
68 if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc))
69 {
70 Start += ConflictingDesc.u.BusNumber.Start + ConflictingDesc.u.BusNumber.Length;
71 }
72 else
73 {
74 DPRINT1("Satisfying bus number requirement with 0x%x (length: 0x%x)\n", Start, CmDesc->u.BusNumber.Length);
75 return TRUE;
76 }
77 }
78
79 return FALSE;
80}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
static BOOLEAN IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
Definition: pnpres.c:27
@ Start
Definition: partlist.h:33

Referenced by IopFixupResourceListWithRequirements().

◆ IopFindDmaResource()

static BOOLEAN IopFindDmaResource ( IN PIO_RESOURCE_DESCRIPTOR  IoDesc,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR  CmDesc 
)
static

Definition at line 160 of file pnpres.c.

163{
164 ULONG Channel;
165
166 ASSERT(IoDesc->Type == CmDesc->Type);
167 ASSERT(IoDesc->Type == CmResourceTypeDma);
168
169 for (Channel = IoDesc->u.Dma.MinimumChannel;
170 Channel <= IoDesc->u.Dma.MaximumChannel;
171 Channel++)
172 {
173 CmDesc->u.Dma.Channel = Channel;
174 CmDesc->u.Dma.Port = 0;
175
177 {
178 DPRINT1("Satisfying DMA requirement with channel 0x%x\n", Channel);
179 return TRUE;
180 }
181 }
182
183 return FALSE;
184}

Referenced by IopFixupResourceListWithRequirements().

◆ IopFindInterruptResource()

static BOOLEAN IopFindInterruptResource ( IN PIO_RESOURCE_DESCRIPTOR  IoDesc,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR  CmDesc 
)
static

Definition at line 188 of file pnpres.c.

191{
193
194 ASSERT(IoDesc->Type == CmDesc->Type);
195 ASSERT(IoDesc->Type == CmResourceTypeInterrupt);
196
197 for (Vector = IoDesc->u.Interrupt.MinimumVector;
198 Vector <= IoDesc->u.Interrupt.MaximumVector;
199 Vector++)
200 {
201 CmDesc->u.Interrupt.Vector = Vector;
202 CmDesc->u.Interrupt.Level = Vector;
203 CmDesc->u.Interrupt.Affinity = (KAFFINITY)-1;
204
206 {
207 DPRINT1("Satisfying interrupt requirement with IRQ 0x%x\n", Vector);
208 return TRUE;
209 }
210 }
211
212 DPRINT1("Failed to satisfy interrupt requirement with IRQ 0x%x-0x%x\n",
213 IoDesc->u.Interrupt.MinimumVector,
214 IoDesc->u.Interrupt.MaximumVector);
215 return FALSE;
216}
ULONG_PTR KAFFINITY
Definition: compat.h:85

Referenced by IopFixupResourceListWithRequirements().

◆ IopFindMemoryResource()

static BOOLEAN IopFindMemoryResource ( IN PIO_RESOURCE_DESCRIPTOR  IoDesc,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR  CmDesc 
)
static

Definition at line 84 of file pnpres.c.

87{
89 CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc;
90
91 ASSERT(IoDesc->Type == CmDesc->Type);
92 ASSERT(IoDesc->Type == CmResourceTypeMemory);
93
94 /* HACK */
95 if (IoDesc->u.Memory.Alignment == 0)
96 IoDesc->u.Memory.Alignment = 1;
97
98 for (Start = (ULONGLONG)IoDesc->u.Memory.MinimumAddress.QuadPart;
99 Start <= (ULONGLONG)IoDesc->u.Memory.MaximumAddress.QuadPart - IoDesc->u.Memory.Length + 1;
100 Start += IoDesc->u.Memory.Alignment)
101 {
102 CmDesc->u.Memory.Length = IoDesc->u.Memory.Length;
103 CmDesc->u.Memory.Start.QuadPart = (LONGLONG)Start;
104
105 if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc))
106 {
107 Start += (ULONGLONG)ConflictingDesc.u.Memory.Start.QuadPart +
108 ConflictingDesc.u.Memory.Length;
109 }
110 else
111 {
112 DPRINT1("Satisfying memory requirement with 0x%I64x (length: 0x%x)\n", Start, CmDesc->u.Memory.Length);
113 return TRUE;
114 }
115 }
116
117 return FALSE;
118}
int64_t LONGLONG
Definition: typedefs.h:68
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by IopFixupResourceListWithRequirements().

◆ IopFindPortResource()

static BOOLEAN IopFindPortResource ( IN PIO_RESOURCE_DESCRIPTOR  IoDesc,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR  CmDesc 
)
static

Definition at line 122 of file pnpres.c.

125{
127 CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc;
128
129 ASSERT(IoDesc->Type == CmDesc->Type);
130 ASSERT(IoDesc->Type == CmResourceTypePort);
131
132 /* HACK */
133 if (IoDesc->u.Port.Alignment == 0)
134 IoDesc->u.Port.Alignment = 1;
135
136 for (Start = (ULONGLONG)IoDesc->u.Port.MinimumAddress.QuadPart;
137 Start <= (ULONGLONG)IoDesc->u.Port.MaximumAddress.QuadPart - IoDesc->u.Port.Length + 1;
138 Start += IoDesc->u.Port.Alignment)
139 {
140 CmDesc->u.Port.Length = IoDesc->u.Port.Length;
141 CmDesc->u.Port.Start.QuadPart = (LONGLONG)Start;
142
143 if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc))
144 {
145 Start += (ULONGLONG)ConflictingDesc.u.Port.Start.QuadPart + ConflictingDesc.u.Port.Length;
146 }
147 else
148 {
149 DPRINT("Satisfying port requirement with 0x%I64x (length: 0x%x)\n", Start, CmDesc->u.Port.Length);
150 return TRUE;
151 }
152 }
153
154 DPRINT1("IopFindPortResource failed!\n");
155 return FALSE;
156}

Referenced by IopFixupResourceListWithRequirements().

◆ IopFixupResourceListWithRequirements()

NTSTATUS NTAPI IopFixupResourceListWithRequirements ( IN PIO_RESOURCE_REQUIREMENTS_LIST  RequirementsList,
OUT PCM_RESOURCE_LIST ResourceList 
)

Definition at line 219 of file pnpres.c.

222{
223 ULONG i, OldCount;
224 BOOLEAN AlternateRequired = FALSE;
225 PIO_RESOURCE_LIST ResList;
226
227 /* Save the initial resource count when we got here so we can restore if an alternate fails */
228 if (*ResourceList != NULL)
229 OldCount = (*ResourceList)->List[0].PartialResourceList.Count;
230 else
231 OldCount = 0;
232
233 ResList = &RequirementsList->List[0];
234 for (i = 0; i < RequirementsList->AlternativeLists; i++, ResList = IopGetNextResourceList(ResList))
235 {
236 ULONG ii;
237
238 /* We need to get back to where we were before processing the last alternative list */
239 if (OldCount == 0 && *ResourceList != NULL)
240 {
241 /* Just free it and kill the pointer */
244 }
245 else if (OldCount != 0)
246 {
247 PCM_RESOURCE_LIST NewList;
248
249 /* Let's resize it */
250 (*ResourceList)->List[0].PartialResourceList.Count = OldCount;
251
252 /* Allocate the new smaller list */
254 if (!NewList)
255 return STATUS_NO_MEMORY;
256
257 /* Copy the old stuff back */
259
260 /* Free the old one */
262
263 /* Store the pointer to the new one */
264 *ResourceList = NewList;
265 }
266
267 for (ii = 0; ii < ResList->Count; ii++)
268 {
269 ULONG iii;
270 PCM_PARTIAL_RESOURCE_LIST PartialList = (*ResourceList) ? &(*ResourceList)->List[0].PartialResourceList : NULL;
271 PIO_RESOURCE_DESCRIPTOR IoDesc = &ResList->Descriptors[ii];
272 BOOLEAN Matched = FALSE;
273
274 /* Skip alternates if we don't need one */
275 if (!AlternateRequired && (IoDesc->Option & IO_RESOURCE_ALTERNATIVE))
276 {
277 DPRINT("Skipping unneeded alternate\n");
278 continue;
279 }
280
281 /* Check if we couldn't satsify a requirement or its alternates */
282 if (AlternateRequired && !(IoDesc->Option & IO_RESOURCE_ALTERNATIVE))
283 {
284 DPRINT1("Unable to satisfy preferred resource or alternates in list %lu\n", i);
285
286 /* Break out of this loop and try the next list */
287 break;
288 }
289
290 for (iii = 0; PartialList && iii < PartialList->Count && !Matched; iii++)
291 {
292 /* Partial resource descriptors can be of variable size (CmResourceTypeDeviceSpecific),
293 but only one is allowed and it must be the last one in the list! */
294 PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc = &PartialList->PartialDescriptors[iii];
295
296 /* First check types */
297 if (IoDesc->Type != CmDesc->Type)
298 continue;
299
300 switch (IoDesc->Type)
301 {
303 /* Make sure it satisfies our vector range */
304 if (CmDesc->u.Interrupt.Vector >= IoDesc->u.Interrupt.MinimumVector &&
305 CmDesc->u.Interrupt.Vector <= IoDesc->u.Interrupt.MaximumVector)
306 {
307 /* Found it */
308 Matched = TRUE;
309 }
310 else
311 {
312 DPRINT("Interrupt - Not a match! 0x%x not inside 0x%x to 0x%x\n",
313 CmDesc->u.Interrupt.Vector,
314 IoDesc->u.Interrupt.MinimumVector,
315 IoDesc->u.Interrupt.MaximumVector);
316 }
317 break;
318
321 /* Make sure the length matches and it satisfies our address range */
322 if (CmDesc->u.Memory.Length == IoDesc->u.Memory.Length &&
323 (ULONGLONG)CmDesc->u.Memory.Start.QuadPart >= (ULONGLONG)IoDesc->u.Memory.MinimumAddress.QuadPart &&
324 (ULONGLONG)CmDesc->u.Memory.Start.QuadPart + CmDesc->u.Memory.Length - 1 <= (ULONGLONG)IoDesc->u.Memory.MaximumAddress.QuadPart)
325 {
326 /* Found it */
327 Matched = TRUE;
328 }
329 else
330 {
331 DPRINT("Memory/Port - Not a match! 0x%I64x with length 0x%x not inside 0x%I64x to 0x%I64x with length 0x%x\n",
332 CmDesc->u.Memory.Start.QuadPart,
333 CmDesc->u.Memory.Length,
334 IoDesc->u.Memory.MinimumAddress.QuadPart,
335 IoDesc->u.Memory.MaximumAddress.QuadPart,
336 IoDesc->u.Memory.Length);
337 }
338 break;
339
341 /* Make sure the length matches and it satisfies our bus number range */
342 if (CmDesc->u.BusNumber.Length == IoDesc->u.BusNumber.Length &&
343 CmDesc->u.BusNumber.Start >= IoDesc->u.BusNumber.MinBusNumber &&
344 CmDesc->u.BusNumber.Start + CmDesc->u.BusNumber.Length - 1 <= IoDesc->u.BusNumber.MaxBusNumber)
345 {
346 /* Found it */
347 Matched = TRUE;
348 }
349 else
350 {
351 DPRINT("Bus Number - Not a match! 0x%x with length 0x%x not inside 0x%x to 0x%x with length 0x%x\n",
352 CmDesc->u.BusNumber.Start,
353 CmDesc->u.BusNumber.Length,
354 IoDesc->u.BusNumber.MinBusNumber,
355 IoDesc->u.BusNumber.MaxBusNumber,
356 IoDesc->u.BusNumber.Length);
357 }
358 break;
359
361 /* Make sure it fits in our channel range */
362 if (CmDesc->u.Dma.Channel >= IoDesc->u.Dma.MinimumChannel &&
363 CmDesc->u.Dma.Channel <= IoDesc->u.Dma.MaximumChannel)
364 {
365 /* Found it */
366 Matched = TRUE;
367 }
368 else
369 {
370 DPRINT("DMA - Not a match! 0x%x not inside 0x%x to 0x%x\n",
371 CmDesc->u.Dma.Channel,
372 IoDesc->u.Dma.MinimumChannel,
373 IoDesc->u.Dma.MaximumChannel);
374 }
375 break;
376
377 default:
378 /* Other stuff is fine */
379 Matched = TRUE;
380 break;
381 }
382 }
383
384 /* Check if we found a matching descriptor */
385 if (!Matched)
386 {
387 PCM_RESOURCE_LIST NewList;
390 BOOLEAN FoundResource = TRUE;
391
392 /* Setup the new CM descriptor */
393 NewDesc.Type = IoDesc->Type;
394 NewDesc.Flags = IoDesc->Flags;
395 NewDesc.ShareDisposition = IoDesc->ShareDisposition;
396
397 /* Let'se see if we can find a resource to satisfy this */
398 switch (IoDesc->Type)
399 {
401 /* Find an available interrupt */
402 if (!IopFindInterruptResource(IoDesc, &NewDesc))
403 {
404 DPRINT1("Failed to find an available interrupt resource (0x%x to 0x%x)\n",
405 IoDesc->u.Interrupt.MinimumVector, IoDesc->u.Interrupt.MaximumVector);
406
407 FoundResource = FALSE;
408 }
409 break;
410
412 /* Find an available port range */
413 if (!IopFindPortResource(IoDesc, &NewDesc))
414 {
415 DPRINT1("Failed to find an available port resource (0x%I64x to 0x%I64x length: 0x%x)\n",
416 IoDesc->u.Port.MinimumAddress.QuadPart, IoDesc->u.Port.MaximumAddress.QuadPart,
417 IoDesc->u.Port.Length);
418
419 FoundResource = FALSE;
420 }
421 break;
422
424 /* Find an available memory range */
425 if (!IopFindMemoryResource(IoDesc, &NewDesc))
426 {
427 DPRINT1("Failed to find an available memory resource (0x%I64x to 0x%I64x length: 0x%x)\n",
428 IoDesc->u.Memory.MinimumAddress.QuadPart, IoDesc->u.Memory.MaximumAddress.QuadPart,
429 IoDesc->u.Memory.Length);
430
431 FoundResource = FALSE;
432 }
433 break;
434
436 /* Find an available bus address range */
437 if (!IopFindBusNumberResource(IoDesc, &NewDesc))
438 {
439 DPRINT1("Failed to find an available bus number resource (0x%x to 0x%x length: 0x%x)\n",
440 IoDesc->u.BusNumber.MinBusNumber, IoDesc->u.BusNumber.MaxBusNumber,
441 IoDesc->u.BusNumber.Length);
442
443 FoundResource = FALSE;
444 }
445 break;
446
448 /* Find an available DMA channel */
449 if (!IopFindDmaResource(IoDesc, &NewDesc))
450 {
451 DPRINT1("Failed to find an available dma resource (0x%x to 0x%x)\n",
452 IoDesc->u.Dma.MinimumChannel, IoDesc->u.Dma.MaximumChannel);
453
454 FoundResource = FALSE;
455 }
456 break;
457
458 default:
459 DPRINT1("Unsupported resource type: %x\n", IoDesc->Type);
460 FoundResource = FALSE;
461 break;
462 }
463
464 /* Check if it's missing and required */
465 if (!FoundResource && IoDesc->Option == 0)
466 {
467 /* Break out of this loop and try the next list */
468 DPRINT1("Unable to satisfy required resource in list %lu\n", i);
469 break;
470 }
471 else if (!FoundResource)
472 {
473 /* Try an alternate for this preferred descriptor */
474 AlternateRequired = TRUE;
475 continue;
476 }
477 else
478 {
479 /* Move on to the next preferred or required descriptor after this one */
480 AlternateRequired = FALSE;
481 }
482
483 /* Figure out what we need */
484 if (PartialList == NULL)
485 {
486 /* We need a new list */
487 NewList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST));
488 if (!NewList)
489 return STATUS_NO_MEMORY;
490
491 /* Set it up */
492 NewList->Count = 1;
493 NewList->List[0].InterfaceType = RequirementsList->InterfaceType;
494 NewList->List[0].BusNumber = RequirementsList->BusNumber;
495 NewList->List[0].PartialResourceList.Version = 1;
496 NewList->List[0].PartialResourceList.Revision = 1;
497 NewList->List[0].PartialResourceList.Count = 1;
498
499 /* Set our pointer */
500 DescPtr = &NewList->List[0].PartialResourceList.PartialDescriptors[0];
501 }
502 else
503 {
504 /* Allocate the new larger list */
506 if (!NewList)
507 return STATUS_NO_MEMORY;
508
509 /* Copy the old stuff back */
511
512 /* Set our pointer */
513 DescPtr = &NewList->List[0].PartialResourceList.PartialDescriptors[NewList->List[0].PartialResourceList.Count];
514
515 /* Increment the descriptor count */
516 NewList->List[0].PartialResourceList.Count++;
517
518 /* Free the old list */
520 }
521
522 /* Copy the descriptor in */
523 *DescPtr = NewDesc;
524
525 /* Store the new list */
526 *ResourceList = NewList;
527 }
528 }
529
530 /* Check if we need an alternate with no resources left */
531 if (AlternateRequired)
532 {
533 DPRINT1("Unable to satisfy preferred resource or alternates in list %lu\n", i);
534
535 /* Try the next alternate list */
536 continue;
537 }
538
539 /* We're done because we satisfied one of the alternate lists */
540 return STATUS_SUCCESS;
541 }
542
543 /* We ran out of alternates */
544 DPRINT1("Out of alternate lists!\n");
545
546 /* Free the list */
547 if (*ResourceList)
548 {
551 }
552
553 /* Fail */
555}
#define IO_RESOURCE_ALTERNATIVE
Definition: edit.c:119
static BOOLEAN IopFindPortResource(IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
Definition: pnpres.c:122
static BOOLEAN IopFindMemoryResource(IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
Definition: pnpres.c:84
static BOOLEAN IopFindDmaResource(IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
Definition: pnpres.c:160
static BOOLEAN IopFindInterruptResource(IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
Definition: pnpres.c:188
FORCEINLINE PIO_RESOURCE_LIST IopGetNextResourceList(_In_ const IO_RESOURCE_LIST *ResourceList)
Definition: pnpres.c:17
static BOOLEAN IopFindBusNumberResource(IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
Definition: pnpres.c:51
struct _IO_RESOURCE_DESCRIPTOR::@21::@28 BusNumber
union _IO_RESOURCE_DESCRIPTOR::@21 u
struct _IO_RESOURCE_DESCRIPTOR::@21::@25 Dma
struct _IO_RESOURCE_DESCRIPTOR::@21::@22 Port
struct _IO_RESOURCE_DESCRIPTOR::@21::@24 Interrupt
UCHAR ShareDisposition
Definition: edit.c:61
struct _IO_RESOURCE_DESCRIPTOR::@21::@23 Memory
ULONG Count
Definition: edit.c:124
_In_ WDFIORESREQLIST RequirementsList
Definition: wdfresource.h:65

Referenced by IopAssignDeviceResources(), and IopLegacyResourceAllocation().

◆ IopGetNextResourceList()

FORCEINLINE PIO_RESOURCE_LIST IopGetNextResourceList ( _In_ const IO_RESOURCE_LIST ResourceList)

Definition at line 17 of file pnpres.c.

19{
20 ASSERT((ResourceList->Count > 0) && (ResourceList->Count < 1000));
21 return (PIO_RESOURCE_LIST)(
22 &ResourceList->Descriptors[ResourceList->Count]);
23}

Referenced by IopFixupResourceListWithRequirements().

◆ IopTranslateDeviceResources()

static NTSTATUS IopTranslateDeviceResources ( IN PDEVICE_NODE  DeviceNode)
static

Definition at line 969 of file pnpres.c.

971{
972 PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
973 PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated;
974 PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
975 ULONG i, j, ListSize;
977
978 if (!DeviceNode->ResourceList)
979 {
980 DeviceNode->ResourceListTranslated = NULL;
981 return STATUS_SUCCESS;
982 }
983
984 /* That's easy to translate a resource list. Just copy the
985 * untranslated one and change few fields in the copy
986 */
987 ListSize = PnpDetermineResourceListSize(DeviceNode->ResourceList);
988
989 DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, ListSize);
990 if (!DeviceNode->ResourceListTranslated)
991 {
993 goto cleanup;
994 }
995 RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, ListSize);
996
997 FullDescriptor = &DeviceNode->ResourceList->List[0];
998 for (i = 0; i < DeviceNode->ResourceList->Count; i++)
999 {
1000 pPartialResourceList = &FullDescriptor->PartialResourceList;
1001 FullDescriptor = CmiGetNextResourceDescriptor(FullDescriptor);
1002
1003 for (j = 0; j < pPartialResourceList->Count; j++)
1004 {
1005 /* Partial resource descriptors can be of variable size (CmResourceTypeDeviceSpecific),
1006 but only one is allowed and it must be the last one in the list! */
1007 DescriptorRaw = &pPartialResourceList->PartialDescriptors[j];
1008
1009 /* Calculate the location of the translated resource descriptor */
1010 DescriptorTranslated = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)(
1011 (PUCHAR)DeviceNode->ResourceListTranslated +
1012 ((PUCHAR)DescriptorRaw - (PUCHAR)DeviceNode->ResourceList));
1013
1014 switch (DescriptorRaw->Type)
1015 {
1016 case CmResourceTypePort:
1017 {
1018 ULONG AddressSpace = 1; /* IO space */
1020 DeviceNode->ResourceList->List[i].InterfaceType,
1021 DeviceNode->ResourceList->List[i].BusNumber,
1022 DescriptorRaw->u.Port.Start,
1023 &AddressSpace,
1024 &DescriptorTranslated->u.Port.Start))
1025 {
1027 DPRINT1("Failed to translate port resource (Start: 0x%I64x)\n", DescriptorRaw->u.Port.Start.QuadPart);
1028 goto cleanup;
1029 }
1030
1031 if (AddressSpace == 0)
1032 {
1033 DPRINT1("Guessed incorrect address space: 1 -> 0\n");
1034
1035 /* FIXME: I think all other CM_RESOURCE_PORT_XXX flags are
1036 * invalid for this state but I'm not 100% sure */
1037 DescriptorRaw->Flags =
1038 DescriptorTranslated->Flags = CM_RESOURCE_PORT_MEMORY;
1039 }
1040 break;
1041 }
1043 {
1044 KIRQL Irql;
1045 DescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector(
1046 DeviceNode->ResourceList->List[i].InterfaceType,
1047 DeviceNode->ResourceList->List[i].BusNumber,
1048 DescriptorRaw->u.Interrupt.Level,
1049 DescriptorRaw->u.Interrupt.Vector,
1050 &Irql,
1051 &DescriptorTranslated->u.Interrupt.Affinity);
1052 DescriptorTranslated->u.Interrupt.Level = Irql;
1053 if (!DescriptorTranslated->u.Interrupt.Vector)
1054 {
1056 DPRINT1("Failed to translate interrupt resource (Vector: 0x%x | Level: 0x%x)\n", DescriptorRaw->u.Interrupt.Vector,
1057 DescriptorRaw->u.Interrupt.Level);
1058 goto cleanup;
1059 }
1060 break;
1061 }
1063 {
1064 ULONG AddressSpace = 0; /* Memory space */
1066 DeviceNode->ResourceList->List[i].InterfaceType,
1067 DeviceNode->ResourceList->List[i].BusNumber,
1068 DescriptorRaw->u.Memory.Start,
1069 &AddressSpace,
1070 &DescriptorTranslated->u.Memory.Start))
1071 {
1073 DPRINT1("Failed to translate memory resource (Start: 0x%I64x)\n", DescriptorRaw->u.Memory.Start.QuadPart);
1074 goto cleanup;
1075 }
1076
1077 if (AddressSpace != 0)
1078 {
1079 DPRINT1("Guessed incorrect address space: 0 -> 1\n");
1080
1081 /* This should never happen for memory space */
1082 ASSERT(FALSE);
1083 }
1084 }
1085
1086 case CmResourceTypeDma:
1090 /* Nothing to do */
1091 break;
1092 default:
1093 DPRINT1("Unknown resource descriptor type 0x%x\n", DescriptorRaw->Type);
1095 goto cleanup;
1096 }
1097 }
1098 }
1099 return STATUS_SUCCESS;
1100
1101cleanup:
1102 /* Yes! Also delete ResourceList because ResourceList and
1103 * ResourceListTranslated should be a pair! */
1104 ExFreePool(DeviceNode->ResourceList);
1105 DeviceNode->ResourceList = NULL;
1106 if (DeviceNode->ResourceListTranslated)
1107 {
1108 ExFreePool(DeviceNode->ResourceListTranslated);
1109 DeviceNode->ResourceList = NULL;
1110 }
1111 return Status;
1112}
_Out_ PKIRQL Irql
Definition: csq.h:179
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
BOOLEAN NTAPI HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress)
Definition: bus.c:140
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR * PCM_PARTIAL_RESOURCE_DESCRIPTOR
#define CmResourceTypeDevicePrivate
Definition: hwresource.cpp:131
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
#define CM_RESOURCE_PORT_MEMORY
Definition: cmtypes.h:108
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
unsigned char * PUCHAR
Definition: typedefs.h:53
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274

Referenced by IopAssignDeviceResources().

◆ IopUpdateControlKeyWithResources()

static NTSTATUS IopUpdateControlKeyWithResources ( IN PDEVICE_NODE  DeviceNode)
static

Definition at line 716 of file pnpres.c.

718{
722 HANDLE EnumKey, InstanceKey, ControlKey;
725
726 /* Open the Enum key */
728 if (!NT_SUCCESS(Status))
729 return Status;
730
731 /* Open the instance key (eg. Root\PNP0A03) */
732 Status = IopOpenRegistryKeyEx(&InstanceKey, EnumKey, &DeviceNode->InstancePath, KEY_ENUMERATE_SUB_KEYS);
734
735 if (!NT_SUCCESS(Status))
736 return Status;
737
738 /* Create/Open the Control key */
740 &Control,
742 InstanceKey,
743 NULL);
744 Status = ZwCreateKey(&ControlKey,
747 0,
748 NULL,
750 NULL);
751 ZwClose(InstanceKey);
752
753 if (!NT_SUCCESS(Status))
754 return Status;
755
756 /* Write the resource list */
757 Status = ZwSetValueKey(ControlKey,
758 &ValueName,
759 0,
761 DeviceNode->ResourceList,
763 ZwClose(ControlKey);
764
765 if (!NT_SUCCESS(Status))
766 return Status;
767
768 return STATUS_SUCCESS;
769}
static LONG WINAPI EnumKey(HANDLE hcKey, DWORD dwIndex, LPWSTR pszName, PDWORD pcchName, PFILETIME pftLastWriteTime, HANDLE hSpooler)
Definition: localmon.c:169
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define REG_RESOURCE_LIST
Definition: nt_native.h:1502
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define KEY_SET_VALUE
Definition: nt_native.h:1017
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:885
#define ENUM_ROOT
Definition: io.h:53
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166

Referenced by IopAssignDeviceResources().

◆ IopUpdateResourceMap()

NTSTATUS IopUpdateResourceMap ( IN PDEVICE_NODE  DeviceNode,
PWCHAR  Level1Key,
PWCHAR  Level2Key 
)

Definition at line 802 of file pnpres.c.

806{
809 HANDLE PnpMgrLevel1, PnpMgrLevel2, ResourceMapKey;
812
814 L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
816 &KeyName,
818 NULL,
819 NULL);
820 Status = ZwCreateKey(&ResourceMapKey,
823 0,
824 NULL,
826 &Disposition);
827 if (!NT_SUCCESS(Status))
828 return Status;
829
830 RtlInitUnicodeString(&KeyName, Level1Key);
832 &KeyName,
834 ResourceMapKey,
835 NULL);
836 Status = ZwCreateKey(&PnpMgrLevel1,
839 0,
840 NULL,
842 &Disposition);
843 ZwClose(ResourceMapKey);
844 if (!NT_SUCCESS(Status))
845 return Status;
846
847 RtlInitUnicodeString(&KeyName, Level2Key);
849 &KeyName,
851 PnpMgrLevel1,
852 NULL);
853 Status = ZwCreateKey(&PnpMgrLevel2,
856 0,
857 NULL,
859 &Disposition);
860 ZwClose(PnpMgrLevel1);
861 if (!NT_SUCCESS(Status))
862 return Status;
863
864 if (DeviceNode->ResourceList)
865 {
866 UNICODE_STRING NameU;
867 UNICODE_STRING RawSuffix, TranslatedSuffix;
868 ULONG OldLength = 0;
869
870 ASSERT(DeviceNode->ResourceListTranslated);
871
872 RtlInitUnicodeString(&TranslatedSuffix, L".Translated");
873 RtlInitUnicodeString(&RawSuffix, L".Raw");
874
875 Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
877 0,
878 NULL,
879 &OldLength);
881 {
882 ASSERT(OldLength);
883
884 NameU.Buffer = ExAllocatePool(PagedPool, OldLength + TranslatedSuffix.Length);
885 if (!NameU.Buffer)
886 {
887 ZwClose(PnpMgrLevel2);
889 }
890
891 NameU.Length = 0;
892 NameU.MaximumLength = (USHORT)OldLength + TranslatedSuffix.Length;
893
894 Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
896 NameU.MaximumLength,
897 NameU.Buffer,
898 &OldLength);
899 if (!NT_SUCCESS(Status))
900 {
901 ZwClose(PnpMgrLevel2);
902 ExFreePool(NameU.Buffer);
903 return Status;
904 }
905 }
906 else if (!NT_SUCCESS(Status))
907 {
908 /* Some failure */
909 ZwClose(PnpMgrLevel2);
910 return Status;
911 }
912 else
913 {
914 /* This should never happen */
915 ASSERT(FALSE);
916 }
917
918 NameU.Length = (USHORT)OldLength - sizeof(UNICODE_NULL); /* Remove final NULL */
919
920 RtlAppendUnicodeStringToString(&NameU, &RawSuffix);
921
922 Status = ZwSetValueKey(PnpMgrLevel2,
923 &NameU,
924 0,
926 DeviceNode->ResourceList,
928 if (!NT_SUCCESS(Status))
929 {
930 ZwClose(PnpMgrLevel2);
931 ExFreePool(NameU.Buffer);
932 return Status;
933 }
934
935 /* "Remove" the suffix by setting the length back to what it used to be */
936 NameU.Length = (USHORT)OldLength - sizeof(UNICODE_NULL); /* Remove final NULL */
937
938 RtlAppendUnicodeStringToString(&NameU, &TranslatedSuffix);
939
940 Status = ZwSetValueKey(PnpMgrLevel2,
941 &NameU,
942 0,
944 DeviceNode->ResourceListTranslated,
945 PnpDetermineResourceListSize(DeviceNode->ResourceListTranslated));
946 ZwClose(PnpMgrLevel2);
947 ExFreePool(NameU.Buffer);
948
949 if (!NT_SUCCESS(Status))
950 return Status;
951 }
952 else
953 {
954 ZwClose(PnpMgrLevel2);
955 }
956
957 return STATUS_SUCCESS;
958}
#define OBJ_OPENIF
Definition: winternl.h:229
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:1382
USHORT MaximumLength
Definition: env_spec_w32.h:370
@ DevicePropertyPhysicalDeviceObjectName
Definition: iotypes.h:1206

Referenced by IopUpdateResourceMapForPnPDevice().

◆ IopUpdateResourceMapForPnPDevice()

NTSTATUS IopUpdateResourceMapForPnPDevice ( IN PDEVICE_NODE  DeviceNode)

Definition at line 961 of file pnpres.c.

963{
964 return IopUpdateResourceMap(DeviceNode, L"PnP Manager", L"PnpManager");
965}
NTSTATUS IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2Key)
Definition: pnpres.c:802

Referenced by IopAssignDeviceResources(), and IopSendRemoveDevice().