⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comemuldrv.c

📁 虚拟串口程序源代码 使用Vc开发的
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -