3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: pagefile.c,v 1.32 2003/07/11 01:23:15 royce Exp $
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/mm/pagefile.c
23 * PURPOSE: Paging file functions
24 * PROGRAMMER: David Welch (welch@mcmail.com)
29 /* INCLUDES *****************************************************************/
31 #include <ddk/ntddk.h>
32 #include <internal/io.h>
33 #include <internal/mm.h>
34 #include <napi/core.h>
35 #include <internal/ps.h>
38 #include <internal/debug.h>
40 /* TYPES *********************************************************************/
42 typedef struct _PAGINGFILE
44 LIST_ENTRY PagingFileListEntry
;
45 PFILE_OBJECT FileObject
;
46 LARGE_INTEGER MaximumSize
;
47 LARGE_INTEGER CurrentSize
;
51 KSPIN_LOCK AllocMapLock
;
53 PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers
;
54 } PAGINGFILE
, *PPAGINGFILE
;
56 /* GLOBALS *******************************************************************/
58 #define MAX_PAGING_FILES (32)
60 /* List of paging files, both used and free */
61 static PPAGINGFILE PagingFileList
[MAX_PAGING_FILES
];
63 /* Lock for examining the list of paging files */
64 static KSPIN_LOCK PagingFileListLock
;
66 /* Number of paging files */
67 static ULONG MiPagingFileCount
;
69 /* Number of pages that are available for swapping */
70 static ULONG MiFreeSwapPages
;
72 /* Number of pages that have been allocated for swapping */
73 static ULONG MiUsedSwapPages
;
76 * Number of pages that have been reserved for swapping but not yet allocated
78 static ULONG MiReservedSwapPages
;
81 * Ratio between reserved and available swap pages, e.g. setting this to five
82 * forces one swap page to be available for every five swap pages that are
83 * reserved. Setting this to zero turns off commit checking altogether.
85 #define MM_PAGEFILE_COMMIT_RATIO (1)
88 * Number of pages that can be used for potentially swapable memory without
89 * pagefile space being reserved. The intention is that this allows smss
90 * to start up and create page files while ordinarily having a commit
93 #define MM_PAGEFILE_COMMIT_GRACE (256)
95 static PVOID MmCoreDumpPageFrame
;
96 static PULONG MmCoreDumpBlockMap
;
97 static ULONG MmCoreDumpSize
;
98 static PULONG MmCoreDumpBlockMap
= NULL
;
99 static MM_DUMP_POINTERS MmCoreDumpDeviceFuncs
;
100 ULONG MmCoreDumpType
;
103 * Translate between a swap entry and a file and offset pair.
105 #define FILE_FROM_ENTRY(i) ((i) >> 24)
106 #define OFFSET_FROM_ENTRY(i) (((i) & 0xffffff) - 1)
107 #define ENTRY_FROM_FILE_OFFSET(i, j) (((i) << 24) | ((j) + 1))
109 static BOOLEAN MmSwapSpaceMessage
= FALSE
;
111 /* FUNCTIONS *****************************************************************/
114 MmShowOutOfSpaceMessagePagingFile(VOID
)
116 if (!MmSwapSpaceMessage
)
118 DPRINT1("MM: Out of swap space.\n");
119 MmSwapSpaceMessage
= TRUE
;
123 NTSTATUS
MmWriteToSwapPage(SWAPENTRY SwapEntry
, PMDL Mdl
)
126 LARGE_INTEGER file_offset
;
127 IO_STATUS_BLOCK Iosb
;
130 PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers
;
132 DPRINT("MmWriteToSwapPage\n");
137 return(STATUS_UNSUCCESSFUL
);
140 i
= FILE_FROM_ENTRY(SwapEntry
);
141 offset
= OFFSET_FROM_ENTRY(SwapEntry
);
143 if (i
>= MAX_PAGING_FILES
)
145 DPRINT1("Bad swap entry 0x%.8X\n", SwapEntry
);
148 if (PagingFileList
[i
]->FileObject
== NULL
||
149 PagingFileList
[i
]->FileObject
->DeviceObject
== NULL
)
151 DPRINT1("Bad paging file 0x%.8X\n", SwapEntry
);
155 file_offset
.QuadPart
= offset
* PAGE_SIZE
;
156 RetrievalPointers
= PagingFileList
[i
]->RetrievalPointers
;
158 for (j
= 0; j
< RetrievalPointers
->NumberOfPairs
; j
++)
160 if ((ULONGLONG
) file_offset
.QuadPart
< RetrievalPointers
->Pair
[j
].Vcn
)
164 file_offset
.QuadPart
+= RetrievalPointers
->Pair
[0].Lcn
- RetrievalPointers
->StartVcn
;
168 file_offset
.QuadPart
+= RetrievalPointers
->Pair
[j
].Lcn
- RetrievalPointers
->Pair
[j
-1].Vcn
;
173 if (j
>= RetrievalPointers
->NumberOfPairs
)
179 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
180 Status
= IoPageWrite(PagingFileList
[i
]->FileObject
,
185 if (Status
== STATUS_PENDING
)
187 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
193 NTSTATUS
MmReadFromSwapPage(SWAPENTRY SwapEntry
, PMDL Mdl
)
196 LARGE_INTEGER file_offset
;
197 IO_STATUS_BLOCK Iosb
;
200 PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers
;
202 DPRINT("MmReadFromSwapPage\n");
207 return(STATUS_UNSUCCESSFUL
);
210 i
= FILE_FROM_ENTRY(SwapEntry
);
211 offset
= OFFSET_FROM_ENTRY(SwapEntry
);
213 if (i
>= MAX_PAGING_FILES
)
215 DPRINT1("Bad swap entry 0x%.8X\n", SwapEntry
);
218 if (PagingFileList
[i
]->FileObject
== NULL
||
219 PagingFileList
[i
]->FileObject
->DeviceObject
== NULL
)
221 DPRINT1("Bad paging file 0x%.8X\n", SwapEntry
);
225 file_offset
.QuadPart
= offset
* PAGE_SIZE
;
226 RetrievalPointers
= PagingFileList
[i
]->RetrievalPointers
;
228 for (j
= 0; j
< RetrievalPointers
->NumberOfPairs
; j
++)
230 if ((ULONGLONG
) file_offset
.QuadPart
< RetrievalPointers
->Pair
[j
].Vcn
)
234 file_offset
.QuadPart
+= RetrievalPointers
->Pair
[0].Lcn
- RetrievalPointers
->StartVcn
;
238 file_offset
.QuadPart
+= RetrievalPointers
->Pair
[j
].Lcn
- RetrievalPointers
->Pair
[j
-1].Vcn
;
243 if (j
>= RetrievalPointers
->NumberOfPairs
)
248 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
249 Status
= IoPageRead(PagingFileList
[i
]->FileObject
,
254 if (Status
== STATUS_PENDING
)
256 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
263 MmInitPagingFile(VOID
)
267 KeInitializeSpinLock(&PagingFileListLock
);
271 MiReservedSwapPages
= 0;
273 for (i
= 0; i
< MAX_PAGING_FILES
; i
++)
275 PagingFileList
[i
] = NULL
;
277 MiPagingFileCount
= 0;
280 * Initialize the crash dump support.
282 MmCoreDumpPageFrame
= MmAllocateSection(PAGE_SIZE
);
283 if (MmCoreDumpType
== MM_CORE_DUMP_TYPE_FULL
)
285 MmCoreDumpSize
= MmStats
.NrTotalPages
* 4096 + 1024 * 1024;
289 MmCoreDumpSize
= 1024 * 1024;
294 MmReserveSwapPages(ULONG Nr
)
297 ULONG MiAvailSwapPages
;
299 KeAcquireSpinLock(&PagingFileListLock
, &oldIrql
);
301 (MiFreeSwapPages
* MM_PAGEFILE_COMMIT_RATIO
) + MM_PAGEFILE_COMMIT_GRACE
;
302 MiReservedSwapPages
= MiReservedSwapPages
+ Nr
;
303 if (MM_PAGEFILE_COMMIT_RATIO
!= 0 && MiAvailSwapPages
< MiReservedSwapPages
)
305 KeReleaseSpinLock(&PagingFileListLock
, oldIrql
);
308 KeReleaseSpinLock(&PagingFileListLock
, oldIrql
);
313 MmDereserveSwapPages(ULONG Nr
)
317 KeAcquireSpinLock(&PagingFileListLock
, &oldIrql
);
318 MiReservedSwapPages
= MiReservedSwapPages
- Nr
;
319 KeReleaseSpinLock(&PagingFileListLock
, oldIrql
);
323 MiAllocPageFromPagingFile(PPAGINGFILE PagingFile
)
328 KeAcquireSpinLock(&PagingFile
->AllocMapLock
, &oldIrql
);
330 for (i
= 0; i
< PagingFile
->AllocMapSize
; i
++)
332 for (j
= 0; j
< 32; j
++)
334 if (!(PagingFile
->AllocMap
[i
] & (1 << j
)))
343 PagingFile
->AllocMap
[i
] |= (1 << j
);
344 PagingFile
->UsedPages
++;
345 PagingFile
->FreePages
--;
346 KeReleaseSpinLock(&PagingFile
->AllocMapLock
, oldIrql
);
347 return((i
* 32) + j
);
350 KeReleaseSpinLock(&PagingFile
->AllocMapLock
, oldIrql
);
355 MmFreeSwapPage(SWAPENTRY Entry
)
361 i
= FILE_FROM_ENTRY(Entry
);
362 off
= OFFSET_FROM_ENTRY(Entry
);
364 KeAcquireSpinLock(&PagingFileListLock
, &oldIrql
);
365 if (PagingFileList
[i
] == NULL
)
369 KeAcquireSpinLockAtDpcLevel(&PagingFileList
[i
]->AllocMapLock
);
371 PagingFileList
[i
]->AllocMap
[off
/ 32] &= (~(1 << (off
% 32)));
373 PagingFileList
[i
]->FreePages
++;
374 PagingFileList
[i
]->UsedPages
--;
379 KeReleaseSpinLockFromDpcLevel(&PagingFileList
[i
]->AllocMapLock
);
380 KeReleaseSpinLock(&PagingFileListLock
, oldIrql
);
384 MmIsAvailableSwapPage(VOID
)
386 return(MiFreeSwapPages
> 0);
390 MmAllocSwapPage(VOID
)
397 KeAcquireSpinLock(&PagingFileListLock
, &oldIrql
);
399 if (MiFreeSwapPages
== 0)
401 KeReleaseSpinLock(&PagingFileListLock
, oldIrql
);
405 for (i
= 0; i
< MAX_PAGING_FILES
; i
++)
407 if (PagingFileList
[i
] != NULL
&&
408 PagingFileList
[i
]->FreePages
>= 1)
410 off
= MiAllocPageFromPagingFile(PagingFileList
[i
]);
411 if (off
== 0xFFFFFFFF)
414 KeReleaseSpinLock(&PagingFileListLock
, oldIrql
);
415 return(STATUS_UNSUCCESSFUL
);
419 KeReleaseSpinLock(&PagingFileListLock
, oldIrql
);
421 entry
= ENTRY_FROM_FILE_OFFSET(i
, off
);
426 KeReleaseSpinLock(&PagingFileListLock
, oldIrql
);
432 MmDumpToPagingFile(ULONG BugCode
,
433 ULONG BugCodeParameter1
,
434 ULONG BugCodeParameter2
,
435 ULONG BugCodeParameter3
,
436 ULONG BugCodeParameter4
,
437 PKTRAP_FRAME TrapFrame
)
439 PMM_CORE_DUMP_HEADER Headers
;
442 UCHAR MdlBase
[sizeof(MDL
) + sizeof(PVOID
)];
443 PMDL Mdl
= (PMDL
)MdlBase
;
444 PETHREAD Thread
= PsGetCurrentThread();
447 ULONG NextOffset
= 0;
450 if (MmCoreDumpBlockMap
== NULL
)
452 return(STATUS_UNSUCCESSFUL
);
455 DbgPrint("MM: Dumping core");
457 /* Prepare the dump headers. */
458 Headers
= (PMM_CORE_DUMP_HEADER
)MmCoreDumpPageFrame
;
459 Headers
->Magic
= MM_CORE_DUMP_HEADER_MAGIC
;
460 Headers
->Version
= MM_CORE_DUMP_HEADER_VERSION
;
461 Headers
->Type
= MmCoreDumpType
;
462 if (TrapFrame
!= NULL
)
464 if (!(TrapFrame
->Eflags
& (1 << 17)))
466 memcpy(&Headers
->TrapFrame
, TrapFrame
,
467 sizeof(KTRAP_FRAME
) - (4 * sizeof(DWORD
)));
471 memcpy(&Headers
->TrapFrame
, TrapFrame
, sizeof(KTRAP_FRAME
));
474 Headers
->BugCheckCode
= BugCode
;
475 Headers
->BugCheckParameters
[0] = BugCodeParameter1
;
476 Headers
->BugCheckParameters
[1] = BugCodeParameter2
;
477 Headers
->BugCheckParameters
[2] = BugCodeParameter3
;
478 Headers
->BugCheckParameters
[3] = BugCodeParameter4
;
479 Headers
->FaultingStackBase
= (PVOID
)Thread
->Tcb
.StackLimit
;
480 Headers
->FaultingStackSize
= StackSize
=
481 (ULONG
)(Thread
->Tcb
.StackBase
- Thread
->Tcb
.StackLimit
);
482 Headers
->PhysicalMemorySize
= MmStats
.NrTotalPages
* PAGE_SIZE
;
484 /* Initialize the dump device. */
485 Context
= MmCoreDumpDeviceFuncs
.Context
;
486 Status
= MmCoreDumpDeviceFuncs
.DeviceInit(Context
);
487 if (!NT_SUCCESS(Status
))
489 DPRINT1("MM: Failed to initialize core dump device.\n");
493 /* Initialize the MDL. */
495 Mdl
->Size
= sizeof(MDL
) + sizeof(PVOID
);
496 Mdl
->MdlFlags
= MDL_SOURCE_IS_NONPAGED_POOL
;
498 Mdl
->MappedSystemVa
= MmCoreDumpPageFrame
;
500 Mdl
->ByteCount
= PAGE_SIZE
;
502 MdlMap
= (PULONG
)(Mdl
+ 1);
504 /* Dump the header. */
505 MdlMap
[0] = MmGetPhysicalAddress(MmCoreDumpPageFrame
).u
.LowPart
;
506 Status
= MmCoreDumpDeviceFuncs
.DeviceWrite(Context
,
507 MmCoreDumpBlockMap
[NextOffset
],
509 if (!NT_SUCCESS(Status
))
511 DPRINT1("MM: Failed to write core dump header\n.");
516 /* Write out the kernel mode stack of the faulting thread. */
517 for (i
= 0; i
< (StackSize
/ PAGE_SIZE
); i
++)
519 Mdl
->MappedSystemVa
= (PVOID
)(Thread
->Tcb
.StackLimit
+ (i
* PAGE_SIZE
));
520 MdlMap
[0] = MmGetPhysicalAddress(Mdl
->MappedSystemVa
).u
.LowPart
;
522 MmCoreDumpDeviceFuncs
.DeviceWrite(Context
,
523 MmCoreDumpBlockMap
[NextOffset
],
525 if (!NT_SUCCESS(Status
))
527 DPRINT1("MM: Failed to write page to core dump.\n");
534 /* Write out the contents of physical memory. */
535 if (MmCoreDumpType
== MM_CORE_DUMP_TYPE_FULL
)
537 for (i
= 0; i
< MmStats
.NrTotalPages
; i
++)
539 LARGE_INTEGER PhysicalAddress
;
540 PhysicalAddress
.QuadPart
= i
* PAGE_SIZE
;
541 MdlMap
[0] = i
* PAGE_SIZE
;
542 MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame
,
546 MmCoreDumpDeviceFuncs
.DeviceWrite(Context
,
547 MmCoreDumpBlockMap
[NextOffset
],
549 if (!NT_SUCCESS(Status
))
551 DPRINT1("MM: Failed to write page to core dump.\n");
560 return(STATUS_SUCCESS
);
564 NtCreatePagingFile(IN PUNICODE_STRING FileName
,
565 IN PLARGE_INTEGER InitialSize
,
566 IN PLARGE_INTEGER MaximumSize
,
570 OBJECT_ATTRIBUTES ObjectAttributes
;
572 IO_STATUS_BLOCK IoStatus
;
573 PFILE_OBJECT FileObject
;
574 PPAGINGFILE PagingFile
;
578 FILE_FS_SIZE_INFORMATION FsSizeInformation
;
579 PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers
;
581 ULONG BytesPerAllocationUnit
;
585 DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n",
586 FileName
, InitialSize
->QuadPart
);
588 if (MiPagingFileCount
>= MAX_PAGING_FILES
)
590 return(STATUS_TOO_MANY_PAGING_FILES
);
593 InitializeObjectAttributes(&ObjectAttributes
,
599 Status
= IoCreateFile(&FileHandle
,
607 FILE_SYNCHRONOUS_IO_NONALERT
,
612 SL_OPEN_PAGING_FILE
);
613 if (!NT_SUCCESS(Status
))
618 Status
= NtQueryVolumeInformationFile(FileHandle
,
621 sizeof(FILE_FS_SIZE_INFORMATION
),
622 FileFsSizeInformation
);
623 if (!NT_SUCCESS(Status
))
629 BytesPerAllocationUnit
= FsSizeInformation
.SectorsPerAllocationUnit
* FsSizeInformation
.BytesPerSector
;
630 if (BytesPerAllocationUnit
< PAGE_SIZE
)
633 return STATUS_UNSUCCESSFUL
;
636 Status
= NtSetInformationFile(FileHandle
,
639 sizeof(LARGE_INTEGER
),
640 FileAllocationInformation
);
641 if (!NT_SUCCESS(Status
))
647 Status
= ObReferenceObjectByHandle(FileHandle
,
653 if (!NT_SUCCESS(Status
))
659 RetrievalPointers
= ExAllocatePool(NonPagedPool
, sizeof(GET_RETRIEVAL_DESCRIPTOR
) + sizeof(MAPPING_PAIR
));
661 if (RetrievalPointers
== NULL
)
663 ObDereferenceObject(FileObject
);
665 return(STATUS_NO_MEMORY
);
672 Status
= NtFsControlFile(FileHandle
,
677 FSCTL_GET_RETRIEVAL_POINTERS
,
679 sizeof(LARGE_INTEGER
),
681 sizeof(GET_RETRIEVAL_DESCRIPTOR
) + sizeof(MAPPING_PAIR
));
682 if (!NT_SUCCESS(Status
))
684 ExFreePool(RetrievalPointers
);
685 ObDereferenceObject(FileObject
);
689 ExtentCount
+= RetrievalPointers
->NumberOfPairs
;
690 if (RetrievalPointers
->Pair
[0].Vcn
< (ULONGLONG
) InitialSize
->QuadPart
/ BytesPerAllocationUnit
)
692 Vcn
.QuadPart
= RetrievalPointers
->Pair
[0].Vcn
;
699 ExFreePool(RetrievalPointers
);
701 PagingFile
= ExAllocatePool(NonPagedPool
, sizeof(*PagingFile
));
702 if (PagingFile
== NULL
)
704 ObDereferenceObject(FileObject
);
706 return(STATUS_NO_MEMORY
);
709 PagingFile
->FileObject
= FileObject
;
710 PagingFile
->MaximumSize
.QuadPart
= MaximumSize
->QuadPart
;
711 PagingFile
->CurrentSize
.QuadPart
= InitialSize
->QuadPart
;
712 PagingFile
->FreePages
= InitialSize
->QuadPart
/ PAGE_SIZE
;
713 PagingFile
->UsedPages
= 0;
714 KeInitializeSpinLock(&PagingFile
->AllocMapLock
);
716 AllocMapSize
= (PagingFile
->FreePages
/ 32) + 1;
717 PagingFile
->AllocMap
= ExAllocatePool(NonPagedPool
,
718 AllocMapSize
* sizeof(ULONG
));
719 PagingFile
->AllocMapSize
= AllocMapSize
;
721 if (PagingFile
->AllocMap
== NULL
)
723 ExFreePool(PagingFile
);
724 ObDereferenceObject(FileObject
);
726 return(STATUS_NO_MEMORY
);
729 Size
= sizeof(GET_RETRIEVAL_DESCRIPTOR
) + ExtentCount
* sizeof(MAPPING_PAIR
);
730 PagingFile
->RetrievalPointers
= ExAllocatePool(NonPagedPool
, Size
);
731 if (PagingFile
->RetrievalPointers
== NULL
)
733 ExFreePool(PagingFile
->AllocMap
);
734 ExFreePool(PagingFile
);
735 ObDereferenceObject(FileObject
);
737 return(STATUS_NO_MEMORY
);
741 Status
= NtFsControlFile(FileHandle
,
746 FSCTL_GET_RETRIEVAL_POINTERS
,
748 sizeof(LARGE_INTEGER
),
749 PagingFile
->RetrievalPointers
,
751 if (!NT_SUCCESS(Status
))
753 ExFreePool(PagingFile
->RetrievalPointers
);
754 ExFreePool(PagingFile
->AllocMap
);
755 ExFreePool(PagingFile
);
756 ObDereferenceObject(FileObject
);
758 return(STATUS_NO_MEMORY
);
761 if (PagingFile
->RetrievalPointers
->NumberOfPairs
!= ExtentCount
||
762 PagingFile
->RetrievalPointers
->Pair
[ExtentCount
- 1].Vcn
!=
763 (ULONGLONG
) InitialSize
->QuadPart
/ BytesPerAllocationUnit
)
765 ExFreePool(PagingFile
->RetrievalPointers
);
766 ExFreePool(PagingFile
->AllocMap
);
767 ExFreePool(PagingFile
);
768 ObDereferenceObject(FileObject
);
770 return(STATUS_UNSUCCESSFUL
);
774 * Change the entries from lcn's to volume offset's.
776 PagingFile
->RetrievalPointers
->StartVcn
*= BytesPerAllocationUnit
;
777 for (i
= 0; i
< ExtentCount
; i
++)
779 PagingFile
->RetrievalPointers
->Pair
[i
].Lcn
*= BytesPerAllocationUnit
;
780 PagingFile
->RetrievalPointers
->Pair
[i
].Vcn
*= BytesPerAllocationUnit
;
783 KeAcquireSpinLock(&PagingFileListLock
, &oldIrql
);
784 for (i
= 0; i
< MAX_PAGING_FILES
; i
++)
786 if (PagingFileList
[i
] == NULL
)
788 PagingFileList
[i
] = PagingFile
;
792 MiFreeSwapPages
= MiFreeSwapPages
+ PagingFile
->FreePages
;
794 KeReleaseSpinLock(&PagingFileListLock
, oldIrql
);
796 /* Check whether this pagefile can be a crash dump target. */
797 if (PagingFile
->CurrentSize
.QuadPart
>= MmCoreDumpSize
&&
798 MmCoreDumpBlockMap
!= NULL
)
801 ExAllocatePool(NonPagedPool
,
802 (MmCoreDumpSize
/ PAGE_SIZE
) * sizeof(ULONG
));
803 if (MmCoreDumpBlockMap
== NULL
)
805 DPRINT1("Failed to allocate block map.\n");
807 return(STATUS_SUCCESS
);
809 Status
= ZwFsControlFile(FileHandle
,
814 FSCTL_GET_DUMP_BLOCK_MAP
,
818 (MmCoreDumpSize
/ PAGE_SIZE
) * sizeof(ULONG
));
819 if (!NT_SUCCESS(Status
))
821 DPRINT1("Failed to get dump block map (Status %X)\n", Status
);
823 ExFreePool(MmCoreDumpBlockMap
);
824 MmCoreDumpBlockMap
= NULL
;
825 return(STATUS_SUCCESS
);
827 Status
= ZwDeviceIoControlFile(FileHandle
,
832 IOCTL_GET_DUMP_POINTERS
,
835 &MmCoreDumpDeviceFuncs
,
836 sizeof(MmCoreDumpDeviceFuncs
));
837 if (!NT_SUCCESS(Status
))
839 DPRINT1("Failed to get dump block map (Status %X)\n", Status
);
841 ExFreePool(MmCoreDumpBlockMap
);
842 MmCoreDumpBlockMap
= NULL
;
843 return(STATUS_SUCCESS
);
848 MmSwapSpaceMessage
= FALSE
;
850 return(STATUS_SUCCESS
);