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

📄 rw.c

📁 usb to rs232 虚拟RS232串口驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/*++

Copyright (c) 2005-2006  E0 Technology,Inc.

Module Name:

	rw.c

Abstract:

	Virtual Com Port Driver for USB to RS232 Converter of E0 Technology,Inc.

Environment:

	Kernel mode

Notes:

Revision History:

    2006/3/1 : 	created.
--*/


#include "usb2com.h"

NTSTATUS
ReadIntUrbComplete(
    	IN PDEVICE_OBJECT DeviceObject,
    	IN PIRP Irp,
    	IN PVOID Context
    	);
NTSTATUS
StopReadIntUrb(
	IN PDEVICE_EXTENSION deviceExtension
	);
NTSTATUS
StartReadIntUrb(
	IN PDEVICE_OBJECT DeviceObject,
	IN PUSBD_PIPE_INFORMATION PipeInfo
	);
void
IrpCancelRoutine(
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp);
PIRP
DequeueReadIrp(
	PDEVICE_EXTENSION deviceExtension
	);
	
NTSTATUS QueueOrCompleteReadIrp(
	PDEVICE_EXTENSION deviceExtension,
	PIRP Irp);

NTSTATUS
WriteIntUrbComplete(
    	IN PDEVICE_OBJECT DeviceObject,
    	IN PIRP Irp,
    	IN PVOID Context
    	);
    
PIRP 
DequeueWriteIrp(
	IN PDEVICE_EXTENSION deviceExtension
	);

NTSTATUS
QueueOrStartWriteIrp(
	IN PDEVICE_EXTENSION deviceExtension,
	IN PIRP Irp);

VOID 
WriteIrpCancelRoutine(
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp);

NTSTATUS
StopWriteIntUrb(
	IN PDEVICE_EXTENSION deviceExtension
	);
	
NTSTATUS
StartWriteIntUrb(
	PDEVICE_OBJECT	DeviceObject
	);
	
NTSTATUS
PrepareWriteIntUrb(
	IN PDEVICE_OBJECT DeviceObject,
	IN PUSBD_PIPE_INFORMATION PipeInfo
	);

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

Routine Description:

	This is the IRP_MJ_READ routine set in our dispatch table;
	ReadFile() calls from user mode ultimately land here

Arguments:

    DeviceObject - pointer to the device object for this instance of the 82930
                    device.

    IRP - pointer to the IRP_MJ_READ

Return Value:

    NT status code

--*/
{

    //NTSTATUS ntStatus = USB2COM_StagedReadWrite(DeviceObject,
      //                            Irp,
        //                          TRUE);	// false to write, true to read
	NTSTATUS ntStatus = QueueOrCompleteReadIrp(DeviceObject->DeviceExtension,Irp);
    return ntStatus;                                  

}

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

Routine Description:
	This is the IRP_MJ_WRITE routine set in our dispatch table;
	WriteFile() calls from user mode ultimately land here

Arguments:

    DeviceObject - pointer to the device object for this instance of the 82930
                    device.

    IRP - pointer to the IRP_MJ_WRITE

Return Value:

    NT status code

--*/
{

    //NTSTATUS ntStatus = USB2COM_StagedReadWrite(DeviceObject,
      //                            Irp,
        //                          FALSE);	// false to write, true to read
    NTSTATUS ntStatus = QueueOrStartWriteIrp(
    				DeviceObject->DeviceExtension,
    				Irp);
    return ntStatus;                                  
}


PUSB2COM_PIPEINFO USB2COM_PipeWithName( 
    IN PDEVICE_OBJECT DeviceObject,
    IN PUNICODE_STRING FileName
   )
/*++

Routine Description:

    Given a PUSBD_PIPE_INFORMATION, return our device extension pipe info struct
      that has this hanndle, else NULL

--*/
{
    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension; 
    PUSB2COM_PIPEINFO pipeInfo = NULL;
    ULONG i, nameLen, ix, uval , umultiplier;

	nameLen = FileName->Length/2;

    if (nameLen != 0) {

		USB2COM_KdPrint( DBGLVL_DEFAULT,("USB2COM_PipeWithName FileName = %ws\n", FileName->Buffer ));

		// Get pipe# to open
		ix = nameLen -1;  // index last char of pipe name

		// if last char isn't digit, decrement till it is
		while( ( (FileName->Buffer[ ix ] < (WCHAR) '0') ||
				(FileName->Buffer[ ix ] > (WCHAR) '9') ) && ix )
				ix--;  

		if (  ix  )  {  //  filename better have had at least one ascii digit!    

			//
			// A name was specified, convert it to a pipe id.
			// Parse the ansi ascii decimal 0-based pipe number 
			//
			uval = 0;
			umultiplier = 1;
			// we're traversing least-to-most significant digits
			while( ( (FileName->Buffer[ ix ] >= (WCHAR) '0') &&
				(FileName->Buffer[ ix ] <= (WCHAR) '9') ) && ix ) {

				uval +=  (umultiplier *
					     (ULONG) (FileName->Buffer[ ix ] - (WCHAR) '0'));
				ix--;
				umultiplier *= 10; 
            }
		}
        pipeInfo = &deviceExtension->PipeInfo[ uval ];
    }

    USB2COM_KdPrint ( DBGLVL_HIGH, ("Exit USB2COM_PipeWithName() pipeInfo = 0x%x, ix = %d\n", pipeInfo, uval ));

    return pipeInfo;
}

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

