mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 09:43:04 +00:00
[HALACPI]: Begin rough implementation of the Hal ACPI PnP Driver. Will probably need some changes to the ReactOS PnP Manager to work properly (it is not initialized yet).
[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
This commit is contained in:
parent
44c2da0137
commit
9e478e990f
5 changed files with 876 additions and 0 deletions
817
reactos/hal/halx86/generic/acpi/halpnpdd.c
Normal file
817
reactos/hal/halx86/generic/acpi/halpnpdd.c
Normal file
|
@ -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 */
|
|
@ -18,6 +18,47 @@ BOOLEAN HalpNMIInProgress;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* 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
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
HalpCheckPowerButton(VOID)
|
HalpCheckPowerButton(VOID)
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<directory name="generic">
|
<directory name="generic">
|
||||||
<directory name="acpi">
|
<directory name="acpi">
|
||||||
<file>halacpi.c</file>
|
<file>halacpi.c</file>
|
||||||
|
<file>halpnpdd.c</file>
|
||||||
</directory>
|
</directory>
|
||||||
<directory name="bus">
|
<directory name="bus">
|
||||||
<file>bushndlr.c</file>
|
<file>bushndlr.c</file>
|
||||||
|
|
|
@ -227,4 +227,11 @@ HalpSetupAcpiPhase0(
|
||||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||||||
);
|
);
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
HalAcpiGetTable(
|
||||||
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
|
IN ULONG Signature
|
||||||
|
);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -697,6 +697,16 @@ HalpMapPhysicalMemory64(
|
||||||
IN ULONG PageCount
|
IN ULONG PageCount
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
HalpOpenRegistryKey(
|
||||||
|
IN PHANDLE KeyHandle,
|
||||||
|
IN HANDLE RootKey,
|
||||||
|
IN PUNICODE_STRING KeyName,
|
||||||
|
IN ACCESS_MASK DesiredAccess,
|
||||||
|
IN BOOLEAN Create
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
KeUpdateSystemTime(
|
KeUpdateSystemTime(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue