Archived from groups: microsoft.public.windowsxp.device_driver.dev (More info?)
Hello all,
I am using my driver sample from Win2k DDK isousb sample driver , and
wanted to add support in it
for Bulk OUT . So i added an IOCTL for Bulk Transfer . This also
worked fine , however for a limited buffer
size . So i decided to add mutli-staging to it( IRP reuse ) , and for
that basically used the sample code in Bulkusb.sys XP DDK sample .
BulkUsb.sys was handling Bulk write requests through IRP_MJ_WRITE
dispatch routine , but i am doint it through
IOCTLs.
This however crashes my system , and i am at a loss to understand why.
When i single step through the completion routine in the Kernel
debugger , by setting a breakpoint
in the completion routine , and when it hits the breakpoint second
time , sometimes single steppign thru the code
and taking function call stack trace , a call to NT!IoCancelIRP is
showing up , looks like somebody is canceling the
IRP
At other times when not single stepping but with KD attached , it
breaks with a second chance AV in the
IoBuildPartialMdl() function call in completion routine
If KD is not attached , the system crashes and the bugcheck code is
something like MULTIPLE_COMPLETION_ROUTINES ( i fogot
the exact code but u get the idea )
Some of the code snippets from IOctlDispatcher , Bulk_Write_Handler
and CompletionRoutine are as follows:
The EXACT source ( lengthy ) to these functions is also at the very
end of the message .
I would very much appreciate any help
thanks in advance
Taha
IN DEVIOCTL DISPATCH ROUTINE
===============================
//
// map the portion of user-buffer described by an mdl to another
mdl
//
IoBuildPartialMdl(Irp->MdlAddress,
mdl,
(PVOID) virtualAddress,
stageLength);
IN CASE OF ERRORS , we jump to a label which has the following (
completes IRP )
--------------------------------------------------------------------------------
// 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 ( !USBXGA_CanAcceptIoRequests( FdoDeviceObject ) )
{
USBXGA_KdPrint( DBGLVL_DEFAULT,("USBXGA_ProcessIOCTL...USBXGA_CanAcceptIoRequests
Fail\n" ));
ntStatus = STATUS_DELETE_PENDING;
Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = 0;
// get pointers and lengths of the caller's (user's) IO buffer
ioBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength =
irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength =
irpStack->Parameters.DeviceIoControl.OutputBufferLength;
if ( FALSE == bFoundBulkPipe )
{
USBXGA_KdPrint( DBGLVL_DEFAULT,("\n
USBXGA_Bulk_Write_Multiple_Stage() ERROR! , did not find a Bulk Pipe
in the interface - Exiting" ));
ntStatus = STATUS_INVALID_PARAMETER;
goto BulkUsb_DispatchReadWrite_Exit;
}
if(NULL == rwContext )
{
USBXGA_KdPrint( DBGLVL_DEFAULT,("\n
USBXGA_Bulk_Write_Multiple_Stage() ...ERROR! Failed to alloc mem for
rwContext.. Exiting \n" ));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto BulkUsb_DispatchReadWrite_Exit;
}
if(Irp->MdlAddress)
{
totalLength = MmGetMdlByteCount(Irp->MdlAddress);
}
else
{
//just log to the debugger that we got a NULL MDL Address
USBXGA_KdPrint( DBGLVL_DEFAULT,("\n
USBXGA_Bulk_Write_Multiple_Stage() ... Info Only : Irp->MdlAddress is
NULL \n" ));
}
if(totalLength > USBXGA_ARBITRARY_MAX_BULK_BUFFER_SIZE )
{
USBXGA_KdPrint( DBGLVL_DEFAULT,("\n
USBXGA_Bulk_Write_Multiple_Stage() ...ERROR! total buffer length is
GREATER than Arbitrary total size.. Exiting \n" ));
ntStatus = STATUS_INVALID_PARAMETER;
ExFreePool(rwContext);
goto BulkUsb_DispatchReadWrite_Exit;
}
if(totalLength == 0)
{
USBXGA_KdPrint( DBGLVL_DEFAULT,("\n
USBXGA_Bulk_Write_Multiple_Stage() ... Info Only : Transfer data
length = 0\n" ));
ntStatus = STATUS_SUCCESS;
ExFreePool(rwContext);
goto BulkUsb_DispatchReadWrite_Exit;
}
if(NULL == mdl )
{
USBXGA_KdPrint( DBGLVL_DEFAULT,("\n
USBXGA_Bulk_Write_Multiple_Stage() ... ERROR! Failed to alloc mem for
mdl .. Exiting \n" ));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
ExFreePool(rwContext);
goto BulkUsb_DispatchReadWrite_Exit;
}
//
// map the portion of user-buffer described by an mdl to another
mdl
//
IoBuildPartialMdl(Irp->MdlAddress,
mdl,
(PVOID) virtualAddress,
stageLength);
//
// since we return STATUS_PENDING call IoMarkIrpPending.
// This is the boiler plate code.
// This may cause extra overhead of an APC for the Irp completion
// but this is the correct thing to do.
//
IoMarkIrpPending(Irp);
USBXGA_IncrementIoCount(fdo);
USBXGA_KdPrint( DBGLVL_DEFAULT,("\n
USBXGA_Bulk_Write_Multiple_Stage() ... Info only: About to Call
IoCallDriver \n" ));
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
if(!NT_SUCCESS(ntStatus))
{
USBXGA_KdPrint( DBGLVL_DEFAULT,("\n IoCallDriver fails with status
%X\n", ntStatus));
//
// if the device was yanked out, then the pipeInformation
// field is invalid.
// similarly if the request was cancelled, then we need not
// invoked reset pipe/device.
//
if( (ntStatus != STATUS_CANCELLED) &&
(ntStatus != STATUS_DEVICE_NOT_CONNECTED)
)
{
ntStatus = USBXGA_ResetPipe(fdo, bulkPipeInfo);
if(!NT_SUCCESS(ntStatus))
{
USBXGA_KdPrint( DBGLVL_DEFAULT,("\n
USBXGA_Bulk_Write_Multiple_Stage() ... ERROR! USBXGA_ResetPipe failed
with ntstatus == %x , Attempting to Reset Device\n" , ntStatus));
}
}
else
{
USBXGA_KdPrint( DBGLVL_DEFAULT,("\n
USBXGA_Bulk_Write_Multiple_Stage() ... ntStatus is STATUS_CANCELLED or
STATUS_DEVICE_NOT_CONNECTED\n" ));
}
}
//
// we return STATUS_PENDING and not the status returned by the
lower layer.
//
return STATUS_PENDING;
You are about to answer a thread that has been inactive for more than 6 months. If you still wish to proceed, please ensure that your posting is original and does not duplicate or overlap any prior responses to this thread.