[HALACPI]: Begin rough implementation of the Hal ACPI PnP Driver. Will probably need...
authorSir Richard <sir_richard@svn.reactos.org>
Wed, 31 Mar 2010 20:58:42 +0000 (20:58 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Wed, 31 Mar 2010 20:58:42 +0000 (20:58 +0000)
[HAL]: Implement helper registry routine.
[HAL]: Implement function to set ACPI mode the "Windows way", which is to enable/disable the firmware mapper. PnP Manager should probably check this in the future.

svn path=/trunk/; revision=46628

reactos/hal/halx86/generic/acpi/halpnpdd.c [new file with mode: 0644]
reactos/hal/halx86/generic/misc.c
reactos/hal/halx86/hal_generic.rbuild
reactos/hal/halx86/include/halacpi.h
reactos/hal/halx86/include/halp.h

diff --git a/reactos/hal/halx86/generic/acpi/halpnpdd.c b/reactos/hal/halx86/generic/acpi/halpnpdd.c
new file mode 100644 (file)
index 0000000..81bed55
--- /dev/null
@@ -0,0 +1,817 @@
+/*
+ * PROJECT:         ReactOS HAL
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            hal/halx86/generic/acpi/halpnpdd.c
+ * PURPOSE:         HAL Plug and Play Device Driver
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <hal.h>
+#define NDEBUG
+#include <debug.h>
+
+typedef enum _EXTENSION_TYPE
+{
+    PdoExtensionType = 0xC0,
+    FdoExtensionType
+} EXTENSION_TYPE;
+
+typedef enum _PDO_TYPE
+{
+    AcpiPdo = 0x80,
+    WdPdo
+} PDO_TYPE;
+
+typedef struct _FDO_EXTENSION
+{
+    EXTENSION_TYPE ExtensionType;
+    struct _PDO_EXTENSION* ChildPdoList;
+    PDEVICE_OBJECT PhysicalDeviceObject;
+    PDEVICE_OBJECT FunctionalDeviceObject;
+    PDEVICE_OBJECT AttachedDeviceObject;
+} FDO_EXTENSION, *PFDO_EXTENSION;
+
+typedef struct _PDO_EXTENSION
+{
+    EXTENSION_TYPE ExtensionType;
+    struct _PDO_EXTENSION* Next;
+    PDEVICE_OBJECT PhysicalDeviceObject;
+    PFDO_EXTENSION ParentFdoExtension;
+    PDO_TYPE PdoType;
+    PDESCRIPTION_HEADER WdTable;
+    LONG InterfaceReferenceCount;
+} PDO_EXTENSION, *PPDO_EXTENSION;
+
+/* GLOBALS ********************************************************************/
+
+PDRIVER_OBJECT HalpDriverObject;
+BOOLEAN HalDisableFirmwareMapper = TRUE;
+PWCHAR HalHardwareIdString = L"acpipic_up";
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+NTSTATUS
+NTAPI
+HalpMarkAcpiHal(VOID)
+{
+    NTSTATUS Status;
+    UNICODE_STRING KeyString;
+    HANDLE KeyHandle;
+    HANDLE Handle;
+    
+    /* Open the control set key */
+    RtlInitUnicodeString(&KeyString,
+                         L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET");
+    Status = HalpOpenRegistryKey(&Handle, 0, &KeyString, KEY_ALL_ACCESS, FALSE);
+    if (NT_SUCCESS(Status))
+    {
+        /* Open the PNP key */
+        RtlInitUnicodeString(&KeyString, L"Control\\Pnp");
+        Status = HalpOpenRegistryKey(&KeyHandle,
+                                     Handle,
+                                     &KeyString,
+                                     KEY_ALL_ACCESS,
+                                     TRUE);
+        /* Close root key */
+        ZwClose(Handle);
+        
+        /* Check if PNP BIOS key exists */
+        if (NT_SUCCESS(Status))
+        {
+            /* Set the disable value to false -- we need the mapper */
+            RtlInitUnicodeString(&KeyString, L"DisableFirmwareMapper");
+            Status = ZwSetValueKey(KeyHandle,
+                                   &KeyString,
+                                   0,
+                                   REG_DWORD,
+                                   &HalDisableFirmwareMapper,
+                                   sizeof(HalDisableFirmwareMapper));
+            
+            /* Close subkey */
+            ZwClose(KeyHandle);
+        }
+    }
+    
+    /* Return status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+HalpAddDevice(IN PDRIVER_OBJECT DriverObject,
+              IN PDEVICE_OBJECT TargetDevice)
+{
+    NTSTATUS Status;
+    PFDO_EXTENSION FdoExtension;
+    PPDO_EXTENSION PdoExtension;
+    PDEVICE_OBJECT DeviceObject, PdoDeviceObject, AttachedDevice;
+    PDESCRIPTION_HEADER Wdrt;
+    DbgPrint("HAL: PnP Driver ADD!\n");
+
+    /* Create the FDO */
+    Status = IoCreateDevice(DriverObject,
+                            sizeof(FDO_EXTENSION), 
+                            NULL,
+                            FILE_DEVICE_BUS_EXTENDER,
+                            0,
+                            FALSE,
+                            &DeviceObject);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Should not happen */
+        DbgBreakPoint();
+        return Status;
+    }
+    
+    /* Setup the FDO extension */
+    FdoExtension = DeviceObject->DeviceExtension;
+    FdoExtension->ExtensionType = FdoExtensionType;
+    FdoExtension->PhysicalDeviceObject = TargetDevice;
+    FdoExtension->FunctionalDeviceObject = DeviceObject;
+    
+    /* FDO is done initializing */
+    DeviceObject->Flags &= DO_DEVICE_INITIALIZING;
+    
+    /* Attach to the physical device object (the bus) */
+    AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject, TargetDevice);
+    if (!AttachedDevice)
+    {
+        /* Failed, undo everything */
+        IoDeleteDevice(DeviceObject);
+        return STATUS_NO_SUCH_DEVICE;
+    }
+    
+    /* Save the attachment */
+    FdoExtension->AttachedDeviceObject = AttachedDevice;
+    
+    /* Create the PDO */
+    Status = IoCreateDevice(DriverObject,
+                            sizeof(PDO_EXTENSION),
+                            NULL,
+                            FILE_DEVICE_BUS_EXTENDER,
+                            FILE_AUTOGENERATED_DEVICE_NAME,
+                            FALSE,
+                            &PdoDeviceObject);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        DbgPrint("HAL: Could not create ACPI device object status=0x%08x\n", Status);
+        return Status;
+    }
+    
+    /* Setup the PDO device extension */
+    PdoExtension = PdoDeviceObject->DeviceExtension;
+    PdoExtension->Next = NULL;
+    PdoExtension->ExtensionType = PdoExtensionType;
+    PdoExtension->PhysicalDeviceObject = PdoDeviceObject;
+    PdoExtension->ParentFdoExtension = FdoExtension;
+    PdoExtension->PdoType = AcpiPdo;
+
+    /* Find the ACPI watchdog table */
+    Wdrt = HalAcpiGetTable(0, 'TRDW');
+    if (!Wdrt)
+    {
+        /* None exists, there is nothing to do more */
+        PdoDeviceObject->Flags &= DO_DEVICE_INITIALIZING;
+        FdoExtension->ChildPdoList = PdoExtension;
+    }
+    else
+    {
+        /* FIXME: TODO */
+        DPRINT1("You have an ACPI Watchdog. That's great! You should be proud ;-)\n");
+        PdoDeviceObject->Flags &= DO_DEVICE_INITIALIZING;
+        FdoExtension->ChildPdoList = PdoExtension;
+    }
+
+    /* Return status */
+    DPRINT1("Device added %lx\n", Status);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+HalpQueryInterface(IN PDEVICE_OBJECT DeviceObject,
+                   IN CONST GUID* InterfaceType,
+                   IN USHORT Version,
+                   IN PVOID InterfaceSpecificData,
+                   IN ULONG InterfaceBufferSize,
+                   IN PINTERFACE Interface,
+                   OUT PULONG Length)
+{
+    UNIMPLEMENTED;
+    while (TRUE);
+    return STATUS_NO_SUCH_DEVICE;
+}
+
+NTSTATUS
+NTAPI
+HalpQueryDeviceRelations(IN PDEVICE_OBJECT DeviceObject,
+                         IN DEVICE_RELATION_TYPE RelationType,
+                         OUT PDEVICE_RELATIONS* DeviceRelations)
+{
+    EXTENSION_TYPE ExtensionType;
+    PPDO_EXTENSION PdoExtension;
+    PFDO_EXTENSION FdoExtension;
+    PDEVICE_RELATIONS PdoRelations, FdoRelations;
+    PDEVICE_OBJECT* ObjectEntry;
+    ULONG i = 0, PdoCount = 0;
+    
+    /* Get FDO device extension and PDO count */
+    FdoExtension = DeviceObject->DeviceExtension;
+    ExtensionType = FdoExtension->ExtensionType;
+    
+    /* What do they want? */
+    if (RelationType == BusRelations)
+    {
+        /* This better be an FDO */
+        if (ExtensionType == FdoExtensionType)
+        {
+            /* Count how many PDOs we have */
+            PdoExtension = FdoExtension->ChildPdoList;
+            while (PdoExtension)
+            {
+                /* Next one */
+                PdoExtension = PdoExtension->Next;
+                PdoCount++;
+            }
+            
+            /* Allocate our structure */
+            FdoRelations = ExAllocatePoolWithTag(PagedPool,
+                                                 FIELD_OFFSET(DEVICE_RELATIONS,
+                                                              Objects) +
+                                                 4 * PdoCount,
+                                                 ' laH');
+            if (!FdoRelations) return STATUS_INSUFFICIENT_RESOURCES;
+            
+            /* Save our count */
+            FdoRelations->Count = PdoCount;
+            
+            /* Query existing relations */
+            ObjectEntry = FdoRelations->Objects;
+            if (*DeviceRelations)
+            {
+                /* Check if there were any */
+                if ((*DeviceRelations)->Count)
+                {
+                    /* Loop them all */
+                    do
+                    {
+                        /* Copy into our structure */
+                        *ObjectEntry++ = (*DeviceRelations)->Objects[i];
+                    }
+                    while (++i < (*DeviceRelations)->Count);
+                }
+                
+                /* Free existing structure */
+                ExFreePoolWithTag(*DeviceRelations, 0);
+            }
+            
+            /* Now check if we have a PDO list */
+            PdoExtension = FdoExtension->ChildPdoList;
+            if (PdoExtension)
+            {
+                /* Loop the PDOs */
+                do
+                {
+                    /* Save our own PDO and reference it */
+                    *ObjectEntry++ = PdoExtension->PhysicalDeviceObject;
+                    ObfReferenceObject(PdoExtension->PhysicalDeviceObject);
+                    
+                    /* Go to our next PDO */
+                    PdoExtension = PdoExtension->Next;
+                }
+                while (PdoExtension);
+            }
+            
+            /* Return the new structure */
+            *DeviceRelations = FdoRelations;
+            return STATUS_SUCCESS;
+        }
+    }
+    else
+    {
+        /* The only other thing we support is a target relation for the PDO */
+        if ((RelationType == TargetDeviceRelation) &&
+            (ExtensionType == PdoExtensionType))
+        {
+            /* Only one entry */
+            PdoRelations = ExAllocatePoolWithTag(PagedPool,
+                                                 sizeof(DEVICE_RELATIONS),
+                                                 ' laH');
+            if (!PdoRelations) return STATUS_INSUFFICIENT_RESOURCES;
+            
+            /* Fill it out and reference us */
+            PdoRelations->Count = 1;
+            PdoRelations->Objects[0] = DeviceObject;
+            ObfReferenceObject(DeviceObject);
+            
+            /* Return it */
+            *DeviceRelations = PdoRelations;
+            return STATUS_SUCCESS;
+        }
+    }
+    
+    /* We don't support anything else */
+    return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+HalpQueryCapabilities(IN PDEVICE_OBJECT DeviceObject,
+                      OUT PDEVICE_CAPABILITIES Capabilities)
+{
+    PPDO_EXTENSION PdoExtension;
+    NTSTATUS Status;
+    PAGED_CODE();
+    
+    /* Get the extension and check for valid version */
+    PdoExtension = DeviceObject->DeviceExtension;
+    ASSERT(Capabilities->Version == 1);
+    if (Capabilities->Version == 1)
+    {
+        /* Can't lock or eject us */
+        Capabilities->LockSupported = FALSE;
+        Capabilities->EjectSupported = FALSE;
+        
+        /* Can't remove or dock us */
+        Capabilities->Removable = FALSE;
+        Capabilities->DockDevice = FALSE;
+        
+        /* Can't access us raw */
+        Capabilities->RawDeviceOK = FALSE;
+        
+        /* We have a unique ID, and don't bother the user */
+        Capabilities->UniqueID = TRUE;
+        Capabilities->SilentInstall = TRUE;
+        
+        /* Fill out the adress */
+        Capabilities->Address = InterfaceTypeUndefined;
+        Capabilities->UINumber = InterfaceTypeUndefined;
+        
+        /* Fill out latencies */
+        Capabilities->D1Latency = 0;
+        Capabilities->D2Latency = 0;
+        Capabilities->D3Latency = 0;
+        
+        /* Fill out supported device states */
+        Capabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
+        Capabilities->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
+        Capabilities->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
+        Capabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
+        
+        /* Done */
+        Status = STATUS_SUCCESS;
+    }
+    else
+    {
+        /* Fail */
+        Status = STATUS_NOT_SUPPORTED;
+    }
+    
+    /* Return status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+HalpQueryResources(IN PDEVICE_OBJECT DeviceObject,
+                   OUT PCM_RESOURCE_LIST *Resources)
+{
+    UNIMPLEMENTED;
+    while (TRUE);
+    return STATUS_NO_SUCH_DEVICE;
+}
+
+NTSTATUS
+NTAPI
+HalpQueryResourceRequirements(IN PDEVICE_OBJECT DeviceObject,
+                              OUT PIO_RESOURCE_REQUIREMENTS_LIST *Requirements)
+{
+    UNIMPLEMENTED;
+    while (TRUE);
+    return STATUS_NO_SUCH_DEVICE;
+}
+
+NTSTATUS
+NTAPI
+HalpQueryIdPdo(IN PDEVICE_OBJECT DeviceObject,
+               IN BUS_QUERY_ID_TYPE IdType,
+               OUT PUSHORT *BusQueryId)
+{
+    PPDO_EXTENSION PdoExtension;
+    PDO_TYPE PdoType;
+    PWCHAR Id;
+    NTSTATUS Status;
+    ULONG Length;
+    PWCHAR Buffer;
+
+    /* Get the PDO type */
+    PdoExtension = DeviceObject->DeviceExtension;
+    PdoType = PdoExtension->PdoType;
+
+    /* What kind of ID is being requested? */
+    DPRINT("ID: %d\n", IdType);
+    switch (IdType)
+    {
+        case BusQueryDeviceID:
+        case BusQueryHardwareIDs:
+            
+            /* What kind of PDO is this? */
+            if (PdoType == AcpiPdo)
+            {
+                /* PCI ID */
+                Id = L"ACPI_HAL\\PNP0C08";
+            }
+            else if (PdoType == WdPdo)
+            {
+                /* WatchDog ID */
+                Id = L"ACPI_HAL\\PNP0C18";
+            }
+            else
+            {
+                /* Unknown */
+                return STATUS_NOT_SUPPORTED;
+            }
+            
+            /* Static length */
+            Length = 32;
+            break;
+            
+        case BusQueryInstanceID:
+                    
+            /* And our instance ID */
+            Id = L"0";
+            Length = sizeof(L"0") + sizeof(UNICODE_NULL);
+            break;
+            
+        case BusQueryCompatibleIDs:
+        default:
+            
+            /* We don't support anything else */
+            return STATUS_NOT_SUPPORTED;
+    }
+    
+    /* Allocate the buffer */
+    Buffer = ExAllocatePoolWithTag(PagedPool,
+                                   Length + sizeof(UNICODE_NULL),
+                                   ' laH');
+    if (Buffer)
+    {
+        /* Copy the string and null-terminate it */
+        RtlCopyMemory(Buffer, Id, Length);
+        Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
+        
+        /* Return string */
+        *BusQueryId = Buffer;
+        Status = STATUS_SUCCESS;
+        DPRINT("Returning: %S\n", *BusQueryId);
+    }
+    else
+    {
+        /* Fail */
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
+    
+    /* Return status */
+    return Status;
+}
+     
+NTSTATUS
+NTAPI
+HalpQueryIdFdo(IN PDEVICE_OBJECT DeviceObject,
+               IN BUS_QUERY_ID_TYPE IdType,
+               OUT PUSHORT *BusQueryId)
+{
+    NTSTATUS Status;
+    ULONG Length;
+    PWCHAR Id;
+    PWCHAR Buffer;
+    
+    /* What kind of ID is being requested? */
+    DPRINT("ID: %d\n", IdType);
+    switch (IdType)
+    {
+        case BusQueryDeviceID:
+        case BusQueryHardwareIDs:
+            
+            /* This is our hardware ID */
+            Id = HalHardwareIdString;
+            Length = wcslen(HalHardwareIdString) + sizeof(UNICODE_NULL);
+            break;
+            
+        case BusQueryInstanceID:
+            
+            /* And our instance ID */
+            Id = L"0";
+            Length = sizeof(L"0") + sizeof(UNICODE_NULL);
+            break;
+            
+        default:
+            
+            /* We don't support anything else */
+            return STATUS_NOT_SUPPORTED;
+    }
+    
+    /* Allocate the buffer */
+    Buffer = ExAllocatePoolWithTag(PagedPool,
+                                   Length + sizeof(UNICODE_NULL),
+                                   ' laH');
+    if (Buffer)
+    {
+        /* Copy the string and null-terminate it */
+        RtlCopyMemory(Buffer, Id, Length);
+        Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+        /* Return string */
+        *BusQueryId = Buffer;
+        Status = STATUS_SUCCESS;
+        DPRINT("Returning: %S\n", *BusQueryId);
+    }
+    else
+    {
+        /* Fail */
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* Return status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+HalpPassIrpFromFdoToPdo(IN PDEVICE_OBJECT DeviceObject,
+                        IN PIRP Irp)
+{
+    PFDO_EXTENSION FdoExtension;
+    
+    /* Get the extension */
+    FdoExtension = DeviceObject->DeviceExtension;
+    
+    /* Pass it to the attached device (our PDO) */
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(FdoExtension->AttachedDeviceObject, Irp);  
+}
+
+NTSTATUS
+NTAPI
+HalpDispatchPnp(IN PDEVICE_OBJECT DeviceObject,
+                IN PIRP Irp)
+{
+    PIO_STACK_LOCATION IoStackLocation;
+    PPDO_EXTENSION PdoExtension;
+    PFDO_EXTENSION FdoExtension;
+    NTSTATUS Status;
+    UCHAR Minor;
+    
+    /* Get the device extension and stack location */
+    FdoExtension = DeviceObject->DeviceExtension;
+    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+    Minor = IoStackLocation->MinorFunction;
+    
+    /* FDO? */
+    if (FdoExtension->ExtensionType == FdoExtensionType)
+    {
+        /* Query the IRP type */
+        switch (Minor)
+        {
+            case IRP_MN_QUERY_DEVICE_RELATIONS:
+                
+                /* Call the worker */
+                DPRINT("Querying device relations for FDO\n");
+                Status = HalpQueryDeviceRelations(DeviceObject,
+                                                  IoStackLocation->Parameters.QueryDeviceRelations.Type,
+                                                  (PVOID)&Irp->IoStatus.Information);
+                break;
+                
+            case IRP_MN_QUERY_INTERFACE:
+
+                /* Call the worker */
+                DPRINT("Querying interface for FDO\n");
+                Status = HalpQueryInterface(DeviceObject,
+                                            IoStackLocation->Parameters.QueryInterface.InterfaceType,
+                                            IoStackLocation->Parameters.QueryInterface.Size,
+                                            IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData,
+                                            IoStackLocation->Parameters.QueryInterface.Version,
+                                            IoStackLocation->Parameters.QueryInterface.Interface,
+                                            (PVOID)&Irp->IoStatus.Information);
+                break;
+                                               
+                
+            case IRP_MN_QUERY_ID:
+                
+                /* Call the worker */
+                DPRINT("Querying ID for FDO\n");
+                Status = HalpQueryIdFdo(DeviceObject,
+                                        IoStackLocation->Parameters.QueryId.IdType,
+                                        (PVOID)&Irp->IoStatus.Information);
+                break;
+                
+            default:
+                
+                /* Pass it to the PDO */
+                DPRINT("Other IRP: %lx\n", Minor);
+                return HalpPassIrpFromFdoToPdo(DeviceObject, Irp);
+        }
+        
+        /* What happpened? */
+        if ((NT_SUCCESS(Status)) || (Status == STATUS_NOT_SUPPORTED))
+        {
+            /* Set the IRP status, unless this isn't understood */
+            if (Status != STATUS_NOT_SUPPORTED) Irp->IoStatus.Status = Status;
+            
+            /* Pass it on */
+            DPRINT("Passing IRP to PDO\n");
+            return HalpPassIrpFromFdoToPdo(DeviceObject, Irp);
+        }
+        
+        /* Otherwise, we failed, so set the status and complete the request */
+        DPRINT1("IRP failed with status: %lx\n", Status);
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
+    }
+    else
+    {
+        /* This is a PDO instead */
+        ASSERT(FdoExtension->ExtensionType == PdoExtensionType);
+        PdoExtension = (PPDO_EXTENSION)FdoExtension;
+        
+        /* Query the IRP type */
+        Status = STATUS_SUCCESS;
+        switch (Minor)
+        {                
+            case IRP_MN_START_DEVICE:
+                
+                /* We only care about a PCI PDO */
+                DPRINT1("Start device received\n");
+                /* Complete the IRP normally */
+                break;
+                
+            case IRP_MN_REMOVE_DEVICE:
+
+                /* Check if this is a PCI device */
+                DPRINT1("Remove device received\n");
+                
+                /* We're done */
+                Status = STATUS_SUCCESS;
+                break;
+
+            case IRP_MN_SURPRISE_REMOVAL:
+                
+                /* Inherit whatever status we had */
+                DPRINT1("Surprise removal IRP\n");
+                Status = Irp->IoStatus.Status;
+                break;
+                
+            case IRP_MN_QUERY_DEVICE_RELATIONS:
+                
+                /* Query the device relations */
+                DPRINT("Querying PDO relations\n");
+                Status = HalpQueryDeviceRelations(DeviceObject,
+                                                  IoStackLocation->Parameters.QueryDeviceRelations.Type,
+                                                  (PVOID)&Irp->IoStatus.Information);
+                break;
+                
+            case IRP_MN_QUERY_INTERFACE:
+                
+                /* Call the worker */
+                DPRINT("Querying interface for PDO\n");
+                Status = HalpQueryInterface(DeviceObject,
+                                            IoStackLocation->Parameters.QueryInterface.InterfaceType,
+                                            IoStackLocation->Parameters.QueryInterface.Size,
+                                            IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData,
+                                            IoStackLocation->Parameters.QueryInterface.Version,
+                                            IoStackLocation->Parameters.QueryInterface.Interface,
+                                            (PVOID)&Irp->IoStatus.Information);
+                break;
+                
+            case IRP_MN_QUERY_CAPABILITIES:
+                
+                /* Call the worker */
+                DPRINT("Querying the capabilities for the PDO\n");
+                Status = HalpQueryCapabilities(DeviceObject,
+                                               IoStackLocation->Parameters.DeviceCapabilities.Capabilities);
+                break;
+                
+            case IRP_MN_QUERY_RESOURCES:
+                
+                /* Call the worker */
+                DPRINT("Querying the resources for the PDO\n");
+                Status = HalpQueryResources(DeviceObject, (PVOID)&Irp->IoStatus.Information);
+                break;
+                
+            case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
+                
+                /* Call the worker */
+                DPRINT("Querying the resource requirements for the PDO\n");
+                Status = HalpQueryResourceRequirements(DeviceObject,
+                                                       (PVOID)&Irp->IoStatus.Information);
+                break;
+
+            case IRP_MN_QUERY_ID:
+                
+                /* Call the worker */
+                DPRINT("Query the ID for the PDO\n");
+                Status = HalpQueryIdPdo(DeviceObject,
+                                        IoStackLocation->Parameters.QueryId.IdType,
+                                        (PVOID)&Irp->IoStatus.Information);
+                break;
+                              
+            default:
+                
+                /* We don't handle anything else, so inherit the old state */
+                DPRINT("Illegal IRP: %lx\n", Minor);
+                Status = Irp->IoStatus.Status;
+                break;
+        }
+               
+        /* If it's not supported, inherit the old status */
+        if (Status == STATUS_NOT_SUPPORTED) Status = Irp->IoStatus.Status;
+        
+        /* Complete the IRP */
+        DPRINT("IRP completed with status: %lx\n", Status);
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
+    }
+}
+
+NTSTATUS
+NTAPI
+HalpDispatchWmi(IN PDEVICE_OBJECT DeviceObject,
+                IN PIRP Irp)
+{
+    DbgPrint("HAL: PnP Driver WMI!\n");
+    while (TRUE);
+    return STATUS_SUCCESS;   
+}
+
+NTSTATUS
+NTAPI
+HalpDispatchPower(IN PDEVICE_OBJECT DeviceObject,
+                  IN PIRP Irp)
+{
+    DbgPrint("HAL: PnP Driver Power!\n");
+    while (TRUE);
+    return STATUS_SUCCESS;   
+}
+
+NTSTATUS
+NTAPI
+HalpDriverEntry(IN PDRIVER_OBJECT DriverObject,
+                IN PUNICODE_STRING RegistryPath)
+{
+    NTSTATUS Status;
+    PDEVICE_OBJECT TargetDevice = NULL;
+    DPRINT("HAL: PnP Driver ENTRY!\n");
+
+    /* This is us */
+    HalpDriverObject = DriverObject;
+    
+    /* Set up add device */
+    DriverObject->DriverExtension->AddDevice = HalpAddDevice;
+    
+    /* Set up the callouts */
+    DriverObject->MajorFunction[IRP_MJ_PNP] = HalpDispatchPnp;
+    DriverObject->MajorFunction[IRP_MJ_POWER] = HalpDispatchPower;
+    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HalpDispatchWmi;
+    
+    /* Tell the PnP about us */
+    Status = IoReportDetectedDevice(DriverObject,
+                                    InterfaceTypeUndefined,
+                                    -1,
+                                    -1,
+                                    NULL,
+                                    NULL,
+                                    FALSE,
+                                    &TargetDevice);
+
+    /* Now add us */
+    if (NT_SUCCESS(Status)) Status = HalpAddDevice(DriverObject, TargetDevice);
+    
+    /* Force re-enumeration??? */
+    IoInvalidateDeviceRelations(TargetDevice, 0);
+
+    /* Return to kernel */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+HaliInitPnpDriver(VOID)
+{
+    NTSTATUS Status;
+    UNICODE_STRING DriverString;
+    PAGED_CODE();
+    
+    /* Create the driver */
+    RtlInitUnicodeString(&DriverString, L"\\Driver\\ACPI_HAL");
+    Status = IoCreateDriver(&DriverString, HalpDriverEntry);
+
+    /* Return status */
+    return Status;
+}
+
+/* EOF */
index f778b17..00ea13b 100644 (file)
@@ -18,6 +18,47 @@ BOOLEAN HalpNMIInProgress;
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
+NTSTATUS 
+NTAPI
+HalpOpenRegistryKey(IN PHANDLE KeyHandle,
+                    IN HANDLE RootKey,
+                    IN PUNICODE_STRING KeyName,
+                    IN ACCESS_MASK DesiredAccess, 
+                    IN BOOLEAN Create)
+{
+    NTSTATUS Status;
+    ULONG Disposition;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    
+    /* Setup the attributes we received */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               RootKey,
+                               NULL);
+
+    /* What to do? */
+    if ( Create )
+    {
+        /* Create the key */
+        Status = ZwCreateKey(KeyHandle,
+                             DesiredAccess,
+                             &ObjectAttributes,
+                             0,
+                             NULL,
+                             REG_OPTION_VOLATILE,
+                             &Disposition);
+    }
+    else
+    {
+        /* Open the key */
+        Status = ZwOpenKey(KeyHandle, DesiredAccess, &ObjectAttributes);
+    }
+        
+    /* We're done */
+    return Status;
+}
+
 VOID
 NTAPI
 HalpCheckPowerButton(VOID)
index d8f8fa2..dccd161 100644 (file)
@@ -58,6 +58,7 @@
                <directory name="generic">
                    <directory name="acpi">
                        <file>halacpi.c</file>
+                       <file>halpnpdd.c</file>
                    </directory>
                        <directory name="bus">
                                <file>bushndlr.c</file>
index aa342ab..1b4e16b 100644 (file)
@@ -227,4 +227,11 @@ HalpSetupAcpiPhase0(
     IN PLOADER_PARAMETER_BLOCK LoaderBlock
 );
 
+PVOID
+NTAPI
+HalAcpiGetTable(
+    IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+    IN ULONG Signature
+);
+
 /* EOF */
index 6ded951..44b81a0 100644 (file)
@@ -697,6 +697,16 @@ HalpMapPhysicalMemory64(
     IN ULONG PageCount
 );
 
+NTSTATUS 
+NTAPI
+HalpOpenRegistryKey(
+    IN PHANDLE KeyHandle,
+    IN HANDLE RootKey,
+    IN PUNICODE_STRING KeyName,
+    IN ACCESS_MASK DesiredAccess, 
+    IN BOOLEAN Create
+);
+
 VOID
 FASTCALL
 KeUpdateSystemTime(