ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

iomdl.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.