mirror of
https://github.com/reactos/reactos.git
synced 2024-06-01 02:01:57 +00:00
219 lines
5.4 KiB
C
219 lines
5.4 KiB
C
|
#include <ntddk.h>
|
||
|
|
||
|
#include <acpi.h>
|
||
|
#include <acpisys.h>
|
||
|
|
||
|
#include <acpi_bus.h>
|
||
|
#include <acpi_drivers.h>
|
||
|
|
||
|
//#define NDEBUG
|
||
|
#include <debug.h>
|
||
|
|
||
|
#ifdef ALLOC_PRAGMA
|
||
|
#pragma alloc_text (INIT, DriverEntry)
|
||
|
#pragma alloc_text (PAGE, Bus_AddDevice)
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
NTAPI
|
||
|
Bus_AddDevice(
|
||
|
PDRIVER_OBJECT DriverObject,
|
||
|
PDEVICE_OBJECT PhysicalDeviceObject
|
||
|
)
|
||
|
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
PDEVICE_OBJECT deviceObject = NULL;
|
||
|
PFDO_DEVICE_DATA deviceData = NULL;
|
||
|
PWCHAR deviceName = NULL;
|
||
|
ULONG nameLength;
|
||
|
|
||
|
PAGED_CODE ();
|
||
|
|
||
|
DPRINT("Add Device: 0x%p\n", PhysicalDeviceObject);
|
||
|
|
||
|
DPRINT1("#################### Bus_CreateClose Creating FDO Device ####################\n");
|
||
|
status = IoCreateDevice(DriverObject,
|
||
|
sizeof(FDO_DEVICE_DATA),
|
||
|
NULL,
|
||
|
FILE_DEVICE_ACPI,
|
||
|
FILE_DEVICE_SECURE_OPEN,
|
||
|
TRUE,
|
||
|
&deviceObject);
|
||
|
if (!NT_SUCCESS(status))
|
||
|
{
|
||
|
DPRINT1("IoCreateDevice() failed with status 0x%X\n", status);
|
||
|
goto End;
|
||
|
}
|
||
|
|
||
|
deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension;
|
||
|
RtlZeroMemory (deviceData, sizeof (FDO_DEVICE_DATA));
|
||
|
|
||
|
//
|
||
|
// Set the initial state of the FDO
|
||
|
//
|
||
|
|
||
|
INITIALIZE_PNP_STATE(deviceData->Common);
|
||
|
|
||
|
deviceData->Common.IsFDO = TRUE;
|
||
|
|
||
|
deviceData->Common.Self = deviceObject;
|
||
|
|
||
|
ExInitializeFastMutex (&deviceData->Mutex);
|
||
|
|
||
|
InitializeListHead (&deviceData->ListOfPDOs);
|
||
|
|
||
|
// Set the PDO for use with PlugPlay functions
|
||
|
|
||
|
deviceData->UnderlyingPDO = PhysicalDeviceObject;
|
||
|
|
||
|
//
|
||
|
// Set the initial powerstate of the FDO
|
||
|
//
|
||
|
|
||
|
deviceData->Common.DevicePowerState = PowerDeviceUnspecified;
|
||
|
deviceData->Common.SystemPowerState = PowerSystemWorking;
|
||
|
|
||
|
deviceObject->Flags |= DO_POWER_PAGABLE;
|
||
|
|
||
|
//
|
||
|
// Attach our FDO to the device stack.
|
||
|
// The return value of IoAttachDeviceToDeviceStack is the top of the
|
||
|
// attachment chain. This is where all the IRPs should be routed.
|
||
|
//
|
||
|
|
||
|
deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack (
|
||
|
deviceObject,
|
||
|
PhysicalDeviceObject);
|
||
|
|
||
|
if (NULL == deviceData->NextLowerDriver) {
|
||
|
|
||
|
status = STATUS_NO_SUCH_DEVICE;
|
||
|
goto End;
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifndef NDEBUG
|
||
|
//
|
||
|
// We will demonstrate here the step to retrieve the name of the PDO
|
||
|
//
|
||
|
|
||
|
status = IoGetDeviceProperty (PhysicalDeviceObject,
|
||
|
DevicePropertyPhysicalDeviceObjectName,
|
||
|
0,
|
||
|
NULL,
|
||
|
&nameLength);
|
||
|
|
||
|
if (status != STATUS_BUFFER_TOO_SMALL)
|
||
|
{
|
||
|
DPRINT1("AddDevice:IoGDP failed (0x%x)\n", status);
|
||
|
goto End;
|
||
|
}
|
||
|
|
||
|
deviceName = ExAllocatePoolWithTag (NonPagedPool,
|
||
|
nameLength, 'IPCA');
|
||
|
|
||
|
if (NULL == deviceName) {
|
||
|
DPRINT1("AddDevice: no memory to alloc for deviceName(0x%x)\n", nameLength);
|
||
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||
|
goto End;
|
||
|
}
|
||
|
|
||
|
status = IoGetDeviceProperty (PhysicalDeviceObject,
|
||
|
DevicePropertyPhysicalDeviceObjectName,
|
||
|
nameLength,
|
||
|
deviceName,
|
||
|
&nameLength);
|
||
|
|
||
|
if (!NT_SUCCESS (status)) {
|
||
|
|
||
|
DPRINT1("AddDevice:IoGDP(2) failed (0x%x)", status);
|
||
|
goto End;
|
||
|
}
|
||
|
|
||
|
DPRINT1("AddDevice: %p to %p->%p (%ws) \n",
|
||
|
deviceObject,
|
||
|
deviceData->NextLowerDriver,
|
||
|
PhysicalDeviceObject,
|
||
|
deviceName);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// We are done with initializing, so let's indicate that and return.
|
||
|
// This should be the final step in the AddDevice process.
|
||
|
//
|
||
|
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||
|
|
||
|
End:
|
||
|
if (deviceName){
|
||
|
ExFreePool(deviceName);
|
||
|
}
|
||
|
if (!NT_SUCCESS(status) && deviceObject){
|
||
|
if (deviceData && deviceData->NextLowerDriver){
|
||
|
IoDetachDevice (deviceData->NextLowerDriver);
|
||
|
}
|
||
|
IoDeleteDevice (deviceObject);
|
||
|
}
|
||
|
return status;
|
||
|
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
NTAPI
|
||
|
ACPIDispatchDeviceControl(
|
||
|
IN PDEVICE_OBJECT DeviceObject,
|
||
|
IN PIRP Irp)
|
||
|
{
|
||
|
PIO_STACK_LOCATION IrpSp;
|
||
|
NTSTATUS Status;
|
||
|
|
||
|
DPRINT("Called. IRP is at (0x%X)\n", Irp);
|
||
|
|
||
|
Irp->IoStatus.Information = 0;
|
||
|
|
||
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||
|
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
|
||
|
default:
|
||
|
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
|
||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (Status != STATUS_PENDING) {
|
||
|
Irp->IoStatus.Status = Status;
|
||
|
|
||
|
DPRINT("Completing IRP at 0x%X\n", Irp);
|
||
|
|
||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||
|
}
|
||
|
|
||
|
DPRINT("Leaving. Status 0x%X\n", Status);
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
NTSTATUS
|
||
|
NTAPI
|
||
|
DriverEntry (
|
||
|
PDRIVER_OBJECT DriverObject,
|
||
|
PUNICODE_STRING RegistryPath
|
||
|
)
|
||
|
{
|
||
|
DPRINT("Driver Entry \n");
|
||
|
|
||
|
//
|
||
|
// Set entry points into the driver
|
||
|
//
|
||
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ACPIDispatchDeviceControl;
|
||
|
DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP;
|
||
|
DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power;
|
||
|
|
||
|
DriverObject->DriverExtension->AddDevice = Bus_AddDevice;
|
||
|
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|