Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeniomdl.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/io/mdl.c 00005 * PURPOSE: I/O Wrappers for MDL Allocation and Deallocation 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES *****************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* FUNCTIONS *****************************************************************/ 00016 00017 /* 00018 * @implemented 00019 */ 00020 PMDL 00021 NTAPI 00022 IoAllocateMdl(IN PVOID VirtualAddress, 00023 IN ULONG Length, 00024 IN BOOLEAN SecondaryBuffer, 00025 IN BOOLEAN ChargeQuota, 00026 IN PIRP Irp) 00027 { 00028 PMDL Mdl = NULL, p; 00029 ULONG Flags = 0; 00030 ULONG Size; 00031 00032 /* Make sure we got a valid length */ 00033 ASSERT(Length != 0); 00034 00035 /* Fail if allocation is over 2GB */ 00036 if (Length & 0x80000000) return NULL; 00037 00038 /* Calculate the number of pages for the allocation */ 00039 Size = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length); 00040 if (Size > 23) 00041 { 00042 /* This is bigger then our fixed-size MDLs. Calculate real size */ 00043 Size *= sizeof(PFN_NUMBER); 00044 Size += sizeof(MDL); 00045 if (Size > MAXUSHORT) return NULL; 00046 } 00047 else 00048 { 00049 /* Use an internal fixed MDL size */ 00050 Size = (23 * sizeof(PFN_NUMBER)) + sizeof(MDL); 00051 Flags |= MDL_ALLOCATED_FIXED_SIZE; 00052 00053 /* Allocate one from the lookaside list */ 00054 Mdl = IopAllocateMdlFromLookaside(LookasideMdlList); 00055 } 00056 00057 /* Check if we don't have an mdl yet */ 00058 if (!Mdl) 00059 { 00060 /* Allocate one from pool */ 00061 Mdl = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MDL); 00062 if (!Mdl) return NULL; 00063 } 00064 00065 /* Initialize it */ 00066 MmInitializeMdl(Mdl, VirtualAddress, Length); 00067 Mdl->MdlFlags |= Flags; 00068 00069 /* Check if an IRP was given too */ 00070 if (Irp) 00071 { 00072 /* Check if it came with a secondary buffer */ 00073 if (SecondaryBuffer) 00074 { 00075 /* Insert the MDL at the end */ 00076 p = Irp->MdlAddress; 00077 while (p->Next) p = p->Next; 00078 p->Next = Mdl; 00079 } 00080 else 00081 { 00082 /* Otherwise, insert it directly */ 00083 Irp->MdlAddress = Mdl; 00084 } 00085 } 00086 00087 /* Return the allocated mdl */ 00088 return Mdl; 00089 } 00090 00091 /* 00092 * @implemented 00093 */ 00094 VOID 00095 NTAPI 00096 IoBuildPartialMdl(IN PMDL SourceMdl, 00097 IN PMDL TargetMdl, 00098 IN PVOID VirtualAddress, 00099 IN ULONG Length) 00100 { 00101 PPFN_NUMBER TargetPages = (PPFN_NUMBER)(TargetMdl + 1); 00102 PPFN_NUMBER SourcePages = (PPFN_NUMBER)(SourceMdl + 1); 00103 ULONG Offset; 00104 ULONG FlagsMask = (MDL_IO_PAGE_READ | 00105 MDL_SOURCE_IS_NONPAGED_POOL | 00106 MDL_MAPPED_TO_SYSTEM_VA | 00107 MDL_IO_SPACE); 00108 00109 /* Calculate the offset */ 00110 Offset = (ULONG)((ULONG_PTR)VirtualAddress - 00111 (ULONG_PTR)SourceMdl->StartVa) - 00112 SourceMdl->ByteOffset; 00113 00114 /* Check if we don't have a length and calculate it */ 00115 if (!Length) Length = SourceMdl->ByteCount - Offset; 00116 00117 /* Write the process, start VA and byte data */ 00118 TargetMdl->StartVa = (PVOID)PAGE_ROUND_DOWN(VirtualAddress); 00119 TargetMdl->Process = SourceMdl->Process; 00120 TargetMdl->ByteCount = Length; 00121 TargetMdl->ByteOffset = BYTE_OFFSET(VirtualAddress); 00122 00123 /* Recalculate the length in pages */ 00124 Length = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length); 00125 00126 /* Set the MDL Flags */ 00127 TargetMdl->MdlFlags &= (MDL_ALLOCATED_FIXED_SIZE | MDL_ALLOCATED_MUST_SUCCEED); 00128 TargetMdl->MdlFlags |= SourceMdl->MdlFlags & FlagsMask; 00129 TargetMdl->MdlFlags |= MDL_PARTIAL; 00130 00131 /* Set the mapped VA */ 00132 TargetMdl->MappedSystemVa = (PCHAR)SourceMdl->MappedSystemVa + Offset; 00133 00134 /* Now do the copy */ 00135 Offset = (ULONG)(((ULONG_PTR)TargetMdl->StartVa - 00136 (ULONG_PTR)SourceMdl->StartVa) >> PAGE_SHIFT); 00137 SourcePages += Offset; 00138 RtlCopyMemory(TargetPages, SourcePages, Length * sizeof(PFN_NUMBER)); 00139 } 00140 00141 /* 00142 * @implemented 00143 */ 00144 VOID 00145 NTAPI 00146 IoFreeMdl(PMDL Mdl) 00147 { 00148 /* Tell Mm to reuse the MDL */ 00149 MmPrepareMdlForReuse(Mdl); 00150 00151 /* Check if this was a pool allocation */ 00152 if (!(Mdl->MdlFlags & MDL_ALLOCATED_FIXED_SIZE)) 00153 { 00154 /* Free it from the pool */ 00155 ExFreePoolWithTag(Mdl, TAG_MDL); 00156 } 00157 else 00158 { 00159 /* Free it from the lookaside */ 00160 IopFreeMdlFromLookaside(Mdl, LookasideMdlList); 00161 } 00162 } 00163 00164 /* EOF */ Generated on Sat May 26 2012 04:36:09 for ReactOS by
1.7.6.1
|