thank you ,Tim Roberts ,right now i use debugView print the driver log,and find the error.
00006340 84.51743317 Drv: ReadWriteBulkEndPoints - begins
00006341 84.51743317 Drv: Transfer length (122880) is bigger then MaximumTransferSize (65536)!
00006342 84.51744843 Drv: ReadWriteBulkEndPoints - ends
if (totalLength > deviceContext->MaximumTransferSize)
{
PSDrv_DbgPrint(1, (“Transfer length (%d) is bigger then MaximumTransferSize (%d)!\n”, totalLength, deviceContext->MaximumTransferSize));
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
and the driver code is :
VOID ReadWriteBulkEndPoints(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN ULONG Length, IN WDF_REQUEST_TYPE RequestType)
{
PMDL newMdl = NULL;
PMDL requestMdl = NULL;
PURB urb = NULL;
WDFMEMORY urbMemory;
ULONG totalLength = Length;
ULONG stageLength = 0;
ULONG urbFlags = 0;
NTSTATUS status;
ULONG_PTR virtualAddress = 0;
PREQUEST_CONTEXT rwContext = NULL;
PFILE_CONTEXT fileContext = NULL;
WDFUSBPIPE pipe;
WDF_USB_PIPE_INFORMATION pipeInfo;
WDF_OBJECT_ATTRIBUTES objectAttribs;
USBD_PIPE_HANDLE usbdPipeHandle;
PDEVICE_CONTEXT deviceContext;
WDF_REQUEST_SEND_OPTIONS sendOptions;
PSDrv_DbgPrint(3, (“ReadWriteBulkEndPoints - begins\n”));
// First validate input parameters.
deviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
if (totalLength > deviceContext->MaximumTransferSize)
{
PSDrv_DbgPrint(1, (“Transfer length (%d) is bigger then MaximumTransferSize (%d)!\n”, totalLength, deviceContext->MaximumTransferSize));
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
if ((RequestType != WdfRequestTypeRead) && (RequestType != WdfRequestTypeWrite))
{
PSDrv_DbgPrint(1, (“RequestType has to be either Read or Write! (RequestType = %d)\n”, RequestType));
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
// Get the pipe associate with this request.
fileContext = GetFileContext(WdfRequestGetFileObject(Request));
pipe = fileContext->Pipe;
WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
WdfUsbTargetPipeGetInformation(pipe, &pipeInfo);
if((WdfUsbPipeTypeBulk != pipeInfo.PipeType) && (WdfUsbPipeTypeInterrupt != pipeInfo.PipeType))
{
PSDrv_DbgPrint(1, (“Usbd pipe type is not bulk or interrupt! (PipeType = %d)\n”, pipeInfo.PipeType));
status = STATUS_INVALID_DEVICE_REQUEST;
goto Exit;
}
rwContext = GetRequestContext(Request);
if(RequestType == WdfRequestTypeRead)
{
status = WdfRequestRetrieveOutputWdmMdl(Request, &requestMdl);
if(!NT_SUCCESS(status))
{
PSDrv_DbgPrint(1, (“WdfRequestRetrieveOutputWdmMdl failed! (Status = %x)\n”, status));
goto Exit;
}
urbFlags |= USBD_TRANSFER_DIRECTION_IN;
rwContext->Read = TRUE;
PSDrv_DbgPrint(3, (“This is a read operation…\n”));
}
else
{
status = WdfRequestRetrieveInputWdmMdl(Request, &requestMdl);
if(!NT_SUCCESS(status))
{
PSDrv_DbgPrint(1, (“WdfRequestRetrieveInputWdmMdl failed! (Status = %x)\n”, status));
goto Exit;
}
urbFlags |= USBD_TRANSFER_DIRECTION_OUT;
rwContext->Read = FALSE;
PSDrv_DbgPrint(3, (“This is a write operation…\n”));
}
urbFlags |= USBD_SHORT_TRANSFER_OK;
virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(requestMdl);
// The transfer request is for totalLength. We can perform a max of MAX_TRANSFER_SIZE in each stage.
if (totalLength > MAX_TRANSFER_SIZE)
{
stageLength = MAX_TRANSFER_SIZE;
}
else
{
stageLength = totalLength;
}
newMdl = IoAllocateMdl((PVOID)virtualAddress, totalLength, FALSE, FALSE, NULL);
if (newMdl == NULL)
{
PSDrv_DbgPrint(1, (“IoAllocateMdl failed! (newMdl is NULL)\n”));
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
// Map the portion of user-buffer described by an mdl to another mdl
IoBuildPartialMdl(requestMdl, newMdl, (PVOID)virtualAddress, stageLength);
WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs);
objectAttribs.ParentObject = Request;
status = WdfMemoryCreate(&objectAttribs, NonPagedPool, POOL_TAG, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), &urbMemory, (PVOID*)&urb);
if (!NT_SUCCESS(status))
{
PSDrv_DbgPrint(1, (“WdfMemoryCreate for urbMemory failed! (Status = %x)\n”, status));
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
usbdPipeHandle = WdfUsbTargetPipeWdmGetPipeHandle(pipe);
UsbBuildInterruptOrBulkTransferRequest(urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), usbdPipeHandle, NULL, newMdl, stageLength, urbFlags, NULL);
status = WdfUsbTargetPipeFormatRequestForUrb(pipe, Request, urbMemory, NULL);
if (!NT_SUCCESS(status))
{
PSDrv_DbgPrint(1, (“WdfUsbTargetPipeFormatRequestForUrb failed! (Status = %x)\n”, status));
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);
// Set REQUEST_CONTEXT parameters.
rwContext->UrbMemory = urbMemory;
rwContext->Mdl = newMdl;
rwContext->Length = totalLength - stageLength;
rwContext->Numxfer = 0;
rwContext->VirtualAddress = virtualAddress + stageLength;
// Set the timeout
if (fileContext->nTimeOut != 0)
{
WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT);
WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_MS(fileContext->nTimeOut));
PSDrv_DbgPrint(3, (“Pipe timeout is set to: %d\n”, fileContext->nTimeOut));
if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), &sendOptions))
{
status = WdfRequestGetStatus(Request);
ASSERT(!NT_SUCCESS(status));
}
}
else
{
if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS))
{
status = WdfRequestGetStatus(Request);
ASSERT(!NT_SUCCESS(status));
}
}
Exit:
if (!NT_SUCCESS(status))
{
WdfRequestCompleteWithInformation(Request, status, 0);
if (newMdl != NULL)
{
IoFreeMdl(newMdl);
}
}
PSDrv_DbgPrint(3, (“ReadWriteBulkEndPoints - ends\n”));
return;
}