7 #include <acpi_drivers.h>
16 #pragma alloc_text (INIT, DriverEntry)
17 #pragma alloc_text (PAGE, Bus_AddDevice)
24 PDRIVER_OBJECT DriverObject
,
25 PDEVICE_OBJECT PhysicalDeviceObject
30 PDEVICE_OBJECT deviceObject
= NULL
;
31 PFDO_DEVICE_DATA deviceData
= NULL
;
32 PWCHAR deviceName
= NULL
;
39 DPRINT("Add Device: 0x%p\n", PhysicalDeviceObject
);
41 DPRINT("#################### Bus_CreateClose Creating FDO Device ####################\n");
42 status
= IoCreateDevice(DriverObject
,
43 sizeof(FDO_DEVICE_DATA
),
46 FILE_DEVICE_SECURE_OPEN
,
49 if (!NT_SUCCESS(status
))
51 DPRINT1("IoCreateDevice() failed with status 0x%X\n", status
);
55 deviceData
= (PFDO_DEVICE_DATA
) deviceObject
->DeviceExtension
;
56 RtlZeroMemory (deviceData
, sizeof (FDO_DEVICE_DATA
));
59 // Set the initial state of the FDO
62 INITIALIZE_PNP_STATE(deviceData
->Common
);
64 deviceData
->Common
.IsFDO
= TRUE
;
66 deviceData
->Common
.Self
= deviceObject
;
68 ExInitializeFastMutex (&deviceData
->Mutex
);
70 InitializeListHead (&deviceData
->ListOfPDOs
);
72 // Set the PDO for use with PlugPlay functions
74 deviceData
->UnderlyingPDO
= PhysicalDeviceObject
;
77 // Set the initial powerstate of the FDO
80 deviceData
->Common
.DevicePowerState
= PowerDeviceUnspecified
;
81 deviceData
->Common
.SystemPowerState
= PowerSystemWorking
;
83 deviceObject
->Flags
|= DO_POWER_PAGABLE
;
86 // Attach our FDO to the device stack.
87 // The return value of IoAttachDeviceToDeviceStack is the top of the
88 // attachment chain. This is where all the IRPs should be routed.
91 deviceData
->NextLowerDriver
= IoAttachDeviceToDeviceStack (
93 PhysicalDeviceObject
);
95 if (NULL
== deviceData
->NextLowerDriver
) {
97 status
= STATUS_NO_SUCH_DEVICE
;
104 // We will demonstrate here the step to retrieve the name of the PDO
107 status
= IoGetDeviceProperty (PhysicalDeviceObject
,
108 DevicePropertyPhysicalDeviceObjectName
,
113 if (status
!= STATUS_BUFFER_TOO_SMALL
)
115 DPRINT1("AddDevice:IoGDP failed (0x%x)\n", status
);
119 deviceName
= ExAllocatePoolWithTag (NonPagedPool
,
122 if (NULL
== deviceName
) {
123 DPRINT1("AddDevice: no memory to alloc for deviceName(0x%x)\n", nameLength
);
124 status
= STATUS_INSUFFICIENT_RESOURCES
;
128 status
= IoGetDeviceProperty (PhysicalDeviceObject
,
129 DevicePropertyPhysicalDeviceObjectName
,
134 if (!NT_SUCCESS (status
)) {
136 DPRINT1("AddDevice:IoGDP(2) failed (0x%x)", status
);
140 DPRINT("AddDevice: %p to %p->%p (%ws) \n",
142 deviceData
->NextLowerDriver
,
143 PhysicalDeviceObject
,
149 // We are done with initializing, so let's indicate that and return.
150 // This should be the final step in the AddDevice process.
152 deviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
156 ExFreePool(deviceName
);
158 if (!NT_SUCCESS(status
) && deviceObject
){
159 if (deviceData
&& deviceData
->NextLowerDriver
){
160 IoDetachDevice (deviceData
->NextLowerDriver
);
162 IoDeleteDevice (deviceObject
);
170 ACPIDispatchCreateClose(
171 IN PDEVICE_OBJECT DeviceObject
,
174 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
175 Irp
->IoStatus
.Information
= 0;
177 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
179 return STATUS_SUCCESS
;
184 ACPIDispatchDeviceControl(
185 IN PDEVICE_OBJECT DeviceObject
,
188 PIO_STACK_LOCATION irpStack
;
189 NTSTATUS status
= STATUS_NOT_SUPPORTED
;
190 PCOMMON_DEVICE_DATA commonData
;
195 irpStack
= IoGetCurrentIrpStackLocation (Irp
);
196 ASSERT (IRP_MJ_DEVICE_CONTROL
== irpStack
->MajorFunction
);
198 commonData
= (PCOMMON_DEVICE_DATA
) DeviceObject
->DeviceExtension
;
200 Irp
->IoStatus
.Information
= 0;
202 if (!commonData
->IsFDO
)
204 switch (irpStack
->Parameters
.DeviceIoControl
.IoControlCode
)
206 case IOCTL_ACPI_EVAL_METHOD
:
207 status
= Bus_PDO_EvalMethod((PPDO_DEVICE_DATA
)commonData
,
211 case IOCTL_GET_SYS_BUTTON_CAPS
:
212 if (irpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(ULONG
))
214 status
= STATUS_BUFFER_TOO_SMALL
;
218 if (wcsstr(((PPDO_DEVICE_DATA
)commonData
)->HardwareIDs
, L
"PNP0C0C") ||
219 wcsstr(((PPDO_DEVICE_DATA
)commonData
)->HardwareIDs
, L
"ACPI_FPB"))
221 DPRINT1("Power button reported to power manager\n");
222 Caps
|= SYS_BUTTON_POWER
;
224 else if (wcsstr(((PPDO_DEVICE_DATA
)commonData
)->HardwareIDs
, L
"PNP0C0E") ||
225 wcsstr(((PPDO_DEVICE_DATA
)commonData
)->HardwareIDs
, L
"ACPI_FSB"))
227 DPRINT1("Sleep button reported to power manager\n");
228 Caps
|= SYS_BUTTON_SLEEP
;
230 else if (wcsstr(((PPDO_DEVICE_DATA
)commonData
)->HardwareIDs
, L
"PNP0C0D"))
232 DPRINT1("Lid button reported to power manager\n");
233 Caps
|= SYS_BUTTON_LID
;
237 DPRINT1("IOCTL_GET_SYS_BUTTON_CAPS sent to a non-button device\n");
238 status
= STATUS_INVALID_PARAMETER
;
243 RtlCopyMemory(Irp
->AssociatedIrp
.SystemBuffer
, &Caps
, sizeof(Caps
));
244 Irp
->IoStatus
.Information
= sizeof(Caps
);
245 status
= STATUS_SUCCESS
;
249 /* TODO: Implement other IOCTLs */
252 DPRINT1("Unsupported IOCTL: %x\n", irpStack
->Parameters
.DeviceIoControl
.IoControlCode
);
257 DPRINT1("IOCTL sent to the ACPI FDO! Kill the caller!\n");
259 if (status
!= STATUS_PENDING
)
261 Irp
->IoStatus
.Status
= status
;
262 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
271 PDRIVER_OBJECT DriverObject
,
272 PUNICODE_STRING RegistryPath
275 DPRINT("Driver Entry \n");
278 // Set entry points into the driver
280 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ACPIDispatchDeviceControl
;
281 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = Bus_PnP
;
282 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = Bus_Power
;
283 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = ACPIDispatchCreateClose
;
284 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = ACPIDispatchCreateClose
;
286 DriverObject
->DriverExtension
->AddDevice
= Bus_AddDevice
;
288 return STATUS_SUCCESS
;