#ifdef __cplusplus
extern "C"
{
#endif
#include "WdmDriver.h"
#include <wmistr.h>
GUID WMI_GUID = {0x87472ba1,0x61bc,0x11d2,{0xb6,0x77,0x0,0xc0,0xdf,0xe4,0xc1,0xf3}};
#ifdef __cplusplus
}
#endif
WMIGUIDREGINFO GuidList[1] =
{
{&WMI_GUID,1,0}
};
UNICODE_STRING servkey;
void DeregisterWmi(IN PDEVICE_OBJECT fdo)
{
IoWMIRegistrationControl(fdo, WMIREG_ACTION_DEREGISTER);
}
NTSTATUS WdmSystemControl(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
PWDM_DEVICE_EXTENSION dx = (PWDM_DEVICE_EXTENSION)fdo->DeviceExtension;
NTSTATUS status;
SYSCTL_IRP_DISPOSITION disposition;
status = WmiSystemControl(&dx->WmiLibInfo, fdo, Irp ,&disposition);
switch(disposition)
{
case IrpProcessed:
break;
case IrpNotCompleted:
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case IrpForward:
case IrpNotWmi:
default:
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(dx->NextDevice,Irp);
}
return status;
}
extern UCHAR ShareMemory[];
NTSTATUS FailWMIRequest(IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN ULONG GuidIndex)
{
PWDM_DEVICE_EXTENSION dx = (PWDM_DEVICE_EXTENSION)fdo->DeviceExtension;
NTSTATUS status;
if (GuidIndex == 0)
status = STATUS_INVALID_DEVICE_REQUEST;
else
status = STATUS_WMI_GUID_NOT_FOUND;
status = WmiCompleteRequest(fdo, Irp, status, 0, IO_NO_INCREMENT);
return status;
}
NTSTATUS SetDataItem(IN PDEVICE_OBJECT fdo,
IN PIRP Irp,
IN ULONG GuidIndex,
IN ULONG InstanceIndex,
IN ULONG DataItemId,
IN ULONG BufferSize,
IN PUCHAR PBuffer)
{
return FailWMIRequest(fdo,Irp,GuidIndex);
}
NTSTATUS SetDataBlock(IN PDEVICE_OBJECT fdo,
IN PIRP Irp,
IN ULONG GuidIndex,
IN ULONG InstanceIndex,
IN ULONG BufferSize,
IN PUCHAR PBuffer)
{
return FailWMIRequest(fdo,Irp,GuidIndex);
}
NTSTATUS QueryDataBlock(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)
{
PWDM_DEVICE_EXTENSION dx = (PWDM_DEVICE_EXTENSION)fdo->DeviceExtension;
NTSTATUS status;
ULONG size = 0;
switch (GuidIndex)
{
case 0:
{
ULONG SymLinkNameLen = dx->ifSymLinkName.Length;
size = sizeof(ULONG) + sizeof(USHORT) + SymLinkNameLen;
if (OutBufferSize < size)
{
status = STATUS_BUFFER_TOO_SMALL;
break;
}
*(ULONG *)PBuffer = *(ULONG *)ShareMemory;
(UCHAR *)PBuffer += sizeof (ULONG);
*(ULONG *)PBuffer = *(USHORT *)SymLinkNameLen;
(UCHAR *)PBuffer += sizeof (ULONG);
RtlCopyMemory(PBuffer, dx->ifSymLinkName.Buffer,SymLinkNameLen);
*InstanceLengthArray = size;
status = STATUS_SUCCESS;
break;
}
default:
status=STATUS_WMI_GUID_NOT_FOUND;
break;
}
status = WmiCompleteRequest(fdo, Irp, status, size, IO_NO_INCREMENT);
return status;
}
NTSTATUS QueryRegInfo(IN PDEVICE_OBJECT fdo,
OUT PULONG PRegFlags,
OUT PUNICODE_STRING PInstanceName,
OUT PUNICODE_STRING *PRegistryPath,
OUT PUNICODE_STRING MofResourceName,
OUT PDEVICE_OBJECT *pdo)
{
PWDM_DEVICE_EXTENSION dx = (PWDM_DEVICE_EXTENSION)fdo->DeviceExtension;
*PRegFlags = WMIREG_FLAG_INSTANCE_PDO;
*PRegistryPath = &servkey;
RtlInitUnicodeString(MofResourceName, L"MofResource");
*pdo = dx->pdo;
return STATUS_SUCCESS;
}
void RegisterWmi(IN PDEVICE_OBJECT fdo)
{
PWDM_DEVICE_EXTENSION dx = (PWDM_DEVICE_EXTENSION)fdo->DeviceExtension;
dx->WmiLibInfo.GuidCount = 1;
dx->WmiLibInfo.GuidList = GuidList;
dx->WmiLibInfo.QueryWmiRegInfo = QueryRegInfo;
dx->WmiLibInfo.QueryWmiDataBlock = QueryDataBlock;
dx->WmiLibInfo.SetWmiDataBlock = SetDataBlock;
dx->WmiLibInfo.SetWmiDataItem = SetDataItem;
dx->WmiLibInfo.ExecuteWmiMethod = NULL;
dx->WmiLibInfo.WmiFunctionControl = NULL;
IoWMIRegistrationControl(fdo, WMIREG_ACTION_REGISTER);
}