?? ocrwblk.c
字號:
Return Value:
NT status code
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PFILE_OBJECT fileObject;
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
ULONG i, nameLen, ix, uval, umultiplier;
NTSTATUS actStat;
PUSBD_INTERFACE_INFORMATION interface;
PUSBD_PIPE_INFORMATION PipeInfo;
deviceExtension = DeviceObject->DeviceExtension;
interface = deviceExtension->UsbInterface;
BULKUSB_KdPrint( DBGLVL_DEFAULT,("entering BulkUsb_Create\n"));
BulkUsb_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 ( !BulkUsb_CanAcceptIoRequests( DeviceObject ) ) {
ntStatus = STATUS_DELETE_PENDING;
Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp,
IO_NO_INCREMENT
);
BulkUsb_DecrementIoCount(DeviceObject);
BULKUSB_KdPrint( DBGLVL_DEFAULT,("ABORTING BulkUsb_Create\n"));
return ntStatus;
}
irpStack = IoGetCurrentIrpStackLocation (Irp);
fileObject = irpStack->FileObject;
// fscontext is null for device
fileObject->FsContext = NULL;
nameLen = fileObject->FileName.Length;
if (nameLen != 0) {
BULKUSB_KdPrint( DBGLVL_DEFAULT,("BulkUsb_Create fileObject->FileName = %ws\n", fileObject->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( ( (fileObject->FileName.Buffer[ ix ] < (WCHAR) '0') ||
(fileObject->FileName.Buffer[ ix ] > (WCHAR) '9') ) && ix )
ix--;
BULKUSB_ASSERT( ix );
if ( !ix ) { // filename better have had at least one ascii digit!
ntStatus = STATUS_INVALID_PARAMETER;
} else {
//
// 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( ( (fileObject->FileName.Buffer[ ix ] >= (WCHAR) '0') &&
(fileObject->FileName.Buffer[ ix ] <= (WCHAR) '9') ) && ix ) {
uval += (umultiplier *
(ULONG) (fileObject->FileName.Buffer[ ix ] - (WCHAR) '0'));
ix--;
umultiplier *= 10;
}
// init status to bad; will set good in below loop on success
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
for (i=0; i<interface->NumberOfPipes; i++) {
PipeInfo = &interface->Pipes[i]; // PUSBD_PIPE_INFORMATION PipeInfo;
// find the corresponding unopened pipe
if ( ( uval == i) && !PipeInfo->PipeFlags) { // PipeFlags set if open
//
// found a match
//
BULKUSB_KdPrint( DBGLVL_DEFAULT,("open pipe %d\n", uval));
fileObject->FsContext = PipeInfo;
PipeInfo->PipeFlags = TRUE; // set flag for opened
ntStatus = STATUS_SUCCESS;
deviceExtension->OpenPipeCount++;
// try to power up device if its not in D0
actStat = BulkUsb_SelfSuspendOrActivate( DeviceObject, FALSE );
break;
}
}
}
} // if ix
Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp,
IO_NO_INCREMENT
);
BulkUsb_DecrementIoCount(DeviceObject);
BULKUSB_KdPrint( DBGLVL_DEFAULT,("exit BulkUsb_Create %x\n", ntStatus));
return ntStatus;
}
BOOLEAN
BulkUsb_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 (BULKUSB_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;
PUCHAR pCon = (PUCHAR) deviceExtension->PendingIoIrps;
ULONG i = 0;
PIRP Irp;
USHORT uDriverCancel = 0; // count cancelled via iocancelirp()
BOOLEAN cRes;
NTSTATUS ntStatus, waitStatus;
// nothing pending
if ( !deviceExtension->PendingIoIrps )
return FALSE;
BULKUSB_KdPrint ( DBGLVL_MAXIMUM, ("enter BulkUsb_CancelPendingIo()\n"));
// the BULKUSB_RW_CONTEXT array is terminated by an entry with a NULL Irp
for ( i = 0; ((PBULKUSB_RW_CONTEXT)pCon)->Irp ; i++ ) {
Irp = ((PBULKUSB_RW_CONTEXT) pCon)->Irp;
//
// Since IoCallDriver has been called on this request, we call IoCancelIrp
// and let our completion routine handle it
//
cRes = IoCancelIrp( Irp );
BULKUSB_KdPrint ( DBGLVL_MAXIMUM, ("BulkUsb_CancelPendingIo() IoCancelIrp() cRes=%d, IRP 0x%x\n", cRes, Irp));
// if cancel call failed, they all will, so dump out
if ( !cRes )
break;
uDriverCancel++; // flag we tried to cancel at least one
// point to next context struct in array
pCon += sizeof( BULKUSB_RW_CONTEXT);
} // end, for
if ( uDriverCancel && cRes ) {
// We only get here if we cancelled at least one and all cancellations were successfull.
// Wait on the event set on last cancel in BulkUsb_AsyncReadWriteComplete();
BULKUSB_KdPrint ( DBGLVL_MAXIMUM, ("BulkUsb_CancelPendingIo() before waiting for StagingDoneEvent()\n" ));
waitStatus = KeWaitForSingleObject(
&deviceExtension->StagingDoneEvent,
Suspended,
KernelMode,
FALSE,
NULL);
BULKUSB_KdPrint ( DBGLVL_MAXIMUM, ("BulkUsb_CancelPendingIo() finished waiting for StagingDoneEvent()\n" ));
}
BULKUSB_KdPrintCond ( DBGLVL_HIGH, uDriverCancel,
("BulkUsb_CancelPendingIo() cancelled %d via IoCancelIrp()\n",uDriverCancel));
return (BOOLEAN) uDriverCancel;
}
NTSTATUS
BulkUsb_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;
ULONG i;
PUSBD_INTERFACE_INFORMATION interface;
PUSBD_PIPE_INFORMATION PipeInfo;
deviceExtension = DeviceObject->DeviceExtension;
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
BULKUSB_KdPrint( DBGLVL_HIGH,("BulkUsb_AbortPipes() Aborting open Pipe %d\n", i));
urb = BULKUSB_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 =
PipeInfo->PipeHandle;
ntStatus = BulkUsb_CallUSBD(DeviceObject, urb);
BULKUSB_ExFreePool(urb);
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
BULKUSB_KdPrint( DBGLVL_HIGH,("BulkUsb_AbortPipes() FAILED urb alloc\n" ));
break;
}
if (!(NT_SUCCESS(ntStatus))) {
// if we failed, dump out
#if DBG
if ( gpDbg )
gpDbg->PipeErrorCount++;
#endif
break;
}
else {
PipeInfo->PipeFlags = FALSE; // mark the pipe 'closed'
deviceExtension->OpenPipeCount--;
#if DBG
if ( gpDbg )
gpDbg->AbortPipeCount++;
#endif
}
} // end, if pipe open
} // end, for all pipes
return ntStatus;
}
BOOLEAN
BulkUsb_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;
}
BULKUSB_KdPrintCond( DBGLVL_MAXIMUM, !fCan, ("**** FALSE return from BulkUsb_CanAcceptIoRequests()!\n"));
return fCan;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -