Click here to Skip to main content
11,925,006 members (53,567 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


3 bookmarked

Empty Standby List in Windows

, 1 Jan 2015 CPOL
Rate this:
Please Sign up or sign in to vote.
How to create an empty standby list in Windows


The makers of process hacker know the Windows kernel inside and out!  Fortunately for them, they are also fluent in C++: the language that the Windows kernel was designed on. For the rest of us, we struggle to make C# perform similar functions. One of those functions is the ability to release memory from the windows standby memory. That is what we will do here.


Obviously, the procedures used here are fundamentally taken from Process Hacker's source code - Thanks!

Next, the hardest part is getting the Kernel privileges. While I've significantly tweaked the code, my thanks must also go to Nick Lowe - Thanks!

Note: I have trimmed almost all code that is not related to the task itself. If you want to know more about either project, please visit their websites.

Step One: Setting Kernel Privileges

Microsoft has designed the API to take a structure that contains an array of structures. There are no good Marshaling procedures for this - they either assume the array is length=1 or require that the size of the array be predetermined at compilation. For this purpose, I designed a class that holds the exact structure that Microsoft requires in unmanaged memory via an System.IntPtr. I had to resort to one unsafe procedure at this point ... but I'm sure that can be bypassed with more work in the future.

[return: MarshalAs(UnmanagedType.Bool)]
[SuppressUnmanagedCodeSecurity, DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(AccessTokenHandle accessTokenHandle,
[MarshalAs(UnmanagedType.Bool)] bool disableAllPrivileges, IntPtr NewPriviledges,
	Int32 bufferLength, ref IntPtr PriorPriviledges, out Int32 returnLength);	

Combining my class with Nick Lowe's privilege code, we can setup our kernel privileges with:

	myProcessToken = new AccessTokenHandle(System.Diagnostics.Process.GetCurrentProcess(),
	ProcessPrivileges.TokenAccessRights.AdjustPrivileges | TokenAccessRights.Query);
myProcessToken.EnablePrivilege(Privilege.Debug, Privilege.ProfileSingleProcess);	

Step Two: Sending the Command to the Kernel

This time, Microsoft simply wants an int array. These Marshal easily, so all we need is:

public static extern NtStatus NtSetSystemInformation
(SYSTEM_INFORMATION_CLASS InfoClass, int[] Info, uint Length);

	result = 0;
	arr = new int[] { (int)Commands.MemoryPurgeStandbyList };
result = NativeMethods.NtSetSystemInformation
arr, (uint)(sizeof(int) * arr.Length));
if (result > 0)
	throw new System.ComponentModel.Win32Exception();	


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Member 10018957
Systems Engineer RedDotNet
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.151125.3 | Last Updated 1 Jan 2015
Article Copyright 2015 by Member 10018957
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid