[3/5] ntoskrnl.exe: Use MmInitializeMdl in IoAllocateMdl.

Sebastian Lackner sebastian at fds-team.de
Sun Oct 16 01:53:29 CDT 2016


Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
---

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



More information about the wine-patches mailing list