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

📄 main.c

📁 好东东
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 2005  Changzhi Zhou All Rights Reserved

Module Name:

    main.c

Abstract:

    This module is main module that deals with
	DriverEntry, AddDevice, Unload, handles to device name.
	SampleIoCrement and SampleIoDecrement.

Environment:

    Kernel mode

Revision History:

	Changzhi Zhou Dec 20  2004

--*/
#include <wdm.h>
#include <ntddk.h>
#include <initguid.h>

#include "main.h"
#include "..\inc\wdmioctl.h"
#include <wmistr.h>
#include <wmilib.h>


#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, AddDevice)
#pragma alloc_text (PAGE, SamplePnpDispatch)
#pragma alloc_text (PAGE, Unload)
#endif

NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    Installable driver initialization entry point.
    This entry point is called directly by the I/O system.

Arguments:

    DriverObject - pointer to the driver object

    RegistryPath - pointer to a unicode string representing the path,
                   to driver-specific key in the registry.

Return Value:

    STATUS_SUCCESS if successful,
    STATUS_UNSUCCESSFUL otherwise.

--*/
{	
	NTSTATUS            status;

    UNREFERENCED_PARAMETER (RegistryPath);

    DbgPrint("------  VirtualSerial Build on %s %s -------\n", __DATE__, __TIME__ );

	status = STATUS_SUCCESS;

    DriverObject->MajorFunction[IRP_MJ_PNP]				= SamplePnpDispatch;
    DriverObject->MajorFunction[IRP_MJ_POWER]			= SamplePowerDispatch;
    DriverObject->MajorFunction[IRP_MJ_CREATE]			= SampleCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]			= SampleClose;
	DriverObject->MajorFunction[IRP_MJ_CLEANUP ]		= SampleCleanup;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]	= SampleIoControl;

	DriverObject->MajorFunction[IRP_MJ_WRITE]           = SampleWrite;
	DriverObject->MajorFunction[IRP_MJ_READ]            = SampleRead;

    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = ToasterSystemControl;

    DriverObject->DriverExtension->AddDevice			= AddDevice;
    DriverObject->DriverUnload							= Unload;

    return status;
}



