Or use the ADDRESS_AND_SIZE_TO_SPAN_PAGES macro on the virtual address
and length of the MDL.
-p
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@exgate.tek.com
Sent: Tuesday, April 27, 2004 10:49 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Help on IoAllocateMdl()
Thanks,
So if I want to use pMdl->Size to figure out how many pages have been
described, should I cast it to USHORT? Like the following:
TotalPages = (((USHORT)(pMdl->Size) - sizeof(MDL)) / sizeof(ULONG));
By definition in WDM.h, the type of pMdl->Size is CSHORT, which is
“short”.
zhong
-----Original Message-----
From: Tony Mason [mailto:xxxxx@osr.com]
Sent: Tuesday, April 27, 2004 9:45 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Help on IoAllocateMdl()
The MDL in question describes a memory region that is 33,554,432 bytes
long (see the “ByteCount” field.) This requires exactly 8193 page
entries (32768 bytes, not starting on a page boundary) plus the fixed
size (28 byte) MDL structure itself. Thus, the size of the MDL is
32,794 bytes. When you sign extend this, you get -32736.
Regards,
Tony
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@exgate.tek.com
Sent: Tuesday, April 27, 2004 12:23 PM
To: ntdev redirect
Subject: RE: [ntdev] Help on IoAllocateMdl()
Tony:
I absolutely agree with you. It does not make sense to have a negative
value
for size. But that is why I am asking for help.
Here is the output from WinDbg after I call IoAllocateMdl() in the
following
code snippet:
Name Value
Type
pMdl 0xfec3e000 struct _MDL * struct
_MDL
*
Next 0x00000000 struct _MDL * struct _MDL *
Size -32736 short
MdlFlags 0
short
Process 0x006c0065 struct _EPROCESS * struct
_EPROCESS *
MappedSystemVa 0x00fe0000 void *
StartVa 0x04490000
void
*
ByteCount 0x2000000
unsigned long
ByteOffset 0x40 unsigned
long
pUserVa 0x0449040 unsigned
long *
The following is the code I am executing. The function PciMemLock() is
directly called from the DispatchControl() routine.
NTSTATUS DispatchControl(PDEVICE_OBJECT fdo, PIRP Irp)
{
…
case PLX_IOCTL_MEMORY_LOCK:
DrvTraceNoInfo((“PLX_IOCTL_MEMORY_LOCK\n”));
if (pdx->devpower > MIN_WORKING_POWER_STATE)
{
pIoBuffer->ReturnCode = ApiPowerDown;
}
else
{
pIoBuffer->ReturnCode = ApiSuccess;
PciMem.UserAddr = (ULONG)pIoBuffer->u.MemLock.pUserVa;
PciMem.Size = pIoBuffer->u.MemLock.Size;
status = PciMemLock(pdx, &PciMem,
pIoBuffer->u.MemLock.Option, stack->FileObject);
}
break;
…
}
NTSTATUS
PciMemLock(PDEVICE_EXTENSION pdx, PCI_MEMORY * pPciMem, UCHAR Option,
PVOID
pOwner)
{
ULONG * pUserVa = (ULONG*)pPciMem->UserAddr;
ULONG nSize = pPciMem->Size;
MDL_ENTRY *pMdlEntry = NULL;
BOOLEAN bFlag;
DrvTrace(DRV_IOCTL, (“Lock the user memory %p, size %d\n”,pUserVa,
nSize));
pMdlEntry = (MDL_ENTRY*)ExAllocatePoolWithTag(NonPagedPool,
sizeof(MDL_ENTRY), 0x4C4D454D);
if (pMdlEntry == NULL)
{
DrvTrace(DRV_IOCTL, (“ERROR - Unable to build MDL Entry for the
user
buffer.\n”));
return STATUS_INSUFFICIENT_RESOURCES;
}
switch (Option)
{
case USER_BUFFER_ALLOC:
// The buffer must be already allocated by the user application
if ((pUserVa == NULL) || (nSize == 0)) {
DrvTrace(DRV_IOCTL, (“ERROR - The buffer is
uninitialized\n”));
ExFreePool(pMdlEntry);
return STATUS_INVALID_PARAMETER;
}
// Try to allocate MDL for the user buffer
pMdlEntry->pMdl = IoAllocateMdl(
(PVOID)pUserVa,
nSize,
FALSE,
FALSE,
NULL
);
if (pMdlEntry->pMdl == NULL) // WinDbg output
caught here.
{
DrvTrace(DRV_IOCTL, (“ERROR - Unable to build MDL for the
user
buffer.\n”));
ExFreePool(pMdlEntry);
return STATUS_INSUFFICIENT_RESOURCES;
}
// Attempt to lock the user buffer into memory. May raise memory
access violation
// if the memory is not available or can’t access.
bFlag = FALSE;
__try
{
MmProbeAndLockPages(
pMdlEntry->pMdl,
UserMode,
IoModifyAccess
);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// Flag the exception
bFlag = TRUE;
}
// Verify that the pages were locked
if (bFlag)
{
DrvTrace(DRV_DMAOPEN, (“ERROR - Unable to lock pages\n”));
IoFreeMdl(
pMdlEntry->pMdl
);
ExFreePool(pMdlEntry);
return STATUS_ACCESS_VIOLATION;
}
break;
case KERNEL_BUFFER_ALLOC_PAGED:
return STATUS_NOT_SUPPORTED;
break;
case KERNEL_BUFFER_ALLOC_NONPAGED:
return STATUS_NOT_SUPPORTED;
break;
default:
return STATUS_INVALID_PARAMETER;
break;
}
pMdlEntry->pOwner = pOwner;
ExInterlockedInsertTailList(
&(pdx->List_Mdl),
&(pMdlEntry->ListEntry),
&(pdx->Lock_MdlList)
);
return STATUS_SUCCESS;
}
Can you see any wrong doing in my code?
Thanks,
zhong
-----Original Message-----
From: Tony Mason [mailto:xxxxx@osr.com]
Sent: Monday, April 26, 2004 5:11 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Help on IoAllocateMdl()
Size cannot be negative, so your question doesn’t make any sense. Size
is a positive value from 28 to 65535 (28 being the smallest possible
MDL). To go “negative” (that is above 32767 so when you cast from an
unsigned number to a signed number you get sign extension) you would be
describing a memory region that is 8185 pages long ((32768-28)/4) or
just shy of 32MB. The largest possible MDL that can be described then
is thus 16377 pages (67080192 bytes).
Thus, the answer to your question is that it means the memory region you
are attempting to describe is between 3334145 and 67080192 bytes long.
I have not confirmed this, but I wouldn’t be surprised to find out that
the size is truncated if the memory region is LARGER than the 67080192
number.
Regards,
Tony Mason
Consulting Partner
OSR Open Systems Resources Inc
http://www.osr.com
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@exgate.tek.com
Sent: Monday, April 26, 2004 7:44 PM
To: ntdev redirect
Subject: [ntdev] Help on IoAllocateMdl()
When I call IoAllocateMdl() to create MDL for the user memory, sometimes
I
got a negative value for pMdl->Size but IoAllocateMdl() did not fail.
Can
anyone explain it to me? The data type for Size in MDL is CSHORT
(#define
short CSHORT), so the negative value is allowed for the Size. However,
when
a size is negative, how can I use it to determine the size of MDL
allocated?
Thanks,
zhong
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@osr.com
To unsubscribe send a blank email to xxxxx@lists.osr.com
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@exgate.tek.com
To unsubscribe send a blank email to xxxxx@lists.osr.com
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@osr.com
To unsubscribe send a blank email to xxxxx@lists.osr.com
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@exgate.tek.com
To unsubscribe send a blank email to xxxxx@lists.osr.com
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com