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

📄 main.c

📁 好东东
💻 C
📖 第 1 页 / 共 2 页
字号:
	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;
}


BOOLEAN InitializeSerialDevName( PUNICODE_STRING lpDeviceName )
/*++

Routine Description:

	Initialize serial device name. This name is available in Kernel Mode.

Arguments:

    PUNICODE_STRING lpDeviceName - the pointer to device name string.

Return Value:

    return TRUE if it is successful, otherwise return FALSE.

--*/
{

	WCHAR				instanceNumberBuffer[ 4 ];
	UNICODE_STRING		instanceStr;
	static ULONG				currentInstance = 10;
	// 首先处理deviceObjName,这是一个核心态使用的设备名,形如"\\Device\\SiSerial0"
	// Zero out allocated memory pointers so we know if they must be freed
	RtlZeroMemory( lpDeviceName, sizeof(UNICODE_STRING) );
	lpDeviceName->MaximumLength = DEVICE_OBJECT_NAME_LENGTH * sizeof(WCHAR);
	lpDeviceName->Buffer = ExAllocatePool(PagedPool, lpDeviceName->MaximumLength + sizeof(WCHAR));
	if ( lpDeviceName->Buffer == NULL) {
		DebugPrint(("Couldn't allocate memory for device name\n"));
		return FALSE;
	}
	RtlZeroMemory( lpDeviceName->Buffer, lpDeviceName->MaximumLength + sizeof(WCHAR));
	// now, the size of deviceObjName.Buffer is (128 + 1)(WCHAR)
	RtlAppendUnicodeToString( lpDeviceName, DEVICE_NAME);	// L"\\Device\\VSer"
	
	// 处理 lpDeviceName 的后缀序号
	RtlInitUnicodeString(&instanceStr, NULL);
	instanceStr.MaximumLength	= sizeof(instanceNumberBuffer);
	instanceStr.Buffer			= instanceNumberBuffer;	// 20 WCHAR
	currentInstance++;
	RtlIntegerToUnicodeString( currentInstance, 10, &instanceStr);
	RtlAppendUnicodeStringToString( lpDeviceName, &instanceStr);
	DebugPrint(("DeviceName:\n"));
	DebugPrint(("----------- %ws\n", lpDeviceName->Buffer ));
	return TRUE;
}

NTSTATUS
SerialUndoExternalNaming(
	IN PDEVICE_EXTENSION	deviceExtension
	)
/*++

Routine Description:

	Delete or unregister external name, SymbolicLinkName and DOS name.

Arguments:

    deviceExtension - pointer to a device object extension.

Return Value:

    NT status code.

--*/
{
	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
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);
	}
	DebugPrint(("SERIAL: Leave SerialRemoveDevObj\n"));

	return STATUS_SUCCESS;
}

NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG info)
{
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = info;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}
    
VOID
Unload(
    IN PDRIVER_OBJECT DriverObject
    )
/*++

Routine Description:

    Free all the allocated resources in DriverEntry, etc.

Arguments:

    DriverObject - pointer to a driver object.

Return Value:

    VOID.

--*/
{
    PAGED_CODE ();

    //
    // The device object(s) should be NULL now
    // (since we unload, all the devices objects associated with this
    // driver must be deleted.
    //
	DebugPrint( ("Is unloading......\n") );
    ASSERT(DriverObject->DeviceObject == NULL);
    
    //
    // We should not be unloaded until all the devices we control 
    // have been removed from our queue.  
    //
    DebugPrint (("Unload:  unload\n"));

    return;
}

LONG
SampleIoIncrement(
    IN OUT PDEVICE_EXTENSION DeviceExtension
    )
/* ++
 
Routine Description:

	Increment deviceExtension->OutStandingIO within the scope of IOCountLock.

Arguments:

	deviceExtension - pointer to a device object extension.

Return Value:

	deviceExtension->OutStandingIO

--*/
{
    LONG  result = 0;
    KIRQL oldIrql;

    KeAcquireSpinLock(&DeviceExtension->IOCountLock, &oldIrql);

    result = InterlockedIncrement(&DeviceExtension->OutStandingIO);

    //
    // when OutStandingIO bumps from 1 to 2, clear the StopEvent
    //

    if(result == 2) {

        KeClearEvent(&DeviceExtension->StopEvent);
    }

    KeReleaseSpinLock(&DeviceExtension->IOCountLock, oldIrql);
	DebugPrint(("SampleIncrement: %d\n", result));

    return result;
}

LONG
SampleIoDecrement(
    IN OUT PDEVICE_EXTENSION DeviceExtension
    )
/*++
 
Routine Description:
	
	  Decrement deviceExtension->OutStandingIO within the scope of IOCountLock.

Arguments:

	deviceExtension - pointer to a device object extension.

Return Value:

	deviceExtension->OutStandingIO

--*/
{
    LONG  result = 0;
    KIRQL oldIrql;

    KeAcquireSpinLock(&DeviceExtension->IOCountLock, &oldIrql);

    result = InterlockedDecrement(&DeviceExtension->OutStandingIO);

    if(result == 1) {

        KeSetEvent(&DeviceExtension->StopEvent, IO_NO_INCREMENT, FALSE);
    }

    if(result == 0) {

        ASSERT(Removed == DeviceExtension->DevicePnPState);

        KeSetEvent(&DeviceExtension->RemoveEvent, IO_NO_INCREMENT, FALSE);
    }

    KeReleaseSpinLock(&DeviceExtension->IOCountLock, oldIrql);
	DebugPrint(("SampleIoDecrement: %d\n", result));


    return result;
}

⌨️ 快捷键说明

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