Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

MDL address is NULL

21 views
Skip to first unread message

Rik van der Heijden

unread,
Jun 11, 2009, 9:07:47 AM6/11/09
to
Hi All,

I know there were a lot of questions about it. I'm making an USB driver
and i want to do some IOcontrols. I'm want to do it with direct IO
because buffered is to slow in our application. I'm now busy with my
handling. But my MDLaddress is null.

I checked deviceObject->Flags |= DO_DIRECT_IO; and my IOctl code is set
with METHOD_IN_DIRECT.

The driver is based on the BulkUsb Driver that comes with the WDK. I
made an IOcontrol wich must perform a write to the device. I lend it
from the write-command.

I will copy my iocontrol handling here. If something is nog clear. Just
ask, I will tell. ;)

Sorry for my bad english. but maybe someone sees what i'm doing wrong.

Greetings,


Rik van der Heijden

case IOCTL_ITEC_WRITE_BULK:
{
PURB urb;
PMDL mdl;
ULONG totalLength;
ULONG stageLength;
ULONG urbFlags;
BOOLEAN read;
PBULKUSB_RW_CONTEXT rwContext;
PUSBD_PIPE_INFORMATION pipeInformation;
ULONG_PTR virtualAddress;
PIO_STACK_LOCATION nextStack;


urb = NULL;
mdl = NULL;
rwContext = NULL;
totalLength = 0;
read = FALSE;
//info = 0;
pipeInformation =
&deviceExtension->UsbInterface->Pipes[BULK_OUT_PIPE_NUMBER];
info = pipeInformation->MaximumPacketSize;

if(deviceExtension->DeviceState != Working)
{
ntStatus = STATUS_INVALID_DEVICE_STATE;
goto Itec_Write_Exit;
}

rwContext = ExAllocatePool(NonPagedPool,
sizeof(BULKUSB_RW_CONTEXT));
if(rwContext == NULL)
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto Itec_Write_Exit;
}

if(Irp->MdlAddress)
{
totalLength = MmGetMdlByteCount(Irp->MdlAddress);
}

if(totalLength == 0)
{
ntStatus = STATUS_SUCCESS;
ExFreePool(rwContext);
goto Itec_Write_Exit;
}

urbFlags = USBD_SHORT_TRANSFER_OK;
virtualAddress = (ULONG_PTR)
MmGetMdlVirtualAddress(Irp->MdlAddress);

if(read)
urbFlags |= USBD_TRANSFER_DIRECTION_IN;
else
urbFlags |= USBD_TRANSFER_DIRECTION_OUT;

//
// the transfer request is for totalLength.
// we can perform a max of BULKUSB_MAX_TRANSFER_SIZE
// in each stage.
//
if(totalLength > BULKUSB_MAX_TRANSFER_SIZE)
stageLength = BULKUSB_MAX_TRANSFER_SIZE;
else
stageLength = totalLength;

mdl = IoAllocateMdl ((PVOID) virtualAddress,
totalLength,
FALSE,
FALSE,
NULL);

if(mdl == NULL)
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
ExFreePool(rwContext);
rwContext = NULL;
goto Itec_Write_Exit;
}

//
// map the portion of user-buffer described by an mdl to
another mdl
//
IoBuildPartialMdl (Irp->MdlAddress,
mdl,
(PVOID) virtualAddress,
stageLength);
urb = ExAllocatePool (NonPagedPool,
sizeof(struct
_URB_BULK_OR_INTERRUPT_TRANSFER));

if(urb == NULL) {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
ExFreePool(rwContext);
rwContext = NULL;
IoFreeMdl(mdl);
goto Itec_Write_Exit;
}

UsbBuildInterruptOrBulkTransferRequest (
urb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
pipeInformation->PipeHandle,
NULL,
mdl,
stageLength,
urbFlags,
NULL);

//
// set BULKUSB_RW_CONTEXT parameters.
//
rwContext->Urb = urb;
rwContext->Mdl = mdl;
rwContext->Length = totalLength - stageLength;
rwContext->Numxfer = 0;
rwContext->VirtualAddress = virtualAddress + stageLength;
rwContext->DeviceExtension = deviceExtension;

//
// use the original read/write irp as an internal
// device control irp
//
nextStack = IoGetNextIrpStackLocation (Irp);
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.Others.Argument1 = (PVOID) urb;
nextStack->Parameters.DeviceIoControl.IoControlCode =

IOCTL_INTERNAL_USB_SUBMIT_URB;

IoSetCompletionRoutine (Irp,
BulkUsb_ReadWriteCompletion,
rwContext,
TRUE,
TRUE,
TRUE);

//
// 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);
BulkUsb_IoIncrement (deviceExtension);

ntStatus = IoCallDriver
(deviceExtension->TopOfStackDeviceObject,
Irp);

if (!NT_SUCCESS(ntStatus))
{
if ((ntStatus != STATUS_CANCELLED) &&
(ntStatus != STATUS_DEVICE_NOT_CONNECTED))
{
ntStatus = BulkUsb_ResetPipe (DeviceObject,
pipeInformation);
if (!NT_SUCCESS (ntStatus))
{
ntStatus = BulkUsb_ResetDevice(DeviceObject);
}
}
}
ntStatus = STATUS_PENDING;

Itec_Write_Exit:

Scott Noone

unread,
Jun 11, 2009, 9:20:02 AM6/11/09
to
How do you call DeviceIoControl in user mode? It's a little weird, but the
MDL will describe the data buffer specified as the OutputBuffer parameter to
the DeviceIoControl call. See
http://msdn.microsoft.com/en-us/library/ms795857.aspx

-scott

--
Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com


"Rik van der Heijden" <rik.vande...@gmail.com> wrote in message
news:uWIoTWp6...@TK2MSFTNGP06.phx.gbl...

0 new messages