1 /*
2 * PROJECT: ReactOS HAL
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: hal/halx86/legacy/halpnpdd.c
5 * PURPOSE: HAL Plug and Play Device Driver
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <hal.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 typedef enum _EXTENSION_TYPE
16 {
17 PdoExtensionType = 0xC0,
18 FdoExtensionType
19 } EXTENSION_TYPE;
20
21 typedef enum _PDO_TYPE
22 {
23 AcpiPdo = 0x80,
24 WdPdo
25 } PDO_TYPE;
26
27 typedef struct _FDO_EXTENSION
28 {
29 EXTENSION_TYPE ExtensionType;
30 struct _PDO_EXTENSION* ChildPdoList;
31 PDEVICE_OBJECT PhysicalDeviceObject;
32 PDEVICE_OBJECT FunctionalDeviceObject;
33 PDEVICE_OBJECT AttachedDeviceObject;
34 } FDO_EXTENSION, *PFDO_EXTENSION;
35
36 typedef struct _PDO_EXTENSION
37 {
38 EXTENSION_TYPE ExtensionType;
39 struct _PDO_EXTENSION* Next;
40 PDEVICE_OBJECT PhysicalDeviceObject;
41 PFDO_EXTENSION ParentFdoExtension;
42 PDO_TYPE PdoType;
43 PDESCRIPTION_HEADER WdTable;
44 LONG InterfaceReferenceCount;
45 } PDO_EXTENSION, *PPDO_EXTENSION;
46
47 /* GLOBALS ********************************************************************/
48
49 PDRIVER_OBJECT HalpDriverObject;
50
51 /* PRIVATE FUNCTIONS **********************************************************/
52
53 NTSTATUS
54 NTAPI
HalpAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT TargetDevice)55 HalpAddDevice(IN PDRIVER_OBJECT DriverObject,
56 IN PDEVICE_OBJECT TargetDevice)
57 {
58 NTSTATUS Status;
59 PFDO_EXTENSION FdoExtension;
60 PPDO_EXTENSION PdoExtension;
61 PDEVICE_OBJECT DeviceObject, AttachedDevice;
62 PDEVICE_OBJECT PdoDeviceObject;
63 // PDESCRIPTION_HEADER Wdrt;
64
65 DPRINT("HAL: PnP Driver ADD!\n");
66
67 /* Create the FDO */
68 Status = IoCreateDevice(DriverObject,
69 sizeof(FDO_EXTENSION),
70 NULL,
71 FILE_DEVICE_BUS_EXTENDER,
72 0,
73 FALSE,
74 &DeviceObject);
75 if (!NT_SUCCESS(Status))
76 {
77 /* Should not happen */
78 DbgBreakPoint();
79 return Status;
80 }
81
82 /* Setup the FDO extension */
83 FdoExtension = DeviceObject->DeviceExtension;
84 FdoExtension->ExtensionType = FdoExtensionType;
85 FdoExtension->PhysicalDeviceObject = TargetDevice;
86 FdoExtension->FunctionalDeviceObject = DeviceObject;
87 FdoExtension->ChildPdoList = NULL;
88
89 /* FDO is done initializing */
90 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
91
92 /* Attach to the physical device object (the bus) */
93 AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject, TargetDevice);
94 if (!AttachedDevice)
95 {
96 /* Failed, undo everything */
97 IoDeleteDevice(DeviceObject);
98 return STATUS_NO_SUCH_DEVICE;
99 }
100
101 /* Save the attachment */
102 FdoExtension->AttachedDeviceObject = AttachedDevice;
103
104 /* Create the PDO */
105 Status = IoCreateDevice(DriverObject,
106 sizeof(PDO_EXTENSION),
107 NULL,
108 FILE_DEVICE_BUS_EXTENDER,
109 FILE_AUTOGENERATED_DEVICE_NAME,
110 FALSE,
111 &PdoDeviceObject);
112 if (!NT_SUCCESS(Status))
113 {
114 /* Fail */
115 DPRINT1("HAL: Could not create ACPI device object status=0x%08x\n", Status);
116 return Status;
117 }
118
119 /* Setup the PDO device extension */
120 PdoExtension = PdoDeviceObject->DeviceExtension;
121 PdoExtension->ExtensionType = PdoExtensionType;
122 PdoExtension->PhysicalDeviceObject = PdoDeviceObject;
123 PdoExtension->ParentFdoExtension = FdoExtension;
124 PdoExtension->PdoType = AcpiPdo;
125
126 /* Add the PDO to the head of the list */
127 PdoExtension->Next = FdoExtension->ChildPdoList;
128 FdoExtension->ChildPdoList = PdoExtension;
129
130 /* Initialization is finished */
131 PdoDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
132
133 /* Return status */
134 DPRINT("Device added %lx\n", Status);
135 return Status;
136 }
137
138 NTSTATUS
139 NTAPI
HalpQueryInterface(IN PDEVICE_OBJECT DeviceObject,IN CONST GUID * InterfaceType,IN USHORT Version,IN PVOID InterfaceSpecificData,IN ULONG InterfaceBufferSize,IN PINTERFACE Interface,OUT PULONG Length)140 HalpQueryInterface(IN PDEVICE_OBJECT DeviceObject,
141 IN CONST GUID* InterfaceType,
142 IN USHORT Version,
143 IN PVOID InterfaceSpecificData,
144 IN ULONG InterfaceBufferSize,
145 IN PINTERFACE Interface,
146 OUT PULONG Length)
147 {
148 DPRINT1("HalpQueryInterface({%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}) is UNIMPLEMENTED\n",
149 InterfaceType->Data1, InterfaceType->Data2, InterfaceType->Data3,
150 InterfaceType->Data4[0], InterfaceType->Data4[1],
151 InterfaceType->Data4[2], InterfaceType->Data4[3],
152 InterfaceType->Data4[4], InterfaceType->Data4[5],
153 InterfaceType->Data4[6], InterfaceType->Data4[7]);
154 return STATUS_NOT_SUPPORTED;
155 }
156
157 NTSTATUS
158 NTAPI
HalpQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject,IN DEVICE_RELATION_TYPE RelationType,OUT PDEVICE_RELATIONS * DeviceRelations)159 HalpQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject,
160 IN DEVICE_RELATION_TYPE RelationType,
161 OUT PDEVICE_RELATIONS* DeviceRelations)
162 {
163 EXTENSION_TYPE ExtensionType;
164 PPDO_EXTENSION PdoExtension;
165 PFDO_EXTENSION FdoExtension;
166 PDEVICE_RELATIONS PdoRelations, FdoRelations;
167 PDEVICE_OBJECT* ObjectEntry;
168 ULONG i = 0, PdoCount = 0;
169
170 /* Get FDO device extension and PDO count */
171 FdoExtension = DeviceObject->DeviceExtension;
172 ExtensionType = FdoExtension->ExtensionType;
173
174 /* What do they want? */
175 if (RelationType == BusRelations)
176 {
177 /* This better be an FDO */
178 if (ExtensionType == FdoExtensionType)
179 {
180 /* Count how many PDOs we have */
181 PdoExtension = FdoExtension->ChildPdoList;
182 while (PdoExtension)
183 {
184 /* Next one */
185 PdoExtension = PdoExtension->Next;
186 PdoCount++;
187 }
188
189 /* Add the PDOs that already exist in the device relations */
190 if (*DeviceRelations)
191 {
192 PdoCount += (*DeviceRelations)->Count;
193 }
194
195 /* Allocate our structure */
196 FdoRelations = ExAllocatePoolWithTag(PagedPool,
197 FIELD_OFFSET(DEVICE_RELATIONS,
198 Objects) +
199 sizeof(PDEVICE_OBJECT) * PdoCount,
200 TAG_HAL);
201 if (!FdoRelations) return STATUS_INSUFFICIENT_RESOURCES;
202
203 /* Save our count */
204 FdoRelations->Count = PdoCount;
205
206 /* Query existing relations */
207 ObjectEntry = FdoRelations->Objects;
208 if (*DeviceRelations)
209 {
210 /* Check if there were any */
211 if ((*DeviceRelations)->Count)
212 {
213 /* Loop them all */
214 do
215 {
216 /* Copy into our structure */
217 *ObjectEntry++ = (*DeviceRelations)->Objects[i];
218 }
219 while (++i < (*DeviceRelations)->Count);
220 }
221
222 /* Free existing structure */
223 ExFreePool(*DeviceRelations);
224 }
225
226 /* Now check if we have a PDO list */
227 PdoExtension = FdoExtension->ChildPdoList;
228 if (PdoExtension)
229 {
230 /* Loop the PDOs */
231 do
232 {
233 /* Save our own PDO and reference it */
234 *ObjectEntry++ = PdoExtension->PhysicalDeviceObject;
235 ObReferenceObject(PdoExtension->PhysicalDeviceObject);
236
237 /* Go to our next PDO */
238 PdoExtension = PdoExtension->Next;
239 }
240 while (PdoExtension);
241 }
242
243 /* Return the new structure */
244 *DeviceRelations = FdoRelations;
245 return STATUS_SUCCESS;
246 }
247 }
248 else
249 {
250 /* The only other thing we support is a target relation for the PDO */
251 if ((RelationType == TargetDeviceRelation) &&
252 (ExtensionType == PdoExtensionType))
253 {
254 /* Only one entry */
255 PdoRelations = ExAllocatePoolWithTag(PagedPool,
256 sizeof(DEVICE_RELATIONS),
257 TAG_HAL);
258 if (!PdoRelations) return STATUS_INSUFFICIENT_RESOURCES;
259
260 /* Fill it out and reference us */
261 PdoRelations->Count = 1;
262 PdoRelations->Objects[0] = DeviceObject;
263 ObReferenceObject(DeviceObject);
264
265 /* Return it */
266 *DeviceRelations = PdoRelations;
267 return STATUS_SUCCESS;
268 }
269 }
270
271 /* We don't support anything else */
272 return STATUS_NOT_SUPPORTED;
273 }
274
275 NTSTATUS
276 NTAPI
HalpQueryCapabilities(IN PDEVICE_OBJECT DeviceObject,OUT PDEVICE_CAPABILITIES Capabilities)277 HalpQueryCapabilities(IN PDEVICE_OBJECT DeviceObject,
278 OUT PDEVICE_CAPABILITIES Capabilities)
279 {
280 //PPDO_EXTENSION PdoExtension;
281 NTSTATUS Status;
282 PAGED_CODE();
283
284 /* Get the extension and check for valid version */
285 //PdoExtension = DeviceObject->DeviceExtension;
286 ASSERT(Capabilities->Version == 1);
287 if (Capabilities->Version == 1)
288 {
289 /* Can't lock or eject us */
290 Capabilities->LockSupported = FALSE;
291 Capabilities->EjectSupported = FALSE;
292
293 /* Can't remove or dock us */
294 Capabilities->Removable = FALSE;
295 Capabilities->DockDevice = FALSE;
296
297 /* Can't access us raw */
298 Capabilities->RawDeviceOK = FALSE;
299
300 /* We have a unique ID, and don't bother the user */
301 Capabilities->UniqueID = TRUE;
302 Capabilities->SilentInstall = TRUE;
303
304 /* Fill out the address */
305 Capabilities->Address = InterfaceTypeUndefined;
306 Capabilities->UINumber = InterfaceTypeUndefined;
307
308 /* Fill out latencies */
309 Capabilities->D1Latency = 0;
310 Capabilities->D2Latency = 0;
311 Capabilities->D3Latency = 0;
312
313 /* Fill out supported device states */
314 Capabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
315 Capabilities->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
316 Capabilities->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
317 Capabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
318
319 /* Done */
320 Status = STATUS_SUCCESS;
321 }
322 else
323 {
324 /* Fail */
325 Status = STATUS_NOT_SUPPORTED;
326 }
327
328 /* Return status */
329 return Status;
330 }
331
332 NTSTATUS
333 NTAPI
HalpQueryResources(IN PDEVICE_OBJECT DeviceObject,OUT PCM_RESOURCE_LIST * Resources)334 HalpQueryResources(IN PDEVICE_OBJECT DeviceObject,
335 OUT PCM_RESOURCE_LIST *Resources)
336 {
337 PPDO_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
338 NTSTATUS Status;
339 PCM_RESOURCE_LIST ResourceList;
340 // PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
341 // PIO_RESOURCE_DESCRIPTOR Descriptor;
342 // PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDesc;
343 // ULONG i;
344 PAGED_CODE();
345
346 /* Only the ACPI PDO has requirements */
347 if (DeviceExtension->PdoType == AcpiPdo)
348 {
349 #if 0
350 /* Query ACPI requirements */
351 Status = HalpQueryAcpiResourceRequirements(&RequirementsList);
352 if (!NT_SUCCESS(Status)) return Status;
353
354 ASSERT(RequirementsList->AlternativeLists == 1);
355 #endif
356
357 /* Allocate the resourcel ist */
358 ResourceList = ExAllocatePoolWithTag(PagedPool,
359 sizeof(CM_RESOURCE_LIST),
360 TAG_HAL);
361 if (!ResourceList )
362 {
363 /* Fail, no memory */
364 Status = STATUS_INSUFFICIENT_RESOURCES;
365 // ExFreePoolWithTag(RequirementsList, TAG_HAL);
366 return Status;
367 }
368
369 /* Initialize it */
370 RtlZeroMemory(ResourceList, sizeof(CM_RESOURCE_LIST));
371 ResourceList->Count = 1;
372
373 /* Setup the list fields */
374 ResourceList->List[0].BusNumber = 0;
375 ResourceList->List[0].InterfaceType = PCIBus;
376 ResourceList->List[0].PartialResourceList.Version = 1;
377 ResourceList->List[0].PartialResourceList.Revision = 1;
378 ResourceList->List[0].PartialResourceList.Count = 0;
379
380 /* Setup the first descriptor */
381 //PartialDesc = ResourceList->List[0].PartialResourceList.PartialDescriptors;
382
383 /* Find the requirement descriptor for the SCI */
384 #if 0
385 for (i = 0; i < RequirementsList->List[0].Count; i++)
386 {
387 /* Get this descriptor */
388 Descriptor = &RequirementsList->List[0].Descriptors[i];
389 if (Descriptor->Type == CmResourceTypeInterrupt)
390 {
391 /* Copy requirements descriptor into resource descriptor */
392 PartialDesc->Type = CmResourceTypeInterrupt;
393 PartialDesc->ShareDisposition = Descriptor->ShareDisposition;
394 PartialDesc->Flags = Descriptor->Flags;
395 ASSERT(Descriptor->u.Interrupt.MinimumVector ==
396 Descriptor->u.Interrupt.MaximumVector);
397 PartialDesc->u.Interrupt.Vector = Descriptor->u.Interrupt.MinimumVector;
398 PartialDesc->u.Interrupt.Level = Descriptor->u.Interrupt.MinimumVector;
399 PartialDesc->u.Interrupt.Affinity = 0xFFFFFFFF;
400
401 ResourceList->List[0].PartialResourceList.Count++;
402
403 break;
404 }
405 }
406 #endif
407
408 /* Return resources and success */
409 *Resources = ResourceList;
410
411 // ExFreePoolWithTag(RequirementsList, TAG_HAL);
412
413 return STATUS_SUCCESS;
414 }
415 else if (DeviceExtension->PdoType == WdPdo)
416 {
417 /* Watchdog doesn't */
418 return STATUS_NOT_SUPPORTED;
419 }
420 else
421 {
422 /* This shouldn't happen */
423 return STATUS_UNSUCCESSFUL;
424 }
425 }
426
427 NTSTATUS
428 NTAPI
HalpQueryResourceRequirements(IN PDEVICE_OBJECT DeviceObject,OUT PIO_RESOURCE_REQUIREMENTS_LIST * Requirements)429 HalpQueryResourceRequirements(IN PDEVICE_OBJECT DeviceObject,
430 OUT PIO_RESOURCE_REQUIREMENTS_LIST *Requirements)
431 {
432 PPDO_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
433 PAGED_CODE();
434
435 /* Only the ACPI PDO has requirements */
436 if (DeviceExtension->PdoType == AcpiPdo)
437 {
438 /* Query ACPI requirements */
439 // return HalpQueryAcpiResourceRequirements(Requirements);
440 return STATUS_SUCCESS;
441 }
442 else if (DeviceExtension->PdoType == WdPdo)
443 {
444 /* Watchdog doesn't */
445 return STATUS_NOT_SUPPORTED;
446 }
447 else
448 {
449 /* This shouldn't happen */
450 return STATUS_UNSUCCESSFUL;
451 }
452 }
453
454 NTSTATUS
455 NTAPI
HalpQueryIdPdo(IN PDEVICE_OBJECT DeviceObject,IN BUS_QUERY_ID_TYPE IdType,OUT PUSHORT * BusQueryId)456 HalpQueryIdPdo(IN PDEVICE_OBJECT DeviceObject,
457 IN BUS_QUERY_ID_TYPE IdType,
458 OUT PUSHORT *BusQueryId)
459 {
460 PPDO_EXTENSION PdoExtension;
461 PDO_TYPE PdoType;
462 PWCHAR CurrentId;
463 WCHAR Id[100];
464 NTSTATUS Status;
465 ULONG Length = 0;
466 PWCHAR Buffer;
467
468 /* Get the PDO type */
469 PdoExtension = DeviceObject->DeviceExtension;
470 PdoType = PdoExtension->PdoType;
471
472 /* What kind of ID is being requested? */
473 DPRINT("ID: %d\n", IdType);
474 switch (IdType)
475 {
476 case BusQueryDeviceID:
477 case BusQueryHardwareIDs:
478
479 /* What kind of PDO is this? */
480 if (PdoType == AcpiPdo)
481 {
482 /* ACPI ID */
483 CurrentId = L"PCI_HAL\\PNP0A03";
484 RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
485 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
486
487 CurrentId = L"*PNP0A03";
488 RtlCopyMemory(&Id[wcslen(Id) + 1], CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
489 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
490 }
491 #if 0
492 else if (PdoType == WdPdo)
493 {
494 /* WatchDog ID */
495 CurrentId = L"ACPI_HAL\\PNP0C18";
496 RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
497 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
498
499 CurrentId = L"*PNP0C18";
500 RtlCopyMemory(&Id[wcslen(Id) + 1], CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
501 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
502 }
503 #endif
504 else
505 {
506 /* Unknown */
507 return STATUS_NOT_SUPPORTED;
508 }
509 break;
510
511 case BusQueryInstanceID:
512
513 /* Instance ID */
514 CurrentId = L"0";
515 RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL));
516 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
517 break;
518
519 case BusQueryCompatibleIDs:
520 default:
521
522 /* We don't support anything else */
523 return STATUS_NOT_SUPPORTED;
524 }
525
526 /* Allocate the buffer */
527 Buffer = ExAllocatePoolWithTag(PagedPool,
528 Length + sizeof(UNICODE_NULL),
529 TAG_HAL);
530 if (Buffer)
531 {
532 /* Copy the string and null-terminate it */
533 RtlCopyMemory(Buffer, Id, Length);
534 Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
535
536 /* Return string */
537 *BusQueryId = Buffer;
538 Status = STATUS_SUCCESS;
539 DPRINT("Returning: %S\n", *BusQueryId);
540 }
541 else
542 {
543 /* Fail */
544 Status = STATUS_INSUFFICIENT_RESOURCES;
545 }
546
547 /* Return status */
548 return Status;
549 }
550
551 NTSTATUS
552 NTAPI
HalpQueryIdFdo(IN PDEVICE_OBJECT DeviceObject,IN BUS_QUERY_ID_TYPE IdType,OUT PUSHORT * BusQueryId)553 HalpQueryIdFdo(IN PDEVICE_OBJECT DeviceObject,
554 IN BUS_QUERY_ID_TYPE IdType,
555 OUT PUSHORT *BusQueryId)
556 {
557 NTSTATUS Status;
558 ULONG Length;
559 PWCHAR Id;
560 PWCHAR Buffer;
561
562 /* What kind of ID is being requested? */
563 DPRINT("ID: %d\n", IdType);
564 switch (IdType)
565 {
566 case BusQueryDeviceID:
567 case BusQueryHardwareIDs:
568
569 /* This is our hardware ID */
570 Id = HalHardwareIdString;
571 break;
572
573 case BusQueryInstanceID:
574
575 /* And our instance ID */
576 Id = L"0";
577 break;
578
579 default:
580
581 /* We don't support anything else */
582 return STATUS_NOT_SUPPORTED;
583 }
584
585 /* Calculate the length */
586 Length = (wcslen(Id) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
587
588 /* Allocate the buffer */
589 Buffer = ExAllocatePoolWithTag(PagedPool,
590 Length + sizeof(UNICODE_NULL),
591 TAG_HAL);
592 if (Buffer)
593 {
594 /* Copy the string and null-terminate it */
595 RtlCopyMemory(Buffer, Id, Length);
596 Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
597
598 /* Return string */
599 *BusQueryId = Buffer;
600 Status = STATUS_SUCCESS;
601 DPRINT("Returning: %S\n", *BusQueryId);
602 }
603 else
604 {
605 /* Fail */
606 Status = STATUS_INSUFFICIENT_RESOURCES;
607 }
608
609 /* Return status */
610 return Status;
611 }
612
613 NTSTATUS
614 NTAPI
HalpDispatchPnp(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)615 HalpDispatchPnp(IN PDEVICE_OBJECT DeviceObject,
616 IN PIRP Irp)
617 {
618 PIO_STACK_LOCATION IoStackLocation;
619 //PPDO_EXTENSION PdoExtension;
620 PFDO_EXTENSION FdoExtension;
621 NTSTATUS Status;
622 UCHAR Minor;
623
624 /* Get the device extension and stack location */
625 FdoExtension = DeviceObject->DeviceExtension;
626 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
627 Minor = IoStackLocation->MinorFunction;
628
629 /* FDO? */
630 if (FdoExtension->ExtensionType == FdoExtensionType)
631 {
632 /* Query the IRP type */
633 switch (Minor)
634 {
635 case IRP_MN_QUERY_DEVICE_RELATIONS:
636
637 /* Call the worker */
638 DPRINT("Querying device relations for FDO\n");
639 Status = HalpQueryDeviceRelations(DeviceObject,
640 IoStackLocation->Parameters.QueryDeviceRelations.Type,
641 (PVOID)&Irp->IoStatus.Information);
642 break;
643
644 case IRP_MN_QUERY_INTERFACE:
645
646 /* Call the worker */
647 DPRINT("Querying interface for FDO\n");
648 Status = HalpQueryInterface(DeviceObject,
649 IoStackLocation->Parameters.QueryInterface.InterfaceType,
650 IoStackLocation->Parameters.QueryInterface.Size,
651 IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData,
652 IoStackLocation->Parameters.QueryInterface.Version,
653 IoStackLocation->Parameters.QueryInterface.Interface,
654 (PVOID)&Irp->IoStatus.Information);
655 break;
656
657 case IRP_MN_QUERY_ID:
658
659 /* Call the worker */
660 DPRINT("Querying ID for FDO\n");
661 Status = HalpQueryIdFdo(DeviceObject,
662 IoStackLocation->Parameters.QueryId.IdType,
663 (PVOID)&Irp->IoStatus.Information);
664 break;
665
666 case IRP_MN_QUERY_CAPABILITIES:
667
668 /* Call the worker */
669 DPRINT("Querying the capabilities for the FDO\n");
670 Status = HalpQueryCapabilities(DeviceObject,
671 IoStackLocation->Parameters.DeviceCapabilities.Capabilities);
672 break;
673
674 default:
675
676 DPRINT("Other IRP: %lx\n", Minor);
677 Status = STATUS_NOT_SUPPORTED;
678 break;
679 }
680
681 /* What happpened? */
682 if ((NT_SUCCESS(Status)) || (Status == STATUS_NOT_SUPPORTED))
683 {
684 /* Set the IRP status, unless this isn't understood */
685 if (Status != STATUS_NOT_SUPPORTED)
686 {
687 Irp->IoStatus.Status = Status;
688 }
689
690 /* Pass it on */
691 IoSkipCurrentIrpStackLocation(Irp);
692 return IoCallDriver(FdoExtension->AttachedDeviceObject, Irp);
693 }
694
695 /* Otherwise, we failed, so set the status and complete the request */
696 DPRINT1("IRP failed with status: %lx\n", Status);
697 Irp->IoStatus.Status = Status;
698 IoCompleteRequest(Irp, IO_NO_INCREMENT);
699 return Status;
700 }
701 else
702 {
703 /* This is a PDO instead */
704 ASSERT(FdoExtension->ExtensionType == PdoExtensionType);
705 //PdoExtension = (PPDO_EXTENSION)FdoExtension;
706
707 /* Query the IRP type */
708 Status = STATUS_SUCCESS;
709 switch (Minor)
710 {
711 case IRP_MN_START_DEVICE:
712
713 /* We only care about a PCI PDO */
714 DPRINT("Start device received\n");
715 /* Complete the IRP normally */
716 break;
717
718 case IRP_MN_REMOVE_DEVICE:
719
720 /* Check if this is a PCI device */
721 DPRINT("Remove device received\n");
722
723 /* We're done */
724 Status = STATUS_SUCCESS;
725 break;
726
727 case IRP_MN_SURPRISE_REMOVAL:
728
729 /* Inherit whatever status we had */
730 DPRINT("Surprise removal IRP\n");
731 Status = Irp->IoStatus.Status;
732 break;
733
734 case IRP_MN_QUERY_DEVICE_RELATIONS:
735
736 /* Query the device relations */
737 DPRINT("Querying PDO relations\n");
738 Status = HalpQueryDeviceRelations(DeviceObject,
739 IoStackLocation->Parameters.QueryDeviceRelations.Type,
740 (PVOID)&Irp->IoStatus.Information);
741 break;
742
743 case IRP_MN_QUERY_INTERFACE:
744
745 /* Call the worker */
746 DPRINT("Querying interface for PDO\n");
747 Status = HalpQueryInterface(DeviceObject,
748 IoStackLocation->Parameters.QueryInterface.InterfaceType,
749 IoStackLocation->Parameters.QueryInterface.Size,
750 IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData,
751 IoStackLocation->Parameters.QueryInterface.Version,
752 IoStackLocation->Parameters.QueryInterface.Interface,
753 (PVOID)&Irp->IoStatus.Information);
754 break;
755
756 case IRP_MN_QUERY_CAPABILITIES:
757
758 /* Call the worker */
759 DPRINT("Querying the capabilities for the PDO\n");
760 Status = HalpQueryCapabilities(DeviceObject,
761 IoStackLocation->Parameters.DeviceCapabilities.Capabilities);
762 break;
763
764 case IRP_MN_QUERY_RESOURCES:
765
766 /* Call the worker */
767 DPRINT("Querying the resources for the PDO\n");
768 Status = HalpQueryResources(DeviceObject, (PVOID)&Irp->IoStatus.Information);
769 break;
770
771 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
772
773 /* Call the worker */
774 DPRINT("Querying the resource requirements for the PDO\n");
775 Status = HalpQueryResourceRequirements(DeviceObject,
776 (PVOID)&Irp->IoStatus.Information);
777 break;
778
779 case IRP_MN_QUERY_ID:
780
781 /* Call the worker */
782 DPRINT("Query the ID for the PDO\n");
783 Status = HalpQueryIdPdo(DeviceObject,
784 IoStackLocation->Parameters.QueryId.IdType,
785 (PVOID)&Irp->IoStatus.Information);
786 break;
787
788 case IRP_MN_QUERY_DEVICE_TEXT:
789
790 /* Inherit whatever status we had */
791 DPRINT("Query text for the PDO\n");
792 Status = Irp->IoStatus.Status;
793 break;
794
795 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
796
797 /* Inherit whatever status we had */
798 DPRINT("Filter resource requirements for the PDO\n");
799 Status = Irp->IoStatus.Status;
800 break;
801
802 case IRP_MN_QUERY_PNP_DEVICE_STATE:
803
804 /* Inherit whatever status we had */
805 DPRINT("Query device state for the PDO\n");
806 Status = Irp->IoStatus.Status;
807 break;
808
809 case IRP_MN_QUERY_BUS_INFORMATION:
810
811 /* Inherit whatever status we had */
812 DPRINT("Query bus information for the PDO\n");
813 Status = Irp->IoStatus.Status;
814 break;
815
816 default:
817
818 /* We don't handle anything else, so inherit the old state */
819 DPRINT1("Illegal IRP: %lx\n", Minor);
820 Status = Irp->IoStatus.Status;
821 break;
822 }
823
824 /* If it's not supported, inherit the old status */
825 if (Status == STATUS_NOT_SUPPORTED) Status = Irp->IoStatus.Status;
826
827 /* Complete the IRP */
828 DPRINT("IRP completed with status: %lx\n", Status);
829 Irp->IoStatus.Status = Status;
830 IoCompleteRequest(Irp, IO_NO_INCREMENT);
831 return Status;
832 }
833 }
834
835 NTSTATUS
836 NTAPI
HalpDispatchWmi(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)837 HalpDispatchWmi(IN PDEVICE_OBJECT DeviceObject,
838 IN PIRP Irp)
839 {
840 UNIMPLEMENTED_DBGBREAK("HAL: PnP Driver WMI!\n");
841 return STATUS_SUCCESS;
842 }
843
844 NTSTATUS
845 NTAPI
HalpDispatchPower(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)846 HalpDispatchPower(IN PDEVICE_OBJECT DeviceObject,
847 IN PIRP Irp)
848 {
849 PFDO_EXTENSION FdoExtension;
850
851 DPRINT1("HAL: PnP Driver Power!\n");
852 FdoExtension = DeviceObject->DeviceExtension;
853 if (FdoExtension->ExtensionType == FdoExtensionType)
854 {
855 PoStartNextPowerIrp(Irp);
856 IoSkipCurrentIrpStackLocation(Irp);
857 return PoCallDriver(FdoExtension->AttachedDeviceObject, Irp);
858 }
859 else
860 {
861 PoStartNextPowerIrp(Irp);
862 Irp->IoStatus.Status = STATUS_SUCCESS;
863 IoCompleteRequest(Irp, IO_NO_INCREMENT);
864 return STATUS_SUCCESS;
865 }
866 }
867
868 NTSTATUS
869 NTAPI
HalpDriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)870 HalpDriverEntry(IN PDRIVER_OBJECT DriverObject,
871 IN PUNICODE_STRING RegistryPath)
872 {
873 NTSTATUS Status;
874 PDEVICE_OBJECT TargetDevice = NULL;
875
876 DPRINT("HAL: PnP Driver ENTRY!\n");
877
878 /* This is us */
879 HalpDriverObject = DriverObject;
880
881 /* Set up add device */
882 DriverObject->DriverExtension->AddDevice = HalpAddDevice;
883
884 /* Set up the callouts */
885 DriverObject->MajorFunction[IRP_MJ_PNP] = HalpDispatchPnp;
886 DriverObject->MajorFunction[IRP_MJ_POWER] = HalpDispatchPower;
887 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HalpDispatchWmi;
888
889 /* Create the PDO and tell the PnP manager about us*/
890 Status = IoReportDetectedDevice(DriverObject,
891 InterfaceTypeUndefined,
892 -1,
893 -1,
894 NULL,
895 NULL,
896 FALSE,
897 &TargetDevice);
898 if (!NT_SUCCESS(Status))
899 return Status;
900
901 TargetDevice->Flags &= ~DO_DEVICE_INITIALIZING;
902
903 /* Set up the device stack */
904 Status = HalpAddDevice(DriverObject, TargetDevice);
905 if (!NT_SUCCESS(Status))
906 {
907 IoDeleteDevice(TargetDevice);
908 return Status;
909 }
910
911 /* Return to kernel */
912 return Status;
913 }
914
915 NTSTATUS
916 NTAPI
HaliInitPnpDriver(VOID)917 HaliInitPnpDriver(VOID)
918 {
919 NTSTATUS Status;
920 UNICODE_STRING DriverString;
921 PAGED_CODE();
922
923 /* Create the driver */
924 RtlInitUnicodeString(&DriverString, L"\\Driver\\PCI_HAL");
925 Status = IoCreateDriver(&DriverString, HalpDriverEntry);
926
927 /* Return status */
928 return Status;
929 }
930
931 /* EOF */
932