Routine Description:

    This is the dispatch table routine for IRP_MJ_CLOSE.
    It handles user mode CloseHandle() calls for a pipe
    It closes the File Object for the pipe handle it represents.

Arguments:

    DeviceObject - pointer to our FDO (Functional Device Object )


Return Value:

    NT status code

--*/
{
    NTSTATUS ntStatus;
	NTSTATUS actStat;
    PFILE_OBJECT fileObject;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_EXTENSION deviceExtension;
    PUSBD_PIPE_INFORMATION pipeHandle = NULL;
    PUSB2COM_PIPEINFO pipeInfo = NULL;
    NTSTATUS waitStatus;

    USB2COM_KdPrint( DBGLVL_DEFAULT,("entering USB2COM_Close\n"));

    
    USB2COM_IncrementIoCount(DeviceObject);

    deviceExtension = DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation (Irp);
    deviceExtension->PipeInfo[0].fPipeOpened = FALSE;  
    deviceExtension->OpenPipeCount--;
    StopReadIntUrb(deviceExtension);
    deviceExtension->PipeInfo[1].fPipeOpened = FALSE;  
    StopWriteIntUrb(deviceExtension);
    deviceExtension->OpenPipeCount--;
    fileObject = irpStack->FileObject;
    if(fileObject == NULL)
    	goto done;
    if (fileObject->FsContext) {
        // closing pipe handle
        pipeHandle =  fileObject->FsContext;

        pipeInfo = USB2COM_PipeWithName( DeviceObject, &fileObject->FileName );

        if ( NULL == pipeInfo )
            goto done;

		if ( pipeInfo->fPipeOpened ) { // set if opened
			// may have been aborted
			USB2COM_KdPrint( DBGLVL_DEFAULT,("closing pipe %x\n", pipeHandle));
			deviceExtension->OpenPipeCount--;
			pipeInfo->fPipeOpened = FALSE;
		}
		else {
			// pipe was already closed; this can only be if we got a sudden REMOVE_DEVICE
			USB2COM_ASSERT(  deviceExtension->DeviceRemoved );
			USB2COM_KdPrint( DBGLVL_DEFAULT,("Pipe %x was already closed \n", pipeHandle));

		}
    }

done:
	USB2COM_DecrementIoCount(DeviceObject);
	waitStatus = KeWaitForSingleObject(
                    &deviceExtension->NoPendingIoEvent,
                    Suspended,
                    KernelMode,
                    FALSE,
                    NULL);
    DbgPrint("waitStatus %x\n",waitStatus);
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    ntStatus = Irp->IoStatus.Status;


    IoCompleteRequest (Irp,
                       IO_NO_INCREMENT
                       );
                       
	// try to power down device if this is the last pipe
	actStat = USB2COM_SelfSuspendOrActivate( DeviceObject, TRUE );

    USB2COM_KdPrint( DBGLVL_DEFAULT,("exit USB2COM_Close OpenPipeCount = decimal %d, status %x\n",deviceExtension->OpenPipeCount, ntStatus));

    return ntStatus;
}


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

Routine Description:

    This is the dispatch table routine for IRP_MJ_CREATE.
    It's the entry point for CreateFile() calls
    user mode apps may open "<name genned fron GUID>.\yy"
    where yy is the internal pipe id

Arguments:

    DeviceObject - pointer to our FDO ( Functional Device Object )


Return Value:

    NT status code

--*/
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PFILE_OBJECT fileObject;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_EXTENSION deviceExtension;
    ULONG i, ix;
	NTSTATUS actStat;
    PUSBD_INTERFACE_INFORMATION interface;
	PUSBD_PIPE_INFORMATION PipeInfo;
    PUSB2COM_PIPEINFO ourPipeInfo = NULL;
    	KIRQL Irql;



    deviceExtension = DeviceObject->DeviceExtension;
    interface = deviceExtension->UsbInterface;

    USB2COM_KdPrint( DBGLVL_DEFAULT,("entering USB2COM_Create\n"));

	//DbgBreakPoint();
    USB2COM_IncrementIoCount(DeviceObject);

    // Can't accept a new io request if:
    //  1) device is removed, 
    //  2) has never been started, 
    //  3) is stopped,
    //  4) has a remove request pending,
    //  5) has a stop device pending
    if ( !USB2COM_CanAcceptIoRequests( DeviceObject ) ) {
        ntStatus = STATUS_DELETE_PENDING;

		USB2COM_KdPrint( DBGLVL_DEFAULT,("ABORTING USB2COM_Create\n"));
        goto done;
    }
    	KeAcquireSpinLock(&deviceExtension->InputBufferLock, &Irql);
    	ResetCircularBuffer(&deviceExtension->InputBuffer);
	KeReleaseSpinLock(&deviceExtension->InputBufferLock, Irql);

	StartReadIntUrb(
		DeviceObject,
		&interface->Pipes[0]
		);
	deviceExtension->PipeInfo[0].fPipeOpened = TRUE;  

⌨️ 快捷键说明

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