// wmi.c // // // Requires DDK Only // File created on 2/2/2005 // #include "pch.h" #ifdef CPR_WMI_TRACE #include "wmi.tmh" #endif #define WMI_SERIAL_PORT_NAME_INFORMATION 0 #define WMI_SERIAL_PORT_COMM_INFORMATION 1 #define WMI_SERIAL_PORT_HW_INFORMATION 2 #define WMI_SERIAL_PORT_PERF_INFORMATION 3 #define WMI_SERIAL_PORT_PROPERTIES 4 GUID CprSerialPortWmiNameGuid = SERIAL_PORT_WMI_NAME_GUID; GUID CprSerialPortWmiCommGuid = SERIAL_PORT_WMI_COMM_GUID; GUID CprSerialPortWmiHwGuid = SERIAL_PORT_WMI_HW_GUID; GUID CprSerailPortWmiPerfGuid = SERIAL_PORT_WMI_PERF_GUID; GUID CprSerialPortWmiPropertiesGuid = SERIAL_PORT_WMI_PROPERTIES_GUID; WMIGUIDREGINFO CprWmiGuidList[] = { { &CprSerialPortWmiNameGuid, 1, 0 }, { &CprSerialPortWmiCommGuid, 1, 0 }, { &CprSerialPortWmiHwGuid, 1, 0 }, { &CprSerailPortWmiPerfGuid, 1, 0 }, { &CprSerialPortWmiPropertiesGuid, 1, 0 } }; /////////////////////////////////////////////////////////////////////////////////////////////////// // CprWmiRegister // Registers as WMI provider. // // Arguments: // IN DeviceExtension // our device extension // // Return Value: // NT status code. // NTSTATUS CprWmiRegister( IN PCPR_DEVICE_EXTENSION DeviceExtension ) { NTSTATUS status; CprDebugPrint(DeviceExtension, DBG_WMI, DBG_INFO, __FUNCTION__"++"); DeviceExtension->WmiLibContext.GuidCount = sizeof(CprWmiGuidList)/sizeof(WMIGUIDREGINFO); DeviceExtension->WmiLibContext.GuidList = CprWmiGuidList; DeviceExtension->WmiLibContext.QueryWmiRegInfo = CprWmiQueryReginfo; DeviceExtension->WmiLibContext.QueryWmiDataBlock = CprWmiQueryDataBlock; DeviceExtension->WmiLibContext.SetWmiDataBlock = CprWmiSetDataBlock; DeviceExtension->WmiLibContext.SetWmiDataItem = CprWmiSetDataItem; DeviceExtension->WmiLibContext.ExecuteWmiMethod = CprWmiExecuteMethod; DeviceExtension->WmiLibContext.WmiFunctionControl = CprWmiFunctionControl; status = IoWMIRegistrationControl(DeviceExtension->DeviceObject, WMIREG_ACTION_REGISTER); CprDebugPrint1(DeviceExtension, DBG_WMI, DBG_INFO, __FUNCTION__"--. STATUS %x", status); return status; } /////////////////////////////////////////////////////////////////////////////////////////////////// // CprWmiDeRegister // Unregisters as WMI provider. // // Arguments: // IN DeviceExtension // our device extension // // Return Value: // NT status code. // NTSTATUS CprWmiDeRegister( IN PCPR_DEVICE_EXTENSION DeviceExtension ) { NTSTATUS status; CprDebugPrint(DeviceExtension, DBG_WMI, DBG_INFO, __FUNCTION__"++"); status = IoWMIRegistrationControl(DeviceExtension->DeviceObject, WMIREG_ACTION_DEREGISTER); CprDebugPrint1(DeviceExtension, DBG_WMI, DBG_INFO, __FUNCTION__"--. STATUS %x", status); return status; } /////////////////////////////////////////////////////////////////////////////////////////////////// // CprSystemControlDispatch // Dispatch routine for IRP_MJ_SYSTEM_CONTROL requests. // // Arguments: // IN DeviceObject // pointer to the device object for our device // // IN Irp // the IRP_MJ_SYSTEM_CONTROL IRP // // Return Value: // NT status code. // NTSTATUS CprSystemControlDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PCPR_DEVICE_EXTENSION deviceExtension; NTSTATUS status; PIO_STACK_LOCATION stack; SYSCTL_IRP_DISPOSITION disposition; __try { deviceExtension = (PCPR_DEVICE_EXTENSION)DeviceObject->DeviceExtension; CprDebugPrint1(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp); CprDumpIrp(Irp, deviceExtension); if (!CprAcquireRemoveLock(deviceExtension)) { status = STATUS_DELETE_PENDING; Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); CprDebugPrint2(deviceExtension, DBG_WMI, DBG_WARN, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status); return status; } status = WmiSystemControl(&deviceExtension->WmiLibContext, DeviceObject, Irp, &disposition); switch (disposition) { case IrpProcessed: break; case IrpNotCompleted: IoCompleteRequest(Irp, IO_NO_INCREMENT); break; case IrpNotWmi: case IrpForward: default: IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp); break; } CprReleaseRemoveLock(deviceExtension); CprDebugPrint2(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status); } __except( EXCEPTION_EXECUTE_HANDLER ) { status = STATUS_INTERNAL_ERROR; } return status; } NTSTATUS CprWmiQueryReginfo( IN PDEVICE_OBJECT DeviceObject, OUT PULONG RegFlags, OUT PUNICODE_STRING InstanceName, OUT PUNICODE_STRING* RegistryPath, OUT PUNICODE_STRING MofResourceName, OUT PDEVICE_OBJECT* Pdo ) { PCPR_DEVICE_EXTENSION deviceExtension; deviceExtension = (PCPR_DEVICE_EXTENSION)DeviceObject->DeviceExtension; CprDebugPrint(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"++"); *RegFlags = WMIREG_FLAG_INSTANCE_PDO; *RegistryPath = &g_Data.RegistryPath; *Pdo = deviceExtension->PhysicalDeviceObject; CprDebugPrint(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"--"); return STATUS_SUCCESS; } NTSTATUS CprWmiQueryDataBlock( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG InstanceCount, IN OUT PULONG InstanceLengthArray, IN ULONG BufferAvail, OUT PUCHAR Buffer ) { PCPR_DEVICE_EXTENSION deviceExtension; NTSTATUS status; ULONG size = 0; deviceExtension = (PCPR_DEVICE_EXTENSION)DeviceObject->DeviceExtension; CprDebugPrint1(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"++. Index %x", GuidIndex); switch(GuidIndex) { case WMI_SERIAL_PORT_NAME_INFORMATION: size = deviceExtension->WmiIdentifier.Length; if (BufferAvail < (size + sizeof(USHORT))) { size += sizeof(USHORT); status = STATUS_BUFFER_TOO_SMALL; break; } if (deviceExtension->WmiIdentifier.Buffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; break; } *(PUSHORT)Buffer = (USHORT)size; (PUCHAR)Buffer += sizeof(USHORT); RtlCopyMemory(Buffer, deviceExtension->WmiIdentifier.Buffer, size); size += sizeof(USHORT); *InstanceLengthArray = size; status = STATUS_SUCCESS; break; case WMI_SERIAL_PORT_COMM_INFORMATION: size = sizeof(SERIAL_WMI_COMM_DATA); if (BufferAvail < size) { status = STATUS_BUFFER_TOO_SMALL; break; } *InstanceLengthArray = size; *(PSERIAL_WMI_COMM_DATA)Buffer = deviceExtension->WmiCommData; status = STATUS_SUCCESS; break; case WMI_SERIAL_PORT_HW_INFORMATION: size = sizeof(SERIAL_WMI_HW_DATA); if (BufferAvail < size) { status = STATUS_BUFFER_TOO_SMALL; break; } *InstanceLengthArray = size; *(PSERIAL_WMI_HW_DATA)Buffer = deviceExtension->WmiHwData; status = STATUS_SUCCESS; break; case WMI_SERIAL_PORT_PERF_INFORMATION: size = sizeof(SERIAL_WMI_PERF_DATA); if (BufferAvail < size) { status = STATUS_BUFFER_TOO_SMALL; break; } *InstanceLengthArray = size; *(PSERIAL_WMI_PERF_DATA)Buffer = deviceExtension->WmiPerfData; status = STATUS_SUCCESS; break; case WMI_SERIAL_PORT_PROPERTIES: size = sizeof(SERIAL_COMMPROP) + sizeof(ULONG); if (BufferAvail < size) { status = STATUS_BUFFER_TOO_SMALL; break; } *InstanceLengthArray = size; //***************************************************************** //***************************************************************** // TODO: get port properties //***************************************************************** //***************************************************************** *((PULONG)(((PSERIAL_COMMPROP)Buffer)->ProvChar)) = 0; status = STATUS_SUCCESS; break; default: status = STATUS_WMI_GUID_NOT_FOUND; break; } status = WmiCompleteRequest( DeviceObject, Irp, status, size, IO_NO_INCREMENT ); CprDebugPrint1(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"--. STATUS %x", status); return status; } NTSTATUS CprWmiSetDataBlock( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG BufferSize, IN PUCHAR Buffer ) { PCPR_DEVICE_EXTENSION deviceExtension; NTSTATUS status; deviceExtension = (PCPR_DEVICE_EXTENSION)DeviceObject->DeviceExtension; CprDebugPrint1(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"++. Index %x", GuidIndex); switch(GuidIndex) { case WMI_SERIAL_PORT_NAME_INFORMATION: case WMI_SERIAL_PORT_COMM_INFORMATION: case WMI_SERIAL_PORT_HW_INFORMATION: case WMI_SERIAL_PORT_PERF_INFORMATION: case WMI_SERIAL_PORT_PROPERTIES: status = STATUS_INVALID_DEVICE_REQUEST; break; default: status = STATUS_WMI_GUID_NOT_FOUND; break; } status = WmiCompleteRequest( DeviceObject, Irp, status, 0, IO_NO_INCREMENT ); CprDebugPrint1(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"--. STATUS %x", status); return status; } NTSTATUS CprWmiSetDataItem( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG DataItemId, IN ULONG BufferSize, IN PUCHAR Buffer ) { PCPR_DEVICE_EXTENSION deviceExtension; NTSTATUS status; deviceExtension = (PCPR_DEVICE_EXTENSION)DeviceObject->DeviceExtension; CprDebugPrint1(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"++. Index %x", GuidIndex); switch(GuidIndex) { case WMI_SERIAL_PORT_NAME_INFORMATION: case WMI_SERIAL_PORT_COMM_INFORMATION: case WMI_SERIAL_PORT_HW_INFORMATION: case WMI_SERIAL_PORT_PERF_INFORMATION: case WMI_SERIAL_PORT_PROPERTIES: status = STATUS_INVALID_DEVICE_REQUEST; break; default: status = STATUS_WMI_GUID_NOT_FOUND; break; } status = WmiCompleteRequest( DeviceObject, Irp, status, 0, IO_NO_INCREMENT ); CprDebugPrint1(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"--. STATUS %x", status); return status; } NTSTATUS CprWmiExecuteMethod( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG MethodId, IN ULONG InBufferSize, IN ULONG OutBufferSize, IN OUT PUCHAR Buffer ) { PCPR_DEVICE_EXTENSION deviceExtension; NTSTATUS status; deviceExtension = (PCPR_DEVICE_EXTENSION)DeviceObject->DeviceExtension; CprDebugPrint1(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"++. Index %x", GuidIndex); switch(GuidIndex) { case WMI_SERIAL_PORT_NAME_INFORMATION: case WMI_SERIAL_PORT_COMM_INFORMATION: case WMI_SERIAL_PORT_HW_INFORMATION: case WMI_SERIAL_PORT_PERF_INFORMATION: case WMI_SERIAL_PORT_PROPERTIES: status = STATUS_INVALID_DEVICE_REQUEST; break; default: status = STATUS_WMI_GUID_NOT_FOUND; break; } status = WmiCompleteRequest( DeviceObject, Irp, status, 0, IO_NO_INCREMENT ); CprDebugPrint1(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"--. STATUS %x", status); return status; } NTSTATUS CprWmiFunctionControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN WMIENABLEDISABLECONTROL Function, IN BOOLEAN Enable ) { PCPR_DEVICE_EXTENSION deviceExtension; NTSTATUS status; deviceExtension = (PCPR_DEVICE_EXTENSION)DeviceObject->DeviceExtension; CprDebugPrint1(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"++. Index %x", GuidIndex); switch(GuidIndex) { case WMI_SERIAL_PORT_NAME_INFORMATION: case WMI_SERIAL_PORT_COMM_INFORMATION: case WMI_SERIAL_PORT_HW_INFORMATION: case WMI_SERIAL_PORT_PERF_INFORMATION: case WMI_SERIAL_PORT_PROPERTIES: status = STATUS_INVALID_DEVICE_REQUEST; break; default: status = STATUS_WMI_GUID_NOT_FOUND; break; } status = WmiCompleteRequest( DeviceObject, Irp, status, 0, IO_NO_INCREMENT ); CprDebugPrint1(deviceExtension, DBG_WMI, DBG_TRACE, __FUNCTION__"--. STATUS %x", status); return status; }