status = STATUS_SUCCESS;
break;
}
default:
DebugPrintMsg('QueryWmiDataBlock: Bad GUID index');
status = STATUS_WMI_GUID_NOT_FOUND;
break;
}
return WmiCompleteRequest(fdo, Irp, status, size, IO_NO_INCREMENT);
}
The Wdm3
Listing 12.7 SetWmiDataBlock routine
NTSTATUS SetWmiDataBlock(IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG BufferSize, IN PUCHAR PBuffer) {
DebugPrint('SetWmiDataBlock: GuidIndex %d, InstanceIndex %d, BufferSize %d',
GuidIndex,Instancelndex,BufferSize);
PWDM3_DEVICE_EXTENSION dx = (PWDM3_DEVICE_EXTENSION)fdo->DeviceExterision;
if (GuidIndex==GUID_POWER_DEVICE_ENABLE_INDEX) // MSPower_DeviceEnable
{
if (BufferSize<sizeof(BOOLEAN))
return WmiCompleteRequest(fdo, Irp, STATUS_BUFFER_TOO_SMALL, 0, IO_NO_INCREMENT);
// Get Enable property into IdlePowerDownEnable
dx->IdlePowerDownEnable = *(BOOLEAN*)PBuffer;
// Action IdlePowerDownEnable
if (dx->IdlePowerDownEnable) {
DebugPrintMsg('SetWmiDataBlock: Enabling power down');
// Enable power down idling
if (dx->PowerIdleCounter==NULL) dx->PowerIdleCounter = PoRegisterDeviceForIdleDetection(dx->pdo, 30, 60, PowerDeviceD3);
} else {
DebugPrintMsg('SetWmiDataBlock: Disabling power down');
// Disable power down idling
if (dx->PowerIdleCounter!=NULL) dx->PowerIdleCounter = PoRegisterDeviceForIdleDetection(dx->pdo, 0, 0, PowerDeviceD3);
if (dx->PowerState>PowerDeviceD0) {
DebugPrintMsg('SetWmiDataBlock: Disabling power down: power up');
SendDeviceSetPower(dx, PowerDeviceD0);
}
}
return WmiCompleteRequest( fdo, Irp, STATUS_SUCCESS, 0, IO_NO_INCREMENT);
}
return FailWMIRequest(fdo, Irp, GuidIndex);
}
A
Listing 12.8 SetWmiDataItem routine
NTSTATUS SetWmiDataItem(IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG DataltemId, IN ULONG BufferSize, IN PUCHAR PBuffer) {
DebugPrint('SetWmiDataItem: GuidIndex %d, InstanceIndex %d, DataItemId %d, BufferSize %d',
GuidIndex.InstanceIndex, DataItemId, BufferSize);
return FailWMIRequest(fdo, Irp, GuidIndex);
}
NTSTATUS FailWMIRequest(IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN ULONG GuidIndex) {
DebugPrint('FailWMIRequest: GuidIndex %d',GuidIndex);
NTSTATUS status;
if (GuidIndex<0 || GuidIndex>=GUID_COUNT) status = STATUS_WMI_GUID_NOT_FOUND;
else status = STATUS_INVALID_DEVICE_REQUEST;
status = WmiCompleteRequest(fdo, Irp, status, 0, IO_NO_INCREMENT);
return status;
}
Listing 12.9 shows how I think the optional
Listing 12.9 ExecuteWmiMethod routine
NTSTATUS ExecuteWmiMethod(IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG MethodId, IN ULONG InBufferSize, IN ULONG OutBufferSize, IN OUT PUCHAR Buffer) {
DebugPrint('ExecuteWmiMethod: GuidIndex %d, InstanceIndex %d, '
'MethodId %d, InBufferSize %d OutBufferSize %d',
GuidIndex, InstanceIndex, MethodId, InBufferSize, OutBufferSize);
PWOM3_DEVICE_EXTENSION dx = (PWDM3_DEVICE_EXTENSION)fdo->DeviceExtension;
if (GuidIndex==WDM3_WMI_GUID_INDEX && MethodId==0) {
DebugPrintMsg('ExecuteWmiMethod: PowerDown method');
// Power Down
if (dx->PowerState<PowerDeviceD3) SendDeviceSetPower(dx, PowerDeviceD3);
return WmiCompleteRequest(fdo, Irp, STATUS_SUCCESS, 0, IO_NO_INCREMENT);
}
return FailWMIRequest(fdo, Irp, GuidIndex);
}
To fire a WMI event, simply call
The Wdm3 driver provides a helper function
A user application must ask for events first by setting an Enable flag. This request arrives at the driver in its
The W
Listing 12.10 Wdm3FireEvent and WmiFunctionControl routines