ReactOS  0.4.10-dev-358-g66981e1
iomdl.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/io/iomgr/iomdl.c
5  * PURPOSE: I/O Wrappers for MDL Allocation and Deallocation
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* FUNCTIONS *****************************************************************/
16 
17 /*
18  * @implemented
19  */
20 PMDL
21 NTAPI
23  IN ULONG Length,
26  IN PIRP Irp)
27 {
28  PMDL Mdl = NULL, p;
29  ULONG Flags = 0;
30  ULONG Size;
31 
32  /* Make sure we got a valid length */
33  ASSERT(Length != 0);
34 
35  /* Fail if allocation is over 2GB */
36  if (Length & 0x80000000) return NULL;
37 
38  /* Calculate the number of pages for the allocation */
39  Size = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length);
40  if (Size > 23)
41  {
42  /* This is bigger then our fixed-size MDLs. Calculate real size */
43  Size *= sizeof(PFN_NUMBER);
44  Size += sizeof(MDL);
45  if (Size > MAXUSHORT) return NULL;
46  }
47  else
48  {
49  /* Use an internal fixed MDL size */
50  Size = (23 * sizeof(PFN_NUMBER)) + sizeof(MDL);
51  Flags |= MDL_ALLOCATED_FIXED_SIZE;
52 
53  /* Allocate one from the lookaside list */
55  }
56 
57  /* Check if we don't have an mdl yet */
58  if (!Mdl)
59  {
60  /* Allocate one from pool */
62  if (!Mdl) return NULL;
63  }
64 
65  /* Initialize it */
66  MmInitializeMdl(Mdl, VirtualAddress, Length);
67  Mdl->MdlFlags |= Flags;
68 
69  /* Check if an IRP was given too */
70  if (Irp)
71  {
72  /* Check if it came with a secondary buffer */
73  if (SecondaryBuffer)
74  {
75  /* Insert the MDL at the end */
76  p = Irp->MdlAddress;
77  while (p->Next) p = p->Next;
78  p->Next = Mdl;
79  }
80  else
81  {
82  /* Otherwise, insert it directly */
83  Irp->MdlAddress = Mdl;
84  }
85  }
86 
87  /* Return the allocated mdl */
88  return Mdl;
89 }
90 
91 /*
92  * @implemented
93  */
94 VOID
95 NTAPI
99  IN ULONG Length)
100 {
101  PPFN_NUMBER TargetPages = (PPFN_NUMBER)(TargetMdl + 1);
102  PPFN_NUMBER SourcePages = (PPFN_NUMBER)(SourceMdl + 1);
103  ULONG Offset;
104  ULONG FlagsMask = (MDL_IO_PAGE_READ |
107  MDL_IO_SPACE);
108 
109  /* Calculate the offset */
110  Offset = (ULONG)((ULONG_PTR)VirtualAddress -
111  (ULONG_PTR)SourceMdl->StartVa) -
112  SourceMdl->ByteOffset;
113 
114  /* Check if we don't have a length and calculate it */
115  if (!Length) Length = SourceMdl->ByteCount - Offset;
116 
117  /* Write the process, start VA and byte data */
118  TargetMdl->StartVa = (PVOID)PAGE_ROUND_DOWN(VirtualAddress);
119  TargetMdl->Process = SourceMdl->Process;
120  TargetMdl->ByteCount = Length;
121  TargetMdl->ByteOffset = BYTE_OFFSET(VirtualAddress);
122 
123  /* Recalculate the length in pages */
124  Length = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length);
125 
126  /* Set the MDL Flags */
127  TargetMdl->MdlFlags &= (MDL_ALLOCATED_FIXED_SIZE | MDL_ALLOCATED_MUST_SUCCEED);
128  TargetMdl->MdlFlags |= SourceMdl->MdlFlags & FlagsMask;
129  TargetMdl->MdlFlags |= MDL_PARTIAL;
130 
131  /* Set the mapped VA */
132  TargetMdl->MappedSystemVa = (PCHAR)SourceMdl->MappedSystemVa + Offset;
133 
134  /* Now do the copy */
135  Offset = (ULONG)(((ULONG_PTR)TargetMdl->StartVa -
136  (ULONG_PTR)SourceMdl->StartVa) >> PAGE_SHIFT);
137  SourcePages += Offset;
138  RtlCopyMemory(TargetPages, SourcePages, Length * sizeof(PFN_NUMBER));
139 }
140 
141 /*
142  * @implemented
143  */
144 VOID
145 NTAPI
147 {
148  /* Tell Mm to reuse the MDL */
150 
151  /* Check if this was a pool allocation */
152  if (!(Mdl->MdlFlags & MDL_ALLOCATED_FIXED_SIZE))
153  {
154  /* Free it from the pool */
156  }
157  else
158  {
159  /* Free it from the lookaside */
161  }
162 }
163 
164 /* EOF */
#define MDL_IO_PAGE_READ
Definition: mmtypes.h:24
DWORD *typedef PVOID
Definition: winlogon.h:60
_Inout_ PMDL TargetMdl
Definition: iofuncs.h:728
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:38
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_Must_inspect_result_ _In_ BOOLEAN ChargeQuota
Definition: iofuncs.h:649
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
_In_ PIRP Irp
Definition: csq.h:116
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
PVOID PMDL
Definition: usb.h:39
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define MDL_IO_SPACE
Definition: mmtypes.h:29
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
ULONG * PPFN_NUMBER
Definition: ke.h:8
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
ULONG PFN_NUMBER
Definition: ke.h:8
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define MDL_ALLOCATED_MUST_SUCCEED
Definition: mmtypes.h:32
smooth NULL
Definition: ftsmooth.c:416
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
#define IopAllocateMdlFromLookaside
Definition: io.h:107
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
UINTN Size
Definition: acefiex.h:555
#define PCHAR
Definition: match.c:90
unsigned char BOOLEAN
#define TAG_MDL
Definition: tag.h:86
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
MDL
Definition: mmtypes.h:117
VOID UINTN Length
Definition: acefiex.h:744
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3773
#define MmPrepareMdlForReuse(_Mdl)
_In_ ULONG _In_ BOOLEAN SecondaryBuffer
Definition: iofuncs.h:657
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
#define MAXUSHORT
Definition: typedefs.h:81
#define MDL_PARTIAL
Definition: mmtypes.h:22
PVOID PIRP
Definition: usb.h:38
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define IopFreeMdlFromLookaside
Definition: io.h:109
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
GLfloat GLfloat p
Definition: glext.h:8902
#define BYTE_OFFSET(Va)
#define MDL_ALLOCATED_FIXED_SIZE
Definition: mmtypes.h:21