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