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

📄 main.c

📁 windows平台下虚拟串口的driver文件
💻 C
📖 第 1 页 / 共 2 页
字号:

/*++

Copyright (c) 1990-2000  Changzhi Zhou All Rights Reserved

Module Name:

    main.c

Abstract:

	This module contains the entry points  for a virtual serial driver

Author

	Changzhi Zhou	Jul 25, 2003

Environment:

    Kernel mode

Revision History:

    Changzhi Zhou Dec 5 2003

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

#include "main.h"
#include "..\inc\wdmioctl.h"


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


DEVICE_ARRAY	gDeviceArray[ MAX_NUM_DEV ];
KSPIN_LOCK		gSpinLock;
PACKET			gPacketPool[ MAX_PACKET_NUM ];
LIST_ENTRY		gIdleQueue;
KSPIN_LOCK		gPoolSpinLock;



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 = STATUS_SUCCESS;
    //ULONG               ulIndex;
	ULONG				i;
    PDRIVER_DISPATCH  * dispatch;

    UNREFERENCED_PARAMETER (RegistryPath);

    DebugPrint (("-----------  Virtual Serial Device Build on %s %s  ----------\n", __DATE__, __TIME__ ));
    

    //
    // Create dispatch points
    //
	/*
    for (ulIndex = 0, dispatch = DriverObject->MajorFunction;
         ulIndex <= IRP_MJ_MAXIMUM_FUNCTION;
         ulIndex++, dispatch++) {

        *dispatch = DefaultPnpHandler;
    }
	*/

    DriverObject->MajorFunction[IRP_MJ_PNP]				= DispatchPnp;
    DriverObject->MajorFunction[IRP_MJ_POWER]			= DispatchPower;
    DriverObject->MajorFunction[IRP_MJ_CREATE]			= RequestCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]			= RequestClose;
	DriverObject->MajorFunction[IRP_MJ_CLEANUP ]		= RequestCleanup;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]	= RequestControl;

    DriverObject->MajorFunction[IRP_MJ_READ]			= DispatchRead;
    DriverObject->MajorFunction[IRP_MJ_WRITE]			= DispatchWrite;

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

	// Initialize global varible
	RtlZeroMemory( gDeviceArray, sizeof( DEVICE_ARRAY ) * MAX_NUM_DEV );
	KeInitializeSpinLock( &gSpinLock );
	RtlZeroMemory( gPacketPool, sizeof( PACKET ) * MAX_PACKET_NUM );
	InitializeListHead( &gIdleQueue );
	KeInitializeSpinLock( &gPoolSpinLock );

	for( i = 0; i < MAX_PACKET_NUM; i++)
	{
		InsertTailList( &gIdleQueue, &(gPacketPool[ i ].ListEntry) );
	}

    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; 
    
    PAGED_CODE ();

    //
    // Create a device object.
    //
	status = SerialCreateDevObj(DriverObject, &deviceObject);
    
    if (!NT_SUCCESS (status)) {
        //
        // Returning failure here prevents the entire stack from functioning,
        // but most likely the rest of the stack will not be able to create
        // device objects either, so it is still OK.
        //
		DebugPrint(("SerialCreateDevice failed with status %d\n", status ));
        return status;
    }

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

    deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;

	deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
  
    deviceExtension->NextLowerDriver = IoAttachDeviceToDeviceStack (
                                       deviceObject,
                                       PhysicalDeviceObject);
    //
    // Failure for attachment is an indication of a broken plug & play system.
    //
    if(NULL == deviceExtension->NextLowerDriver) {
        IoDeleteDevice(deviceObject);
        return STATUS_UNSUCCESSFUL;
    }

    INITIALIZE_PNP_STATE(deviceExtension);

 
    DebugPrint(("AddDevice: %x to %x->%x \n", deviceObject, 
                       deviceExtension->NextLowerDriver,
                       PhysicalDeviceObject));
	if( !NT_SUCCESS ( status ) ){
		DebugPrint(( "AddDevice:  IoRegisterDeviceInterface failed (%x) \n", status ));
		IoDetachDevice( deviceExtension->NextLowerDriver );
		gDeviceArray[ deviceExtension->localInstance ].deviceExtension = NULL;
		IoDeleteDevice( deviceObject );
		return status;
	}
	deviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    return STATUS_SUCCESS;

}
#if 0
FilterCompletionRoutine(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context
    )
/*++
Routine Description:
    A completion routine for use when calling the lower device objects to
    which our filter deviceobject is attached.

Arguments:

    DeviceObject - Pointer to deviceobject
    Irp          - Pointer to a PnP Irp.
    Context      - Pointer to an event object    
Return Value:

    NT Status is returned.

--*/

{
    UNREFERENCED_PARAMETER(DeviceObject);

    if (Irp->PendingReturned) {
        IoMarkIrpPending(Irp);
    }

    //
    // We could switch on the major and minor functions of the IRP to perform
    // different functions, but we know that Context is an event that needs
    // to be set.
    //

    KeSetEvent((PKEVENT) Context, IO_NO_INCREMENT, FALSE);

    //
    // Allows the caller to use the IRP after it is completed
    //
    return STATUS_MORE_PROCESSING_REQUIRED;
}
#endif

NTSTATUS
DispatchPower(
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP              Irp
    )
/*++

Routine Description:

    This routine is the dispatch routine for power irps.

Arguments:

    DeviceObject - Pointer to the device object.

    Irp - Pointer to the request packet.

Return Value:

    NT Status code
--*/
{
	NTSTATUS	status;
    PDEVICE_EXTENSION   deviceExtension;
    
    PAGED_CODE ();

	DebugPrint(("Enter DispatchPower routine...\n"));

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);
	DebugPrint(("NextLowerDriver:  0x%x\n", deviceExtension->NextLowerDriver ));
	status = PoCallDriver(deviceExtension->NextLowerDriver, Irp);

	DebugPrint(("-Exit Power\n") );
    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;
}


NTSTATUS RequestCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
/*++

Routine Description:

    Create the device

Arguments:

	DeviceObject	- Pointer to deviceobject
	Irp				- Pointer to an IRP_MJ_CREATE

Return Value:

    NT Status is return.

⌨️ 快捷键说明

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