Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhalpnpdd.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS HAL 00003 * LICENSE: BSD - See COPYING.ARM in the top level directory 00004 * FILE: hal/halx86/generic/acpi/halpnpdd.c 00005 * PURPOSE: HAL Plug and Play Device Driver 00006 * PROGRAMMERS: ReactOS Portable Systems Group 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <hal.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 typedef enum _EXTENSION_TYPE 00016 { 00017 PdoExtensionType = 0xC0, 00018 FdoExtensionType 00019 } EXTENSION_TYPE; 00020 00021 typedef enum _PDO_TYPE 00022 { 00023 AcpiPdo = 0x80, 00024 WdPdo 00025 } PDO_TYPE; 00026 00027 typedef struct _FDO_EXTENSION 00028 { 00029 EXTENSION_TYPE ExtensionType; 00030 struct _PDO_EXTENSION* ChildPdoList; 00031 PDEVICE_OBJECT PhysicalDeviceObject; 00032 PDEVICE_OBJECT FunctionalDeviceObject; 00033 PDEVICE_OBJECT AttachedDeviceObject; 00034 } FDO_EXTENSION, *PFDO_EXTENSION; 00035 00036 typedef struct _PDO_EXTENSION 00037 { 00038 EXTENSION_TYPE ExtensionType; 00039 struct _PDO_EXTENSION* Next; 00040 PDEVICE_OBJECT PhysicalDeviceObject; 00041 PFDO_EXTENSION ParentFdoExtension; 00042 PDO_TYPE PdoType; 00043 PDESCRIPTION_HEADER WdTable; 00044 LONG InterfaceReferenceCount; 00045 } PDO_EXTENSION, *PPDO_EXTENSION; 00046 00047 /* GLOBALS ********************************************************************/ 00048 00049 PDRIVER_OBJECT HalpDriverObject; 00050 00051 /* PRIVATE FUNCTIONS **********************************************************/ 00052 00053 VOID 00054 NTAPI 00055 HalpReportDetectedDevices(IN PDRIVER_OBJECT DriverObject, 00056 IN PVOID Context, 00057 IN ULONG Count) 00058 { 00059 PFDO_EXTENSION FdoExtension = Context; 00060 PPDO_EXTENSION PdoExtension; 00061 PDEVICE_OBJECT PdoDeviceObject; 00062 PDESCRIPTION_HEADER Wdrt; 00063 NTSTATUS Status; 00064 00065 /* Create the PDO */ 00066 Status = IoCreateDevice(DriverObject, 00067 sizeof(PDO_EXTENSION), 00068 NULL, 00069 FILE_DEVICE_BUS_EXTENDER, 00070 FILE_AUTOGENERATED_DEVICE_NAME, 00071 FALSE, 00072 &PdoDeviceObject); 00073 if (!NT_SUCCESS(Status)) 00074 { 00075 /* Fail */ 00076 DPRINT1("HAL: Could not create ACPI device object status=0x%08x\n", Status); 00077 return; 00078 } 00079 00080 /* Setup the PDO device extension */ 00081 PdoExtension = PdoDeviceObject->DeviceExtension; 00082 PdoExtension->ExtensionType = PdoExtensionType; 00083 PdoExtension->PhysicalDeviceObject = PdoDeviceObject; 00084 PdoExtension->ParentFdoExtension = FdoExtension; 00085 PdoExtension->PdoType = AcpiPdo; 00086 00087 /* Add the PDO to the head of the list */ 00088 PdoExtension->Next = FdoExtension->ChildPdoList; 00089 FdoExtension->ChildPdoList = PdoExtension; 00090 00091 /* Initialization is finished */ 00092 PdoDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 00093 00094 /* Find the ACPI watchdog table */ 00095 Wdrt = HalAcpiGetTable(0, 'TRDW'); 00096 if (Wdrt) 00097 { 00098 /* FIXME: TODO */ 00099 DPRINT1("You have an ACPI Watchdog. That's great! You should be proud ;-)\n"); 00100 } 00101 00102 /* This will synchronously load the ACPI driver (needed because we're critical for boot) */ 00103 IoSynchronousInvalidateDeviceRelations(FdoExtension->PhysicalDeviceObject, BusRelations); 00104 } 00105 00106 NTSTATUS 00107 NTAPI 00108 HalpAddDevice(IN PDRIVER_OBJECT DriverObject, 00109 IN PDEVICE_OBJECT TargetDevice) 00110 { 00111 NTSTATUS Status; 00112 PFDO_EXTENSION FdoExtension; 00113 PDEVICE_OBJECT DeviceObject, AttachedDevice; 00114 00115 DPRINT("HAL: PnP Driver ADD!\n"); 00116 00117 /* Create the FDO */ 00118 Status = IoCreateDevice(DriverObject, 00119 sizeof(FDO_EXTENSION), 00120 NULL, 00121 FILE_DEVICE_BUS_EXTENDER, 00122 0, 00123 FALSE, 00124 &DeviceObject); 00125 if (!NT_SUCCESS(Status)) 00126 { 00127 /* Should not happen */ 00128 DbgBreakPoint(); 00129 return Status; 00130 } 00131 00132 /* Setup the FDO extension */ 00133 FdoExtension = DeviceObject->DeviceExtension; 00134 FdoExtension->ExtensionType = FdoExtensionType; 00135 FdoExtension->PhysicalDeviceObject = TargetDevice; 00136 FdoExtension->FunctionalDeviceObject = DeviceObject; 00137 FdoExtension->ChildPdoList = NULL; 00138 00139 /* FDO is done initializing */ 00140 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 00141 00142 /* Attach to the physical device object (the bus) */ 00143 AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject, TargetDevice); 00144 if (!AttachedDevice) 00145 { 00146 /* Failed, undo everything */ 00147 IoDeleteDevice(DeviceObject); 00148 return STATUS_NO_SUCH_DEVICE; 00149 } 00150 00151 /* Save the attachment */ 00152 FdoExtension->AttachedDeviceObject = AttachedDevice; 00153 00154 /* Register for reinitialization to report devices later */ 00155 IoRegisterBootDriverReinitialization(DriverObject, 00156 HalpReportDetectedDevices, 00157 FdoExtension); 00158 00159 /* Return status */ 00160 DPRINT("Device added %lx\n", Status); 00161 return Status; 00162 } 00163 00164 NTSTATUS 00165 NTAPI 00166 HalpQueryInterface(IN PDEVICE_OBJECT DeviceObject, 00167 IN CONST GUID* InterfaceType, 00168 IN USHORT Version, 00169 IN PVOID InterfaceSpecificData, 00170 IN ULONG InterfaceBufferSize, 00171 IN PINTERFACE Interface, 00172 OUT PULONG Length) 00173 { 00174 UNIMPLEMENTED; 00175 return STATUS_NOT_SUPPORTED; 00176 } 00177 00178 NTSTATUS 00179 NTAPI 00180 HalpQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject, 00181 IN DEVICE_RELATION_TYPE RelationType, 00182 OUT PDEVICE_RELATIONS* DeviceRelations) 00183 { 00184 EXTENSION_TYPE ExtensionType; 00185 PPDO_EXTENSION PdoExtension; 00186 PFDO_EXTENSION FdoExtension; 00187 PDEVICE_RELATIONS PdoRelations, FdoRelations; 00188 PDEVICE_OBJECT* ObjectEntry; 00189 ULONG i = 0, PdoCount = 0; 00190 00191 /* Get FDO device extension and PDO count */ 00192 FdoExtension = DeviceObject->DeviceExtension; 00193 ExtensionType = FdoExtension->ExtensionType; 00194 00195 /* What do they want? */ 00196 if (RelationType == BusRelations) 00197 { 00198 /* This better be an FDO */ 00199 if (ExtensionType == FdoExtensionType) 00200 { 00201 /* Count how many PDOs we have */ 00202 PdoExtension = FdoExtension->ChildPdoList; 00203 while (PdoExtension) 00204 { 00205 /* Next one */ 00206 PdoExtension = PdoExtension->Next; 00207 PdoCount++; 00208 } 00209 00210 /* Add the PDOs that already exist in the device relations */ 00211 if (*DeviceRelations) 00212 { 00213 PdoCount += (*DeviceRelations)->Count; 00214 } 00215 00216 /* Allocate our structure */ 00217 FdoRelations = ExAllocatePoolWithTag(PagedPool, 00218 FIELD_OFFSET(DEVICE_RELATIONS, 00219 Objects) + 00220 sizeof(PDEVICE_OBJECT) * PdoCount, 00221 ' laH'); 00222 if (!FdoRelations) return STATUS_INSUFFICIENT_RESOURCES; 00223 00224 /* Save our count */ 00225 FdoRelations->Count = PdoCount; 00226 00227 /* Query existing relations */ 00228 ObjectEntry = FdoRelations->Objects; 00229 if (*DeviceRelations) 00230 { 00231 /* Check if there were any */ 00232 if ((*DeviceRelations)->Count) 00233 { 00234 /* Loop them all */ 00235 do 00236 { 00237 /* Copy into our structure */ 00238 *ObjectEntry++ = (*DeviceRelations)->Objects[i]; 00239 } 00240 while (++i < (*DeviceRelations)->Count); 00241 } 00242 00243 /* Free existing structure */ 00244 ExFreePool(*DeviceRelations); 00245 } 00246 00247 /* Now check if we have a PDO list */ 00248 PdoExtension = FdoExtension->ChildPdoList; 00249 if (PdoExtension) 00250 { 00251 /* Loop the PDOs */ 00252 do 00253 { 00254 /* Save our own PDO and reference it */ 00255 *ObjectEntry++ = PdoExtension->PhysicalDeviceObject; 00256 ObReferenceObject(PdoExtension->PhysicalDeviceObject); 00257 00258 /* Go to our next PDO */ 00259 PdoExtension = PdoExtension->Next; 00260 } 00261 while (PdoExtension); 00262 } 00263 00264 /* Return the new structure */ 00265 *DeviceRelations = FdoRelations; 00266 return STATUS_SUCCESS; 00267 } 00268 } 00269 else 00270 { 00271 /* The only other thing we support is a target relation for the PDO */ 00272 if ((RelationType == TargetDeviceRelation) && 00273 (ExtensionType == PdoExtensionType)) 00274 { 00275 /* Only one entry */ 00276 PdoRelations = ExAllocatePoolWithTag(PagedPool, 00277 sizeof(DEVICE_RELATIONS), 00278 ' laH'); 00279 if (!PdoRelations) return STATUS_INSUFFICIENT_RESOURCES; 00280 00281 /* Fill it out and reference us */ 00282 PdoRelations->Count = 1; 00283 PdoRelations->Objects[0] = DeviceObject; 00284 ObReferenceObject(DeviceObject); 00285 00286 /* Return it */ 00287 *DeviceRelations = PdoRelations; 00288 return STATUS_SUCCESS; 00289 } 00290 } 00291 00292 /* We don't support anything else */ 00293 return STATUS_NOT_SUPPORTED; 00294 } 00295 00296 NTSTATUS 00297 NTAPI 00298 HalpQueryCapabilities(IN PDEVICE_OBJECT DeviceObject, 00299 OUT PDEVICE_CAPABILITIES Capabilities) 00300 { 00301 //PPDO_EXTENSION PdoExtension; 00302 NTSTATUS Status; 00303 PAGED_CODE(); 00304 00305 /* Get the extension and check for valid version */ 00306 //PdoExtension = DeviceObject->DeviceExtension; 00307 ASSERT(Capabilities->Version == 1); 00308 if (Capabilities->Version == 1) 00309 { 00310 /* Can't lock or eject us */ 00311 Capabilities->LockSupported = FALSE; 00312 Capabilities->EjectSupported = FALSE; 00313 00314 /* Can't remove or dock us */ 00315 Capabilities->Removable = FALSE; 00316 Capabilities->DockDevice = FALSE; 00317 00318 /* Can't access us raw */ 00319 Capabilities->RawDeviceOK = FALSE; 00320 00321 /* We have a unique ID, and don't bother the user */ 00322 Capabilities->UniqueID = TRUE; 00323 Capabilities->SilentInstall = TRUE; 00324 00325 /* Fill out the adress */ 00326 Capabilities->Address = InterfaceTypeUndefined; 00327 Capabilities->UINumber = InterfaceTypeUndefined; 00328 00329 /* Fill out latencies */ 00330 Capabilities->D1Latency = 0; 00331 Capabilities->D2Latency = 0; 00332 Capabilities->D3Latency = 0; 00333 00334 /* Fill out supported device states */ 00335 Capabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0; 00336 Capabilities->DeviceState[PowerSystemHibernate] = PowerDeviceD3; 00337 Capabilities->DeviceState[PowerSystemShutdown] = PowerDeviceD3; 00338 Capabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3; 00339 00340 /* Done */ 00341 Status = STATUS_SUCCESS; 00342 } 00343 else 00344 { 00345 /* Fail */ 00346 Status = STATUS_NOT_SUPPORTED; 00347 } 00348 00349 /* Return status */ 00350 return Status; 00351 } 00352 00353 NTSTATUS 00354 NTAPI 00355 HalpQueryResources(IN PDEVICE_OBJECT DeviceObject, 00356 OUT PCM_RESOURCE_LIST *Resources) 00357 { 00358 PPDO_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 00359 NTSTATUS Status; 00360 PCM_RESOURCE_LIST ResourceList; 00361 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; 00362 PIO_RESOURCE_DESCRIPTOR Descriptor; 00363 PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDesc; 00364 ULONG i; 00365 PAGED_CODE(); 00366 00367 /* Only the ACPI PDO has requirements */ 00368 if (DeviceExtension->PdoType == AcpiPdo) 00369 { 00370 /* Query ACPI requirements */ 00371 Status = HalpQueryAcpiResourceRequirements(&RequirementsList); 00372 if (!NT_SUCCESS(Status)) return Status; 00373 00374 ASSERT(RequirementsList->AlternativeLists == 1); 00375 00376 /* Allocate the resourcel ist */ 00377 ResourceList = ExAllocatePoolWithTag(PagedPool, 00378 sizeof(CM_RESOURCE_LIST), 00379 ' laH'); 00380 if (!ResourceList ) 00381 { 00382 /* Fail, no memory */ 00383 Status = STATUS_INSUFFICIENT_RESOURCES; 00384 ExFreePoolWithTag(RequirementsList, ' laH'); 00385 return Status; 00386 } 00387 00388 /* Initialize it */ 00389 RtlZeroMemory(ResourceList, sizeof(CM_RESOURCE_LIST)); 00390 ResourceList->Count = 1; 00391 00392 /* Setup the list fields */ 00393 ResourceList->List[0].BusNumber = -1; 00394 ResourceList->List[0].InterfaceType = PNPBus; 00395 ResourceList->List[0].PartialResourceList.Version = 1; 00396 ResourceList->List[0].PartialResourceList.Revision = 1; 00397 ResourceList->List[0].PartialResourceList.Count = 0; 00398 00399 /* Setup the first descriptor */ 00400 PartialDesc = ResourceList->List[0].PartialResourceList.PartialDescriptors; 00401 00402 /* Find the requirement descriptor for the SCI */ 00403 for (i = 0; i < RequirementsList->List[0].Count; i++) 00404 { 00405 /* Get this descriptor */ 00406 Descriptor = &RequirementsList->List[0].Descriptors[i]; 00407 if (Descriptor->Type == CmResourceTypeInterrupt) 00408 { 00409 /* Copy requirements descriptor into resource descriptor */ 00410 PartialDesc->Type = CmResourceTypeInterrupt; 00411 PartialDesc->ShareDisposition = Descriptor->ShareDisposition; 00412 PartialDesc->Flags = Descriptor->Flags; 00413 ASSERT(Descriptor->u.Interrupt.MinimumVector == 00414 Descriptor->u.Interrupt.MaximumVector); 00415 PartialDesc->u.Interrupt.Vector = Descriptor->u.Interrupt.MinimumVector; 00416 PartialDesc->u.Interrupt.Level = Descriptor->u.Interrupt.MinimumVector; 00417 PartialDesc->u.Interrupt.Affinity = 0xFFFFFFFF; 00418 00419 ResourceList->List[0].PartialResourceList.Count++; 00420 00421 break; 00422 } 00423 } 00424 00425 /* Return resources and success */ 00426 *Resources = ResourceList; 00427 00428 ExFreePoolWithTag(RequirementsList, ' laH'); 00429 00430 return STATUS_SUCCESS; 00431 } 00432 else if (DeviceExtension->PdoType == WdPdo) 00433 { 00434 /* Watchdog doesn't */ 00435 return STATUS_NOT_SUPPORTED; 00436 } 00437 else 00438 { 00439 /* This shouldn't happen */ 00440 return STATUS_UNSUCCESSFUL; 00441 } 00442 } 00443 00444 NTSTATUS 00445 NTAPI 00446 HalpQueryResourceRequirements(IN PDEVICE_OBJECT DeviceObject, 00447 OUT PIO_RESOURCE_REQUIREMENTS_LIST *Requirements) 00448 { 00449 PPDO_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 00450 PAGED_CODE(); 00451 00452 /* Only the ACPI PDO has requirements */ 00453 if (DeviceExtension->PdoType == AcpiPdo) 00454 { 00455 /* Query ACPI requirements */ 00456 return HalpQueryAcpiResourceRequirements(Requirements); 00457 } 00458 else if (DeviceExtension->PdoType == WdPdo) 00459 { 00460 /* Watchdog doesn't */ 00461 return STATUS_NOT_SUPPORTED; 00462 } 00463 else 00464 { 00465 /* This shouldn't happen */ 00466 return STATUS_UNSUCCESSFUL; 00467 } 00468 } 00469 00470 NTSTATUS 00471 NTAPI 00472 HalpQueryIdPdo(IN PDEVICE_OBJECT DeviceObject, 00473 IN BUS_QUERY_ID_TYPE IdType, 00474 OUT PUSHORT *BusQueryId) 00475 { 00476 PPDO_EXTENSION PdoExtension; 00477 PDO_TYPE PdoType; 00478 PWCHAR CurrentId; 00479 WCHAR Id[100]; 00480 NTSTATUS Status; 00481 SIZE_T Length = 0; 00482 PWCHAR Buffer; 00483 00484 /* Get the PDO type */ 00485 PdoExtension = DeviceObject->DeviceExtension; 00486 PdoType = PdoExtension->PdoType; 00487 00488 /* What kind of ID is being requested? */ 00489 DPRINT("ID: %d\n", IdType); 00490 switch (IdType) 00491 { 00492 case BusQueryDeviceID: 00493 case BusQueryHardwareIDs: 00494 00495 /* What kind of PDO is this? */ 00496 if (PdoType == AcpiPdo) 00497 { 00498 /* ACPI ID */ 00499 CurrentId = L"ACPI_HAL\\PNP0C08"; 00500 RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL)); 00501 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL); 00502 00503 CurrentId = L"*PNP0C08"; 00504 RtlCopyMemory(&Id[wcslen(Id) + 1], CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL)); 00505 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL); 00506 } 00507 else if (PdoType == WdPdo) 00508 { 00509 /* WatchDog ID */ 00510 CurrentId = L"ACPI_HAL\\PNP0C18"; 00511 RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL)); 00512 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL); 00513 00514 CurrentId = L"*PNP0C18"; 00515 RtlCopyMemory(&Id[wcslen(Id) + 1], CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL)); 00516 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL); 00517 } 00518 else 00519 { 00520 /* Unknown */ 00521 return STATUS_NOT_SUPPORTED; 00522 } 00523 break; 00524 00525 case BusQueryInstanceID: 00526 00527 /* Instance ID */ 00528 CurrentId = L"0"; 00529 RtlCopyMemory(Id, CurrentId, (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL)); 00530 Length += (wcslen(CurrentId) * sizeof(WCHAR)) + sizeof(UNICODE_NULL); 00531 break; 00532 00533 case BusQueryCompatibleIDs: 00534 default: 00535 00536 /* We don't support anything else */ 00537 return STATUS_NOT_SUPPORTED; 00538 } 00539 00540 00541 /* Allocate the buffer */ 00542 Buffer = ExAllocatePoolWithTag(PagedPool, 00543 Length + sizeof(UNICODE_NULL), 00544 ' laH'); 00545 if (Buffer) 00546 { 00547 /* Copy the string and null-terminate it */ 00548 RtlCopyMemory(Buffer, Id, Length); 00549 Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL; 00550 00551 /* Return string */ 00552 *BusQueryId = Buffer; 00553 Status = STATUS_SUCCESS; 00554 DPRINT("Returning: %S\n", *BusQueryId); 00555 } 00556 else 00557 { 00558 /* Fail */ 00559 Status = STATUS_INSUFFICIENT_RESOURCES; 00560 } 00561 00562 /* Return status */ 00563 return Status; 00564 } 00565 00566 NTSTATUS 00567 NTAPI 00568 HalpQueryIdFdo(IN PDEVICE_OBJECT DeviceObject, 00569 IN BUS_QUERY_ID_TYPE IdType, 00570 OUT PUSHORT *BusQueryId) 00571 { 00572 NTSTATUS Status; 00573 SIZE_T Length; 00574 PWCHAR Id; 00575 PWCHAR Buffer; 00576 00577 /* What kind of ID is being requested? */ 00578 DPRINT("ID: %d\n", IdType); 00579 switch (IdType) 00580 { 00581 case BusQueryDeviceID: 00582 /* HACK */ 00583 Id = L"Root\\ACPI_HAL"; 00584 break; 00585 00586 case BusQueryHardwareIDs: 00587 00588 /* This is our hardware ID */ 00589 Id = HalHardwareIdString; 00590 break; 00591 00592 case BusQueryInstanceID: 00593 00594 /* And our instance ID */ 00595 Id = L"0"; 00596 break; 00597 00598 default: 00599 00600 /* We don't support anything else */ 00601 return STATUS_NOT_SUPPORTED; 00602 } 00603 00604 /* Calculate the length */ 00605 Length = (wcslen(Id) * sizeof(WCHAR)) + sizeof(UNICODE_NULL); 00606 00607 /* Allocate the buffer */ 00608 Buffer = ExAllocatePoolWithTag(PagedPool, 00609 Length + sizeof(UNICODE_NULL), 00610 ' laH'); 00611 if (Buffer) 00612 { 00613 /* Copy the string and null-terminate it */ 00614 RtlCopyMemory(Buffer, Id, Length); 00615 Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL; 00616 00617 /* Return string */ 00618 *BusQueryId = Buffer; 00619 Status = STATUS_SUCCESS; 00620 DPRINT("Returning: %S\n", *BusQueryId); 00621 } 00622 else 00623 { 00624 /* Fail */ 00625 Status = STATUS_INSUFFICIENT_RESOURCES; 00626 } 00627 00628 /* Return status */ 00629 return Status; 00630 } 00631 00632 NTSTATUS 00633 NTAPI 00634 HalpDispatchPnp(IN PDEVICE_OBJECT DeviceObject, 00635 IN PIRP Irp) 00636 { 00637 PIO_STACK_LOCATION IoStackLocation; 00638 //PPDO_EXTENSION PdoExtension; 00639 PFDO_EXTENSION FdoExtension; 00640 NTSTATUS Status; 00641 UCHAR Minor; 00642 00643 /* Get the device extension and stack location */ 00644 FdoExtension = DeviceObject->DeviceExtension; 00645 IoStackLocation = IoGetCurrentIrpStackLocation(Irp); 00646 Minor = IoStackLocation->MinorFunction; 00647 00648 /* FDO? */ 00649 if (FdoExtension->ExtensionType == FdoExtensionType) 00650 { 00651 /* Query the IRP type */ 00652 switch (Minor) 00653 { 00654 case IRP_MN_QUERY_DEVICE_RELATIONS: 00655 00656 /* Call the worker */ 00657 DPRINT("Querying device relations for FDO\n"); 00658 Status = HalpQueryDeviceRelations(DeviceObject, 00659 IoStackLocation->Parameters.QueryDeviceRelations.Type, 00660 (PVOID)&Irp->IoStatus.Information); 00661 break; 00662 00663 case IRP_MN_QUERY_INTERFACE: 00664 00665 /* Call the worker */ 00666 DPRINT("Querying interface for FDO\n"); 00667 Status = HalpQueryInterface(DeviceObject, 00668 IoStackLocation->Parameters.QueryInterface.InterfaceType, 00669 IoStackLocation->Parameters.QueryInterface.Size, 00670 IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData, 00671 IoStackLocation->Parameters.QueryInterface.Version, 00672 IoStackLocation->Parameters.QueryInterface.Interface, 00673 (PVOID)&Irp->IoStatus.Information); 00674 break; 00675 00676 00677 case IRP_MN_QUERY_ID: 00678 00679 /* Call the worker */ 00680 DPRINT("Querying ID for FDO\n"); 00681 Status = HalpQueryIdFdo(DeviceObject, 00682 IoStackLocation->Parameters.QueryId.IdType, 00683 (PVOID)&Irp->IoStatus.Information); 00684 break; 00685 00686 case IRP_MN_QUERY_CAPABILITIES: 00687 00688 /* Call the worker */ 00689 DPRINT("Querying the capabilities for the FDO\n"); 00690 Status = HalpQueryCapabilities(DeviceObject, 00691 IoStackLocation->Parameters.DeviceCapabilities.Capabilities); 00692 break; 00693 00694 default: 00695 00696 DPRINT("Other IRP: %lx\n", Minor); 00697 Status = Irp->IoStatus.Status; 00698 break; 00699 } 00700 00701 /* Nowhere for the IRP to go since we also own the PDO */ 00702 Irp->IoStatus.Status = Status; 00703 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00704 return Status; 00705 } 00706 else 00707 { 00708 /* This is a PDO instead */ 00709 ASSERT(FdoExtension->ExtensionType == PdoExtensionType); 00710 //PdoExtension = (PPDO_EXTENSION)FdoExtension; 00711 /* Query the IRP type */ 00712 Status = STATUS_SUCCESS; 00713 switch (Minor) 00714 { 00715 case IRP_MN_START_DEVICE: 00716 00717 /* We only care about a PCI PDO */ 00718 DPRINT1("Start device received\n"); 00719 /* Complete the IRP normally */ 00720 break; 00721 00722 case IRP_MN_REMOVE_DEVICE: 00723 00724 /* Check if this is a PCI device */ 00725 DPRINT1("Remove device received\n"); 00726 00727 /* We're done */ 00728 Status = STATUS_SUCCESS; 00729 break; 00730 00731 case IRP_MN_SURPRISE_REMOVAL: 00732 00733 /* Inherit whatever status we had */ 00734 DPRINT1("Surprise removal IRP\n"); 00735 Status = Irp->IoStatus.Status; 00736 break; 00737 00738 case IRP_MN_QUERY_DEVICE_RELATIONS: 00739 00740 /* Query the device relations */ 00741 DPRINT("Querying PDO relations\n"); 00742 Status = HalpQueryDeviceRelations(DeviceObject, 00743 IoStackLocation->Parameters.QueryDeviceRelations.Type, 00744 (PVOID)&Irp->IoStatus.Information); 00745 break; 00746 00747 case IRP_MN_QUERY_INTERFACE: 00748 00749 /* Call the worker */ 00750 DPRINT("Querying interface for PDO\n"); 00751 Status = HalpQueryInterface(DeviceObject, 00752 IoStackLocation->Parameters.QueryInterface.InterfaceType, 00753 IoStackLocation->Parameters.QueryInterface.Size, 00754 IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData, 00755 IoStackLocation->Parameters.QueryInterface.Version, 00756 IoStackLocation->Parameters.QueryInterface.Interface, 00757 (PVOID)&Irp->IoStatus.Information); 00758 break; 00759 00760 case IRP_MN_QUERY_CAPABILITIES: 00761 00762 /* Call the worker */ 00763 DPRINT("Querying the capabilities for the PDO\n"); 00764 Status = HalpQueryCapabilities(DeviceObject, 00765 IoStackLocation->Parameters.DeviceCapabilities.Capabilities); 00766 break; 00767 00768 case IRP_MN_QUERY_RESOURCES: 00769 00770 /* Call the worker */ 00771 DPRINT("Querying the resources for the PDO\n"); 00772 Status = HalpQueryResources(DeviceObject, (PVOID)&Irp->IoStatus.Information); 00773 break; 00774 00775 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 00776 00777 /* Call the worker */ 00778 DPRINT("Querying the resource requirements for the PDO\n"); 00779 Status = HalpQueryResourceRequirements(DeviceObject, 00780 (PVOID)&Irp->IoStatus.Information); 00781 break; 00782 00783 case IRP_MN_QUERY_ID: 00784 00785 /* Call the worker */ 00786 DPRINT("Query the ID for the PDO\n"); 00787 Status = HalpQueryIdPdo(DeviceObject, 00788 IoStackLocation->Parameters.QueryId.IdType, 00789 (PVOID)&Irp->IoStatus.Information); 00790 break; 00791 00792 default: 00793 00794 /* We don't handle anything else, so inherit the old state */ 00795 DPRINT("Illegal IRP: %lx\n", Minor); 00796 Status = Irp->IoStatus.Status; 00797 break; 00798 } 00799 00800 /* If it's not supported, inherit the old status */ 00801 if (Status == STATUS_NOT_SUPPORTED) Status = Irp->IoStatus.Status; 00802 00803 /* Complete the IRP */ 00804 DPRINT("IRP completed with status: %lx\n", Status); 00805 Irp->IoStatus.Status = Status; 00806 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00807 return Status; 00808 } 00809 } 00810 00811 NTSTATUS 00812 NTAPI 00813 HalpDispatchWmi(IN PDEVICE_OBJECT DeviceObject, 00814 IN PIRP Irp) 00815 { 00816 DPRINT1("HAL: PnP Driver WMI!\n"); 00817 while (TRUE); 00818 return STATUS_SUCCESS; 00819 } 00820 00821 NTSTATUS 00822 NTAPI 00823 HalpDispatchPower(IN PDEVICE_OBJECT DeviceObject, 00824 IN PIRP Irp) 00825 { 00826 DPRINT1("HAL: PnP Driver Power!\n"); 00827 return STATUS_SUCCESS; 00828 } 00829 00830 NTSTATUS 00831 NTAPI 00832 HalpDriverEntry(IN PDRIVER_OBJECT DriverObject, 00833 IN PUNICODE_STRING RegistryPath) 00834 { 00835 NTSTATUS Status; 00836 PDEVICE_OBJECT TargetDevice = NULL; 00837 00838 DPRINT("HAL: PnP Driver ENTRY!\n"); 00839 00840 /* This is us */ 00841 HalpDriverObject = DriverObject; 00842 00843 /* Set up add device */ 00844 DriverObject->DriverExtension->AddDevice = HalpAddDevice; 00845 00846 /* Set up the callouts */ 00847 DriverObject->MajorFunction[IRP_MJ_PNP] = HalpDispatchPnp; 00848 DriverObject->MajorFunction[IRP_MJ_POWER] = HalpDispatchPower; 00849 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HalpDispatchWmi; 00850 00851 /* Create the PDO */ 00852 Status = IoCreateDevice(DriverObject, 00853 0, 00854 NULL, 00855 FILE_DEVICE_CONTROLLER, 00856 0, 00857 FALSE, 00858 &TargetDevice); 00859 if (!NT_SUCCESS(Status)) 00860 return Status; 00861 00862 TargetDevice->Flags &= ~DO_DEVICE_INITIALIZING; 00863 00864 /* Set up the device stack */ 00865 Status = HalpAddDevice(DriverObject, TargetDevice); 00866 if (!NT_SUCCESS(Status)) 00867 { 00868 IoDeleteDevice(TargetDevice); 00869 return Status; 00870 } 00871 00872 /* Tell the PnP manager about us */ 00873 Status = IoReportDetectedDevice(DriverObject, 00874 InterfaceTypeUndefined, 00875 -1, 00876 -1, 00877 NULL, 00878 NULL, 00879 FALSE, 00880 &TargetDevice); 00881 00882 /* Return to kernel */ 00883 return Status; 00884 } 00885 00886 NTSTATUS 00887 NTAPI 00888 HaliInitPnpDriver(VOID) 00889 { 00890 NTSTATUS Status; 00891 UNICODE_STRING DriverString; 00892 PAGED_CODE(); 00893 00894 /* Create the driver */ 00895 RtlInitUnicodeString(&DriverString, L"\\Driver\\ACPI_HAL"); 00896 Status = IoCreateDriver(&DriverString, HalpDriverEntry); 00897 00898 /* Return status */ 00899 return Status; 00900 } 00901 00902 /* EOF */ Generated on Sun May 27 2012 04:28:43 for ReactOS by
1.7.6.1
|