📄 classwmi.c
字号:
if (bufferSize < sizeof(WNODE_ALL_DATA))
{
bufferAvail = 0;
} else {
bufferAvail = bufferSize - sizeof(WNODE_ALL_DATA);
}
wnode->DataBlockOffset = sizeof(WNODE_ALL_DATA);
status = classWmiInfo->ClassQueryWmiDataBlock(
DeviceObject,
Irp,
guidIndex,
bufferAvail,
buffer + sizeof(WNODE_ALL_DATA));
break;
}
case IRP_MN_QUERY_SINGLE_INSTANCE:
{
PWNODE_SINGLE_INSTANCE wnode;
ULONG dataBlockOffset;
wnode = (PWNODE_SINGLE_INSTANCE)buffer;
dataBlockOffset = wnode->DataBlockOffset;
status = classWmiInfo->ClassQueryWmiDataBlock(
DeviceObject,
Irp,
guidIndex,
bufferSize - dataBlockOffset,
(PUCHAR)wnode + dataBlockOffset);
break;
}
case IRP_MN_CHANGE_SINGLE_INSTANCE:
{
PWNODE_SINGLE_INSTANCE wnode;
wnode = (PWNODE_SINGLE_INSTANCE)buffer;
status = classWmiInfo->ClassSetWmiDataBlock(
DeviceObject,
Irp,
guidIndex,
wnode->SizeDataBlock,
(PUCHAR)wnode + wnode->DataBlockOffset);
break;
}
case IRP_MN_CHANGE_SINGLE_ITEM:
{
PWNODE_SINGLE_ITEM wnode;
wnode = (PWNODE_SINGLE_ITEM)buffer;
status = classWmiInfo->ClassSetWmiDataItem(
DeviceObject,
Irp,
guidIndex,
wnode->ItemId,
wnode->SizeDataItem,
(PUCHAR)wnode + wnode->DataBlockOffset);
break;
}
case IRP_MN_EXECUTE_METHOD:
{
PWNODE_METHOD_ITEM wnode;
wnode = (PWNODE_METHOD_ITEM)buffer;
status = classWmiInfo->ClassExecuteWmiMethod(
DeviceObject,
Irp,
guidIndex,
wnode->MethodId,
wnode->SizeDataBlock,
bufferSize - wnode->DataBlockOffset,
buffer + wnode->DataBlockOffset);
break;
}
case IRP_MN_ENABLE_EVENTS:
{
status = classWmiInfo->ClassWmiFunctionControl(
DeviceObject,
Irp,
guidIndex,
EventGeneration,
TRUE);
break;
}
case IRP_MN_DISABLE_EVENTS:
{
status = classWmiInfo->ClassWmiFunctionControl(
DeviceObject,
Irp,
guidIndex,
EventGeneration,
FALSE);
break;
}
case IRP_MN_ENABLE_COLLECTION:
{
status = classWmiInfo->ClassWmiFunctionControl(
DeviceObject,
Irp,
guidIndex,
DataBlockCollection,
TRUE);
break;
}
case IRP_MN_DISABLE_COLLECTION:
{
status = classWmiInfo->ClassWmiFunctionControl(
DeviceObject,
Irp,
guidIndex,
DataBlockCollection,
FALSE);
break;
}
default:
{
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
}
return(status);
} // end ClassSystemControl()
/*++////////////////////////////////////////////////////////////////////////////
ClassWmiCompleteRequest()
Routine Description:
This routine will do the work of completing a WMI irp. Depending upon the
the WMI request this routine will fixup the returned WNODE appropriately.
NOTE: This routine assumes that the ClassRemoveLock is held and it will
release it.
Arguments:
DeviceObject - Supplies a pointer to the device object for this request.
Irp - Supplies the Irp making the request.
Status - Status to complete the irp with. STATUS_BUFFER_TOO_SMALL is used
to indicate that more buffer is required for the data requested.
BufferUsed - number of bytes of actual data to return (not including WMI
specific structures)
PriorityBoost - priority boost to pass to ClassCompleteRequest
Return Value:
status
--*/
SCSIPORT_API
NTSTATUS
ClassWmiCompleteRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN NTSTATUS Status,
IN ULONG BufferUsed,
IN CCHAR PriorityBoost
)
{
PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
UCHAR MinorFunction;
PUCHAR buffer;
ULONG retSize;
UCHAR minorFunction;
ULONG bufferSize;
minorFunction = irpStack->MinorFunction;
buffer = (PUCHAR)irpStack->Parameters.WMI.Buffer;
bufferSize = irpStack->Parameters.WMI.BufferSize;
switch(minorFunction)
{
case IRP_MN_QUERY_ALL_DATA:
{
PWNODE_ALL_DATA wnode;
PWNODE_TOO_SMALL wnodeTooSmall;
ULONG bufferNeeded;
wnode = (PWNODE_ALL_DATA)buffer;
bufferNeeded = sizeof(WNODE_ALL_DATA) + BufferUsed;
if (NT_SUCCESS(Status))
{
retSize = bufferNeeded;
wnode->WnodeHeader.BufferSize = bufferNeeded;
KeQuerySystemTime(&wnode->WnodeHeader.TimeStamp);
wnode->WnodeHeader.Flags |= WNODE_FLAG_FIXED_INSTANCE_SIZE;
wnode->FixedInstanceSize = BufferUsed;
wnode->InstanceCount = 1;
} else if (Status == STATUS_BUFFER_TOO_SMALL) {
wnodeTooSmall = (PWNODE_TOO_SMALL)wnode;
wnodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
wnodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
wnodeTooSmall->SizeNeeded = sizeof(WNODE_ALL_DATA) + BufferUsed;
retSize = sizeof(WNODE_TOO_SMALL);
Status = STATUS_SUCCESS;
} else {
retSize = 0;
}
break;
}
case IRP_MN_QUERY_SINGLE_INSTANCE:
{
PWNODE_SINGLE_INSTANCE wnode;
PWNODE_TOO_SMALL wnodeTooSmall;
ULONG bufferNeeded;
wnode = (PWNODE_SINGLE_INSTANCE)buffer;
bufferNeeded = wnode->DataBlockOffset + BufferUsed;
if (NT_SUCCESS(Status))
{
retSize = bufferNeeded;
wnode->WnodeHeader.BufferSize = bufferNeeded;
KeQuerySystemTime(&wnode->WnodeHeader.TimeStamp);
wnode->SizeDataBlock = BufferUsed;
} else if (Status == STATUS_BUFFER_TOO_SMALL) {
wnodeTooSmall = (PWNODE_TOO_SMALL)wnode;
wnodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
wnodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
wnodeTooSmall->SizeNeeded = bufferNeeded;
retSize = sizeof(WNODE_TOO_SMALL);
Status = STATUS_SUCCESS;
} else {
retSize = 0;
}
break;
}
case IRP_MN_EXECUTE_METHOD:
{
PWNODE_METHOD_ITEM wnode;
PWNODE_TOO_SMALL wnodeTooSmall;
ULONG bufferNeeded;
wnode = (PWNODE_METHOD_ITEM)buffer;
bufferNeeded = wnode->DataBlockOffset + BufferUsed;
if (NT_SUCCESS(Status))
{
retSize = bufferNeeded;
wnode->WnodeHeader.BufferSize = bufferNeeded;
KeQuerySystemTime(&wnode->WnodeHeader.TimeStamp);
wnode->SizeDataBlock = BufferUsed;
} else if (Status == STATUS_BUFFER_TOO_SMALL) {
wnodeTooSmall = (PWNODE_TOO_SMALL)wnode;
wnodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
wnodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
wnodeTooSmall->SizeNeeded = bufferNeeded;
retSize = sizeof(WNODE_TOO_SMALL);
Status = STATUS_SUCCESS;
} else {
retSize = 0;
}
break;
}
default:
{
//
// All other requests don't return any data
retSize = 0;
break;
}
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = retSize;
ClassReleaseRemoveLock(DeviceObject, Irp);
ClassCompleteRequest(DeviceObject, Irp, PriorityBoost);
return(Status);
} // end ClassWmiCompleteRequest()
/*++////////////////////////////////////////////////////////////////////////////
ClassWmiFireEvent()
Routine Description:
This routine will fire a WMI event using the data buffer passed. This
routine may be called at or below DPC level
Arguments:
DeviceObject - Supplies a pointer to the device object for this event
Guid is pointer to the GUID that represents the event
InstanceIndex is the index of the instance of the event
EventDataSize is the number of bytes of data that is being fired with
with the event
EventData is the data that is fired with the events. This may be NULL
if there is no data associated with the event
Return Value:
status
--*/
NTSTATUS
ClassWmiFireEvent(
IN PDEVICE_OBJECT DeviceObject,
IN LPGUID Guid,
IN ULONG InstanceIndex,
IN ULONG EventDataSize,
IN PVOID EventData
)
{
ULONG sizeNeeded;
PWNODE_SINGLE_INSTANCE event;
NTSTATUS status;
if (EventData == NULL)
{
EventDataSize = 0;
}
sizeNeeded = sizeof(WNODE_SINGLE_INSTANCE) + EventDataSize;
event = ExAllocatePoolWithTag(NonPagedPool, sizeNeeded, CLASS_TAG_WMI);
if (event != NULL)
{
RtlZeroMemory(event, sizeNeeded);
event->WnodeHeader.Guid = *Guid;
event->WnodeHeader.ProviderId = IoWMIDeviceObjectToProviderId(DeviceObject);
event->WnodeHeader.BufferSize = sizeNeeded;
event->WnodeHeader.Flags = WNODE_FLAG_SINGLE_INSTANCE |
WNODE_FLAG_EVENT_ITEM |
WNODE_FLAG_STATIC_INSTANCE_NAMES;
KeQuerySystemTime(&event->WnodeHeader.TimeStamp);
event->InstanceIndex = InstanceIndex;
event->SizeDataBlock = EventDataSize;
event->DataBlockOffset = sizeof(WNODE_SINGLE_INSTANCE);
if (EventData != NULL)
{
RtlCopyMemory( &event->VariableData, EventData, EventDataSize);
}
status = IoWMIWriteEvent(event);
if (! NT_SUCCESS(status))
{
ExFreePool(event);
}
} else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
return(status);
} // end ClassWmiFireEvent()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -