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