?? ocrwiso.c
字號:
return ntStatus;
}
PISOUSB_PIPEINFO IsoUsb_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;
PISOUSB_PIPEINFO pipeInfo = NULL;
ULONG i, nameLen, ix, uval , umultiplier;
nameLen = FileName->Length;
if (nameLen != 0) {
ISOUSB_KdPrint( DBGLVL_DEFAULT,("IsoUsb_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 ];
}
ISOUSB_KdPrint ( DBGLVL_HIGH, ("Exit IsoUsb_PipeWithName() pipeInfo = 0x%x, ix = %d\n", pipeInfo, uval ));
return pipeInfo;
}
NTSTATUS
IsoUsb_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;
PISOUSB_PIPEINFO pipeInfo = NULL;
ISOUSB_KdPrint( DBGLVL_DEFAULT,("entering IsoUsb_Close\n"));
IsoUsb_IncrementIoCount(DeviceObject);
deviceExtension = DeviceObject->DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation (Irp);
fileObject = irpStack->FileObject;
if (fileObject->FsContext) {
// closing pipe handle
pipeHandle = fileObject->FsContext;
pipeInfo = IsoUsb_PipeWithName( DeviceObject, &fileObject->FileName );
if ( NULL == pipeInfo )
goto done;
if ( pipeInfo->fPipeOpened ) { // set if opened
// may have been aborted
ISOUSB_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
ISOUSB_ASSERT( deviceExtension->DeviceRemoved );
ISOUSB_KdPrint( DBGLVL_DEFAULT,("Pipe %x was already closed \n", pipeHandle));
}
}
done:
IsoUsb_DecrementIoCount(DeviceObject);
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 = IsoUsb_SelfSuspendOrActivate( DeviceObject, TRUE );
ISOUSB_KdPrint( DBGLVL_DEFAULT,("exit IsoUsb_Close OpenPipeCount = decimal %d, status %x\n",deviceExtension->OpenPipeCount, ntStatus));
return ntStatus;
}
NTSTATUS
IsoUsb_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;
PISOUSB_PIPEINFO ourPipeInfo = NULL;
deviceExtension = DeviceObject->DeviceExtension;
interface = deviceExtension->UsbInterface;
ISOUSB_KdPrint( DBGLVL_DEFAULT,("entering IsoUsb_Create\n"));
IsoUsb_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 ( !IsoUsb_CanAcceptIoRequests( DeviceObject ) ) {
ntStatus = STATUS_DELETE_PENDING;
ISOUSB_KdPrint( DBGLVL_DEFAULT,("ABORTING IsoUsb_Create\n"));
goto done;
}
irpStack = IoGetCurrentIrpStackLocation (Irp);
fileObject = irpStack->FileObject;
// fscontext is null for device
fileObject->FsContext = NULL;
if ( 0 == fileObject->FileName.Length ) // this is the case if opening device as opposed to pipe
goto done; // nothing more to do
ourPipeInfo = IsoUsb_PipeWithName( DeviceObject, &fileObject->FileName );
if ( !ourPipeInfo ) {
ntStatus = STATUS_INVALID_PARAMETER;
goto done;
}
// 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;
if ( ourPipeInfo == &deviceExtension->PipeInfo[i] ) {
//
// found a match
//
ISOUSB_KdPrint( DBGLVL_DEFAULT,("open pipe %d\n", i));
fileObject->FsContext = PipeInfo;
ourPipeInfo->fPipeOpened = TRUE; // set flag for opened
ntStatus = STATUS_SUCCESS;
deviceExtension->OpenPipeCount++;
// try to power up device if its not in D0
actStat = IsoUsb_SelfSuspendOrActivate( DeviceObject, FALSE );
break;
}
}
done:
Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp,
IO_NO_INCREMENT
);
IsoUsb_DecrementIoCount(DeviceObject);
ISOUSB_KdPrint( DBGLVL_DEFAULT,("exit IsoUsb_Create %x\n", ntStatus));
return ntStatus;
}
NTSTATUS
IsoUsb_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;
PISOUSB_PIPEINFO PipeInfo;
deviceExtension = DeviceObject->DeviceExtension;
interface = deviceExtension->UsbInterface;
for (i=0; i<interface->NumberOfPipes; i++) {
PipeInfo = &deviceExtension->PipeInfo[i]; // PISOUSB_PIPEINFO PipeInfo;
if ( PipeInfo->fPipeOpened ) { // we set this if open, clear if closed
ISOUSB_KdPrint( DBGLVL_HIGH,("IsoUsb_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 = IsoUsb_CallUSBD(DeviceObject, urb);
ExFreePool(urb);
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
ISOUSB_KdPrint( DBGLVL_HIGH,("IsoUsb_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->fPipeOpened = 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
IsoUsb_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;
}
ISOUSB_KdPrintCond( DBGLVL_MAXIMUM, !fCan, ("**** FALSE return from IsoUsb_CanAcceptIoRequests()!\n"));
return fCan;
}
//******************************************************************************
//
// IsoUsb_CompletionStop()
//
// IO Completion Routine which just stops further completion of the Irp
//
//******************************************************************************
NTSTATUS
IsoUsb_CompletionStop (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
return STATUS_MORE_PROCESSING_REQUIRED;
}
//******************************************************************************
//
// IsoUsb_GetCurrentFrame()
//
//******************************************************************************
ULONG
IsoUsb_GetCurrentFrame (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION deviceExtension;
PIO_STACK_LOCATION nextStack;
NTSTATUS ntStatus;
struct _URB_GET_CURRENT_FRAME_NUMBER urb;
deviceExtension = DeviceObject->DeviceExtension;
// Initialize the URB
//
urb.Hdr.Function = URB_FUNCTION_GET_CURRENT_FRAME_NUMBER;
urb.Hdr.Length = sizeof(urb);
urb.FrameNumber = (ULONG)-1;
// Set the IRP parameters to pass the URB down the stack
//
nextStack = IoGetNextIrpStackLocation(Irp);
nextStack->Parameters.Others.Argument1 = &urb;
nextStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
// Since this Irp is borrowed for URB_FUNCTION_GET_CURRENT_FRAME_NUMBER
// before it is passed down later for the real URB request after this
// routine returns, set a completion routine which stop further completion
// of the Irp.
//
IoSetCompletionRoutine(
Irp,
IsoUsb_CompletionStop, // this routine does nothing but return STATUS_MORE_PROCESSING_REQUIRED
NULL, // Context
TRUE, // InvokeOnSuccess
TRUE, // InvokeOnError
TRUE // InvokeOnCancel
);
// Now pass the Irp down the stack
//
ntStatus = IoCallDriver(
deviceExtension->TopOfStackDeviceObject,
Irp
);
// Don't need to wait for completion because
// URB_FUNCTION_GET_CURRENT_FRAME_NUMBER will never return STATUS_PENDING
ISOUSB_KdPrint ( DBGLVL_MEDIUM, (" IsoUsb_GetCurrentFrame() offset = 0x%08X, decimal %d\n",
urb.FrameNumber,
urb.FrameNumber));
return urb.FrameNumber;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -