implement user mode catchable exceptions, refactor system status codes to use NTLSTATUS_ prefix, update build scripts to use shared literal macros for linker arguments, update named queue lifetime cleanup to include KeNamedQueueUnpublishHandle.
This commit is contained in:
1 parent
1f5477cf66
commit
b7fcfce6f7
140 files changed
+7649
-3943
No files matched your search
+31
-31
@@ -522,49 +522,49 @@ __declspec(dllexport) PHYSICAL_ADDRESS MmPfnAllocateContiguous(size_t count, MM_
|
||||
__declspec(dllexport) KSTATUS MmPfnRetain(PHYSICAL_ADDRESS frame) {
|
||||
size_t pfn = MmPfnIndex(frame);
|
||||
if (pfn == MM_PFN_INVALID_INDEX)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gPfnLock);
|
||||
MM_PFN* entry = &gPfnDatabase[pfn];
|
||||
if (entry->State == MmPfnStateInvalid || entry->State == MmPfnStateFree || entry->State == MmPfnStateZeroed) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (entry->RefCount == UINT16_MAX) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_FAILURE;
|
||||
return NTLSTATUS_FAILURE;
|
||||
}
|
||||
entry->RefCount++;
|
||||
gPfnRetains++;
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Releases a reference and returns the frame to the free list when the last owner leaves.
|
||||
__declspec(dllexport) KSTATUS MmPfnRelease(PHYSICAL_ADDRESS frame) {
|
||||
size_t pfn = MmPfnIndex(frame);
|
||||
if (pfn == MM_PFN_INVALID_INDEX)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gPfnLock);
|
||||
MM_PFN* entry = &gPfnDatabase[pfn];
|
||||
if (entry->State == MmPfnStateInvalid || entry->State == MmPfnStateFree || entry->State == MmPfnStateZeroed) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (entry->PinCount) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_ACCESS_DENIED;
|
||||
return NTLSTATUS_ACCESS_DENIED;
|
||||
}
|
||||
gPfnReleases++;
|
||||
if (entry->RefCount > 1) {
|
||||
entry->RefCount--;
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
if (entry->MappedCount) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_ACCESS_DENIED;
|
||||
return NTLSTATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
entry->State = MmPfnStateFree;
|
||||
@@ -578,7 +578,7 @@ __declspec(dllexport) KSTATUS MmPfnRelease(PHYSICAL_ADDRESS frame) {
|
||||
gFreeFrames++;
|
||||
gPfnFrees++;
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Frees a frame that is expected to have a single owner.
|
||||
@@ -590,119 +590,119 @@ __declspec(dllexport) KSTATUS MmPfnFree(PHYSICAL_ADDRESS frame) {
|
||||
__declspec(dllexport) KSTATUS MmPfnPin(PHYSICAL_ADDRESS frame) {
|
||||
size_t pfn = MmPfnIndex(frame);
|
||||
if (pfn == MM_PFN_INVALID_INDEX)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gPfnLock);
|
||||
MM_PFN* entry = &gPfnDatabase[pfn];
|
||||
if (entry->State == MmPfnStateInvalid || entry->State == MmPfnStateFree || entry->State == MmPfnStateZeroed) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (entry->PinCount == UINT16_MAX) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_FAILURE;
|
||||
return NTLSTATUS_FAILURE;
|
||||
}
|
||||
entry->PinCount++;
|
||||
gPfnPins++;
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Removes one pin from a frame.
|
||||
__declspec(dllexport) KSTATUS MmPfnUnpin(PHYSICAL_ADDRESS frame) {
|
||||
size_t pfn = MmPfnIndex(frame);
|
||||
if (pfn == MM_PFN_INVALID_INDEX)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gPfnLock);
|
||||
MM_PFN* entry = &gPfnDatabase[pfn];
|
||||
if (!entry->PinCount) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
}
|
||||
entry->PinCount--;
|
||||
gPfnUnpins++;
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Records that a VAD now maps this frame into a user address space.
|
||||
__declspec(dllexport) KSTATUS MmPfnAddMapping(PHYSICAL_ADDRESS frame) {
|
||||
size_t pfn = MmPfnIndex(frame);
|
||||
if (pfn == MM_PFN_INVALID_INDEX)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gPfnLock);
|
||||
MM_PFN* entry = &gPfnDatabase[pfn];
|
||||
if (entry->State == MmPfnStateInvalid || entry->State == MmPfnStateFree || entry->State == MmPfnStateZeroed) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (entry->MappedCount == UINT32_MAX) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_FAILURE;
|
||||
return NTLSTATUS_FAILURE;
|
||||
}
|
||||
entry->MappedCount++;
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Removes one user VAD mapping reference from a frame.
|
||||
__declspec(dllexport) KSTATUS MmPfnRemoveMapping(PHYSICAL_ADDRESS frame) {
|
||||
size_t pfn = MmPfnIndex(frame);
|
||||
if (pfn == MM_PFN_INVALID_INDEX)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gPfnLock);
|
||||
MM_PFN* entry = &gPfnDatabase[pfn];
|
||||
if (entry->State == MmPfnStateInvalid || entry->State == MmPfnStateFree || entry->State == MmPfnStateZeroed ||
|
||||
entry->MappedCount == 0) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
}
|
||||
entry->MappedCount--;
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Moves a clean, unshared frame to standby so pressure can reclaim it later.
|
||||
__declspec(dllexport) KSTATUS MmPfnMoveToStandby(PHYSICAL_ADDRESS frame) {
|
||||
size_t pfn = MmPfnIndex(frame);
|
||||
if (pfn == MM_PFN_INVALID_INDEX)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gPfnLock);
|
||||
MM_PFN* entry = &gPfnDatabase[pfn];
|
||||
if (entry->State != MmPfnStateActive || entry->PinCount || entry->MappedCount || entry->RefCount != 1) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_ACCESS_DENIED;
|
||||
return NTLSTATUS_ACCESS_DENIED;
|
||||
}
|
||||
if (entry->Usage != MmPfnUseCleanFileCache && entry->Usage != MmPfnUseImage) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
entry->State = MmPfnStateStandby;
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Reactivates a standby frame after a cache or image lookup found it still useful.
|
||||
__declspec(dllexport) KSTATUS MmPfnActivate(PHYSICAL_ADDRESS frame) {
|
||||
size_t pfn = MmPfnIndex(frame);
|
||||
if (pfn == MM_PFN_INVALID_INDEX)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gPfnLock);
|
||||
MM_PFN* entry = &gPfnDatabase[pfn];
|
||||
if (entry->State != MmPfnStateStandby || !entry->RefCount) {
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
entry->State = MmPfnStateActive;
|
||||
KeReleaseSpinlock(&gPfnLock, flags);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns the number of frames that are immediately available for allocation.
|
||||
|
||||
Reference in new issue
Block a user