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

📄 pnp.c

📁 windows平台下虚拟串口的driver文件
💻 C
📖 第 1 页 / 共 2 页
字号:
	pDevExt->bIsOpen				= FALSE;
	pDevExt->PowerState				= PowerDeviceD0;
	pDevExt->CreatedSymbolicLink    = FALSE;
	pDevExt->CreatedSerialCommEntry	= FALSE;
	pDevExt->BufferSize				= 1024;

    //+	by zcz
    //deviceObject->DeviceType = deviceExtension->NextLowerDriver->DeviceType;

    //deviceObject->Characteristics = 
    //                      deviceExtension->NextLowerDriver->Characteristics;
	//---
	//++	Initialize serial section
	KeInitializeSpinLock( &pDevExt->CancelSpinLock );
	InitializeListHead( &pDevExt->ReadIrpQueue );
	InitializeListHead( &pDevExt->WriteIrpQueue );
	InitializeListHead( &pDevExt->ReadDataQueue );
	KeInitializeSpinLock( &pDevExt->ReadQueueSpinLock );
	//-

    //
    // Set the initial state of the Filter DO
    //
	*NewDeviceObject = deviceObject;
	
	ExFreePool(deviceObjName.Buffer);

	DebugPrint(("Leave SerialCreateDevObj\n") );

	return STATUS_SUCCESS;
	
SerialCreateDevObjError:
	
	DebugPrint(("SERIAL: SerialCreateDevObj Error, Cleaning up\n") );
	
	//
	// Free the allocated strings for the NT and symbolic names if they exist.
	//
	
	if (deviceObjName.Buffer != NULL) {
		ExFreePool(deviceObjName.Buffer);
	}
	
	if (deviceObject) {
		if (pDevExt->DeviceName.Buffer != NULL) {
			ExFreePool(pDevExt->DeviceName.Buffer);
		}
		gDeviceArray[ currentInstance ].deviceExtension = NULL;
		IoDeleteDevice(deviceObject);
	}
	
	*NewDeviceObject = NULL;
	
	DebugPrint(("SERIAL: Leave SerialCreateDevObj\n") );
	return status;
}


NTSTATUS
SerialRemoveDevObj(IN PDEVICE_OBJECT PDevObj)
/*++

Routine Description:

    Removes a serial device object from the system.

Arguments:

    PDevObj - A pointer to the Device Object we want removed.

Return Value:

    Always TRUE

--*/
{
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)PDevObj->DeviceExtension;
	PAGED_CODE();
	
	DebugPrint(("SERIAL: Enter SerialRemoveDevObj\n"));
	
	
	//
	// Free memory allocated in the extension
	//
	
	if (pDevExt->DeviceName.Buffer != NULL) {
		ExFreePool(pDevExt->DeviceName.Buffer);
	}
	
	if (pDevExt->SymbolicLinkName.Buffer != NULL) {
		ExFreePool(pDevExt->SymbolicLinkName.Buffer);
	}
	
	if (pDevExt->DosName.Buffer != NULL) {
		ExFreePool(pDevExt->DosName.Buffer);
	}

	if( pDevExt->BufferSize != 0 ){
		pDevExt->BufferSize = 0;
	}
	
	DebugPrint(("SERIAL: Leave SerialRemoveDevObj\n"));
	
	return STATUS_SUCCESS;
}

