From: Sushma on
>
> MmGetSystemAddressForMdlSafe
>

I get status unsuccessful followed by reset port request in completion
routine. I copy the mdl buffer and then create a new request and
submit it. Here is code snippet. Please let me know if I'm missing
anything here. Is below code the correct way to copy the mdl buffer.

DispatchRoutine()
{
totalLength = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
virtualAddress = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
if (virtualAddress == NULL) {
return status;
}
buffer = ExAllocatePoolWithTag(NonPagedPool, totalLength, 'LDMN');
if (buffer == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}

byteCnt = MmGetMdlByteCount(Irp->MdlAddress);

RtlCopyMemory(buffer, (PVOID)virtualAddress, byteCnt);

newMdl = IoAllocateMdl((PVOID) buffer,totalLength,FALSE,FALSE,NULL);
if (newMdl == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}

DevExt->newMdl = newMdl;
DevExt->buffer = buffer;

//Complete Original Request
WdfRequestComplete(Request, STATUS_SUCCESS);

}

HelperRoutine()
{
ioTarget = WdfDeviceGetIoTarget(DevExt->WdfDevice);

WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = ioTarget;

status = WdfRequestCreate(&attributes,ioTarget,&Request);

if (!NT_SUCCESS(status)) {
return status;
}

WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = Request;

status =
WdfMemoryCreate(&attributes,NonPagedPool,POOL_TAG,sizeof(struct
_URB_BULK_OR_INTERRUPT_TRANSFER),&urbMemory,(PVOID*) &pUrb);

if (!NT_SUCCESS(status)) {
return STATUS_INSUFFICIENT_RESOURCES;
}

DevExt->NewRequest = Request;
Irp = WdfRequestWdmGetIrp(Request);
Irp->MdlAddress = DevExt->newMdl;

MmBuildMdlForNonPagedPool(DevExt->newMdl);

UsbBuildInterruptOrBulkTransferRequest(
pUrb,
sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER),
PipeHandle,
NULL,
DevExt->newMdl,
DevExt->totalLength,
TransferFlags,
NULL
);

NextStack = IoGetNextIrpStackLocation(WdfRequestWdmGetIrp(Request));

NextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
NextStack->Parameters.Others.Argument1 = pUrb;
NextStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;

WdfRequestSetCompletionRoutine(NewRequest, CompletionRoutine,
DevExt);
if (WdfRequestSend(Request, WdfDeviceGetIoTarget(DevExt->WdfDevice),
WDF_NO_SEND_OPTIONS) == FALSE)
{
status = WdfRequestGetStatus(Request);
}
}

CompletionRoutine()
{
// Status UnSuccessfull is returned here
}