?? rw.c
字號:
/*++
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 + -