NTSTATUS
SerialDoExternalNaming(
	IN PDEVICE_EXTENSION	deviceExtension,
	IN LONG					ComX
	)
{
	NTSTATUS		status;
	ULONG			bufLen;
	WCHAR			ComXBuffer[ 4 ];
	UNICODE_STRING	instanceStr;

	DebugPrint(("Enter SerialdoExternalNaming routine...\n"));
	if( deviceExtension->CreatedSymbolicLink || deviceExtension->CreatedSerialCommEntry ){
		DebugPrint(("Already create symboliclink or serial commentry\n"));
		return STATUS_UNSUCCESSFUL;
	}
	ASSERT( deviceExtension->SymbolicLinkName.Buffer == NULL );
	ASSERT( deviceExtension->DosName.Buffer == NULL );

	RtlInitUnicodeString(&instanceStr, NULL);
	instanceStr.MaximumLength = sizeof( ComXBuffer );
	instanceStr.Buffer = ComXBuffer;	// 4 WCHAR
	RtlIntegerToUnicodeString( ComX, 10, &instanceStr );

	// 将SymbolicLinkName设置为 \DosDevices\COMn 的形式。其中n = ComX
	RtlZeroMemory( &deviceExtension->SymbolicLinkName, sizeof( UNICODE_STRING ) );
	deviceExtension->SymbolicLinkName.MaximumLength = DEVICE_OBJECT_NAME_LENGTH + sizeof( WCHAR );
	deviceExtension->SymbolicLinkName.Buffer = ExAllocatePoolWithTag( PagedPool, deviceExtension->SymbolicLinkName.MaximumLength, 'SymL' );
	if( deviceExtension->SymbolicLinkName.Buffer == NULL ){
		DebugPrint(("SERIAL: Couldn't allocate memory for symbolic link name\n"));
		status = STATUS_INSUFFICIENT_RESOURCES;
		goto SerialDoExternalNamingError;
	}
	RtlZeroMemory( deviceExtension->SymbolicLinkName.Buffer, deviceExtension->SymbolicLinkName.MaximumLength );
	RtlAppendUnicodeToString( &deviceExtension->SymbolicLinkName, DOS_DEVICE_NAME );	//L"\\DosDevices\\COM"
	RtlAppendUnicodeStringToString( &deviceExtension->SymbolicLinkName, &instanceStr);
	DebugPrint(("SymbolicLinkName:   %wZ\n",  deviceExtension->SymbolicLinkName ));

	// 将DosName初始化 COMn 的形式, 其中 n = ComX
	deviceExtension->DosName.MaximumLength = 64 + sizeof(WCHAR);
	deviceExtension->DosName.Buffer = ExAllocatePoolWithTag( PagedPool, 64 + sizeof( WCHAR ), 'Name' );
	if( deviceExtension->DosName.Buffer == NULL ){
		DebugPrint(("SERIAL: Couldn't allocate memory for Dos name\n"));
		status =  STATUS_INSUFFICIENT_RESOURCES;
		goto SerialDoExternalNamingError;
	}
	deviceExtension->DosName.Length = 0;
	RtlZeroMemory( deviceExtension->DosName.Buffer, deviceExtension->DosName.MaximumLength );
	RtlAppendUnicodeToString( &deviceExtension->DosName, L"COM" );
	RtlAppendUnicodeStringToString( &deviceExtension->DosName, &instanceStr);
	DebugPrint(("DosName:   %wZ\n", &deviceExtension->DosName ));
	DebugPrint(("DeviceName:    %wZ\n", &deviceExtension->DeviceName ));

	// 生成符号连接,至此本设备对win32应用表现的Dos设备名为 \DosDevices\COMn
	status = IoCreateSymbolicLink( &deviceExtension->SymbolicLinkName, &deviceExtension->DeviceName );
	if( !NT_SUCCESS( status )){
		DebugPrint(("SERIAL:  Couldn't create the symbolic link with error %d\n", status));
		goto SerialDoExternalNamingError;
	}else{
		DebugPrint(("Create the symbolic link OK\n"));
		deviceExtension->CreatedSymbolicLink = TRUE;
	}
	// 在注册表的 HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM 中,添加ComX的键值
	// 若不进行这一步,则超级终端程序无法检测到本虚拟串口设备
	status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, SERIAL_DEVICE_MAP,
		deviceExtension->DeviceName.Buffer, REG_SZ,
		deviceExtension->DosName.Buffer,
		deviceExtension->DosName.Length + sizeof(WCHAR));
	if( !NT_SUCCESS( status )){
		DebugPrint(("SERIAL: Couldn't create the device map entry\n------- for port %wZ\n", deviceExtension->DeviceName ));
		goto SerialDoExternalNamingError;
	}
	deviceExtension->ComX = ComX;
	deviceExtension->CreatedSerialCommEntry = TRUE;

SerialDoExternalNamingError:

	if( !NT_SUCCESS( status )){
		if( deviceExtension->DosName.Buffer != NULL ){
			ExFreePool( deviceExtension->DosName.Buffer );
			deviceExtension->DosName.Buffer = NULL;
			deviceExtension->CreatedSerialCommEntry = FALSE;
		}
		if( deviceExtension->CreatedSymbolicLink ){
			IoDeleteSymbolicLink( &deviceExtension->SymbolicLinkName );
			deviceExtension->CreatedSymbolicLink = FALSE;
		}
		if( deviceExtension->SymbolicLinkName.Buffer != NULL ){
			ExFreePool( deviceExtension->SymbolicLinkName.Buffer );
			deviceExtension->SymbolicLinkName.Buffer = NULL;
		}
	}
	return status;
}

