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 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 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 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 adress */ 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 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 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 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 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 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 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 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 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 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