2006-06-30 15:59:06 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2015-10-04 11:54:25 +00:00
|
|
|
* FILE: ntoskrnl/io/iomgr/iomdl.c
|
2006-06-30 15:59:06 +00:00
|
|
|
* PURPOSE: I/O Wrappers for MDL Allocation and Deallocation
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
1998-08-25 04:27:26 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
2004-08-15 16:39:12 +00:00
|
|
|
#include <ntoskrnl.h>
|
2004-05-15 22:51:38 +00:00
|
|
|
#define NDEBUG
|
2008-08-30 16:31:06 +00:00
|
|
|
#include <debug.h>
|
1998-08-25 04:27:26 +00:00
|
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2003-07-10 15:47:00 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2000-03-26 19:38:32 +00:00
|
|
|
PMDL
|
2006-06-30 15:59:06 +00:00
|
|
|
NTAPI
|
|
|
|
IoAllocateMdl(IN PVOID VirtualAddress,
|
|
|
|
IN ULONG Length,
|
|
|
|
IN BOOLEAN SecondaryBuffer,
|
|
|
|
IN BOOLEAN ChargeQuota,
|
|
|
|
IN PIRP Irp)
|
1998-08-25 04:27:26 +00:00
|
|
|
{
|
2006-06-30 15:59:06 +00:00
|
|
|
PMDL Mdl = NULL, p;
|
|
|
|
ULONG Flags = 0;
|
|
|
|
ULONG Size;
|
|
|
|
|
2009-10-20 16:47:01 +00:00
|
|
|
/* Make sure we got a valid length */
|
|
|
|
ASSERT(Length != 0);
|
|
|
|
|
2006-06-30 15:59:06 +00:00
|
|
|
/* Fail if allocation is over 2GB */
|
|
|
|
if (Length & 0x80000000) return NULL;
|
|
|
|
|
|
|
|
/* Calculate the number of pages for the allocation */
|
|
|
|
Size = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length);
|
|
|
|
if (Size > 23)
|
|
|
|
{
|
|
|
|
/* This is bigger then our fixed-size MDLs. Calculate real size */
|
|
|
|
Size *= sizeof(PFN_NUMBER);
|
|
|
|
Size += sizeof(MDL);
|
|
|
|
if (Size > MAXUSHORT) return NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Use an internal fixed MDL size */
|
|
|
|
Size = (23 * sizeof(PFN_NUMBER)) + sizeof(MDL);
|
|
|
|
Flags |= MDL_ALLOCATED_FIXED_SIZE;
|
|
|
|
|
|
|
|
/* Allocate one from the lookaside list */
|
|
|
|
Mdl = IopAllocateMdlFromLookaside(LookasideMdlList);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we don't have an mdl yet */
|
|
|
|
if (!Mdl)
|
|
|
|
{
|
|
|
|
/* Allocate one from pool */
|
|
|
|
Mdl = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MDL);
|
|
|
|
if (!Mdl) return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize it */
|
|
|
|
MmInitializeMdl(Mdl, VirtualAddress, Length);
|
|
|
|
Mdl->MdlFlags |= Flags;
|
|
|
|
|
|
|
|
/* Check if an IRP was given too */
|
|
|
|
if (Irp)
|
|
|
|
{
|
|
|
|
/* Check if it came with a secondary buffer */
|
|
|
|
if (SecondaryBuffer)
|
|
|
|
{
|
|
|
|
/* Insert the MDL at the end */
|
|
|
|
p = Irp->MdlAddress;
|
|
|
|
while (p->Next) p = p->Next;
|
|
|
|
p->Next = Mdl;
|
2004-04-20 19:04:11 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-06-30 15:59:06 +00:00
|
|
|
/* Otherwise, insert it directly */
|
|
|
|
Irp->MdlAddress = Mdl;
|
2004-04-20 19:04:11 +00:00
|
|
|
}
|
|
|
|
}
|
2005-04-05 05:12:16 +00:00
|
|
|
|
2006-06-30 15:59:06 +00:00
|
|
|
/* Return the allocated mdl */
|
|
|
|
return Mdl;
|
1998-08-25 04:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 15:47:00 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2000-03-26 19:38:32 +00:00
|
|
|
VOID
|
2006-06-30 15:59:06 +00:00
|
|
|
NTAPI
|
|
|
|
IoBuildPartialMdl(IN PMDL SourceMdl,
|
|
|
|
IN PMDL TargetMdl,
|
|
|
|
IN PVOID VirtualAddress,
|
|
|
|
IN ULONG Length)
|
1998-08-25 04:27:26 +00:00
|
|
|
{
|
2007-09-24 14:01:54 +00:00
|
|
|
PPFN_NUMBER TargetPages = (PPFN_NUMBER)(TargetMdl + 1);
|
|
|
|
PPFN_NUMBER SourcePages = (PPFN_NUMBER)(SourceMdl + 1);
|
2006-06-30 15:59:06 +00:00
|
|
|
ULONG Offset;
|
2008-12-26 20:34:40 +00:00
|
|
|
ULONG FlagsMask = (MDL_IO_PAGE_READ |
|
|
|
|
MDL_SOURCE_IS_NONPAGED_POOL |
|
|
|
|
MDL_MAPPED_TO_SYSTEM_VA |
|
|
|
|
MDL_IO_SPACE);
|
2006-06-30 15:59:06 +00:00
|
|
|
|
|
|
|
/* Calculate the offset */
|
|
|
|
Offset = (ULONG)((ULONG_PTR)VirtualAddress -
|
|
|
|
(ULONG_PTR)SourceMdl->StartVa) -
|
|
|
|
SourceMdl->ByteOffset;
|
|
|
|
|
|
|
|
/* Check if we don't have a length and calculate it */
|
|
|
|
if (!Length) Length = SourceMdl->ByteCount - Offset;
|
|
|
|
|
|
|
|
/* Write the process, start VA and byte data */
|
|
|
|
TargetMdl->StartVa = (PVOID)PAGE_ROUND_DOWN(VirtualAddress);
|
|
|
|
TargetMdl->Process = SourceMdl->Process;
|
|
|
|
TargetMdl->ByteCount = Length;
|
|
|
|
TargetMdl->ByteOffset = BYTE_OFFSET(VirtualAddress);
|
|
|
|
|
|
|
|
/* Recalculate the length in pages */
|
|
|
|
Length = ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length);
|
|
|
|
|
|
|
|
/* Set the MDL Flags */
|
2008-12-26 21:57:11 +00:00
|
|
|
TargetMdl->MdlFlags &= (MDL_ALLOCATED_FIXED_SIZE | MDL_ALLOCATED_MUST_SUCCEED);
|
2008-12-26 20:34:40 +00:00
|
|
|
TargetMdl->MdlFlags |= SourceMdl->MdlFlags & FlagsMask;
|
2006-06-30 15:59:06 +00:00
|
|
|
TargetMdl->MdlFlags |= MDL_PARTIAL;
|
|
|
|
|
|
|
|
/* Set the mapped VA */
|
|
|
|
TargetMdl->MappedSystemVa = (PCHAR)SourceMdl->MappedSystemVa + Offset;
|
|
|
|
|
|
|
|
/* Now do the copy */
|
[HAL/NDK]
- Make Vector parameter in HalEnableSystemInterrupt, HalDisableSystemInterrupt and HalBeginSystemInterrupt an ULONG, not an UCHAR
[NDK]
- 64bit fixes for HANDLE_TABLE, KPROCESS, SECTION_IMAGE_INFORMATION, MMADDRESS_LIST, MMVAD_FLAGS, MMVAD, MMVAD_LONG, MMVAD_SHORT, MEMORY_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR, LdrVerifyMappedImageMatchesChecksum
- KDPC_DATA::DpcQueueDepth is signed on amd64, unsigned on x86
[NTOSKRNL]
- Fix hundreds of MSVC and amd64 warnings
- add a pragma message to FstubFixupEfiPartition, since it looks broken
- Move portable Ke constants from <arch>/cpu.c to krnlinit.c
- Fixed a bug in amd64 KiGeneralProtectionFaultHandler
svn path=/trunk/; revision=53734
2011-09-18 13:11:45 +00:00
|
|
|
Offset = (ULONG)(((ULONG_PTR)TargetMdl->StartVa -
|
|
|
|
(ULONG_PTR)SourceMdl->StartVa) >> PAGE_SHIFT);
|
2006-06-30 15:59:06 +00:00
|
|
|
SourcePages += Offset;
|
2007-09-24 14:01:54 +00:00
|
|
|
RtlCopyMemory(TargetPages, SourcePages, Length * sizeof(PFN_NUMBER));
|
1998-08-25 04:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 15:47:00 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2006-06-30 15:59:06 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
2000-03-26 19:38:32 +00:00
|
|
|
IoFreeMdl(PMDL Mdl)
|
2005-04-05 05:12:16 +00:00
|
|
|
{
|
2006-06-30 15:59:06 +00:00
|
|
|
/* Tell Mm to reuse the MDL */
|
|
|
|
MmPrepareMdlForReuse(Mdl);
|
|
|
|
|
|
|
|
/* Check if this was a pool allocation */
|
|
|
|
if (!(Mdl->MdlFlags & MDL_ALLOCATED_FIXED_SIZE))
|
|
|
|
{
|
|
|
|
/* Free it from the pool */
|
|
|
|
ExFreePoolWithTag(Mdl, TAG_MDL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Free it from the lookaside */
|
|
|
|
IopFreeMdlFromLookaside(Mdl, LookasideMdlList);
|
|
|
|
}
|
1998-08-25 04:27:26 +00:00
|
|
|
}
|
2000-03-05 19:17:43 +00:00
|
|
|
|
|
|
|
/* EOF */
|