NTSTATUS EmptyWorkingSet()

in Silhouette/Utils.cpp [96:160]


NTSTATUS EmptyWorkingSet(BOOLEAN bAllowAsync)
{
    QUOTA_LIMITS_EX quotaLimits = { 0, };
    VM_COUNTERS_EX2 before = { 0, };
    VM_COUNTERS_EX2 after = { 0, };
    NTSTATUS ntStatus = STATUS_SUCCESS;;
    ULONG returnLength = 0;
    BOOLEAN bHaveInitialSnapshot = FALSE;
    BOOLEAN bShouldPurge = TRUE;

    if (KeGetCurrentIrql() > PASSIVE_LEVEL)
    {
        if (bAllowAsync)
        {
            return EmptyWorkingSetAsync();
        }
        else
        {
            return STATUS_INVALID_STATE_TRANSITION;
        }
    }

    ntStatus = ZwQueryInformationProcess(ghLsass, ProcessVmCounters, &before, sizeof(before), &returnLength);
    if (NT_SUCCESS(ntStatus))
    {
        if (before.PrivateWorkingSetSize <= PAGE_SIZE)
        {
            // DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Silhouette: Empty aborted: %zu\n", before.PrivateWorkingSetSize);
            goto Cleanup;
        }

        bHaveInitialSnapshot = TRUE;
    }

    // DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Silhouette: Emptying working set\n");

    quotaLimits.MinimumWorkingSetSize = (SIZE_T)-1;
    quotaLimits.MaximumWorkingSetSize = (SIZE_T)-1;

    ntStatus = ZwSetInformationProcess( ghLsass, ProcessQuotaLimits, &quotaLimits, sizeof(quotaLimits) );
    if (!NT_SUCCESS(ntStatus))
    {
        goto Cleanup;
    }

    if (bHaveInitialSnapshot)
    {
        // If EmptyWorkingSet() didn't remove any pages, skip the MM list purge
        ntStatus = ZwQueryInformationProcess(ghLsass, ProcessVmCounters, &after, sizeof(after), &returnLength);
        if (NT_SUCCESS(ntStatus) && (after.PrivateWorkingSetSize == before.PrivateWorkingSetSize))
        {
            // DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Silhouette: Purge ineffective\n");
            bShouldPurge = FALSE;
        }
    }

    if (bShouldPurge)
    {
        // DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Silhouette: Purging.  Delta: %lld\n", before.PrivateWorkingSetSize - after.PrivateWorkingSetSize);
        ntStatus = PurgeModifiedAndStandbyLists();
    }

Cleanup:
    return ntStatus;
}