📄 pnp.c
字号:
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 + -