ReactOS 0.4.15-dev-7670-g69b08be
pnpres.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * COPYRIGHT: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/io/pnpmgr/pnpres.c
5 * PURPOSE: Resource handling code
6 * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
7 * ReactOS Portable Systems Group
8 */
9
10#include <ntoskrnl.h>
11
12#define NDEBUG
13#include <debug.h>
14
19{
20 ASSERT((ResourceList->Count > 0) && (ResourceList->Count < 1000));
21 return (PIO_RESOURCE_LIST)(
22 &ResourceList->Descriptors[ResourceList->Count]);
23}
24
25static
29 OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
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}
48
49static
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}
81
82static
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}
119
120static
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}
157
158static
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}
185
186static
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}
217
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}
556
557static
562 IN BOOLEAN Silent,
563 OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
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}
713
714static
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}
770
771static
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}
799
800
804 PWCHAR Level1Key,
805 PWCHAR Level2Key)
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}
959
963{
964 return IopUpdateResourceMap(DeviceNode, L"PnP Manager", L"PnpManager");
965}
966
967static
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}
1113
1115NTAPI
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}
1216
1217static
1218BOOLEAN
1220 IN PCM_RESOURCE_LIST ResourceList1,
1221 IN PCM_RESOURCE_LIST ResourceList2,
1222 IN BOOLEAN Silent,
1223 OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
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}
1253
1257 IN BOOLEAN Silent,
1258 OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
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}
1498
@ DeviceNode
Definition: Node.h:9
unsigned char BOOLEAN
unsigned long long UINT64
unsigned int UINT32
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define IO_RESOURCE_ALTERNATIVE
Definition: edit.c:119
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST
#define CM_PROB_TRANSLATION_FAILED
Definition: cfg.h:63
#define CM_PROB_NORMAL_CONFLICT
Definition: cfg.h:42
FORCEINLINE PCM_FULL_RESOURCE_DESCRIPTOR CmiGetNextResourceDescriptor(_In_ const CM_FULL_RESOURCE_DESCRIPTOR *ResourceDescriptor)
Definition: cmreslist.h:54
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_Out_ PKIRQL Irql
Definition: csq.h:179
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG_PTR KAFFINITY
Definition: compat.h:85
static void cleanup(void)
Definition: main.c:1335
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#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
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
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
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
NTSTATUS NTAPI HalAdjustResourceList(IN PIO_RESOURCE_REQUIREMENTS_LIST *ResourceList)
Definition: bus.c:26
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
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR * PCM_PARTIAL_RESOURCE_DESCRIPTOR
#define CmResourceTypeDma
Definition: hwresource.cpp:126
#define CmResourceTypeDevicePrivate
Definition: hwresource.cpp:131
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
@ InterfaceTypeUndefined
Definition: hwresource.cpp:136
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define CmResourceTypeBusNumber
Definition: hwresource.cpp:128
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
_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_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
@ KeyNameInformation
Definition: winternl.h:831
static LONG WINAPI EnumKey(HANDLE hcKey, DWORD dwIndex, LPWSTR pszName, PDWORD pcchName, PFILETIME pftLastWriteTime, HANDLE hSpooler)
Definition: localmon.c:169
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _In_
Definition: ms_sal.h:308
#define KernelMode
Definition: asm.h:34
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
#define CM_RESOURCE_PORT_MEMORY
Definition: cmtypes.h:108
@ DeviceNodeResourcesAssigned
Definition: iotypes.h:425
#define DNF_NO_RESOURCE_REQUIRED
Definition: iotypes.h:178
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyBasicInformation
Definition: nt_native.h:1131
@ KeyValueBasicInformation
Definition: nt_native.h:1180
@ KeyValuePartialInformation
Definition: nt_native.h:1182
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_RESOURCE_LIST
Definition: nt_native.h:1502
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define UNICODE_NULL
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:885
ULONG NTAPI PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList)
Definition: pnpmgr.c:1237
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)
PNP_DEVNODE_STATE PiSetDevNodeState(_In_ PDEVICE_NODE DeviceNode, _In_ PNP_DEVNODE_STATE NewState)
Definition: devnode.c:108
#define ENUM_ROOT
Definition: io.h:53
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#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
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
NTSTATUS IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2Key)
Definition: pnpres.c:802
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
NTSTATUS NTAPI IopAssignDeviceResources(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:1116
static NTSTATUS IopTranslateDeviceResources(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:969
static NTSTATUS IopUpdateControlKeyWithResources(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:716
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 IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
Definition: pnpres.c:27
static NTSTATUS IopFilterResourceRequirements(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:773
static BOOLEAN IopFindDmaResource(IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
Definition: pnpres.c:160
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
NTSTATUS NTAPI IopDetectResourceConflict(IN PCM_RESOURCE_LIST ResourceList, IN BOOLEAN Silent, OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
Definition: pnpres.c:1255
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
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
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@394::@400 Dma
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@394::@402 BusNumber
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@394::@397 Interrupt
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@394::@396 Port
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@394 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@394::@399 Memory
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
CM_FULL_RESOURCE_DESCRIPTOR List[1]
Definition: hwresource.cpp:165
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
IO_RESOURCE_DESCRIPTOR Descriptors[1]
Definition: edit.c:125
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TAG_IO
Definition: tag.h:80
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
@ Start
Definition: partlist.h:33
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:309
_In_ WDFIORESREQLIST RequirementsList
Definition: wdfresource.h:65
#define FORCEINLINE
Definition: wdftypes.h:67
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:30
_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
@ CmResourceShareShared
Definition: cmtypes.h:243
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
@ DevicePropertyPhysicalDeviceObjectName
Definition: iotypes.h:1206
__wchar_t WCHAR
Definition: xmlstorage.h:180