From: Sebastian Lackner Subject: [3/5] ntoskrnl.exe: Use MmInitializeMdl in IoAllocateMdl. Message-Id: <7e39e9c9-3fa8-ae4f-a338-ad22a940e088@fds-team.de> Date: Sun, 16 Oct 2016 08:53:29 +0200 Signed-off-by: Sebastian Lackner --- Please note that the existing logic to compute nb_pages is flawed when length == 0 and address is a multiple of the page size. Process is not explicitly assigned because the pages are not locked yet. It is also missing in the MmInitializeMdl macro from the Windows header files. dlls/ntoskrnl.exe/ntoskrnl.c | 19 ++++--------------- include/ddk/wdm.h | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 912d084..eac81f7 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -744,31 +744,20 @@ PVOID WINAPI IoAllocateErrorLogEntry( PVOID IoObject, UCHAR EntrySize ) */ PMDL WINAPI IoAllocateMdl( PVOID va, ULONG length, BOOLEAN secondary, BOOLEAN charge_quota, IRP *irp ) { + SIZE_T mdl_size; PMDL mdl; - ULONG_PTR address = (ULONG_PTR)va; - ULONG_PTR page_address; - SIZE_T nb_pages, mdl_size; TRACE("(%p, %u, %i, %i, %p)\n", va, length, secondary, charge_quota, irp); if (charge_quota) FIXME("Charge quota is not yet supported\n"); - /* FIXME: We suppose that page size is 4096 */ - page_address = address & ~(4096 - 1); - nb_pages = (((address + length - 1) & ~(4096 - 1)) - page_address) / 4096 + 1; - - mdl_size = sizeof(MDL) + nb_pages * sizeof(PVOID); - - mdl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mdl_size); + mdl_size = sizeof(MDL) + sizeof(PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(va, length); + mdl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, mdl_size ); if (!mdl) return NULL; - mdl->Size = mdl_size; - mdl->Process = NULL; /* FIXME: IoGetCurrentProcess */ - mdl->StartVa = (PVOID)page_address; - mdl->ByteCount = length; - mdl->ByteOffset = address - page_address; + MmInitializeMdl( mdl, va, length ); if (!irp) return mdl; diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 3e93469..61de490 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -28,6 +28,15 @@ #define POINTER_ALIGNMENT #endif +/* FIXME: We suppose that page size is 4096 */ +#define PAGE_SIZE 0x1000 +#define PAGE_SHIFT 12 + +#define BYTE_OFFSET(va) ((ULONG)((ULONG_PTR)(va) & (PAGE_SIZE - 1))) +#define PAGE_ALIGN(va) ((PVOID)((ULONG_PTR)(va) & ~(PAGE_SIZE - 1))) +#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(va, length) \ + ((BYTE_OFFSET(va) + ((SIZE_T)(length)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT) + typedef LONG KPRIORITY; typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK; @@ -1035,6 +1044,17 @@ typedef struct _MDL { } MDL, *PMDL; typedef MDL *PMDLX; +typedef ULONG PFN_NUMBER, *PPFN_NUMBER; + +static inline void MmInitializeMdl(MDL *mdl, void *va, SIZE_T length) +{ + mdl->Next = NULL; + mdl->Size = sizeof(MDL) + sizeof(PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(va, length); + mdl->MdlFlags = 0; + mdl->StartVa = (void *)PAGE_ALIGN(va); + mdl->ByteOffset = BYTE_OFFSET(va); + mdl->ByteCount = length; +} typedef struct _KTIMER { DISPATCHER_HEADER Header; -- 2.9.0