ReactOS 0.4.15-dev-7961-gdcf9eb0
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 */
20PMDL
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 */
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);
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 */
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 */
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 */
94VOID
100{
101 PPFN_NUMBER TargetPages = (PPFN_NUMBER)(TargetMdl + 1);
102 PPFN_NUMBER SourcePages = (PPFN_NUMBER)(SourceMdl + 1);
104 ULONG FlagsMask = (MDL_IO_PAGE_READ |
108
109 /* Calculate the offset */
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 */
119 TargetMdl->Process = SourceMdl->Process;
120 TargetMdl->ByteCount = Length;
121 TargetMdl->ByteOffset = BYTE_OFFSET(VirtualAddress);
122
123 /* Recalculate the length in pages */
125
126 /* Set the MDL Flags */
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 */
144VOID
145NTAPI
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 */
unsigned char BOOLEAN
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define ULONG_PTR
Definition: config.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define NonPagedPool
Definition: env_spec_w32.h:307
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
GLfloat GLfloat p
Definition: glext.h:8902
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
@ LookasideMdlList
Definition: mmtypes.h:170
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IopFreeMdlFromLookaside
Definition: io.h:114
#define IopAllocateMdlFromLookaside
Definition: io.h:112
ULONG * PPFN_NUMBER
Definition: ke.h:9
ULONG PFN_NUMBER
Definition: ke.h:9
#define TAG_MDL
Definition: tag.h:89
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Inout_ PMDL TargetMdl
Definition: iofuncs.h:730
_Must_inspect_result_ _In_ BOOLEAN ChargeQuota
Definition: iofuncs.h:651
_In_ ULONG _In_ BOOLEAN SecondaryBuffer
Definition: iofuncs.h:660
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
#define BYTE_OFFSET(Va)
#define MmPrepareMdlForReuse(_Mdl)
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
MDL
Definition: mmtypes.h:117
#define MDL_ALLOCATED_MUST_SUCCEED
Definition: mmtypes.h:32
#define MDL_IO_SPACE
Definition: mmtypes.h:29
#define MDL_ALLOCATED_FIXED_SIZE
Definition: mmtypes.h:21
#define MDL_PARTIAL
Definition: mmtypes.h:22
#define MDL_IO_PAGE_READ
Definition: mmtypes.h:24
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18