Thread: [Com0com-cvs] com0com/sys wmi.c,NONE,1.1
The virtual serial port driver for Windows.
Brought to you by:
vfrolov
From: Vyacheslav F. <vf...@us...> - 2006-08-23 13:10:03
|
Update of /cvsroot/com0com/com0com/sys In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv26152 Added Files: wmi.c Log Message: Initial revision --- NEW FILE: wmi.c --- /* * $Id: wmi.c,v 1.1 2006/08/23 13:09:55 vfrolov Exp $ * * Copyright (c) 2006 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * $Log: wmi.c,v $ * Revision 1.1 2006/08/23 13:09:55 vfrolov * Initial revision * * */ #include "precomp.h" #include <wmidata.h> #include <wmilib.h> #pragma warning(push, 3) #include <wmistr.h> #pragma warning(pop) #include "strutils.h" #include "commprop.h" /* * FILE_ID used by HALT_UNLESS to put it on BSOD */ #define FILE_ID 0xB GUID guidWmiPortName = SERIAL_PORT_WMI_NAME_GUID; GUID guidWmiPortComm = SERIAL_PORT_WMI_COMM_GUID; GUID guidWmiPortHW = SERIAL_PORT_WMI_HW_GUID; GUID guidWmiPortPerf = SERIAL_PORT_WMI_PERF_GUID; GUID guidWmiPortProperties = SERIAL_PORT_WMI_PROPERTIES_GUID; #define COC_WMI_PORT_NAME 0 #define COC_WMI_PORT_COMM 1 #define COC_WMI_PORT_HW 2 #define COC_WMI_PORT_PERF 3 #define COC_WMI_PORT_PROPERTIES 4 #define COC_WMI_LIST_SIZE 5 WMIGUIDREGINFO guidWmiList[COC_WMI_LIST_SIZE] = { {&guidWmiPortName, 1, 0}, {&guidWmiPortComm, 1, 0}, {&guidWmiPortHW, 1, 0}, {&guidWmiPortPerf, 1, 0}, {&guidWmiPortProperties, 1, 0}, }; NTSTATUS QueryWmiRegInfo( IN PDEVICE_OBJECT pDevObj, OUT PULONG pRegFlags, OUT PUNICODE_STRING pInstanceName, OUT PUNICODE_STRING *ppRegistryPath, OUT PUNICODE_STRING pMofResourceName, OUT PDEVICE_OBJECT *ppPhDevObj) { PC0C_FDOPORT_EXTENSION pDevExt = (PC0C_FDOPORT_EXTENSION)pDevObj->DeviceExtension; UNREFERENCED_PARAMETER(pInstanceName); UNREFERENCED_PARAMETER(pMofResourceName); Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"QueryWmiRegInfo"); *ppRegistryPath = &c0cGlobal.registryPath; *pRegFlags = WMIREG_FLAG_INSTANCE_PDO; *ppPhDevObj = pDevExt->pPhDevObj; return STATUS_SUCCESS; } NTSTATUS QueryWmiDataBlock( IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN ULONG guidIndex, IN ULONG instanceIndex, IN ULONG instanceCount, IN OUT PULONG pInstanceLengthArray, IN ULONG bufSize, OUT PUCHAR pBuf) { NTSTATUS status; ULONG size; KIRQL oldIrql; PC0C_FDOPORT_EXTENSION pDevExt = (PC0C_FDOPORT_EXTENSION)pDevObj->DeviceExtension; UNREFERENCED_PARAMETER(instanceIndex); UNREFERENCED_PARAMETER(instanceCount); switch(guidIndex) { case COC_WMI_PORT_NAME: Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"QueryWmiDataBlock PORT_NAME"); size = wcslen(pDevExt->portName) * sizeof(pDevExt->portName[0]); if (bufSize < (size + sizeof(USHORT))) { size += sizeof(USHORT); status = STATUS_BUFFER_TOO_SMALL; break; } *(USHORT *)pBuf = (USHORT)size; RtlCopyMemory(pBuf + sizeof(USHORT), pDevExt->portName, size); size += sizeof(USHORT); status = STATUS_SUCCESS; break; case COC_WMI_PORT_COMM: Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"QueryWmiDataBlock PORT_COMM"); size = sizeof(SERIAL_WMI_COMM_DATA); if (bufSize < size) { status = STATUS_BUFFER_TOO_SMALL; break; } KeAcquireSpinLock(&pDevExt->controlLock, &oldIrql); ((PSERIAL_WMI_COMM_DATA)pBuf)->BaudRate = pDevExt->baudRate.BaudRate; ((PSERIAL_WMI_COMM_DATA)pBuf)->BitsPerByte = pDevExt->lineControl.WordLength; ((PSERIAL_WMI_COMM_DATA)pBuf)->ParityCheckEnable = TRUE; switch (pDevExt->lineControl.Parity) { default: case NO_PARITY: ((PSERIAL_WMI_COMM_DATA)pBuf)->Parity = SERIAL_WMI_PARITY_NONE; ((PSERIAL_WMI_COMM_DATA)pBuf)->ParityCheckEnable = FALSE; break; case ODD_PARITY: ((PSERIAL_WMI_COMM_DATA)pBuf)->Parity = SERIAL_WMI_PARITY_ODD; break; case EVEN_PARITY: ((PSERIAL_WMI_COMM_DATA)pBuf)->Parity = SERIAL_WMI_PARITY_EVEN; break; case MARK_PARITY: ((PSERIAL_WMI_COMM_DATA)pBuf)->Parity = SERIAL_WMI_PARITY_MARK; break; case SPACE_PARITY: ((PSERIAL_WMI_COMM_DATA)pBuf)->Parity = SERIAL_WMI_PARITY_SPACE; break; } switch (pDevExt->lineControl.StopBits) { default: case STOP_BIT_1: ((PSERIAL_WMI_COMM_DATA)pBuf)->StopBits = SERIAL_WMI_STOP_1; break; case STOP_BITS_1_5: ((PSERIAL_WMI_COMM_DATA)pBuf)->StopBits = SERIAL_WMI_STOP_1_5; break; case STOP_BITS_2: ((PSERIAL_WMI_COMM_DATA)pBuf)->StopBits = SERIAL_WMI_STOP_2; break; } KeReleaseSpinLock(&pDevExt->controlLock, oldIrql); KeAcquireSpinLock(pDevExt->pIoPortLocal->pIoLock, &oldIrql); ((PSERIAL_WMI_COMM_DATA)pBuf)->XoffCharacter = pDevExt->pIoPortLocal->specialChars.XoffChar; ((PSERIAL_WMI_COMM_DATA)pBuf)->XoffXmitThreshold = pDevExt->pIoPortLocal->handFlow.XoffLimit; ((PSERIAL_WMI_COMM_DATA)pBuf)->XonCharacter = pDevExt->pIoPortLocal->specialChars.XonChar; ((PSERIAL_WMI_COMM_DATA)pBuf)->XonXmitThreshold = pDevExt->pIoPortLocal->handFlow.XonLimit; KeReleaseSpinLock(pDevExt->pIoPortLocal->pIoLock, oldIrql); ((PSERIAL_WMI_COMM_DATA)pBuf)->MaximumBaudRate = 128L * 1024L; ((PSERIAL_WMI_COMM_DATA)pBuf)->MaximumOutputBufferSize = (ULONG)-1L; ((PSERIAL_WMI_COMM_DATA)pBuf)->MaximumInputBufferSize = (ULONG)-1L; ((PSERIAL_WMI_COMM_DATA)pBuf)->Support16BitMode = FALSE; ((PSERIAL_WMI_COMM_DATA)pBuf)->SupportDTRDSR = TRUE; ((PSERIAL_WMI_COMM_DATA)pBuf)->SupportIntervalTimeouts = TRUE; ((PSERIAL_WMI_COMM_DATA)pBuf)->SupportParityCheck = TRUE; ((PSERIAL_WMI_COMM_DATA)pBuf)->SupportRTSCTS = TRUE; ((PSERIAL_WMI_COMM_DATA)pBuf)->SupportXonXoff = TRUE; ((PSERIAL_WMI_COMM_DATA)pBuf)->SettableBaudRate = TRUE; ((PSERIAL_WMI_COMM_DATA)pBuf)->SettableDataBits = TRUE; ((PSERIAL_WMI_COMM_DATA)pBuf)->SettableFlowControl = TRUE; ((PSERIAL_WMI_COMM_DATA)pBuf)->SettableParity = TRUE; ((PSERIAL_WMI_COMM_DATA)pBuf)->SettableParityCheck = TRUE; ((PSERIAL_WMI_COMM_DATA)pBuf)->SettableStopBits = TRUE; ((PSERIAL_WMI_COMM_DATA)pBuf)->IsBusy = (BOOLEAN)pDevExt->openCount; status = STATUS_SUCCESS; break; case COC_WMI_PORT_HW: Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"QueryWmiDataBlock PORT_HW"); size = sizeof(SERIAL_WMI_HW_DATA); if (bufSize < size) { status = STATUS_BUFFER_TOO_SMALL; break; } RtlZeroMemory((PSERIAL_WMI_HW_DATA)pBuf, size); status = STATUS_SUCCESS; break; case COC_WMI_PORT_PERF: Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"QueryWmiDataBlock PORT_PERF"); size = sizeof(SERIAL_WMI_PERF_DATA); if (bufSize < size) { status = STATUS_BUFFER_TOO_SMALL; break; } KeAcquireSpinLock(pDevExt->pIoPortLocal->pIoLock, &oldIrql); ((PSERIAL_WMI_PERF_DATA)pBuf)->ReceivedCount = pDevExt->pIoPortLocal->perfStats.ReceivedCount; ((PSERIAL_WMI_PERF_DATA)pBuf)->TransmittedCount = pDevExt->pIoPortLocal->perfStats.TransmittedCount; ((PSERIAL_WMI_PERF_DATA)pBuf)->FrameErrorCount = pDevExt->pIoPortLocal->perfStats.FrameErrorCount; ((PSERIAL_WMI_PERF_DATA)pBuf)->SerialOverrunErrorCount = pDevExt->pIoPortLocal->perfStats.SerialOverrunErrorCount; ((PSERIAL_WMI_PERF_DATA)pBuf)->BufferOverrunErrorCount = pDevExt->pIoPortLocal->perfStats.BufferOverrunErrorCount; ((PSERIAL_WMI_PERF_DATA)pBuf)->ParityErrorCount = pDevExt->pIoPortLocal->perfStats.ParityErrorCount; KeReleaseSpinLock(pDevExt->pIoPortLocal->pIoLock, oldIrql); status = STATUS_SUCCESS; break; case COC_WMI_PORT_PROPERTIES: Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"QueryWmiDataBlock PORT_PROPERTIES"); status = GetCommProp(pDevExt, pBuf, bufSize, &size); break; default: Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"QueryWmiDataBlock ???"); size = 0; status = STATUS_WMI_GUID_NOT_FOUND; } if (status == STATUS_SUCCESS) *pInstanceLengthArray = size; status = WmiCompleteRequest(pDevObj, pIrp, status, size, IO_NO_INCREMENT); return status; } NTSTATUS SetWmiDataBlock( IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN ULONG guidIndex, IN ULONG instanceIndex, IN ULONG bufSize, IN PUCHAR pBuf) { NTSTATUS status; ULONG size = 0; UNREFERENCED_PARAMETER(guidIndex); UNREFERENCED_PARAMETER(instanceIndex); UNREFERENCED_PARAMETER(bufSize); UNREFERENCED_PARAMETER(pBuf); Trace0((PC0C_COMMON_EXTENSION)pDevObj->DeviceExtension, L"SetWmiDataBlock"); status = STATUS_WMI_GUID_NOT_FOUND; status = WmiCompleteRequest(pDevObj, pIrp, status, size, IO_NO_INCREMENT); return status; } NTSTATUS SetWmiDataItem( IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN ULONG guidIndex, IN ULONG instanceIndex, IN ULONG dataItemId, IN ULONG bufSize, IN PUCHAR pBuf) { NTSTATUS status; ULONG size = 0; UNREFERENCED_PARAMETER(guidIndex); UNREFERENCED_PARAMETER(instanceIndex); UNREFERENCED_PARAMETER(dataItemId); UNREFERENCED_PARAMETER(bufSize); UNREFERENCED_PARAMETER(pBuf); Trace0((PC0C_COMMON_EXTENSION)pDevObj->DeviceExtension, L"SetWmiDataItem"); status = STATUS_WMI_GUID_NOT_FOUND; status = WmiCompleteRequest(pDevObj, pIrp, status, size, IO_NO_INCREMENT); return status; } WMILIB_CONTEXT wmiLibContext = { COC_WMI_LIST_SIZE, guidWmiList, QueryWmiRegInfo, QueryWmiDataBlock, SetWmiDataBlock, SetWmiDataItem, NULL /*ExecuteWmiMethod*/, NULL /*WmiFunctionControl*/ }; NTSTATUS FdoPortWmi( IN PC0C_FDOPORT_EXTENSION pDevExt, IN PIRP pIrp) { NTSTATUS status; SYSCTL_IRP_DISPOSITION disposition; status = WmiSystemControl(&wmiLibContext, pDevExt->pDevObj, pIrp, &disposition); switch(disposition) { case IrpProcessed: Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"IrpProcessed"); break; case IrpNotCompleted: TraceCode((PC0C_COMMON_EXTENSION)pDevExt, "IrpNotCompleted ", NULL, (ULONG)IoGetCurrentIrpStackLocation(pIrp)->Parameters.WMI.DataPath, &status); IoCompleteRequest(pIrp, IO_NO_INCREMENT); break; case IrpForward: Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"IrpForward"); goto forward; case IrpNotWmi: Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"IrpNotWmi"); goto forward; default: Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"Irp???"); goto forward; forward: IoSkipCurrentIrpStackLocation(pIrp); status = IoCallDriver(pDevExt->pLowDevObj, pIrp); } return status; } NTSTATUS c0cSystemControlDispatch(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { NTSTATUS status; PC0C_COMMON_EXTENSION pDevExt = pDevObj->DeviceExtension; #if DBG ULONG code = IoGetCurrentIrpStackLocation(pIrp)->MinorFunction; #endif /* DBG */ HALT_UNLESS2(IoGetCurrentIrpStackLocation(pIrp)->MajorFunction == IRP_MJ_SYSTEM_CONTROL, IoGetCurrentIrpStackLocation(pIrp)->MajorFunction, IoGetCurrentIrpStackLocation(pIrp)->MinorFunction); TraceIrp("c0cSystemControlDispatch", pIrp, NULL, TRACE_FLAG_PARAMS); status = STATUS_NO_SUCH_DEVICE; switch (pDevExt->doType) { case C0C_DOTYPE_FP: status = FdoPortWmi((PC0C_FDOPORT_EXTENSION)pDevExt, pIrp); break; case C0C_DOTYPE_FB: IoSkipCurrentIrpStackLocation(pIrp); status = IoCallDriver(((PC0C_COMMON_FDO_EXTENSION)pDevExt)->pLowDevObj, pIrp); break; case C0C_DOTYPE_PP: status = STATUS_NOT_SUPPORTED; default: pIrp->IoStatus.Status = status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); } #if DBG if (status != STATUS_SUCCESS) TraceCode(pDevExt, "WMI_", codeNameTableWmi, code, &status); #endif /* DBG */ return status; } |