MmNumberOfPagingFiles = 0;
}
-static ULONG
-MiAllocPageFromPagingFile(PMMPAGING_FILE PagingFile)
-{
- KIRQL oldIrql;
- ULONG off;
-
- KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql);
- off = RtlFindClearBitsAndSet(PagingFile->AllocMap, 1, 0);
- KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
-
- return off;
-}
-
VOID
NTAPI
MmFreeSwapPage(SWAPENTRY Entry)
{
KeBugCheck(MEMORY_MANAGEMENT);
}
- KeAcquireSpinLockAtDpcLevel(&PagingFile->AllocMapLock);
RtlClearBit(PagingFile->AllocMap, off >> 5);
MiFreeSwapPages++;
MiUsedSwapPages--;
- KeReleaseSpinLockFromDpcLevel(&PagingFile->AllocMapLock);
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
}
if (MmPagingFile[i] != NULL &&
MmPagingFile[i]->FreePages >= 1)
{
- off = MiAllocPageFromPagingFile(MmPagingFile[i]);
+ off = RtlFindClearBitsAndSet(MmPagingFile[i]->AllocMap, 1, 0);
if (off == 0xFFFFFFFF)
{
KeBugCheck(MEMORY_MANAGEMENT);
/* If we failed, relax a bit constraints, someone may be already holding the
* the file, so share write, don't attempt to replace and don't delete on close
* (basically, don't do anything conflicting)
+ * This can happen if the caller attempts to extend a page file.
*/
if (!NT_SUCCESS(Status))
{
+ ULONG i;
+
Status = IoCreateFile(&FileHandle,
SYNCHRONIZE | FILE_WRITE_DATA,
&ObjectAttributes,
CreateFileTypeNone,
NULL,
SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Dacl, 'lcaD');
+ ExFreePoolWithTag(Buffer, TAG_MM);
+ return Status;
+ }
+
+ /* We opened it! Check we are that "someone" ;-)
+ * First, get the opened file object.
+ */
+ Status = ObReferenceObjectByHandle(FileHandle,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ IoFileObjectType,
+ KernelMode,
+ (PVOID*)&FileObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ZwClose(FileHandle);
+ ExFreePoolWithTag(Dacl, 'lcaD');
+ ExFreePoolWithTag(Buffer, TAG_MM);
+ return Status;
+ }
+
+ /* Find if it matches a previous page file */
+ PagingFile = NULL;
+ if (MmNumberOfPagingFiles > 0)
+ {
+ i = 0;
+
+ while (MmPagingFile[i]->FileObject->SectionObjectPointer != FileObject->SectionObjectPointer)
+ {
+ ++i;
+ if (i >= MmNumberOfPagingFiles)
+ {
+ break;
+ }
+ }
+
+ /* This is the matching page file */
+ PagingFile = MmPagingFile[i];
+ }
+
+ /* If we didn't find the page file, fail */
+ if (PagingFile == NULL)
+ {
+ ObDereferenceObject(FileObject);
+ ZwClose(FileHandle);
+ ExFreePoolWithTag(Dacl, 'lcaD');
+ ExFreePoolWithTag(Buffer, TAG_MM);
+ return STATUS_NOT_FOUND;
+ }
+
+ /* FIXME: implement parameters checking and page file extension */
+ UNIMPLEMENTED;
+
+ ObDereferenceObject(FileObject);
+ ZwClose(FileHandle);
+ ExFreePoolWithTag(Dacl, 'lcaD');
+ ExFreePoolWithTag(Buffer, TAG_MM);
+ return STATUS_NOT_IMPLEMENTED;
}
if (!NT_SUCCESS(Status))
PagingFile->CurrentSize.QuadPart = SafeInitialSize.QuadPart;
PagingFile->FreePages = (ULONG)(SafeInitialSize.QuadPart / PAGE_SIZE);
PagingFile->UsedPages = 0;
- KeInitializeSpinLock(&PagingFile->AllocMapLock);
PagingFile->PageFileName = PageFileName;
AllocMapSize = sizeof(RTL_BITMAP) + (((PagingFile->FreePages + 31) / 32) * sizeof(ULONG));