ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

halpnpdd.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.