ReactOS  0.4.15-dev-3456-g4a17d4b
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 
25 static
26 BOOLEAN
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 
49 static
50 BOOLEAN
54 {
55  ULONG Start;
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 
82 static
83 BOOLEAN
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 
120 static
121 BOOLEAN
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 
158 static
159 BOOLEAN
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 
176  if (!IopCheckDescriptorForConflict(CmDesc, NULL))
177  {
178  DPRINT1("Satisfying DMA requirement with channel 0x%x\n", Channel);
179  return TRUE;
180  }
181  }
182 
183  return FALSE;
184 }
185 
186 static
187 BOOLEAN
191 {
192  ULONG Vector;
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 
205  if (!IopCheckDescriptorForConflict(CmDesc, NULL))
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 */
243  *ResourceList = NULL;
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 
320  case CmResourceTypePort:
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 
360  case CmResourceTypeDma:
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 
411  case CmResourceTypePort:
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 
447  case CmResourceTypeDma:
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  {
550  *ResourceList = NULL;
551  }
552 
553  /* Fail */
555 }
556 
557 static
558 BOOLEAN
562  IN BOOLEAN Silent,
563  OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
564 {
565  ULONG i, ii;
566  BOOLEAN Result = FALSE;
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! */
579  PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc2 = &ResList->PartialDescriptors[ii];
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  }
616  case CmResourceTypePort:
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  }
679  case CmResourceTypeDma:
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 
700 ByeBye:
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 
714 static
715 NTSTATUS
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);
733  ZwClose(EnumKey);
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 
771 static
772 NTSTATUS
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,
784  &IoStatusBlock,
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 
801 NTSTATUS
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 
960 NTSTATUS
963 {
964  return IopUpdateResourceMap(DeviceNode, L"PnP Manager", L"PnpManager");
965 }
966 
967 static
968 NTSTATUS
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  }
1062  case CmResourceTypeMemory:
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 
1101 cleanup:
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 
1114 NTSTATUS
1115 NTAPI
1118 {
1119  NTSTATUS Status;
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 */
1172  Status = IopFixupResourceListWithRequirements(DeviceNode->ResourceRequirements,
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 
1184 Finish:
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 
1205 ByeBye:
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 
1217 static
1218 BOOLEAN
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;
1226  BOOLEAN Result = FALSE;
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! */
1239  PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc = &ResList->PartialDescriptors[ii];
1240 
1242  ResourceList2,
1243  Silent,
1244  ConflictingDescriptor);
1245  if (Result) goto ByeBye;
1246  }
1247  }
1248 
1249 ByeBye:
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;
1268  NTSTATUS Status;
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,
1290  &RequiredLength);
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,
1310  &RequiredLength);
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,
1330  &ObjectAttributes);
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,
1343  &RequiredLength);
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,
1363  &RequiredLength);
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,
1394  &RequiredLength);
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,
1414  &RequiredLength);
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,
1429  &RequiredLength);
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,
1447  &RequiredLength);
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 
1485 cleanup:
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 
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
struct _IO_RESOURCE_DESCRIPTOR::@1527::@1529 Memory
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
#define IN
Definition: typedefs.h:39
return STATUS_NOT_SUPPORTED
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR * PCM_PARTIAL_RESOURCE_DESCRIPTOR
#define CmResourceTypeDevicePrivate
Definition: hwresource.cpp:131
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
struct _IO_RESOURCE_DESCRIPTOR::@1527::@1528 Port
PNP_DEVNODE_STATE PiSetDevNodeState(_In_ PDEVICE_NODE DeviceNode, _In_ PNP_DEVNODE_STATE NewState)
Definition: devnode.c:108
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static BOOLEAN IopFindMemoryResource(IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
Definition: pnpres.c:84
union _IO_RESOURCE_DESCRIPTOR::@1527 u
USHORT MaximumLength
Definition: env_spec_w32.h:370
CM_FULL_RESOURCE_DESCRIPTOR List[1]
Definition: hwresource.cpp:165
#define TRUE
Definition: types.h:120
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2272
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI IopDetectResourceConflict(IN PCM_RESOURCE_LIST ResourceList, IN BOOLEAN Silent, OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
Definition: pnpres.c:1255
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376::@381 Memory
#define DNF_NO_RESOURCE_REQUIRED
Definition: iotypes.h:178
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST
uint16_t * PWCHAR
Definition: typedefs.h:56
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 OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_Out_ PKIRQL Irql
Definition: csq.h:179
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:304
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define OBJ_OPENIF
Definition: winternl.h:229
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376 u
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376::@382 Dma
static NTSTATUS IopFilterResourceRequirements(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:773
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
return STATUS_NOT_IMPLEMENTED
#define L(x)
Definition: ntvdm.h:50
static BOOLEAN IopFindInterruptResource(IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
Definition: pnpres.c:188
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
ULONG NTAPI PnpDetermineResourceListSize(IN PCM_RESOURCE_LIST ResourceList)
Definition: pnpmgr.c:1807
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
unsigned int UINT32
struct _IO_RESOURCE_DESCRIPTOR::@1527::@1531 Dma
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376::@384 BusNumber
static BOOLEAN IopFindBusNumberResource(IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
Definition: pnpres.c:51
NTSTATUS NTAPI IopAssignDeviceResources(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:1116
unsigned char BOOLEAN
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
#define CM_PROB_NORMAL_CONFLICT
Definition: cfg.h:42
_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:426
#define _In_
Definition: ms_sal.h:308
NTSTATUS NTAPI HalAdjustResourceList(IN PIO_RESOURCE_REQUIREMENTS_LIST *ResourceList)
Definition: bus.c:26
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:1952
#define REG_RESOURCE_LIST
Definition: nt_native.h:1502
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
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
Status
Definition: gdiplustypes.h:24
int64_t LONGLONG
Definition: typedefs.h:68
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static LONG WINAPI EnumKey(HANDLE hcKey, DWORD dwIndex, LPWSTR pszName, PDWORD pcchName, PFILETIME pftLastWriteTime, HANDLE hSpooler)
Definition: localmon.c:169
uint64_t ULONGLONG
Definition: typedefs.h:67
#define ENUM_ROOT
Definition: io.h:53
NTSTATUS IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2Key)
Definition: pnpres.c:802
#define CM_PROB_TRANSLATION_FAILED
Definition: cfg.h:63
struct _IO_RESOURCE_DESCRIPTOR::@1527::@1534 BusNumber
static BOOLEAN IopFindPortResource(IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
Definition: pnpres.c:122
#define IO_RESOURCE_ALTERNATIVE
Definition: partlist.h:33
Definition: Node.h:9
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
FORCEINLINE PCM_FULL_RESOURCE_DESCRIPTOR CmiGetNextResourceDescriptor(_In_ const CM_FULL_RESOURCE_DESCRIPTOR *ResourceDescriptor)
Definition: cmreslist.h:54
static NTSTATUS IopUpdateControlKeyWithResources(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:716
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
static NTSTATUS IopTranslateDeviceResources(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:969
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3375
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
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 ExAllocatePool(type, size)
Definition: fbtusb.h:44
static BOOLEAN IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
Definition: pnpres.c:27
NTSTATUS IopUpdateResourceMapForPnPDevice(IN PDEVICE_NODE DeviceNode)
Definition: pnpres.c:961
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 CM_RESOURCE_PORT_MEMORY
Definition: cmtypes.h:108
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376::@378 Port
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1455
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
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 IopFindDmaResource(IN PIO_RESOURCE_DESCRIPTOR IoDesc, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc)
Definition: pnpres.c:160
unsigned short USHORT
Definition: pedump.c:61
ULONG_PTR KAFFINITY
Definition: compat.h:85
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG Vector
Definition: iofuncs.h:800
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define FORCEINLINE
Definition: wdftypes.h:67
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
#define NULL
Definition: types.h:112
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
FORCEINLINE PIO_RESOURCE_LIST IopGetNextResourceList(_In_ const IO_RESOURCE_LIST *ResourceList)
Definition: pnpres.c:17
_In_ WDFIORESREQLIST RequirementsList
Definition: wdfresource.h:65
#define DPRINT1
Definition: precomp.h:8
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
char * cleanup(char *str)
Definition: wpickclick.c:99
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define CmResourceTypeBusNumber
Definition: hwresource.cpp:128
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376::@379 Interrupt
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
unsigned long long UINT64
#define DPRINT
Definition: sndvol32.h:71
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSTATUS NTAPI IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, IN UCHAR MinorFunction, IN PIO_STACK_LOCATION Stack)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define CmResourceTypeDma
Definition: hwresource.cpp:126
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
NTSTATUS NTAPI IopFixupResourceListWithRequirements(IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList, OUT PCM_RESOURCE_LIST *ResourceList)
Definition: pnpres.c:219
struct _IO_RESOURCE_DESCRIPTOR::@1527::@1530 Interrupt
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68