2005-01-26 20:31:05 +00:00
|
|
|
/*
|
|
|
|
* ReactOS kernel
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
2009-10-27 10:34:16 +00:00
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2005-01-26 20:31:05 +00:00
|
|
|
*/
|
2006-01-01 10:24:27 +00:00
|
|
|
/*
|
1999-12-10 17:04:37 +00:00
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: ntoskrnl/mm/pagefile.c
|
|
|
|
* PURPOSE: Paging file functions
|
2005-01-26 20:31:05 +00:00
|
|
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
|
|
|
* UPDATE HISTORY:
|
|
|
|
* Created 22/05/98
|
1999-12-10 17:04:37 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
2004-08-15 16:39:12 +00:00
|
|
|
#include <ntoskrnl.h>
|
2002-02-08 02:57:10 +00:00
|
|
|
#define NDEBUG
|
2008-08-30 16:31:06 +00:00
|
|
|
#include <debug.h>
|
1999-12-10 17:04:37 +00:00
|
|
|
|
2005-11-28 23:25:31 +00:00
|
|
|
#if defined (ALLOC_PRAGMA)
|
|
|
|
#pragma alloc_text(INIT, MmInitPagingFile)
|
|
|
|
#endif
|
|
|
|
|
2007-02-23 07:56:01 +00:00
|
|
|
PVOID
|
|
|
|
NTAPI
|
|
|
|
MiFindExportedRoutineByName(IN PVOID DllBase,
|
|
|
|
IN PANSI_STRING ExportName);
|
2005-11-28 23:25:31 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
/* TYPES *********************************************************************/
|
|
|
|
|
2001-01-08 02:14:06 +00:00
|
|
|
typedef struct _PAGINGFILE
|
1999-12-10 17:04:37 +00:00
|
|
|
{
|
|
|
|
LIST_ENTRY PagingFileListEntry;
|
|
|
|
PFILE_OBJECT FileObject;
|
2002-03-18 16:16:47 +00:00
|
|
|
LARGE_INTEGER MaximumSize;
|
|
|
|
LARGE_INTEGER CurrentSize;
|
1999-12-10 17:04:37 +00:00
|
|
|
ULONG FreePages;
|
|
|
|
ULONG UsedPages;
|
|
|
|
PULONG AllocMap;
|
|
|
|
KSPIN_LOCK AllocMapLock;
|
|
|
|
ULONG AllocMapSize;
|
2005-01-26 20:31:05 +00:00
|
|
|
PRETRIEVAL_POINTERS_BUFFER RetrievalPointers;
|
2004-04-10 22:36:07 +00:00
|
|
|
}
|
|
|
|
PAGINGFILE, *PPAGINGFILE;
|
1999-12-10 17:04:37 +00:00
|
|
|
|
2003-11-30 17:19:28 +00:00
|
|
|
typedef struct _RETRIEVEL_DESCRIPTOR_LIST
|
|
|
|
{
|
2004-04-10 22:36:07 +00:00
|
|
|
struct _RETRIEVEL_DESCRIPTOR_LIST* Next;
|
2005-01-26 20:31:05 +00:00
|
|
|
RETRIEVAL_POINTERS_BUFFER RetrievalPointers;
|
2003-11-30 17:19:28 +00:00
|
|
|
}
|
|
|
|
RETRIEVEL_DESCRIPTOR_LIST, *PRETRIEVEL_DESCRIPTOR_LIST;
|
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
|
2004-04-10 22:36:07 +00:00
|
|
|
#define PAIRS_PER_RUN (1024)
|
2003-11-30 17:19:28 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
#define MAX_PAGING_FILES (32)
|
|
|
|
|
2001-02-06 00:11:20 +00:00
|
|
|
/* List of paging files, both used and free */
|
1999-12-10 17:04:37 +00:00
|
|
|
static PPAGINGFILE PagingFileList[MAX_PAGING_FILES];
|
2001-03-25 03:34:30 +00:00
|
|
|
|
2001-02-06 00:11:20 +00:00
|
|
|
/* Lock for examining the list of paging files */
|
1999-12-10 17:04:37 +00:00
|
|
|
static KSPIN_LOCK PagingFileListLock;
|
|
|
|
|
2002-03-18 16:16:47 +00:00
|
|
|
/* Number of paging files */
|
|
|
|
static ULONG MiPagingFileCount;
|
2009-10-31 01:02:35 +00:00
|
|
|
ULONG MmNumberOfPagingFiles;
|
2002-03-18 16:16:47 +00:00
|
|
|
|
2001-02-06 00:11:20 +00:00
|
|
|
/* Number of pages that are available for swapping */
|
[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
|
|
|
PFN_COUNT MiFreeSwapPages;
|
2001-03-25 03:34:30 +00:00
|
|
|
|
2001-02-06 00:11:20 +00:00
|
|
|
/* Number of pages that have been allocated for swapping */
|
[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
|
|
|
PFN_COUNT MiUsedSwapPages;
|
2001-03-25 03:34:30 +00:00
|
|
|
|
2010-04-20 22:47:51 +00:00
|
|
|
BOOLEAN MmZeroPageFile;
|
|
|
|
|
2004-04-10 22:36:07 +00:00
|
|
|
/*
|
2005-05-09 01:38:29 +00:00
|
|
|
* Number of pages that have been reserved for swapping but not yet allocated
|
2001-02-06 00:11:20 +00:00
|
|
|
*/
|
[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
|
|
|
static PFN_COUNT MiReservedSwapPages;
|
1999-12-10 17:04:37 +00:00
|
|
|
|
2004-04-10 22:36:07 +00:00
|
|
|
/*
|
2001-02-06 00:11:20 +00:00
|
|
|
* Ratio between reserved and available swap pages, e.g. setting this to five
|
|
|
|
* forces one swap page to be available for every five swap pages that are
|
|
|
|
* reserved. Setting this to zero turns off commit checking altogether.
|
|
|
|
*/
|
2000-07-04 08:52:47 +00:00
|
|
|
#define MM_PAGEFILE_COMMIT_RATIO (1)
|
2001-03-25 03:34:30 +00:00
|
|
|
|
2001-02-06 00:11:20 +00:00
|
|
|
/*
|
|
|
|
* Number of pages that can be used for potentially swapable memory without
|
2002-01-08 00:49:02 +00:00
|
|
|
* pagefile space being reserved. The intention is that this allows smss
|
2001-02-06 00:11:20 +00:00
|
|
|
* to start up and create page files while ordinarily having a commit
|
|
|
|
* ratio of one.
|
|
|
|
*/
|
2000-07-04 08:52:47 +00:00
|
|
|
#define MM_PAGEFILE_COMMIT_GRACE (256)
|
|
|
|
|
2001-02-06 00:11:20 +00:00
|
|
|
/*
|
|
|
|
* Translate between a swap entry and a file and offset pair.
|
|
|
|
*/
|
2009-02-19 11:47:34 +00:00
|
|
|
#define FILE_FROM_ENTRY(i) ((i) & 0x0f)
|
|
|
|
#define OFFSET_FROM_ENTRY(i) ((i) >> 11)
|
2011-11-15 18:36:26 +00:00
|
|
|
#define ENTRY_FROM_FILE_OFFSET(i, j) ((i) | ((j) << 11) | 0x400)
|
2000-07-07 10:30:57 +00:00
|
|
|
|
2013-10-07 12:33:03 +00:00
|
|
|
/* Make sure there can be only 16 paging files */
|
|
|
|
C_ASSERT(FILE_FROM_ENTRY(0xffffffff) < MAX_PAGING_FILES);
|
|
|
|
|
2002-08-17 01:42:03 +00:00
|
|
|
static BOOLEAN MmSwapSpaceMessage = FALSE;
|
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2008-04-25 07:55:12 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
2010-07-15 22:50:12 +00:00
|
|
|
MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages)
|
2008-04-25 07:55:12 +00:00
|
|
|
{
|
2010-07-15 22:50:12 +00:00
|
|
|
memcpy(Mdl + 1, Pages, sizeof(PFN_NUMBER) * (PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGE_SIZE));
|
[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
|
|
|
|
2008-04-25 07:55:12 +00:00
|
|
|
/* FIXME: this flag should be set by the caller perhaps? */
|
|
|
|
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-07 17:44:54 +00:00
|
|
|
BOOLEAN
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2010-11-22 22:18:02 +00:00
|
|
|
MmIsFileObjectAPagingFile(PFILE_OBJECT FileObject)
|
2005-05-07 17:44:54 +00:00
|
|
|
{
|
|
|
|
ULONG i;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-05-07 17:44:54 +00:00
|
|
|
/* Loop through all the paging files */
|
|
|
|
for (i = 0; i < MiPagingFileCount; i++)
|
|
|
|
{
|
|
|
|
/* Check if this is one of them */
|
|
|
|
if (PagingFileList[i]->FileObject == FileObject) return TRUE;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-05-07 17:44:54 +00:00
|
|
|
/* Nothing found */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2002-08-17 01:42:03 +00:00
|
|
|
VOID
|
2005-09-14 01:05:50 +00:00
|
|
|
NTAPI
|
2002-08-17 01:42:03 +00:00
|
|
|
MmShowOutOfSpaceMessagePagingFile(VOID)
|
|
|
|
{
|
2004-04-10 22:36:07 +00:00
|
|
|
if (!MmSwapSpaceMessage)
|
|
|
|
{
|
2002-08-17 01:42:03 +00:00
|
|
|
DPRINT1("MM: Out of swap space.\n");
|
|
|
|
MmSwapSpaceMessage = TRUE;
|
2004-04-10 22:36:07 +00:00
|
|
|
}
|
2002-08-17 01:42:03 +00:00
|
|
|
}
|
|
|
|
|
2008-12-03 17:28:59 +00:00
|
|
|
static LARGE_INTEGER
|
2005-01-26 20:31:05 +00:00
|
|
|
MmGetOffsetPageFile(PRETRIEVAL_POINTERS_BUFFER RetrievalPointers, LARGE_INTEGER Offset)
|
2003-11-30 17:19:28 +00:00
|
|
|
{
|
|
|
|
/* Simple binary search */
|
|
|
|
ULONG first, last, mid;
|
|
|
|
first = 0;
|
2005-01-26 20:31:05 +00:00
|
|
|
last = RetrievalPointers->ExtentCount - 1;
|
2003-11-30 17:19:28 +00:00
|
|
|
while (first <= last)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
mid = (last - first) / 2 + first;
|
2005-01-26 20:31:05 +00:00
|
|
|
if (Offset.QuadPart < RetrievalPointers->Extents[mid].NextVcn.QuadPart)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
if (mid == 0)
|
|
|
|
{
|
2005-01-26 20:31:05 +00:00
|
|
|
Offset.QuadPart += RetrievalPointers->Extents[0].Lcn.QuadPart - RetrievalPointers->StartingVcn.QuadPart;
|
2004-04-10 22:36:07 +00:00
|
|
|
return Offset;
|
|
|
|
}
|
|
|
|
else
|
2003-11-30 17:19:28 +00:00
|
|
|
{
|
2005-01-26 20:31:05 +00:00
|
|
|
if (Offset.QuadPart >= RetrievalPointers->Extents[mid-1].NextVcn.QuadPart)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
2005-01-26 20:31:05 +00:00
|
|
|
Offset.QuadPart += RetrievalPointers->Extents[mid].Lcn.QuadPart - RetrievalPointers->Extents[mid-1].NextVcn.QuadPart;
|
2004-04-10 22:36:07 +00:00
|
|
|
return Offset;
|
|
|
|
}
|
|
|
|
last = mid - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-01-26 20:31:05 +00:00
|
|
|
if (mid == RetrievalPointers->ExtentCount - 1)
|
2003-11-30 17:19:28 +00:00
|
|
|
{
|
2004-04-10 22:36:07 +00:00
|
|
|
break;
|
|
|
|
}
|
2005-01-26 20:31:05 +00:00
|
|
|
if (Offset.QuadPart < RetrievalPointers->Extents[mid+1].NextVcn.QuadPart)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
2005-01-26 20:31:05 +00:00
|
|
|
Offset.QuadPart += RetrievalPointers->Extents[mid+1].Lcn.QuadPart - RetrievalPointers->Extents[mid].NextVcn.QuadPart;
|
2004-04-10 22:36:07 +00:00
|
|
|
return Offset;
|
|
|
|
}
|
|
|
|
first = mid + 1;
|
|
|
|
}
|
|
|
|
}
|
2008-12-07 18:05:28 +00:00
|
|
|
KeBugCheck(MEMORY_MANAGEMENT);
|
2003-12-30 18:52:06 +00:00
|
|
|
#if defined(__GNUC__)
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2003-11-30 17:19:28 +00:00
|
|
|
return (LARGE_INTEGER)0LL;
|
2003-12-30 18:52:06 +00:00
|
|
|
#else
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2003-12-30 18:52:06 +00:00
|
|
|
{
|
2004-04-10 22:36:07 +00:00
|
|
|
const LARGE_INTEGER dummy =
|
|
|
|
{
|
|
|
|
0
|
|
|
|
};
|
|
|
|
return dummy;
|
2003-12-30 18:52:06 +00:00
|
|
|
}
|
|
|
|
#endif
|
2003-11-30 17:19:28 +00:00
|
|
|
}
|
|
|
|
|
2005-09-14 01:05:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2010-07-15 22:50:12 +00:00
|
|
|
MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
|
2000-07-07 10:30:57 +00:00
|
|
|
{
|
[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
|
|
|
ULONG i;
|
|
|
|
ULONG_PTR offset;
|
2000-07-07 10:30:57 +00:00
|
|
|
LARGE_INTEGER file_offset;
|
|
|
|
IO_STATUS_BLOCK Iosb;
|
|
|
|
NTSTATUS Status;
|
2002-08-28 07:13:04 +00:00
|
|
|
KEVENT Event;
|
2004-06-06 09:13:21 +00:00
|
|
|
UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
|
|
|
|
PMDL Mdl = (PMDL)MdlBase;
|
2003-05-11 09:48:57 +00:00
|
|
|
|
|
|
|
DPRINT("MmWriteToSwapPage\n");
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2000-07-07 10:30:57 +00:00
|
|
|
if (SwapEntry == 0)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
2008-12-07 18:05:28 +00:00
|
|
|
KeBugCheck(MEMORY_MANAGEMENT);
|
2004-04-10 22:36:07 +00:00
|
|
|
return(STATUS_UNSUCCESSFUL);
|
|
|
|
}
|
|
|
|
|
2000-07-07 10:30:57 +00:00
|
|
|
i = FILE_FROM_ENTRY(SwapEntry);
|
|
|
|
offset = OFFSET_FROM_ENTRY(SwapEntry);
|
2002-01-08 00:49:02 +00:00
|
|
|
|
|
|
|
if (PagingFileList[i]->FileObject == NULL ||
|
2004-04-10 22:36:07 +00:00
|
|
|
PagingFileList[i]->FileObject->DeviceObject == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("Bad paging file 0x%.8X\n", SwapEntry);
|
2008-12-07 18:05:28 +00:00
|
|
|
KeBugCheck(MEMORY_MANAGEMENT);
|
2004-04-10 22:36:07 +00:00
|
|
|
}
|
|
|
|
|
2004-06-06 09:13:21 +00:00
|
|
|
MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
|
2004-08-01 07:24:59 +00:00
|
|
|
MmBuildMdlFromPages(Mdl, &Page);
|
2008-04-25 07:55:12 +00:00
|
|
|
Mdl->MdlFlags |= MDL_PAGES_LOCKED;
|
2004-06-06 09:13:21 +00:00
|
|
|
|
2003-05-11 09:48:57 +00:00
|
|
|
file_offset.QuadPart = offset * PAGE_SIZE;
|
2003-11-30 17:19:28 +00:00
|
|
|
file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2002-08-28 07:13:04 +00:00
|
|
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
IO Manager Cleanup continues:
- Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of
one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some
objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third
system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile,
IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an
example).
- Cleaned up some IRP code and fixed a couple of bugs, mainly:
- Write I/O Type in IRP
- Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code)
- Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect
behaviour. Code should never depend on a buffer being zeroed!
- Remove a lot of duplicated code and helper/alternate functions that weren't really useful.
- Free MDL and IRP on some failures where we didn't
- Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted
in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the
old revision and copy/pasting the new code directly above it. The functions which we touched are:
- IoAllocateIrp
- IoBuild[A]SyncronousFsdRequest
- IoBuildDeviceIoControlRequest
- IoInitializeIrp
- IoPageRead, IoSynchronousPageWrite
svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
|
|
|
Status = IoSynchronousPageWrite(PagingFileList[i]->FileObject,
|
|
|
|
Mdl,
|
|
|
|
&file_offset,
|
|
|
|
&Event,
|
|
|
|
&Iosb);
|
2002-08-28 07:13:04 +00:00
|
|
|
if (Status == STATUS_PENDING)
|
|
|
|
{
|
|
|
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
2004-06-06 09:13:21 +00:00
|
|
|
Status = Iosb.Status;
|
2002-08-28 07:13:04 +00:00
|
|
|
}
|
[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
|
|
|
|
2008-04-25 07:55:12 +00:00
|
|
|
if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
|
|
|
|
{
|
|
|
|
MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
|
|
|
|
}
|
2000-07-07 10:30:57 +00:00
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
2005-09-14 01:05:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2010-07-15 22:50:12 +00:00
|
|
|
MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
|
2000-07-07 10:30:57 +00:00
|
|
|
{
|
[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
|
|
|
ULONG i;
|
|
|
|
ULONG_PTR offset;
|
2000-07-07 10:30:57 +00:00
|
|
|
LARGE_INTEGER file_offset;
|
|
|
|
IO_STATUS_BLOCK Iosb;
|
|
|
|
NTSTATUS Status;
|
2002-08-28 07:13:04 +00:00
|
|
|
KEVENT Event;
|
2004-06-06 09:13:21 +00:00
|
|
|
UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
|
|
|
|
PMDL Mdl = (PMDL)MdlBase;
|
2003-05-11 09:48:57 +00:00
|
|
|
|
|
|
|
DPRINT("MmReadFromSwapPage\n");
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2000-07-07 10:30:57 +00:00
|
|
|
if (SwapEntry == 0)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
2008-12-07 18:05:28 +00:00
|
|
|
KeBugCheck(MEMORY_MANAGEMENT);
|
2004-04-10 22:36:07 +00:00
|
|
|
return(STATUS_UNSUCCESSFUL);
|
|
|
|
}
|
|
|
|
|
2000-07-07 10:30:57 +00:00
|
|
|
i = FILE_FROM_ENTRY(SwapEntry);
|
|
|
|
offset = OFFSET_FROM_ENTRY(SwapEntry);
|
2002-01-08 00:49:02 +00:00
|
|
|
|
|
|
|
if (PagingFileList[i]->FileObject == NULL ||
|
2004-04-10 22:36:07 +00:00
|
|
|
PagingFileList[i]->FileObject->DeviceObject == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("Bad paging file 0x%.8X\n", SwapEntry);
|
2008-12-07 18:05:28 +00:00
|
|
|
KeBugCheck(MEMORY_MANAGEMENT);
|
2004-04-10 22:36:07 +00:00
|
|
|
}
|
2003-05-11 09:48:57 +00:00
|
|
|
|
2004-06-06 09:13:21 +00:00
|
|
|
MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
|
2004-08-01 07:24:59 +00:00
|
|
|
MmBuildMdlFromPages(Mdl, &Page);
|
2008-04-25 07:55:12 +00:00
|
|
|
Mdl->MdlFlags |= MDL_PAGES_LOCKED;
|
2004-06-06 09:13:21 +00:00
|
|
|
|
2003-11-30 17:19:28 +00:00
|
|
|
file_offset.QuadPart = offset * PAGE_SIZE;
|
|
|
|
file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2002-08-28 07:13:04 +00:00
|
|
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
2000-07-07 10:30:57 +00:00
|
|
|
Status = IoPageRead(PagingFileList[i]->FileObject,
|
2004-04-10 22:36:07 +00:00
|
|
|
Mdl,
|
|
|
|
&file_offset,
|
|
|
|
&Event,
|
|
|
|
&Iosb);
|
2002-08-28 07:13:04 +00:00
|
|
|
if (Status == STATUS_PENDING)
|
|
|
|
{
|
|
|
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
2004-06-06 09:13:21 +00:00
|
|
|
Status = Iosb.Status;
|
2002-08-28 07:13:04 +00:00
|
|
|
}
|
2008-04-25 07:55:12 +00:00
|
|
|
if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
|
|
|
|
{
|
|
|
|
MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
|
|
|
|
}
|
2000-07-07 10:30:57 +00:00
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
2005-09-14 01:05:50 +00:00
|
|
|
VOID
|
|
|
|
INIT_FUNCTION
|
|
|
|
NTAPI
|
2001-02-06 00:11:20 +00:00
|
|
|
MmInitPagingFile(VOID)
|
1999-12-10 17:04:37 +00:00
|
|
|
{
|
2000-07-04 08:52:47 +00:00
|
|
|
ULONG i;
|
2004-04-10 22:36:07 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
KeInitializeSpinLock(&PagingFileListLock);
|
2004-04-10 22:36:07 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
MiFreeSwapPages = 0;
|
|
|
|
MiUsedSwapPages = 0;
|
|
|
|
MiReservedSwapPages = 0;
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2000-07-04 08:52:47 +00:00
|
|
|
for (i = 0; i < MAX_PAGING_FILES; i++)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
PagingFileList[i] = NULL;
|
|
|
|
}
|
2002-03-18 16:16:47 +00:00
|
|
|
MiPagingFileCount = 0;
|
1999-12-10 17:04:37 +00:00
|
|
|
}
|
|
|
|
|
2001-02-06 00:11:20 +00:00
|
|
|
BOOLEAN
|
2005-09-14 01:05:50 +00:00
|
|
|
NTAPI
|
2001-02-06 00:11:20 +00:00
|
|
|
MmReserveSwapPages(ULONG Nr)
|
1999-12-10 17:04:37 +00:00
|
|
|
{
|
|
|
|
KIRQL oldIrql;
|
2001-02-06 00:11:20 +00:00
|
|
|
ULONG MiAvailSwapPages;
|
2004-04-10 22:36:07 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
2001-02-06 00:11:20 +00:00
|
|
|
MiAvailSwapPages =
|
2004-04-10 22:36:07 +00:00
|
|
|
(MiFreeSwapPages * MM_PAGEFILE_COMMIT_RATIO) + MM_PAGEFILE_COMMIT_GRACE;
|
2002-08-14 20:58:39 +00:00
|
|
|
MiReservedSwapPages = MiReservedSwapPages + Nr;
|
2007-11-20 19:15:02 +00:00
|
|
|
if ((MM_PAGEFILE_COMMIT_RATIO != 0) && (MiAvailSwapPages < MiReservedSwapPages))
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
1999-12-10 17:04:37 +00:00
|
|
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
2001-02-06 00:11:20 +00:00
|
|
|
return(TRUE);
|
1999-12-10 17:04:37 +00:00
|
|
|
}
|
|
|
|
|
2004-04-10 22:36:07 +00:00
|
|
|
VOID
|
2005-09-14 01:05:50 +00:00
|
|
|
NTAPI
|
2001-02-06 00:11:20 +00:00
|
|
|
MmDereserveSwapPages(ULONG Nr)
|
1999-12-10 17:04:37 +00:00
|
|
|
{
|
|
|
|
KIRQL oldIrql;
|
2004-04-10 22:36:07 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
|
|
|
MiReservedSwapPages = MiReservedSwapPages - Nr;
|
|
|
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
|
|
|
}
|
|
|
|
|
2004-04-10 22:36:07 +00:00
|
|
|
static ULONG
|
2001-02-06 00:11:20 +00:00
|
|
|
MiAllocPageFromPagingFile(PPAGINGFILE PagingFile)
|
1999-12-10 17:04:37 +00:00
|
|
|
{
|
|
|
|
KIRQL oldIrql;
|
2001-12-06 00:54:54 +00:00
|
|
|
ULONG i, j;
|
2004-04-10 22:36:07 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql);
|
2004-04-10 22:36:07 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
for (i = 0; i < PagingFile->AllocMapSize; i++)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
for (j = 0; j < 32; j++)
|
|
|
|
{
|
|
|
|
if (!(PagingFile->AllocMap[i] & (1 << j)))
|
|
|
|
{
|
2004-06-19 08:53:35 +00:00
|
|
|
PagingFile->AllocMap[i] |= (1 << j);
|
|
|
|
PagingFile->UsedPages++;
|
|
|
|
PagingFile->FreePages--;
|
|
|
|
KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
|
|
|
|
return((i * 32) + j);
|
2004-04-10 22:36:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
|
2001-12-31 19:06:49 +00:00
|
|
|
return(0xFFFFFFFF);
|
1999-12-10 17:04:37 +00:00
|
|
|
}
|
|
|
|
|
2004-04-10 22:36:07 +00:00
|
|
|
VOID
|
2005-09-14 01:05:50 +00:00
|
|
|
NTAPI
|
2001-02-06 00:11:20 +00:00
|
|
|
MmFreeSwapPage(SWAPENTRY Entry)
|
1999-12-10 17:04:37 +00:00
|
|
|
{
|
|
|
|
ULONG i;
|
[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
|
|
|
ULONG_PTR off;
|
1999-12-10 17:04:37 +00:00
|
|
|
KIRQL oldIrql;
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2000-07-07 10:30:57 +00:00
|
|
|
i = FILE_FROM_ENTRY(Entry);
|
|
|
|
off = OFFSET_FROM_ENTRY(Entry);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
2001-12-31 19:06:49 +00:00
|
|
|
if (PagingFileList[i] == NULL)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
2008-12-07 18:05:28 +00:00
|
|
|
KeBugCheck(MEMORY_MANAGEMENT);
|
2004-04-10 22:36:07 +00:00
|
|
|
}
|
1999-12-10 17:04:37 +00:00
|
|
|
KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2004-06-19 08:53:35 +00:00
|
|
|
PagingFileList[i]->AllocMap[off >> 5] &= (~(1 << (off % 32)));
|
2005-05-09 01:38:29 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
PagingFileList[i]->FreePages++;
|
|
|
|
PagingFileList[i]->UsedPages--;
|
2004-04-10 22:36:07 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
MiFreeSwapPages++;
|
|
|
|
MiUsedSwapPages--;
|
2004-04-10 22:36:07 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
KeReleaseSpinLockFromDpcLevel(&PagingFileList[i]->AllocMapLock);
|
|
|
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
|
|
|
}
|
|
|
|
|
2002-08-14 20:58:39 +00:00
|
|
|
BOOLEAN
|
2005-09-14 01:05:50 +00:00
|
|
|
NTAPI
|
2002-08-14 20:58:39 +00:00
|
|
|
MmIsAvailableSwapPage(VOID)
|
|
|
|
{
|
2004-04-10 22:36:07 +00:00
|
|
|
return(MiFreeSwapPages > 0);
|
2002-08-14 20:58:39 +00:00
|
|
|
}
|
|
|
|
|
2004-04-10 22:36:07 +00:00
|
|
|
SWAPENTRY
|
2005-09-14 01:05:50 +00:00
|
|
|
NTAPI
|
2001-02-06 00:11:20 +00:00
|
|
|
MmAllocSwapPage(VOID)
|
1999-12-10 17:04:37 +00:00
|
|
|
{
|
|
|
|
KIRQL oldIrql;
|
|
|
|
ULONG i;
|
|
|
|
ULONG off;
|
2004-04-10 22:36:07 +00:00
|
|
|
SWAPENTRY entry;
|
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
2004-04-10 22:36:07 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
if (MiFreeSwapPages == 0)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
for (i = 0; i < MAX_PAGING_FILES; i++)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
if (PagingFileList[i] != NULL &&
|
|
|
|
PagingFileList[i]->FreePages >= 1)
|
|
|
|
{
|
|
|
|
off = MiAllocPageFromPagingFile(PagingFileList[i]);
|
|
|
|
if (off == 0xFFFFFFFF)
|
|
|
|
{
|
2008-12-07 18:05:28 +00:00
|
|
|
KeBugCheck(MEMORY_MANAGEMENT);
|
2004-04-10 22:36:07 +00:00
|
|
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
|
|
|
return(STATUS_UNSUCCESSFUL);
|
|
|
|
}
|
|
|
|
MiUsedSwapPages++;
|
|
|
|
MiFreeSwapPages--;
|
|
|
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
|
|
|
|
|
|
|
entry = ENTRY_FROM_FILE_OFFSET(i, off);
|
|
|
|
return(entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
2008-12-07 18:05:28 +00:00
|
|
|
KeBugCheck(MEMORY_MANAGEMENT);
|
1999-12-10 17:04:37 +00:00
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2006-09-07 05:07:34 +00:00
|
|
|
static PRETRIEVEL_DESCRIPTOR_LIST FASTCALL
|
2004-03-04 00:07:03 +00:00
|
|
|
MmAllocRetrievelDescriptorList(ULONG Pairs)
|
|
|
|
{
|
|
|
|
ULONG Size;
|
|
|
|
PRETRIEVEL_DESCRIPTOR_LIST RetDescList;
|
|
|
|
|
2005-01-26 20:31:05 +00:00
|
|
|
Size = sizeof(RETRIEVEL_DESCRIPTOR_LIST) + Pairs * 2 * sizeof(LARGE_INTEGER);
|
2004-03-04 00:07:03 +00:00
|
|
|
RetDescList = ExAllocatePool(NonPagedPool, Size);
|
|
|
|
if (RetDescList)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
RtlZeroMemory(RetDescList, Size);
|
|
|
|
}
|
2004-03-04 00:07:03 +00:00
|
|
|
|
|
|
|
return RetDescList;
|
|
|
|
}
|
|
|
|
|
2008-11-29 20:47:48 +00:00
|
|
|
NTSTATUS NTAPI
|
2005-01-24 00:43:39 +00:00
|
|
|
NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
|
|
|
IN PLARGE_INTEGER InitialSize,
|
|
|
|
IN PLARGE_INTEGER MaximumSize,
|
2004-04-10 22:36:07 +00:00
|
|
|
IN ULONG Reserved)
|
1999-12-10 17:04:37 +00:00
|
|
|
{
|
2009-08-24 20:39:23 +00:00
|
|
|
NTSTATUS Status;
|
1999-12-10 17:04:37 +00:00
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
HANDLE FileHandle;
|
|
|
|
IO_STATUS_BLOCK IoStatus;
|
|
|
|
PFILE_OBJECT FileObject;
|
|
|
|
PPAGINGFILE PagingFile;
|
|
|
|
KIRQL oldIrql;
|
|
|
|
ULONG AllocMapSize;
|
2003-05-11 09:48:57 +00:00
|
|
|
FILE_FS_SIZE_INFORMATION FsSizeInformation;
|
2003-11-30 17:19:28 +00:00
|
|
|
PRETRIEVEL_DESCRIPTOR_LIST RetDescList;
|
|
|
|
PRETRIEVEL_DESCRIPTOR_LIST CurrentRetDescList;
|
1999-12-10 17:04:37 +00:00
|
|
|
ULONG i;
|
2003-05-11 09:48:57 +00:00
|
|
|
ULONG BytesPerAllocationUnit;
|
|
|
|
LARGE_INTEGER Vcn;
|
|
|
|
ULONG ExtentCount;
|
2005-01-26 20:31:05 +00:00
|
|
|
LARGE_INTEGER MaxVcn;
|
2003-11-30 17:19:28 +00:00
|
|
|
ULONG Count;
|
2004-03-04 00:07:03 +00:00
|
|
|
ULONG Size;
|
2005-01-24 00:18:57 +00:00
|
|
|
KPROCESSOR_MODE PreviousMode;
|
2005-01-24 00:43:39 +00:00
|
|
|
UNICODE_STRING CapturedFileName;
|
|
|
|
LARGE_INTEGER SafeInitialSize, SafeMaximumSize;
|
2001-12-31 19:06:49 +00:00
|
|
|
|
2002-03-18 16:16:47 +00:00
|
|
|
DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n",
|
2004-04-10 22:36:07 +00:00
|
|
|
FileName, InitialSize->QuadPart);
|
|
|
|
|
2002-03-18 16:16:47 +00:00
|
|
|
if (MiPagingFileCount >= MAX_PAGING_FILES)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
return(STATUS_TOO_MANY_PAGING_FILES);
|
|
|
|
}
|
|
|
|
|
2005-01-24 00:18:57 +00:00
|
|
|
PreviousMode = ExGetPreviousMode();
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-08-21 19:04:23 +00:00
|
|
|
if (PreviousMode != KernelMode)
|
2005-01-24 00:18:57 +00:00
|
|
|
{
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_TRY
|
2005-01-24 00:18:57 +00:00
|
|
|
{
|
2005-08-21 19:04:23 +00:00
|
|
|
SafeInitialSize = ProbeForReadLargeInteger(InitialSize);
|
|
|
|
SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
|
2005-01-24 00:18:57 +00:00
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2005-01-24 00:18:57 +00:00
|
|
|
{
|
2009-08-24 20:39:23 +00:00
|
|
|
/* Return the exception code */
|
|
|
|
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
2005-01-24 00:18:57 +00:00
|
|
|
}
|
2008-11-24 13:40:26 +00:00
|
|
|
_SEH2_END;
|
2005-01-24 00:18:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-01-24 00:43:39 +00:00
|
|
|
SafeInitialSize = *InitialSize;
|
|
|
|
SafeMaximumSize = *MaximumSize;
|
2005-01-24 00:18:57 +00:00
|
|
|
}
|
|
|
|
|
2005-12-31 19:50:29 +00:00
|
|
|
/* Pagefiles can't be larger than 4GB and ofcourse the minimum should be
|
|
|
|
smaller than the maximum */
|
|
|
|
if (0 != SafeInitialSize.u.HighPart)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER_2;
|
|
|
|
}
|
|
|
|
if (0 != SafeMaximumSize.u.HighPart)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER_3;
|
|
|
|
}
|
|
|
|
if (SafeMaximumSize.u.LowPart < SafeInitialSize.u.LowPart)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER_MIX;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = ProbeAndCaptureUnicodeString(&CapturedFileName,
|
|
|
|
PreviousMode,
|
|
|
|
FileName);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
2005-01-24 00:43:39 +00:00
|
|
|
&CapturedFileName,
|
2004-04-10 22:36:07 +00:00
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
2002-01-08 00:49:02 +00:00
|
|
|
Status = IoCreateFile(&FileHandle,
|
2004-04-10 22:36:07 +00:00
|
|
|
FILE_ALL_ACCESS,
|
|
|
|
&ObjectAttributes,
|
|
|
|
&IoStatus,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
FILE_OPEN_IF,
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
CreateFileTypeNone,
|
|
|
|
NULL,
|
2005-01-24 22:02:09 +00:00
|
|
|
SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING);
|
2005-02-15 14:37:53 +00:00
|
|
|
|
Major refactoring of the exception handling code + misc fixes:
- Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind
- Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE
- Add w32api excpt.h (based on mingw) with PSDK compatibility fixes
- Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes
- Fix KiUserExceptionDispatcher
- Remove useless NTDLL entrypoint
- Implement NTDLL Ki* callbacks in ASM
- Implement RtlCaptureContext
- Fix RtlRaiseException to handle cases when a user-mode debugger is present
- Fix RtlRaiseStatus as above, plus set the exception address and capture context
- Little cleanup of RTL headers
- Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM
- Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the
exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of
Context.
- Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL.
- Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax
and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some
optimizations to increase speed.
- Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to
support a PKEXCEPTION_FRAME for future PPC compatibility.
- Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them.
- Export ExRaiseStatus/Exception as Rtl*
- Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context
and parameters with SEH.
- Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack.
- Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during
v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the
user-mode callback.
- Implement KiUnexpectedInterrupt and KiCoprocessorError
- Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the
stack when called through System call interface.
- Fix Ntcontinue to respect AlertThread paramter
- Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed
- Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context
flags,...
- Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any
exceptions (the kernel-mode code to handle this isn't written yet though)
svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
|
|
|
ReleaseCapturedUnicodeString(&CapturedFileName,
|
|
|
|
PreviousMode);
|
1999-12-10 17:04:37 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
2005-01-24 00:18:57 +00:00
|
|
|
Status = ZwQueryVolumeInformationFile(FileHandle,
|
2003-05-11 09:48:57 +00:00
|
|
|
&IoStatus,
|
2004-04-10 22:36:07 +00:00
|
|
|
&FsSizeInformation,
|
|
|
|
sizeof(FILE_FS_SIZE_INFORMATION),
|
|
|
|
FileFsSizeInformation);
|
2003-05-11 09:48:57 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
2005-01-24 00:18:57 +00:00
|
|
|
ZwClose(FileHandle);
|
2004-04-10 22:36:07 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2005-12-31 19:50:29 +00:00
|
|
|
BytesPerAllocationUnit = FsSizeInformation.SectorsPerAllocationUnit *
|
|
|
|
FsSizeInformation.BytesPerSector;
|
2006-01-01 10:24:27 +00:00
|
|
|
/* FIXME: If we have 2048 BytesPerAllocationUnit (FAT16 < 128MB) there is
|
|
|
|
* a problem if the paging file is fragmented. Suppose the first cluster
|
|
|
|
* of the paging file is cluster 3042 but cluster 3043 is NOT part of the
|
|
|
|
* paging file but of another file. We can't write a complete page (4096
|
|
|
|
* bytes) to the physical location of cluster 3042 then. */
|
|
|
|
if (BytesPerAllocationUnit % PAGE_SIZE)
|
|
|
|
{
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT1("BytesPerAllocationUnit %lu is not a multiple of PAGE_SIZE %d\n",
|
2006-01-01 10:24:27 +00:00
|
|
|
BytesPerAllocationUnit, PAGE_SIZE);
|
2005-01-24 00:18:57 +00:00
|
|
|
ZwClose(FileHandle);
|
2006-01-01 10:24:27 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
2004-04-10 22:36:07 +00:00
|
|
|
}
|
2001-12-31 19:06:49 +00:00
|
|
|
|
2005-01-24 00:18:57 +00:00
|
|
|
Status = ZwSetInformationFile(FileHandle,
|
2004-04-10 22:36:07 +00:00
|
|
|
&IoStatus,
|
2005-01-24 00:43:39 +00:00
|
|
|
&SafeInitialSize,
|
2004-04-10 22:36:07 +00:00
|
|
|
sizeof(LARGE_INTEGER),
|
|
|
|
FileAllocationInformation);
|
2001-12-31 19:06:49 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
2005-01-24 00:18:57 +00:00
|
|
|
ZwClose(FileHandle);
|
2004-04-10 22:36:07 +00:00
|
|
|
return(Status);
|
|
|
|
}
|
2001-12-31 19:06:49 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
Status = ObReferenceObjectByHandle(FileHandle,
|
2004-04-10 22:36:07 +00:00
|
|
|
FILE_ALL_ACCESS,
|
|
|
|
IoFileObjectType,
|
2005-01-24 00:43:39 +00:00
|
|
|
PreviousMode,
|
2004-04-10 22:36:07 +00:00
|
|
|
(PVOID*)&FileObject,
|
|
|
|
NULL);
|
1999-12-10 17:04:37 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
2005-01-24 00:18:57 +00:00
|
|
|
ZwClose(FileHandle);
|
2004-04-10 22:36:07 +00:00
|
|
|
return(Status);
|
|
|
|
}
|
2003-05-11 09:48:57 +00:00
|
|
|
|
2004-03-04 00:07:03 +00:00
|
|
|
CurrentRetDescList = RetDescList = MmAllocRetrievelDescriptorList(PAIRS_PER_RUN);
|
2003-05-11 09:48:57 +00:00
|
|
|
|
2003-11-30 17:19:28 +00:00
|
|
|
if (CurrentRetDescList == NULL)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
ObDereferenceObject(FileObject);
|
2005-01-24 00:18:57 +00:00
|
|
|
ZwClose(FileHandle);
|
2004-04-10 22:36:07 +00:00
|
|
|
return(STATUS_NO_MEMORY);
|
|
|
|
}
|
2003-05-11 09:48:57 +00:00
|
|
|
|
2003-12-30 18:52:06 +00:00
|
|
|
#if defined(__GNUC__)
|
2003-05-11 09:48:57 +00:00
|
|
|
Vcn.QuadPart = 0LL;
|
2003-12-30 18:52:06 +00:00
|
|
|
#else
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2003-12-30 18:52:06 +00:00
|
|
|
Vcn.QuadPart = 0;
|
|
|
|
#endif
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2003-05-11 09:48:57 +00:00
|
|
|
ExtentCount = 0;
|
2005-01-26 20:31:05 +00:00
|
|
|
MaxVcn.QuadPart = (SafeInitialSize.QuadPart + BytesPerAllocationUnit - 1) / BytesPerAllocationUnit;
|
2003-05-11 09:48:57 +00:00
|
|
|
while(1)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
2005-01-24 00:18:57 +00:00
|
|
|
Status = ZwFsControlFile(FileHandle,
|
2004-04-10 22:36:07 +00:00
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&IoStatus,
|
|
|
|
FSCTL_GET_RETRIEVAL_POINTERS,
|
|
|
|
&Vcn,
|
|
|
|
sizeof(LARGE_INTEGER),
|
|
|
|
&CurrentRetDescList->RetrievalPointers,
|
2005-01-26 20:31:05 +00:00
|
|
|
sizeof(RETRIEVAL_POINTERS_BUFFER) + PAIRS_PER_RUN * 2 * sizeof(LARGE_INTEGER));
|
2004-04-10 22:36:07 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
while (RetDescList)
|
2003-05-11 09:48:57 +00:00
|
|
|
{
|
2004-04-10 22:36:07 +00:00
|
|
|
CurrentRetDescList = RetDescList;
|
|
|
|
RetDescList = RetDescList->Next;
|
|
|
|
ExFreePool(CurrentRetDescList);
|
2003-05-11 09:48:57 +00:00
|
|
|
}
|
2004-04-10 22:36:07 +00:00
|
|
|
ObDereferenceObject(FileObject);
|
2005-01-24 00:18:57 +00:00
|
|
|
ZwClose(FileHandle);
|
2004-04-10 22:36:07 +00:00
|
|
|
return(Status);
|
|
|
|
}
|
2005-01-26 20:31:05 +00:00
|
|
|
ExtentCount += CurrentRetDescList->RetrievalPointers.ExtentCount;
|
|
|
|
if (CurrentRetDescList->RetrievalPointers.Extents[CurrentRetDescList->RetrievalPointers.ExtentCount-1].NextVcn.QuadPart < MaxVcn.QuadPart)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
CurrentRetDescList->Next = MmAllocRetrievelDescriptorList(PAIRS_PER_RUN);
|
|
|
|
if (CurrentRetDescList->Next == NULL)
|
2003-05-11 09:48:57 +00:00
|
|
|
{
|
2004-04-10 22:36:07 +00:00
|
|
|
while (RetDescList)
|
|
|
|
{
|
|
|
|
CurrentRetDescList = RetDescList;
|
|
|
|
RetDescList = RetDescList->Next;
|
|
|
|
ExFreePool(CurrentRetDescList);
|
|
|
|
}
|
|
|
|
ObDereferenceObject(FileObject);
|
2005-01-24 00:18:57 +00:00
|
|
|
ZwClose(FileHandle);
|
2004-04-10 22:36:07 +00:00
|
|
|
return(STATUS_NO_MEMORY);
|
2003-05-11 09:48:57 +00:00
|
|
|
}
|
2005-01-26 20:31:05 +00:00
|
|
|
Vcn = CurrentRetDescList->RetrievalPointers.Extents[CurrentRetDescList->RetrievalPointers.ExtentCount-1].NextVcn;
|
2004-04-10 22:36:07 +00:00
|
|
|
CurrentRetDescList = CurrentRetDescList->Next;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-05-11 09:48:57 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
PagingFile = ExAllocatePool(NonPagedPool, sizeof(*PagingFile));
|
|
|
|
if (PagingFile == NULL)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
while (RetDescList)
|
|
|
|
{
|
|
|
|
CurrentRetDescList = RetDescList;
|
|
|
|
RetDescList = RetDescList->Next;
|
|
|
|
ExFreePool(CurrentRetDescList);
|
|
|
|
}
|
|
|
|
ObDereferenceObject(FileObject);
|
2005-01-24 00:18:57 +00:00
|
|
|
ZwClose(FileHandle);
|
2004-04-10 22:36:07 +00:00
|
|
|
return(STATUS_NO_MEMORY);
|
|
|
|
}
|
|
|
|
|
2004-03-04 00:07:03 +00:00
|
|
|
RtlZeroMemory(PagingFile, sizeof(*PagingFile));
|
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
PagingFile->FileObject = FileObject;
|
2005-01-24 00:43:39 +00:00
|
|
|
PagingFile->MaximumSize.QuadPart = SafeMaximumSize.QuadPart;
|
|
|
|
PagingFile->CurrentSize.QuadPart = SafeInitialSize.QuadPart;
|
|
|
|
PagingFile->FreePages = (ULONG)(SafeInitialSize.QuadPart / PAGE_SIZE);
|
1999-12-10 17:04:37 +00:00
|
|
|
PagingFile->UsedPages = 0;
|
|
|
|
KeInitializeSpinLock(&PagingFile->AllocMapLock);
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2002-03-18 16:16:47 +00:00
|
|
|
AllocMapSize = (PagingFile->FreePages / 32) + 1;
|
2004-04-10 22:36:07 +00:00
|
|
|
PagingFile->AllocMap = ExAllocatePool(NonPagedPool,
|
|
|
|
AllocMapSize * sizeof(ULONG));
|
1999-12-10 17:04:37 +00:00
|
|
|
PagingFile->AllocMapSize = AllocMapSize;
|
2004-04-10 22:36:07 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
if (PagingFile->AllocMap == NULL)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
while (RetDescList)
|
|
|
|
{
|
|
|
|
CurrentRetDescList = RetDescList;
|
|
|
|
RetDescList = RetDescList->Next;
|
|
|
|
ExFreePool(CurrentRetDescList);
|
|
|
|
}
|
|
|
|
ExFreePool(PagingFile);
|
|
|
|
ObDereferenceObject(FileObject);
|
|
|
|
ZwClose(FileHandle);
|
|
|
|
return(STATUS_NO_MEMORY);
|
|
|
|
}
|
2013-08-31 16:02:13 +00:00
|
|
|
DPRINT("ExtentCount: %lu\n", ExtentCount);
|
2005-01-26 20:31:05 +00:00
|
|
|
Size = sizeof(RETRIEVAL_POINTERS_BUFFER) + ExtentCount * 2 * sizeof(LARGE_INTEGER);
|
2003-05-11 09:48:57 +00:00
|
|
|
PagingFile->RetrievalPointers = ExAllocatePool(NonPagedPool, Size);
|
|
|
|
if (PagingFile->RetrievalPointers == NULL)
|
|
|
|
{
|
2004-04-10 22:36:07 +00:00
|
|
|
while (RetDescList)
|
|
|
|
{
|
|
|
|
CurrentRetDescList = RetDescList;
|
|
|
|
RetDescList = RetDescList->Next;
|
|
|
|
ExFreePool(CurrentRetDescList);
|
|
|
|
}
|
2003-05-11 09:48:57 +00:00
|
|
|
ExFreePool(PagingFile->AllocMap);
|
|
|
|
ExFreePool(PagingFile);
|
|
|
|
ObDereferenceObject(FileObject);
|
2005-01-24 00:18:57 +00:00
|
|
|
ZwClose(FileHandle);
|
2003-05-11 09:48:57 +00:00
|
|
|
return(STATUS_NO_MEMORY);
|
|
|
|
}
|
2003-11-30 17:19:28 +00:00
|
|
|
|
2004-03-04 00:07:03 +00:00
|
|
|
RtlZeroMemory(PagingFile->AllocMap, AllocMapSize * sizeof(ULONG));
|
|
|
|
RtlZeroMemory(PagingFile->RetrievalPointers, Size);
|
|
|
|
|
2003-11-30 17:19:28 +00:00
|
|
|
Count = 0;
|
2005-01-26 20:31:05 +00:00
|
|
|
PagingFile->RetrievalPointers->ExtentCount = ExtentCount;
|
|
|
|
PagingFile->RetrievalPointers->StartingVcn = RetDescList->RetrievalPointers.StartingVcn;
|
2003-11-30 17:19:28 +00:00
|
|
|
CurrentRetDescList = RetDescList;
|
|
|
|
while (CurrentRetDescList)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
2005-01-26 20:31:05 +00:00
|
|
|
memcpy(&PagingFile->RetrievalPointers->Extents[Count],
|
|
|
|
CurrentRetDescList->RetrievalPointers.Extents,
|
|
|
|
CurrentRetDescList->RetrievalPointers.ExtentCount * 2 * sizeof(LARGE_INTEGER));
|
|
|
|
Count += CurrentRetDescList->RetrievalPointers.ExtentCount;
|
2004-04-10 22:36:07 +00:00
|
|
|
RetDescList = CurrentRetDescList;
|
|
|
|
CurrentRetDescList = CurrentRetDescList->Next;
|
|
|
|
ExFreePool(RetDescList);
|
|
|
|
}
|
|
|
|
|
2005-01-26 20:31:05 +00:00
|
|
|
if (PagingFile->RetrievalPointers->ExtentCount != ExtentCount ||
|
|
|
|
PagingFile->RetrievalPointers->Extents[ExtentCount - 1].NextVcn.QuadPart != MaxVcn.QuadPart)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
ExFreePool(PagingFile->RetrievalPointers);
|
|
|
|
ExFreePool(PagingFile->AllocMap);
|
|
|
|
ExFreePool(PagingFile);
|
|
|
|
ObDereferenceObject(FileObject);
|
2005-01-24 00:18:57 +00:00
|
|
|
ZwClose(FileHandle);
|
2004-04-10 22:36:07 +00:00
|
|
|
return(STATUS_UNSUCCESSFUL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2003-05-11 09:48:57 +00:00
|
|
|
* Change the entries from lcn's to volume offset's.
|
|
|
|
*/
|
2005-01-26 20:31:05 +00:00
|
|
|
PagingFile->RetrievalPointers->StartingVcn.QuadPart *= BytesPerAllocationUnit;
|
2003-05-11 09:48:57 +00:00
|
|
|
for (i = 0; i < ExtentCount; i++)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
2005-01-26 20:31:05 +00:00
|
|
|
PagingFile->RetrievalPointers->Extents[i].Lcn.QuadPart *= BytesPerAllocationUnit;
|
|
|
|
PagingFile->RetrievalPointers->Extents[i].NextVcn.QuadPart *= BytesPerAllocationUnit;
|
2004-04-10 22:36:07 +00:00
|
|
|
}
|
2003-05-11 09:48:57 +00:00
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
|
|
|
for (i = 0; i < MAX_PAGING_FILES; i++)
|
2004-04-10 22:36:07 +00:00
|
|
|
{
|
|
|
|
if (PagingFileList[i] == NULL)
|
|
|
|
{
|
|
|
|
PagingFileList[i] = PagingFile;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2002-03-18 16:16:47 +00:00
|
|
|
MiFreeSwapPages = MiFreeSwapPages + PagingFile->FreePages;
|
|
|
|
MiPagingFileCount++;
|
1999-12-10 17:04:37 +00:00
|
|
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
2004-04-10 22:36:07 +00:00
|
|
|
|
2005-01-24 00:18:57 +00:00
|
|
|
ZwClose(FileHandle);
|
2002-08-17 01:42:03 +00:00
|
|
|
|
|
|
|
MmSwapSpaceMessage = FALSE;
|
|
|
|
|
1999-12-10 17:04:37 +00:00
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
2000-03-26 19:38:32 +00:00
|
|
|
|
|
|
|
/* EOF */
|