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 /* FUNCTIONS *****************************************************************/
24 IoAllocateMdl(PVOID VirtualAddress
,
26 BOOLEAN SecondaryBuffer
,
34 // Mdl = ExAllocatePoolWithQuota(NonPagedPool,
35 // MmSizeOfMdl(VirtualAddress,Length));
36 Mdl
= ExAllocatePoolWithTag(NonPagedPool
,
37 MmSizeOfMdl(VirtualAddress
,Length
),
42 Mdl
= ExAllocatePoolWithTag(NonPagedPool
,
43 MmSizeOfMdl(VirtualAddress
,Length
),
46 MmInitializeMdl(Mdl
, (char*)VirtualAddress
, Length
);
52 ASSERT(Irp
->MdlAddress
);
54 /* FIXME: add to end of list maybe?? */
55 Mdl
->Next
= Irp
->MdlAddress
->Next
;
56 Irp
->MdlAddress
->Next
= Mdl
;
61 * What if there's allready an mdl at Irp->MdlAddress?
62 * Is that bad and should we do something about it?
64 Irp
->MdlAddress
= Mdl
;
74 * You must IoFreeMdl the slave before freeing the master.
76 * IoBuildPartialMdl is more similar to MmBuildMdlForNonPagedPool, the difference
77 * is that the former takes the physical addresses from the master MDL, while the
78 * latter - from the known location of the NPP.
82 IoBuildPartialMdl(PMDL SourceMdl
,
87 PPFN_TYPE TargetPages
= (PPFN_TYPE
)(TargetMdl
+ 1);
88 PPFN_TYPE SourcePages
= (PPFN_TYPE
)(SourceMdl
+ 1);
92 DPRINT("VirtualAddress 0x%p, SourceMdl->StartVa 0x%p, SourceMdl->MappedSystemVa 0x%p\n",
93 VirtualAddress
, SourceMdl
->StartVa
, SourceMdl
->MappedSystemVa
);
95 TargetMdl
->StartVa
= (PVOID
)PAGE_ROUND_DOWN(VirtualAddress
);
96 TargetMdl
->ByteOffset
= (ULONG_PTR
)VirtualAddress
- (ULONG_PTR
)TargetMdl
->StartVa
;
97 TargetMdl
->ByteCount
= Length
;
98 TargetMdl
->Process
= SourceMdl
->Process
;
99 Delta
= (ULONG_PTR
)VirtualAddress
- ((ULONG_PTR
)SourceMdl
->StartVa
+ SourceMdl
->ByteOffset
);
100 TargetMdl
->MappedSystemVa
= (char*)SourceMdl
->MappedSystemVa
+ Delta
;
102 TargetMdl
->MdlFlags
= SourceMdl
->MdlFlags
& (MDL_IO_PAGE_READ
|MDL_SOURCE_IS_NONPAGED_POOL
|MDL_MAPPED_TO_SYSTEM_VA
);
103 TargetMdl
->MdlFlags
|= MDL_PARTIAL
;
105 Delta
= ((ULONG_PTR
)TargetMdl
->StartVa
- (ULONG_PTR
)SourceMdl
->StartVa
) / PAGE_SIZE
;
106 Count
= ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress
,Length
);
108 SourcePages
+= Delta
;
110 DPRINT("Delta %d, Count %d\n", Delta
, Count
);
112 memcpy(TargetPages
, SourcePages
, Count
* sizeof(PFN_TYPE
));
123 * This unmaps partial mdl's from kernel space but also asserts that non-partial
124 * mdl's isn't still mapped into kernel space.
127 ASSERT_IRQL(DISPATCH_LEVEL
);
129 MmPrepareMdlForReuse(Mdl
);
131 ExFreePoolWithTag(Mdl
, TAG_MDL
);