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