3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/mdl.c
6 * PURPOSE: Io manager mdl functions
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* GLOBALS *******************************************************************/
19 #define TAG_MDL TAG('M', 'D', 'L', ' ')
21 /* FUNCTIONS *****************************************************************/
28 IoAllocateMdl(PVOID VirtualAddress
,
30 BOOLEAN SecondaryBuffer
,
38 // Mdl = ExAllocatePoolWithQuota(NonPagedPool,
39 // MmSizeOfMdl(VirtualAddress,Length));
40 Mdl
= ExAllocatePoolWithTag(NonPagedPool
,
41 MmSizeOfMdl(VirtualAddress
,Length
),
46 Mdl
= ExAllocatePoolWithTag(NonPagedPool
,
47 MmSizeOfMdl(VirtualAddress
,Length
),
50 MmInitializeMdl(Mdl
, (char*)VirtualAddress
, Length
);
56 ASSERT(Irp
->MdlAddress
);
58 /* FIXME: add to end of list maybe?? */
59 Mdl
->Next
= Irp
->MdlAddress
->Next
;
60 Irp
->MdlAddress
->Next
= Mdl
;
65 * What if there's allready an mdl at Irp->MdlAddress?
66 * Is that bad and should we do something about it?
68 Irp
->MdlAddress
= Mdl
;
78 * You must IoFreeMdl the slave before freeing the master.
80 * IoBuildPartialMdl is more similar to MmBuildMdlForNonPagedPool, the difference
81 * is that the former takes the physical addresses from the master MDL, while the
82 * latter - from the known location of the NPP.
86 IoBuildPartialMdl(PMDL SourceMdl
,
91 PPFN_TYPE TargetPages
= (PPFN_TYPE
)(TargetMdl
+ 1);
92 PPFN_TYPE SourcePages
= (PPFN_TYPE
)(SourceMdl
+ 1);
96 DPRINT("VirtualAddress %x, SourceMdl->StartVa %x, SourceMdl->MappedSystemVa %x\n",
97 VirtualAddress
, SourceMdl
->StartVa
, SourceMdl
->MappedSystemVa
);
99 TargetMdl
->StartVa
= (PVOID
)PAGE_ROUND_DOWN(VirtualAddress
);
100 TargetMdl
->ByteOffset
= (ULONG_PTR
)VirtualAddress
- (ULONG_PTR
)TargetMdl
->StartVa
;
101 TargetMdl
->ByteCount
= Length
;
102 TargetMdl
->Process
= SourceMdl
->Process
;
103 Delta
= (ULONG_PTR
)VirtualAddress
- ((ULONG_PTR
)SourceMdl
->StartVa
+ SourceMdl
->ByteOffset
);
104 TargetMdl
->MappedSystemVa
= (char*)SourceMdl
->MappedSystemVa
+ Delta
;
106 TargetMdl
->MdlFlags
= SourceMdl
->MdlFlags
& (MDL_IO_PAGE_READ
|MDL_SOURCE_IS_NONPAGED_POOL
|MDL_MAPPED_TO_SYSTEM_VA
);
107 TargetMdl
->MdlFlags
|= MDL_PARTIAL
;
109 Delta
= ((ULONG_PTR
)TargetMdl
->StartVa
- (ULONG_PTR
)SourceMdl
->StartVa
) / PAGE_SIZE
;
110 Count
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress
,Length
);
112 SourcePages
+= Delta
;
114 DPRINT("Delta %d, Count %d\n", Delta
, Count
);
116 memcpy(TargetPages
, SourcePages
, Count
* sizeof(PFN_TYPE
));
127 * This unmaps partial mdl's from kernel space but also asserts that non-partial
128 * mdl's isn't still mapped into kernel space.
131 ASSERT_IRQL(DISPATCH_LEVEL
);
133 MmPrepareMdlForReuse(Mdl
);