// we will complete it now
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case IrpForward: case IrpNotWmi:
// This irp is either not a WMI irp or is a WMI irp targetted
// at a device lower in the stack.
IoSkipCurrentIrpStacktocation(Irp);
status = IoCallDriver(dx->NextStackDevice, Irp);
break;
default:
DebugPrint('Wdm3SystemControl bad disposition %d',disposition);
// ASSERT(FALSE);
}
return status;
}
At a minimum, you should write
The Wdm3
Return your MOF resource name and your registry path.
If you are writing a WDM driver, you will usually set the WMIREG_FLAG_INSTANCE_PD0 flag and pass the device's PDO. See the DDK documentation for details of other flags that you can set.
Listing 12.5 QueryWmiRegInfo routine
#define MofResourceNameText L'MofResource'
NTSTATUS QueryWmiRegInfo(IN PDEVICE_OBJECT fdo, OUT PULONG PRegFlags, OUT PUNICODE_STRING PInstanceName, OUT PUNICODE_STRING *PRegistryPath, OUT PUNICODE_STRING MofResourceName, OUT PDEVICE_OBJECT *Pdo) {
DebugPrintMsg('QueryWmiRegInfo');
PWDM3_DEVICE_EXTENSION dx = (PWDM3_DEVICE_EXTENSION)fdo->DeviceExtension;
*PRegFlags = WMIREG_FLAG_INSTANCE_PDO;
*PRegistryPath = &Wdm3RegistryPath;
RtlInitUnicodeString( MofResourceName, MofResourceNameText);
*Pdo = dx->pdo;
return STATUS_SUCCESS;
}
A
In the buffer, each instance's data should be aligned on an 8-byte boundary. The actual data should correspond to the class MOF definition. A MOF string should be returned as a counted Unicode, MOF Boolean returned as a BOOLEAN, MOF uint32 returned as a ULONG, MOF uint64 as a ULONGLONG, etc.
Listing 12.6 shows how the Wdm3
Listing 12.6 QueryWmiDataBlock routine
NTSTATUS QueryWmiDataBlock(IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG InstanceCount, IN OUT PULONG InstanceLengthArray, IN ULONG OutBufferSize, OUT PUCHAR PBuffer) {
DebugPrint('QueryWmiDataBlock: GuidIndex %d, InstanceIndex %d, '
'InstanceCount %d, OutBufferSize %d',
GuidIndex,InstanceIndex, InstanceCount, OutBufferSize);
PWDM3_DEVICE_EXTENSI0N dx = (PWDK3_DEVICE_EXTENSION)fdo->DeviceExtension;
NTSTATUS status;
ULONG size =0;
switch( GuidIndex) {
case WDM3_WMI_GUID_INDEX: // Wdm3Information
{
ULONG SymLinkNameLen = dx->ifSymLinkName.Length;
size = sizeof(ULONG)+sizeof(ULONG)+SymLinkNameLen+sizeof(USHORT);
// Check output buffer size
if (OutBufferSize<size) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
// Store uint32 BufferLen
*(ULONG *)PBuffer = BufferSize;
PBuffer +-= sizeof (ULONG);
// Store uint32 BufferFirstWord
ULONG FirstWord = 0;
if (Buffer!=NULL && BufferSize>=4) FirstWord = *(ULONG*)Buffer;
*(ULONG *)PBuffer = FirstWord;
PBuffer += sizeof(ULONG);
// Store string SymbolicLinkName as counted Unicode
*(USHORT *)PBuffer = (USHORT)SymLinkNameLen;
PBuffer += sizeof(USHORT);
RtlCopyMemory(PBuffer, dx->ifSymLinkName.Buffer, SymLinkNameLen);
// Store total size
*InstanceLengthArray = size;
status = STATUS_SUCCESS;
break;
}
case GUID_POWER_DEVICE_ENABLE_INDEX: // MSPower_DeviceEnable
{
size = sizeof(BOOLEAN);
// Check output buffer size
if (OutBufferSize<size) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
// Store boolean IdlePowerDownEnable in Enable property
*(BOOLEAN*)PBuffer = dx->IdlePowerDownEnable;
// Store total size
*InstanceLengthArray = size;