NTSTATUS
AddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
/*++

Routine Description:

    The Plug & Play subsystem is handing us a brand new PDO, for which we
    (by means of INF registration) have been asked to provide a driver.

    We need to determine if we need to be in the driver stack for the device.
    Create a function device object to attach to the stack
    Initialize that device object
    Return status success.

    Remember: We can NOT actually send ANY non pnp IRPS to the given driver
    stack, UNTIL we have received an IRP_MN_START_DEVICE.

Arguments:

    DeviceObject - pointer to a device object.

    PhysicalDeviceObject -  pointer to a device object created by the
                            underlying bus driver.

Return Value:

    NT status code.

--*/
{
    NTSTATUS                status = STATUS_SUCCESS;
    PDEVICE_OBJECT          deviceObject = NULL;
    PDEVICE_EXTENSION       deviceExtension;


	UNICODE_STRING		deviceObjName;

    PAGED_CODE ();
	DbgPrint("------- AddDevice  build on %s %s ---------\n", __DATE__, __TIME__);

	if( FALSE == InitializeSerialDevName( &deviceObjName ) )
		return STATUS_INSUFFICIENT_RESOURCES;
    status = IoCreateDevice (DriverObject,
                             sizeof (DEVICE_EXTENSION),
                             &deviceObjName,
                             FILE_DEVICE_SERIAL_PORT,
                             FILE_DEVICE_SECURE_OPEN,
                             FALSE,
                             &deviceObject);
    if (!NT_SUCCESS (status)) {
		DebugPrint(("IoCreateDevice failed\n"));
		if ( deviceObjName.Buffer != NULL )
			ExFreePool ( deviceObjName.Buffer );
        return status;
    }

    DebugPrint (("AddDevice PDO (0x%x) FDO (0x%x)\n", PhysicalDeviceObject, deviceObject));

    deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
	deviceExtension->DeviceName.MaximumLength = deviceObjName.MaximumLength;
	deviceExtension->DeviceName.Length	= deviceObjName.Length;
	deviceExtension->DeviceName.Buffer = deviceObjName.Buffer;
	deviceExtension->CreatedSerialCommEntry = FALSE;
	deviceExtension->CreatedSymbolicLink	= FALSE;

	// for working thread
	KeInitializeSpinLock( &deviceExtension->ThreadSpinLock );

    deviceExtension->NextLowerDriver = IoAttachDeviceToDeviceStack (
                                       deviceObject,
                                       PhysicalDeviceObject);
    if(NULL == deviceExtension->NextLowerDriver) {

        IoDeleteDevice(deviceObject);
        return STATUS_UNSUCCESSFUL;
    }
    DebugPrint(("AddDevice: %x to %x->%x \n", deviceObject, 
                       deviceExtension->NextLowerDriver,
                       PhysicalDeviceObject));
    // Initialize the remove event to not-signaled.
    //
    KeInitializeEvent(&deviceExtension->RemoveEvent, 
                      SynchronizationEvent, 
                      FALSE);
    //
    // Initialize the stop event to signaled.
    // This event is signaled when the OutstandingIO becomes 1
    //
    KeInitializeEvent(&deviceExtension->StopEvent, 
                      SynchronizationEvent, 
                      TRUE);

    deviceExtension->OutStandingIO = 1;
	deviceExtension->bIsOpen		= FALSE;
    
	KeInitializeSpinLock( &deviceExtension->IOCountLock );
	if ( PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) {
        deviceObject->Flags |= DO_POWER_PAGABLE;
    }

    deviceObject->Flags |= DO_DIRECT_IO;
    deviceExtension->Self = deviceObject;

	// Initialize serial-related parameters
	deviceExtension->WaitOnMaskIrp	= NULL;
	deviceExtension->CurrentBaud	= 0;
	deviceExtension->PendingReadIrp	= NULL;
	KeInitializeTimer ( &deviceExtension->ReadTimer );
	KeInitializeDpc ( &deviceExtension->ReadDpc, ReadDpcRoutine, (PVOID)deviceExtension );
	
	RtlZeroMemory( &deviceExtension->SerialStatus, sizeof( SERIAL_STATUS ) );
	// initialize  members relevant to TDI.
	deviceExtension->RxBuffer	= ExAllocatePoolWithTag( NonPagedPool, RINGBUFFER_SIZE, 'RBuf' );
	if ( deviceExtension->RxBuffer == NULL )
		goto Error_Exit;

	deviceExtension->lpRead	= deviceExtension->RxBuffer;
	deviceExtension->lpRx	= deviceExtension->RxBuffer;

	deviceExtension->hTransAddr	= NULL;
	deviceExtension->lpTransAddrFileObject	= NULL;
	deviceExtension->TDILowerDeviceObject	= NULL;
	deviceExtension->RemoteAddress			= 0x601a8c0;	// 192.168.1.6
	deviceExtension->RemotePort				= 0x7217;		// 6002
	RtlZeroMemory( (PVOID)&deviceExtension->recvContext, sizeof( RECV_CONTEXT ) );

	deviceExtension->recvContext.RemainderBuffer = ExAllocatePoolWithTag ( NonPagedPool, RECVREMAINDER_BUFFER_SIZE, 'Rrem' );
	if ( deviceExtension->recvContext.RemainderBuffer == NULL )
		goto Error_Exit;
    KeInitializeEvent(&deviceExtension->recvContext.Event, 
                      SynchronizationEvent,
                      FALSE);
	RtlZeroMemory ( (PVOID)&deviceExtension->recvContext.ReceiveDatagramInfo, sizeof ( TDI_CONNECTION_INFORMATION ) );
	RtlZeroMemory ( (PVOID)&deviceExtension->recvContext.ReturnInfo, sizeof ( TDI_CONNECTION_INFORMATION ) );

    INITIALIZE_PNP_STATE(deviceExtension);
 
	//++ Register device interface for win32app
	status = IoRegisterDeviceInterface( PhysicalDeviceObject,
					(LPGUID)&GUID_CLASS_COMPORT,
					NULL,
					&deviceExtension->InterfaceName );
	DebugPrint(("InterfaceName:  %ws\n", deviceExtension->InterfaceName.Buffer ));
	if( !NT_SUCCESS ( status ) ){
		DebugPrint(( "AddDevice:  IoRegisterDeviceInterface failed (%x) \n", status ));
		goto Error_Exit;
	}
	//--

    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    return STATUS_SUCCESS;
Error_Exit:
	if( deviceExtension->RxBuffer  )
	{
		ExFreePool ( deviceExtension->RxBuffer );
		deviceExtension->RxBuffer = NULL;
	}
	if ( deviceExtension->recvContext.RemainderBuffer )
	{
		ExFreePool ( deviceExtension->recvContext.RemainderBuffer );
		deviceExtension->recvContext.RemainderBuffer = NULL;
	}

	IoDetachDevice( deviceExtension->NextLowerDriver );
	IoDeleteDevice( deviceObject );
	return status;

}

NTSTATUS
SerialDoExternalNaming(
	IN PDEVICE_EXTENSION	deviceExtension,
	IN LONG					ComX
	)
/*++

Routine Description:

	Create external name, SymbolicLinkName and DOS name.

Arguments:

    deviceExtension - pointer to a device object extension.

    ComX -  indicates the number of Serial Ports.

Return Value:

    NT status code.

--*/
{
	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' );

⌨️ 快捷键说明

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