NTSTATUS
SerialUndoExternalNaming(
	IN PDEVICE_EXTENSION	deviceExtension
	)
{
	NTSTATUS	status = STATUS_SUCCESS;
	if( deviceExtension->CreatedSymbolicLink ){
		IoDeleteSymbolicLink( &deviceExtension->SymbolicLinkName );
		ExFreePool( deviceExtension->SymbolicLinkName.Buffer );
		deviceExtension->SymbolicLinkName.Buffer = NULL;
		deviceExtension->CreatedSymbolicLink = FALSE;
	}else{
		ASSERT( deviceExtension->SymbolicLinkName.Buffer == NULL );
	}
	ASSERT( deviceExtension->DeviceName.Buffer != NULL );
	if( deviceExtension->CreatedSerialCommEntry ){
		status = RtlDeleteRegistryValue( RTL_REGISTRY_DEVICEMAP, SERIAL_DEVICE_MAP, deviceExtension->DeviceName.Buffer );
		if( !NT_SUCCESS( status ) ){
			DebugPrint(("RtlDeleteRegistryValue device map failed\n"));
		}
		ExFreePool( deviceExtension->DosName.Buffer );
		deviceExtension->DosName.Buffer = NULL;
		deviceExtension->CreatedSerialCommEntry = FALSE;
	}else{
		ASSERT( deviceExtension->DosName.Buffer == NULL );
	}
	return status;
}

NTSTATUS
SerialFinishStartDevice(
	IN	PDEVICE_EXTENSION	deviceExtension
	)
{
	// Default Line control protocol. 7E1
	//
	// Seven data bits.
	// Even parity.
	// 1 Stop bits.
	//
	//deviceExtension->LineControl = SERIAL_7_DATA | SERIAL_EVEN_PARITY | SERIAL_NONE_PARITY;
	deviceExtension->LineControl.WordLength = 8;
	deviceExtension->LineControl.Parity		= 0;
	deviceExtension->LineControl.StopBits	= 1;
	deviceExtension->CurrentBaud			= 1200;
	
	deviceExtension->SpecialChars.XonChar	= SERIAL_DEF_XON;
	deviceExtension->SpecialChars.XoffChar	= SERIAL_DEF_XOFF;
	deviceExtension->SpecialChars.EofChar	= 0;
	deviceExtension->SpecialChars.ErrorChar	= 0;
	deviceExtension->SpecialChars.BreakChar	= 0;
	deviceExtension->SpecialChars.EventChar	= 0;

	deviceExtension->HandFlow.ControlHandShake	= SERIAL_DTR_CONTROL;
	deviceExtension->HandFlow.FlowReplace		= SERIAL_DSR_SENSITIVITY;//SERIAL_RTS_CONTROL;
	deviceExtension->HandFlow.XonLimit			= 4096;
	deviceExtension->HandFlow.XoffLimit			= 1024;

	return STATUS_SUCCESS;
}
//++ Register device interface for win32app
NTSTATUS
AddInterface(
	IN	PDEVICE_EXTENSION	deviceExtension
	)
{
	NTSTATUS status;
	status = IoRegisterDeviceInterface( deviceExtension->PhysicalDeviceObject,
					(LPGUID)&GUID_CLASS_COMPORT,
					NULL,
					&deviceExtension->InterfaceName );
	if( !NT_SUCCESS( status )){
		DebugPrint(("SERIAL:  Couldn't register class association\n"));
		deviceExtension->InterfaceName.Buffer = NULL;
		return status;
	}
	status = IoSetDeviceInterfaceState( &deviceExtension->InterfaceName, TRUE );
	if( !NT_SUCCESS( status )){
		DebugPrint(("SERIAL: Couldn't set class association\n"));
	}
	return status;
}
VOID
DelInterface(
	IN	PDEVICE_EXTENSION	deviceExtension
	)
{
	NTSTATUS status;
	if( deviceExtension->InterfaceName.Buffer ){
		status = IoSetDeviceInterfaceState( &deviceExtension->InterfaceName, FALSE );
		if( !NT_SUCCESS( status )){
			DebugPrint(("SERIAL:  IoSetDeviceInterface failed\n"));
		}
		RtlFreeUnicodeString( &deviceExtension->InterfaceName );
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -