📄 ocrw.c
字号:
/*++
Module Name:
Ocrw.c
Abstract:
Read/write io code
Environment:
kernel mode only
--*/
#include "wdm.h"
#include "stdarg.h"
#include "stdio.h"
#define DRIVER
#include "usbdi.h"
#include "usbdlib.h"
#include "usbcom.h"
NTSTATUS
UsbCom_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,NextStack;
PDEVICE_EXTENSION deviceExtension;
PUSBD_PIPE_INFORMATION pipeHandle = NULL;
PUsbCom_PIPEINFO pipeInfo = NULL;
PIRP irp;
CHAR StackSize;
KEVENT event;
DbgPrint("entering UsbCom_Close\n");
UsbCom_IncrementIoCount(DeviceObject);
deviceExtension = DeviceObject->DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation (Irp);
//
// Clean out the holding reasons (since we are closed).
//
deviceExtension->RXHolding = 0;
deviceExtension->TXHolding = 0;
//
// Mark device as not busy for WMI
//
deviceExtension->WmiCommData.IsBusy = FALSE;
//
// All is done. The port has been disabled from interrupting
// so there is no point in keeping the memory around.
//
deviceExtension->BufferSize = 0;
if (deviceExtension->InterruptReadBuffer != NULL) {
ExFreePool(deviceExtension->InterruptReadBuffer);
}
deviceExtension->InterruptReadBuffer = NULL;
UsbCom_DecrementIoCount(DeviceObject);
// UsbCom_DecrementIoCount(DeviceObject);//henry, to balance the read urb.
KeWaitForSingleObject(
&deviceExtension->NoPendingIoEvent,
Suspended,
KernelMode,
FALSE,
NULL);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
ntStatus = Irp->IoStatus.Status;
deviceExtension->DeviceIsOpened = FALSE;
IoCompleteRequest (Irp,
IO_NO_INCREMENT
);
// try to power down device if this is the last pipe
if(!GlobalPdaCount)
actStat = UsbCom_SelfSuspendOrActivate( DeviceObject, TRUE );
DbgPrint("exit UsbCom_Close OpenPipeCount = decimal %d, status %x\n",deviceExtension->OpenPipeCount, ntStatus);
return ntStatus;
}
BOOLEAN
UsbCom_CancelPendingIo(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Cancels pending IO, as on a sudden IRP_MN_REMOVE_DEVICE
This driver maintains and array of info structs (UsbCom_RW_CONTEXT)
on self-generated IRPS for staged read/writes; This routine traverses
it and cancels all pending IO irps
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
device.
Return Value:
TRUE if cancelled any, else FALSE
--*/
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
DbgPrint ("enter UsbCom_CancelPendingIo()\n");
if(deviceExtension->ReadingIrp)
IoCancelIrp(deviceExtension->ReadingIrp);
if(deviceExtension->PollingIrp)
IoCancelIrp(deviceExtension->PollingIrp);
return TRUE;
}
NTSTATUS
UsbCom_AbortPipes(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Called as part of sudden device removal handling.
Cancels any pending transfers for all open pipes.
If any pipes are still open, call USBD with URB_FUNCTION_ABORT_PIPE
Also marks the pipe 'closed' in our saved configuration info.
Arguments:
Ptrs to our FDO
Return Value:
NT status code
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb;
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
ULONG i;
PUSBD_INTERFACE_INFORMATION interface;
PUSBD_PIPE_INFORMATION PipeInfo;
//PUCHAR pInf = (PUCHAR ) deviceExtension->PipeInfo;
interface = deviceExtension->UsbInterface;
for (i=0; i<interface->NumberOfPipes; i++) {
PipeInfo = &interface->Pipes[i]; // PUSBD_PIPE_INFORMATION PipeInfo;
if ( PipeInfo->PipeFlags ) { // we set this if open, clear if closed
DbgPrint("UsbCom_AbortPipes() Aborting open Pipe %d\n", i);
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_PIPE_REQUEST));
if (urb) {
urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
urb->UrbPipeRequest.PipeHandle =
interface->Pipes[i].PipeHandle;
ntStatus = UsbCom_CallUSBD(DeviceObject, urb);
ExFreePool(urb);
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
DbgPrint("UsbCom_AbortPipes() FAILED urb alloc\n" );
break;
}
if (!(NT_SUCCESS(ntStatus))) {
// if we failed, dump out
break;
}
else {
PipeInfo->PipeFlags = FALSE; // mark the pipe 'closed'
deviceExtension->OpenPipeCount--;
}
} // end, if pipe open
} // end, for all pipes
return ntStatus;
}
BOOLEAN
UsbCom_CanAcceptIoRequests(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Check device extension status flags;
Can't accept a new io request if device:
1) is removed,
2) has never been started,
3) is stopped,
4) has a remove request pending, or
5) has a stop device pending
Arguments:
DeviceObject - pointer to the device object for this instance of the 82930
device.
Return Value:
return TRUE if can accept new io requests, else FALSE
--*/
{
PDEVICE_EXTENSION deviceExtension;
BOOLEAN fCan = FALSE;
deviceExtension = DeviceObject->DeviceExtension;
//flag set when processing IRP_MN_REMOVE_DEVICE
if ( !deviceExtension->DeviceRemoved &&
// device must be started( enabled )
deviceExtension->DeviceStarted &&
// flag set when driver has answered success to IRP_MN_QUERY_REMOVE_DEVICE
!deviceExtension->RemoveDeviceRequested &&
// flag set when driver has answered success to IRP_MN_QUERY_STOP_DEVICE
!deviceExtension->StopDeviceRequested ){
fCan = TRUE;
}
return fCan;
}
NTSTATUS
UsbCom_Cleanup(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This function is used to kill all longstanding IO operations.
Arguments:
DeviceObject - Pointer to the device object for this device
Irp - Pointer to the IRP for the current request
Return Value:
The function value is the final status of the call
--*/
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
NTSTATUS status;
//
// We succeed a cleanup on a removing device
//
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information=0L;
DbgPrint("Complete Cleanup Irp: %x\n",Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -