1 // Copyright (c) 2004, Antony C. Roberts
3 // Use of this file is subject to the terms
4 // described in the LICENSE.TXT file that
5 // accompanies this file.
7 // Your use of this file indicates your
8 // acceptance of the terms described in
11 // http://www.freebt.net
22 #define MOFRESOURCENAME L"MofResourceName"
24 #define WMI_FREEBT_DRIVER_INFORMATION 0
26 DEFINE_GUID (FREEBT_WMI_STD_DATA_GUID
, 0x871B1A60, 0xD3EA, 0x4f2f, 0x81, 0x7b, 0x46, 0x5e, 0x44, 0x86, 0x7b, 0xf5);
28 WMIGUIDREGINFO FreeBTWmiGuidList
[1] =
31 &FREEBT_WMI_STD_DATA_GUID
, 1, 0 // driver information
37 NTSTATUS
FreeBT_WmiRegistration(IN OUT PDEVICE_EXTENSION DeviceExtension
)
43 DeviceExtension
->WmiLibInfo
.GuidCount
= sizeof (FreeBTWmiGuidList
) / sizeof (WMIGUIDREGINFO
);
44 DeviceExtension
->WmiLibInfo
.GuidList
= FreeBTWmiGuidList
;
45 DeviceExtension
->WmiLibInfo
.QueryWmiRegInfo
= FreeBT_QueryWmiRegInfo
;
46 DeviceExtension
->WmiLibInfo
.QueryWmiDataBlock
= FreeBT_QueryWmiDataBlock
;
47 DeviceExtension
->WmiLibInfo
.SetWmiDataBlock
= FreeBT_SetWmiDataBlock
;
48 DeviceExtension
->WmiLibInfo
.SetWmiDataItem
= FreeBT_SetWmiDataItem
;
49 DeviceExtension
->WmiLibInfo
.ExecuteWmiMethod
= NULL
;
50 DeviceExtension
->WmiLibInfo
.WmiFunctionControl
= NULL
;
53 ntStatus
= IoWMIRegistrationControl(DeviceExtension
->FunctionalDeviceObject
, WMIREG_ACTION_REGISTER
);
59 NTSTATUS
FreeBT_WmiDeRegistration(IN OUT PDEVICE_EXTENSION DeviceExtension
)
62 return IoWMIRegistrationControl(DeviceExtension
->FunctionalDeviceObject
, WMIREG_ACTION_DEREGISTER
);
66 NTSTATUS
FreeBT_DispatchSysCtrl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
)
68 PDEVICE_EXTENSION deviceExtension
;
69 SYSCTL_IRP_DISPOSITION disposition
;
71 PIO_STACK_LOCATION irpStack
;
75 irpStack
= IoGetCurrentIrpStackLocation (Irp
);
76 deviceExtension
= (PDEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
78 FreeBT_DbgPrint(3, ("FBTUSB: "));
79 FreeBT_DbgPrint(3, (WMIMinorFunctionString(irpStack
->MinorFunction
)));
80 if (Removed
== deviceExtension
->DeviceState
)
82 ntStatus
= STATUS_DELETE_PENDING
;
84 Irp
->IoStatus
.Status
= ntStatus
;
85 Irp
->IoStatus
.Information
= 0;
86 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
92 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchSysCtrl::"));
93 FreeBT_IoIncrement(deviceExtension
);
95 ntStatus
= WmiSystemControl(&deviceExtension
->WmiLibInfo
,
104 // This irp has been processed and may be completed or pending.
109 case IrpNotCompleted
:
111 // This irp has not been completed, but has been fully processed.
112 // we will complete it now
113 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
121 // This irp is either not a WMI irp or is a WMI irp targeted
122 // at a device lower in the stack.
123 IoSkipCurrentIrpStackLocation (Irp
);
124 ntStatus
= IoCallDriver(deviceExtension
->TopOfStackDeviceObject
, Irp
);
130 // We really should never get here, but if we do just forward....
132 IoSkipCurrentIrpStackLocation (Irp
);
133 ntStatus
= IoCallDriver(deviceExtension
->TopOfStackDeviceObject
, Irp
);
140 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchSysCtrl::"));
141 FreeBT_IoDecrement(deviceExtension
);
147 NTSTATUS
FreeBT_QueryWmiRegInfo(
148 IN PDEVICE_OBJECT DeviceObject
,
150 OUT PUNICODE_STRING InstanceName
,
151 OUT PUNICODE_STRING
*RegistryPath
,
152 OUT PUNICODE_STRING MofResourceName
,
153 OUT PDEVICE_OBJECT
*Pdo
159 This routine is a callback into the driver to retrieve the list of
160 guids or data blocks that the driver wants to register with WMI. This
161 routine may not pend or block. Driver should NOT call
166 DeviceObject is the device whose data block is being queried
168 *RegFlags returns with a set of flags that describe the guids being
169 registered for this device. If the device wants enable and disable
170 collection callbacks before receiving queries for the registered
171 guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
172 returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
173 the instance name is determined from the PDO associated with the
174 device object. Note that the PDO must have an associated devnode. If
175 WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
178 InstanceName returns with the instance name for the guids if
179 WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
180 caller will call ExFreePool with the buffer returned.
182 *RegistryPath returns with the registry path of the driver
184 *MofResourceName returns with the name of the MOF resource attached to
185 the binary file. If the driver does not have a mof resource attached
186 then this can be returned as NULL.
188 *Pdo returns with the device object for the PDO associated with this
189 device if the WMIREG_FLAG_INSTANCE_PDO flag is returned in
198 PDEVICE_EXTENSION deviceExtension
;
202 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_QueryWmiRegInfo: Entered\n"));
204 deviceExtension
= (PDEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
206 *RegFlags
= WMIREG_FLAG_INSTANCE_PDO
;
207 *RegistryPath
= &Globals
.FreeBT_RegistryPath
;
208 *Pdo
= deviceExtension
->PhysicalDeviceObject
;
209 RtlInitUnicodeString(MofResourceName
, MOFRESOURCENAME
);
211 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_QueryWmiRegInfo: Leaving\n"));
213 return STATUS_SUCCESS
;
217 NTSTATUS
FreeBT_QueryWmiDataBlock(
218 IN PDEVICE_OBJECT DeviceObject
,
221 IN ULONG InstanceIndex
,
222 IN ULONG InstanceCount
,
223 IN OUT PULONG InstanceLengthArray
,
224 IN ULONG OutBufferSize
,
231 This routine is a callback into the driver to query for the contents of
232 a data block. When the driver has finished filling the data block it
233 must call WmiCompleteRequest to complete the irp. The driver can
234 return STATUS_PENDING if the irp cannot be completed immediately.
238 DeviceObject is the device whose data block is being queried
240 Irp is the Irp that makes this request
242 GuidIndex is the index into the list of guids provided when the
245 InstanceIndex is the index that denotes which instance of the data block
248 InstanceCount is the number of instances expected to be returned for
251 InstanceLengthArray is a pointer to an array of ULONG that returns the
252 lengths of each instance of the data block. If this is NULL then
253 there was not enough space in the output buffer to fulfill the request
254 so the irp should be completed with the buffer needed.
256 OutBufferSize has the maximum size available to write the data
259 Buffer on return is filled with the returned data block
268 PDEVICE_EXTENSION deviceExtension
;
271 WCHAR modelName
[] = L
"Aishverya\0\0";
276 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_QueryWmiDataBlock: Entered\n"));
279 modelNameLen
= (wcslen(modelName
) + 1) * sizeof(WCHAR
);
281 // Only ever registers 1 instance per guid
282 ASSERT((InstanceIndex
== 0) && (InstanceCount
== 1));
284 deviceExtension
= (PDEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
287 case WMI_FREEBT_DRIVER_INFORMATION
:
288 size
= sizeof(ULONG
) + modelNameLen
+ sizeof(USHORT
);
289 if (OutBufferSize
< size
)
291 FreeBT_DbgPrint(3, ("FBTUSB: OutBuffer too small\n"));
292 ntStatus
= STATUS_BUFFER_TOO_SMALL
;
297 * (PULONG
) Buffer
= DebugLevel
;
298 Buffer
+= sizeof(ULONG
);
300 // put length of string ahead of string
301 *((PUSHORT
)Buffer
) = modelNameLen
;
302 Buffer
= (PUCHAR
)Buffer
+ sizeof(USHORT
);
303 RtlCopyBytes((PVOID
)Buffer
, (PVOID
)modelName
, modelNameLen
);
304 *InstanceLengthArray
= size
;
306 ntStatus
= STATUS_SUCCESS
;
310 ntStatus
= STATUS_WMI_GUID_NOT_FOUND
;
314 ntStatus
= WmiCompleteRequest(DeviceObject
,
320 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_QueryWmiDataBlock: Leaving\n"));
327 NTSTATUS
FreeBT_SetWmiDataItem(
328 IN PDEVICE_OBJECT DeviceObject
,
331 IN ULONG InstanceIndex
,
340 This routine is a callback into the driver to set for the contents of
341 a data block. When the driver has finished filling the data block it
342 must call WmiCompleteRequest to complete the irp. The driver can
343 return STATUS_PENDING if the irp cannot be completed immediately.
347 DeviceObject is the device whose data block is being queried
349 Irp is the Irp that makes this request
351 GuidIndex is the index into the list of guids provided when the
354 InstanceIndex is the index that denotes which instance of the data block
357 DataItemId has the id of the data item being set
359 BufferSize has the size of the data item passed
361 Buffer has the new values for the data item
370 PDEVICE_EXTENSION deviceExtension
;
376 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_SetWmiDataItem: Entered\n"));
378 deviceExtension
= (PDEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
383 case WMI_FREEBT_DRIVER_INFORMATION
:
386 if(BufferSize
== sizeof(ULONG
))
388 DebugLevel
= *((PULONG
)Buffer
);
389 ntStatus
= STATUS_SUCCESS
;
390 info
= sizeof(ULONG
);
396 ntStatus
= STATUS_INFO_LENGTH_MISMATCH
;
404 ntStatus
= STATUS_WMI_READ_ONLY
;
411 ntStatus
= STATUS_WMI_GUID_NOT_FOUND
;
415 ntStatus
= WmiCompleteRequest(DeviceObject
,
421 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_SetWmiDataItem: Leaving\n"));
427 NTSTATUS
FreeBT_SetWmiDataBlock(
428 IN PDEVICE_OBJECT DeviceObject
,
431 IN ULONG InstanceIndex
,
439 This routine is a callback into the driver to set the contents of
440 a data block. When the driver has finished filling the data block it
441 must call WmiCompleteRequest to complete the irp. The driver can
442 return STATUS_PENDING if the irp cannot be completed immediately.
446 DeviceObject is the device whose data block is being queried
448 Irp is the Irp that makes this request
450 GuidIndex is the index into the list of guids provided when the
453 InstanceIndex is the index that denotes which instance of the data block
456 BufferSize has the size of the data block passed
458 Buffer has the new values for the data block
462 PDEVICE_EXTENSION deviceExtension
;
468 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_SetWmiDataBlock: Entered\n"));
470 deviceExtension
= (PDEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
475 case WMI_FREEBT_DRIVER_INFORMATION
:
476 if(BufferSize
== sizeof(ULONG
))
478 DebugLevel
= *(PULONG
) Buffer
;
479 ntStatus
= STATUS_SUCCESS
;
480 info
= sizeof(ULONG
);
486 ntStatus
= STATUS_INFO_LENGTH_MISMATCH
;
493 ntStatus
= STATUS_WMI_GUID_NOT_FOUND
;
497 ntStatus
= WmiCompleteRequest(DeviceObject
,
503 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_SetWmiDataBlock: Leaving\n"));
509 PCHAR
WMIMinorFunctionString(UCHAR MinorFunction
)
511 switch (MinorFunction
)
513 case IRP_MN_CHANGE_SINGLE_INSTANCE
:
514 return "IRP_MN_CHANGE_SINGLE_INSTANCE\n";
516 case IRP_MN_CHANGE_SINGLE_ITEM
:
517 return "IRP_MN_CHANGE_SINGLE_ITEM\n";
519 case IRP_MN_DISABLE_COLLECTION
:
520 return "IRP_MN_DISABLE_COLLECTION\n";
522 case IRP_MN_DISABLE_EVENTS
:
523 return "IRP_MN_DISABLE_EVENTS\n";
525 case IRP_MN_ENABLE_COLLECTION
:
526 return "IRP_MN_ENABLE_COLLECTION\n";
528 case IRP_MN_ENABLE_EVENTS
:
529 return "IRP_MN_ENABLE_EVENTS\n";
531 case IRP_MN_EXECUTE_METHOD
:
532 return "IRP_MN_EXECUTE_METHOD\n";
534 case IRP_MN_QUERY_ALL_DATA
:
535 return "IRP_MN_QUERY_ALL_DATA\n";
537 case IRP_MN_QUERY_SINGLE_INSTANCE
:
538 return "IRP_MN_QUERY_SINGLE_INSTANCE\n";
541 return "IRP_MN_REGINFO\n";
544 return "IRP_MN_?????\n";