📄 comemuldrv.c
字号:
//
// ComEmulDrv serial port bridge driver
//
// Copyright (c) 2002
// MixW team
// http://www.mixw.net
//
#ifndef OLDVER
#include <ntddk.h>
#else
#include <wdm.h>
#endif
#include <C:\Work\NTDDK\inc\ntddser.h >
#include "ComEmulDrv.h"
#define SERIAL_DEVICE_MAP L"SERIALCOMM"
//#define COMNUMBER1 L"10"
//#define COMNUMBER2 L"3"
//#define DEFAULT1 L"10"
//#define DEFAULT2 L"11"
#define DEVICENAME L"\\Device\\Serial"
#define DOSDEVICENAME L"\\DosDevices\\COM"
#define REGNAME L"COM"
/*
VOID LogMessage(IN PVOID pObj, IN ULONG val1, IN ULONG val2, IN ULONG val3,
IN ULONG val4, IN PVOID dump, IN ULONG dumplength)
{
PIO_ERROR_LOG_PACKET pLogEntry;
pLogEntry = IoAllocateErrorLogEntry(pObj, (UCHAR)(sizeof(IO_ERROR_LOG_PACKET) +
4*sizeof(ULONG) + dumplength));
if (pLogEntry != NULL )
{
pLogEntry->ErrorCode = STATUS_SUCCESS;
pLogEntry->SequenceNumber = 0;
pLogEntry->MajorFunctionCode = 0;
pLogEntry->IoControlCode = 0;
pLogEntry->RetryCount = 0;
pLogEntry->FinalStatus = STATUS_SUCCESS;
pLogEntry->DumpDataSize = 4*sizeof(ULONG) + dumplength;
pLogEntry->DumpData[0] = val1;
pLogEntry->DumpData[1] = val2;
pLogEntry->DumpData[2] = val3;
pLogEntry->DumpData[3] = val4;
RtlCopyMemory(&pLogEntry->DumpData[4], dump, dumplength);
IoWriteErrorLogEntry(pLogEntry);
}
}
*/
NTSTATUS
MixPortDriverDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
MixPortDriverWriteDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP pIrp
);
NTSTATUS
MixPortDriverReadDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP pIrp
);
VOID DriverCancelWaitIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp);
VOID DriverCheckEvent(IN PSERIAL_DEVICE_EXTENSION pExtension, IN ULONG events);
#define UNIBUFLEN 200
WCHAR Name1Buf[MAXPAIR][UNIBUFLEN],Name2Buf[MAXPAIR][UNIBUFLEN];
WCHAR DosName1Buf[MAXPAIR][UNIBUFLEN],DosName2Buf[MAXPAIR][UNIBUFLEN];
WCHAR Reg1Buf[MAXPAIR][UNIBUFLEN],Reg2Buf[MAXPAIR][UNIBUFLEN];
int PairPresent[MAXPAIR];
int GetStringForCom(int iPair, PWSTR pBuffer, PCWSTR pRegistryPath, PCWSTR pStrPrefix, PCWSTR pKey)
{
UNICODE_STRING sString;
NTSTATUS ntStatus;
UNICODE_STRING Value;
int iValue;
RTL_QUERY_REGISTRY_TABLE Table[2];
WCHAR swKey[UNIBUFLEN];
UNICODE_STRING sKey, sNr;
// Prepare output buffer
sString.MaximumLength = UNIBUFLEN;
sString.Length = 0;
sString.Buffer = pBuffer;
RtlZeroMemory(sString.Buffer, UNIBUFLEN*sizeof(WCHAR));
RtlAppendUnicodeToString(&sString, pStrPrefix);
// Prepare key name
sKey.MaximumLength = UNIBUFLEN;
sKey.Length = 0;
sKey.Buffer = swKey;
sNr.MaximumLength = UNIBUFLEN;
sNr.Length = 0;
sNr.Buffer = swKey+4;
RtlZeroMemory(sKey.Buffer, UNIBUFLEN*sizeof(WCHAR));
RtlAppendUnicodeToString(&sKey, L"Pair");
RtlIntegerToUnicodeString(iPair+1, 10, &sNr);
sKey.Length += sNr.Length;
RtlAppendUnicodeToString(&sKey, L"-Port");
RtlAppendUnicodeToString(&sKey, pKey);
KdPrint(("GetStringForCom, key= %ws\n",sKey.Buffer));
// Read from registry
RtlInitUnicodeString( &Value, NULL );
RtlZeroMemory( Table, sizeof(Table) );
Table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
Table[0].Name = sKey.Buffer/*(PWSTR)pKey*/;
Table[0].EntryContext = &Value;
Table[0].DefaultType = REG_SZ;
Table[0].DefaultData = L"0";
ntStatus = RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE,
pRegistryPath,
Table,
NULL,
NULL );
if ( ntStatus == STATUS_SUCCESS )
{
RtlAppendUnicodeStringToString(&sString, &Value);
KdPrint((" value= %ws\n",Value.Buffer));
RtlUnicodeStringToInteger(&Value, 10, &iValue);
return iValue;
}
else
{
RtlAppendUnicodeToString(&sString, L"0");
KdPrint((" (no) value= %ws\n",Value.Buffer));
return 0;
}
}
VOID MixPortDriverUnload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING uniDOSString1;
UNICODE_STRING uniDOSString2;
int i/*, NumDev=0*/;
PDEVICE_OBJECT p, k;
KdPrint(("Unload\n"));
// Delete sym link and registry
KdPrint(("Delete sym and reg:"));
for (i=0; i<MAXPAIR; i++)
{
if (!PairPresent[i])
continue;
RtlInitUnicodeString(&uniDOSString1, DosName1Buf[i]/*DOSDEVICENAME COMNUMBER1*/);
RtlInitUnicodeString(&uniDOSString2, DosName2Buf[i]/*DOSDEVICENAME COMNUMBER2*/);
//DbgPrint("Dos= %ws\n",DosName1Buf);
IoDeleteSymbolicLink (&uniDOSString1);
IoDeleteSymbolicLink (&uniDOSString2);
RtlDeleteRegistryValue(RTL_REGISTRY_DEVICEMAP, SERIAL_DEVICE_MAP, Name1Buf[i]/*DEVICENAME COMNUMBER1*/);
RtlDeleteRegistryValue(RTL_REGISTRY_DEVICEMAP, SERIAL_DEVICE_MAP, Name2Buf[i]/*DEVICENAME COMNUMBER2*/);
// NumDev += 2;
KdPrint((" %i\n",i));
}
KdPrint(("\n",i));
/*
r (i=0; i<NumDev; i++)
IoDeleteDevice(DriverObject->DeviceObject->NextDevice);
IoDeleteDevice(DriverObject->DeviceObject);
*/
// Delete devices
p = DriverObject->DeviceObject;
KdPrint(("Delete device: "));
while (p)
{
k = p->NextDevice;
IoDeleteDevice(p);
p = k;
KdPrint(("*"));
}
KdPrint(("\n"));
}
//ULONG OpenCnt = 0;
NTSTATUS MixPortDriverCreateDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PSERIAL_DEVICE_EXTENSION pExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// OpenCnt++;
KdPrint(("Create\n"));
// Init the device extension
pExtension->BaudRate = 1200;
pExtension->RTSstate = 0;
pExtension->DTRstate = 0;
pExtension->Timeouts.ReadIntervalTimeout = 0;
pExtension->Timeouts.ReadTotalTimeoutMultiplier = 0;
pExtension->Timeouts.ReadTotalTimeoutConstant = 0;
pExtension->Timeouts.WriteTotalTimeoutMultiplier = 0;
pExtension->Timeouts.WriteTotalTimeoutConstant = 0;
//pExtension->Lc
pExtension->BufHead = 0;
pExtension->BufTail = 0;
pExtension->pOther->BufHead = 0;
pExtension->pOther->BufTail = 0;
pExtension->IsOpen = TRUE;
KeInitializeSpinLock(&pExtension->WriteSpinLock);
KeInitializeSpinLock(&pExtension->IoctlSpinLock);
pExtension->EventMask = 0;
pExtension->HistoryEvents = 0;
pExtension->pWaitIrp = NULL;
pExtension->pReadIrp = NULL;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
//LogMessage(DeviceObject,0xAA,0,0,0,0,0);
return STATUS_SUCCESS;
}
NTSTATUS MixPortDriverCloseDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PSERIAL_DEVICE_EXTENSION pExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// OpenCnt--;
KdPrint(("Close\n"));
pExtension->pWaitIrp = NULL;
pExtension->pReadIrp = NULL;
pExtension->IsOpen = FALSE;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
PDEVICE_OBJECT deviceObject1;
PDEVICE_OBJECT deviceObject2;
NTSTATUS status;
UNICODE_STRING uniNameString1, uniDOSString1;
UNICODE_STRING uniNameString2, uniDOSString2;
PSERIAL_DEVICE_EXTENSION pExtension1;
PSERIAL_DEVICE_EXTENSION pExtension2;
int i;
int cnt;
KdPrint(("DriverEntry, path= %ws\n",RegistryPath->Buffer));
KdPrint(("Create devices:"));
for (i=0; i<MAXPAIR; i++)
PairPresent[i] = FALSE;
for (i=0; i<MAXPAIR; i++)
{
cnt = 0;
// Prepare strings
cnt += GetStringForCom(i, Name1Buf[i], RegistryPath->Buffer, DEVICENAME, L"1");
cnt += GetStringForCom(i, Name2Buf[i], RegistryPath->Buffer, DEVICENAME, L"2");
cnt += GetStringForCom(i, DosName1Buf[i], RegistryPath->Buffer, DOSDEVICENAME, L"1");
cnt += GetStringForCom(i, DosName2Buf[i], RegistryPath->Buffer, DOSDEVICENAME, L"2");
cnt += GetStringForCom(i, Reg1Buf[i], RegistryPath->Buffer, REGNAME, L"1");
cnt += GetStringForCom(i, Reg2Buf[i], RegistryPath->Buffer, REGNAME, L"2");
if (cnt < 4)
{
continue;
}
KdPrint(("Creating: %i",i));
RtlInitUnicodeString(&uniNameString1, Name1Buf[i]);
RtlInitUnicodeString(&uniNameString2, Name2Buf[i]);
RtlInitUnicodeString(&uniDOSString1, DosName1Buf[i]);
RtlInitUnicodeString(&uniDOSString2, DosName2Buf[i]);
status = IoCreateDevice(DriverObject,
sizeof(SERIAL_DEVICE_EXTENSION),
&uniNameString1,
FILE_DEVICE_SERIAL_PORT,
FILE_DEVICE_SECURE_OPEN,
TRUE,
&deviceObject1);
if(!NT_SUCCESS(status))
{
MixPortDriverUnload(DriverObject);
return status;
}
status = IoCreateDevice(DriverObject,
sizeof(SERIAL_DEVICE_EXTENSION),
&uniNameString2,
FILE_DEVICE_SERIAL_PORT,
FILE_DEVICE_SECURE_OPEN,
TRUE,
&deviceObject2);
if(!NT_SUCCESS(status))
{
MixPortDriverUnload(DriverObject);
return status;
}
PairPresent[i] = TRUE;
deviceObject1->Flags |= DO_BUFFERED_IO; // Buffered I/O only!
deviceObject2->Flags |= DO_BUFFERED_IO; // Buffered I/O only!
status = IoCreateSymbolicLink (&uniDOSString1, &uniNameString1);
// if (!NT_SUCCESS(status))
// return status;
status = IoCreateSymbolicLink (&uniDOSString2, &uniNameString2);
// if (!NT_SUCCESS(status))
// return status;
status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, SERIAL_DEVICE_MAP, Name1Buf[i]/*DEVICENAME COMNUMBER1*/, REG_SZ,
Reg1Buf[i]/*REGNAME COMNUMBER1*/, (wcslen(Reg1Buf[i]/*REGNAME COMNUMBER1*/) + 1) * sizeof(WCHAR));
// if (!NT_SUCCESS(status))
// return status;
status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, SERIAL_DEVICE_MAP, Name2Buf[i]/*DEVICENAME COMNUMBER2*/, REG_SZ,
Reg2Buf[i]/*REGNAME COMNUMBER2*/, (wcslen(Reg2Buf[i]/*REGNAME COMNUMBER2*/) + 1) * sizeof(WCHAR));
// if (!NT_SUCCESS(status))
// return status;
// Link
((PSERIAL_DEVICE_EXTENSION)deviceObject1->DeviceExtension)->pOther = ((PSERIAL_DEVICE_EXTENSION)deviceObject2->DeviceExtension);
((PSERIAL_DEVICE_EXTENSION)deviceObject2->DeviceExtension)->pOther = ((PSERIAL_DEVICE_EXTENSION)deviceObject1->DeviceExtension);
((PSERIAL_DEVICE_EXTENSION)deviceObject1->DeviceExtension)->IsOpen = FALSE;
((PSERIAL_DEVICE_EXTENSION)deviceObject2->DeviceExtension)->IsOpen = FALSE;
}
KdPrint(("\n"));
DriverObject->MajorFunction[IRP_MJ_CREATE] = MixPortDriverCreateDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MixPortDriverCloseDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MixPortDriverDeviceControl;
DriverObject->MajorFunction[IRP_MJ_WRITE] = MixPortDriverWriteDispatch;
DriverObject->MajorFunction[IRP_MJ_READ] = MixPortDriverReadDispatch;
DriverObject->DriverUnload = MixPortDriverUnload;
return STATUS_SUCCESS;
}
#define IOCTL_SERIAL_IS_OPENED CTL_CODE(FILE_DEVICE_SERIAL_PORT,50,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_GETDATA CTL_CODE(FILE_DEVICE_SERIAL_PORT,51,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_SETDATA CTL_CODE(FILE_DEVICE_SERIAL_PORT,52,METHOD_BUFFERED,FILE_ANY_ACCESS)
NTSTATUS
MixPortDriverDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP pIrp
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success
PSERIAL_DEVICE_EXTENSION pExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( pIrp );
KIRQL OldIrql;
pIrp->IoStatus.Information = 0;
ntStatus = STATUS_SUCCESS;
//LogMessage(DeviceObject,0xD0,irpSp->Parameters.DeviceIoControl.IoControlCode,0,0,0,0);
//DbgPrint("IOCTL code: %X\n",irpSp->Parameters.DeviceIoControl.IoControlCode);
switch ( irpSp->Parameters.DeviceIoControl.IoControlCode )
{
/*
case IOCTL_SERIAL_IS_OPENED:
{
*((ULONG*)pIrp->AssociatedIrp.SystemBuffer) = (OpenCnt>1);
pIrp->IoStatus.Information = sizeof(ULONG);
break;
}
*/
case IOCTL_SERIAL_SET_BAUD_RATE:
{
//DbgPrint("SetBaudRate\n");
pExtension->BaudRate = ((PSERIAL_BAUD_RATE)(pIrp->AssociatedIrp.SystemBuffer))->BaudRate;
pIrp->IoStatus.Information = 0;
break;
}
case IOCTL_SERIAL_GET_BAUD_RATE:
{
PSERIAL_BAUD_RATE Br = (PSERIAL_BAUD_RATE)pIrp->AssociatedIrp.SystemBuffer;
Br->BaudRate = pExtension->BaudRate;
pIrp->IoStatus.Information = sizeof(SERIAL_BAUD_RATE);
break;
}
case IOCTL_SERIAL_SET_RTS:
{
//DbgPrint("SetRTS\n");
pExtension->RTSstate = 1;
break;
}
case IOCTL_SERIAL_CLR_RTS:
{
//DbgPrint("ClrRTS\n");
pExtension->RTSstate = 0;
break;
}
case IOCTL_SERIAL_SET_DTR:
{
//DbgPrint("SetDTR\n");
pExtension->DTRstate = 1;
break;
}
case IOCTL_SERIAL_CLR_DTR:
{
//DbgPrint("ClrDTR\n");
pExtension->DTRstate = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -