Skip to content

Commit e168b45

Browse files
committed
* Code refactoring
* Fixed possibly throwing wrong win32 error
1 parent b4d1183 commit e168b45

File tree

3 files changed

+62
-49
lines changed

3 files changed

+62
-49
lines changed

MemPlus/Business/RAM/RamOptimizer.cs

Lines changed: 13 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Runtime.InteropServices;
66
using System.Security.Principal;
77
using MemPlus.Business.LOG;
8+
using MemPlus.Business.UTILS;
89

910
namespace MemPlus.Business.RAM
1011
{
@@ -90,44 +91,6 @@ internal sealed class RamOptimizer
9091
private readonly LogController _logController;
9192
#endregion
9293

93-
#region NativeMethods
94-
/// <summary>
95-
/// Retrieves the locally unique identifier (LUID) used on a specified system to locally represent the specified privilege name.
96-
/// </summary>
97-
/// /// <param name="lpSystemName">A pointer to a null-terminated string that specifies the name of the system on which the privilege name is retrieved. If a null string is specified, the function attempts to find the privilege name on the local system</param>
98-
/// <param name="lpName">A pointer to a null-terminated string that specifies the name of the privilege, as defined in the Winnt.h header file. For example, this parameter could specify the constant, SE_SECURITY_NAME, or its corresponding string, "SeSecurityPrivilege"</param>
99-
/// <param name="pluid">A pointer to a variable that receives the LUID by which the privilege is known on the system specified by the lpSystemName parameter.</param>
100-
/// <returns>If the function succeeds, the function returns nonzero. Otherwise, return value will be zero</returns>
101-
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
102-
private static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, ref long pluid);
103-
/// <summary>
104-
/// Enables or disables privileges in the specified access token. Enabling or disabling privileges in an access token requires TOKEN_ADJUST_PRIVILEGES access
105-
/// </summary>
106-
/// <param name="tokenHandle">A handle to the access token that contains the privileges to be modified. The handle must have TOKEN_ADJUST_PRIVILEGES access to the token. If the PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access</param>
107-
/// <param name="disableAllPrivileges">Specifies whether the function disables all of the token's privileges. If this value is TRUE, the function disables all privileges and ignores the NewState parameter. If it is FALSE, the function modifies privileges based on the information pointed to by the NewState parameter</param>
108-
/// <param name="newState">A pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes. If the DisableAllPrivileges parameter is FALSE, the AdjustTokenPrivileges function enables, disables, or removes these privileges for the token</param>
109-
/// <param name="bufferLength">Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be zero if the PreviousState parameter is NULL</param>
110-
/// <param name="previousState">A pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure that contains the previous state of any privileges that the function modifies. That is, if a privilege has been modified by this function, the privilege and its previous state are contained in the TOKEN_PRIVILEGES structure referenced by PreviousState. If the PrivilegeCount member of TOKEN_PRIVILEGES is zero, then no privileges have been changed by this function. This parameter can be NULL</param>
111-
/// <param name="returnLength">A pointer to a variable that receives the required size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be NULL if PreviousState is NULL</param>
112-
/// <returns>If the function succeeds, the return value is nonzero</returns>
113-
[DllImport("advapi32.dll", SetLastError = true)]
114-
private static extern bool AdjustTokenPrivileges(IntPtr tokenHandle, bool disableAllPrivileges, ref TokenPrivileges newState, int bufferLength, IntPtr previousState, IntPtr returnLength);
115-
/// <summary>Change Windows System parameters</summary>
116-
/// <param name="infoClass"></param>
117-
/// <param name="info"></param>
118-
/// <param name="length">Allocated bytes for the Info block</param>
119-
/// <returns>Opposite of boolean. Zero means success, non-zero means fail and use GetLastError</returns>
120-
[DllImport("ntdll.dll")]
121-
private static extern uint NtSetSystemInformation(int infoClass, IntPtr info, int length);
122-
/// <summary>
123-
/// Removes as many pages as possible from the working set of the specified process
124-
/// </summary>
125-
/// <param name="hwProc">A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access right and the PROCESS_SET_QUOTA access right</param>
126-
/// <returns>If the function succeeds, the return value is nonzero</returns>
127-
[DllImport("psapi.dll")]
128-
private static extern int EmptyWorkingSet(IntPtr hwProc);
129-
#endregion
130-
13194
/// <summary>
13295
/// Initialize a new RamOptimizer object
13396
/// </summary>
@@ -158,7 +121,7 @@ internal void EmptyWorkingSetFunction(List<string> processExceptions)
158121
{
159122
_logController.AddLog(new RamLog("Emptying working set for process: " + process.ProcessName));
160123
// Empty the working set of the process
161-
EmptyWorkingSet(process.Handle);
124+
NativeMethods.EmptyWorkingSet(process.Handle);
162125
_logController.AddLog(new RamLog("Successfully emptied working set for process " + process.ProcessName));
163126
}
164127
else
@@ -221,7 +184,9 @@ internal void ClearFileSystemCache(bool clearStandbyCache)
221184
};
222185
systemInfoLength = Marshal.SizeOf(cacheInformation);
223186
gcHandle = GCHandle.Alloc(cacheInformation, GCHandleType.Pinned);
224-
ntSetSystemInformationRet = NtSetSystemInformation((int)SystemInformationClass.SystemFileCacheInformation, gcHandle.AddrOfPinnedObject(), systemInfoLength);
187+
ntSetSystemInformationRet = NativeMethods.NtSetSystemInformation((int)SystemInformationClass.SystemFileCacheInformation, gcHandle.AddrOfPinnedObject(), systemInfoLength);
188+
// If value is not equal to zero, things didn't go right :(
189+
if (ntSetSystemInformationRet != 0) throw new Exception("NtSetSystemInformation: ", new Win32Exception(Marshal.GetLastWin32Error()));
225190
gcHandle.Free();
226191

227192
_logController.AddLog(new RamLog("Done clearing 32 bit FileSystem cache information"));
@@ -238,13 +203,13 @@ internal void ClearFileSystemCache(bool clearStandbyCache)
238203
};
239204
systemInfoLength = Marshal.SizeOf(information64Bit);
240205
gcHandle = GCHandle.Alloc(information64Bit, GCHandleType.Pinned);
241-
ntSetSystemInformationRet = NtSetSystemInformation((int)SystemInformationClass.SystemFileCacheInformation, gcHandle.AddrOfPinnedObject(), systemInfoLength);
206+
ntSetSystemInformationRet = NativeMethods.NtSetSystemInformation((int)SystemInformationClass.SystemFileCacheInformation, gcHandle.AddrOfPinnedObject(), systemInfoLength);
207+
// If value is not equal to zero, things didn't go right :(
208+
if (ntSetSystemInformationRet != 0) throw new Exception("NtSetSystemInformation: ", new Win32Exception(Marshal.GetLastWin32Error()));
242209
gcHandle.Free();
243210

244211
_logController.AddLog(new RamLog("Done clearing 64 bit FileSystem cache information"));
245212
}
246-
// If value is not equal to zero, things didn't go right :(
247-
if (ntSetSystemInformationRet != 0) throw new Exception("NtSetSystemInformation: ", new Win32Exception(Marshal.GetLastWin32Error()));
248213
}
249214

250215
// Clear the standby cache if we have to and if we can also increase the privileges
@@ -255,12 +220,11 @@ internal void ClearFileSystemCache(bool clearStandbyCache)
255220

256221
int systemInfoLength = Marshal.SizeOf(MemoryPurgeStandbyList);
257222
GCHandle gcHandle = GCHandle.Alloc(MemoryPurgeStandbyList, GCHandleType.Pinned);
258-
uint ntSetSystemInformationRet = NtSetSystemInformation((int)SystemInformationClass.SystemMemoryListInformation, gcHandle.AddrOfPinnedObject(), systemInfoLength);
223+
uint ntSetSystemInformationRet = NativeMethods.NtSetSystemInformation((int)SystemInformationClass.SystemMemoryListInformation, gcHandle.AddrOfPinnedObject(), systemInfoLength);
224+
if (ntSetSystemInformationRet != 0) throw new Exception("NtSetSystemInformation: ", new Win32Exception(Marshal.GetLastWin32Error()));
259225
gcHandle.Free();
260226

261227
_logController.AddLog(new RamLog("Done clearing standby cache"));
262-
263-
if (ntSetSystemInformationRet != 0) throw new Exception("NtSetSystemInformation: ", new Win32Exception(Marshal.GetLastWin32Error()));
264228
}
265229
}
266230
catch (Exception ex)
@@ -287,16 +251,16 @@ private bool SetIncreasePrivilege(string privilegeName)
287251

288252
_logController.AddLog(new RamLog("Looking up privilage value"));
289253
// If we can't look up the privilege value, we can't function properly
290-
if (!LookupPrivilegeValue(null, privilegeName, ref newst.Luid)) throw new Exception("LookupPrivilegeValue: ", new Win32Exception(Marshal.GetLastWin32Error()));
254+
if (!NativeMethods.LookupPrivilegeValue(null, privilegeName, ref newst.Luid)) throw new Exception("LookupPrivilegeValue: ", new Win32Exception(Marshal.GetLastWin32Error()));
291255
_logController.AddLog(new RamLog("Done looking up privilage value"));
292256

293257

294258
_logController.AddLog(new RamLog("Adjusting token privilages"));
295259
// Enables or disables privileges in a specified access token
296-
int adjustTokenPrivilegesRet = AdjustTokenPrivileges(current.Token, false, ref newst, 0, IntPtr.Zero, IntPtr.Zero) ? 1 : 0;
297-
_logController.AddLog(new RamLog("Done adjusting token privilages"));
260+
int adjustTokenPrivilegesRet = NativeMethods.AdjustTokenPrivileges(current.Token, false, ref newst, 0, IntPtr.Zero, IntPtr.Zero) ? 1 : 0;
298261
// Return value of zero indicates an error
299262
if (adjustTokenPrivilegesRet == 0) throw new Exception("AdjustTokenPrivileges: ", new Win32Exception(Marshal.GetLastWin32Error()));
263+
_logController.AddLog(new RamLog("Done adjusting token privilages"));
300264
return adjustTokenPrivilegesRet != 0;
301265
}
302266
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using MemPlus.Business.RAM;
4+
5+
namespace MemPlus.Business.UTILS
6+
{
7+
/// <summary>
8+
/// Interaction logic for native methods
9+
/// </summary>
10+
internal static class NativeMethods
11+
{
12+
/// <summary>
13+
/// Retrieves the locally unique identifier (LUID) used on a specified system to locally represent the specified privilege name.
14+
/// </summary>
15+
/// /// <param name="lpSystemName">A pointer to a null-terminated string that specifies the name of the system on which the privilege name is retrieved. If a null string is specified, the function attempts to find the privilege name on the local system</param>
16+
/// <param name="lpName">A pointer to a null-terminated string that specifies the name of the privilege, as defined in the Winnt.h header file. For example, this parameter could specify the constant, SE_SECURITY_NAME, or its corresponding string, "SeSecurityPrivilege"</param>
17+
/// <param name="pluid">A pointer to a variable that receives the LUID by which the privilege is known on the system specified by the lpSystemName parameter.</param>
18+
/// <returns>If the function succeeds, the function returns nonzero. Otherwise, return value will be zero</returns>
19+
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
20+
internal static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, ref long pluid);
21+
/// <summary>
22+
/// Enables or disables privileges in the specified access token. Enabling or disabling privileges in an access token requires TOKEN_ADJUST_PRIVILEGES access
23+
/// </summary>
24+
/// <param name="tokenHandle">A handle to the access token that contains the privileges to be modified. The handle must have TOKEN_ADJUST_PRIVILEGES access to the token. If the PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access</param>
25+
/// <param name="disableAllPrivileges">Specifies whether the function disables all of the token's privileges. If this value is TRUE, the function disables all privileges and ignores the NewState parameter. If it is FALSE, the function modifies privileges based on the information pointed to by the NewState parameter</param>
26+
/// <param name="newState">A pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes. If the DisableAllPrivileges parameter is FALSE, the AdjustTokenPrivileges function enables, disables, or removes these privileges for the token</param>
27+
/// <param name="bufferLength">Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be zero if the PreviousState parameter is NULL</param>
28+
/// <param name="previousState">A pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure that contains the previous state of any privileges that the function modifies. That is, if a privilege has been modified by this function, the privilege and its previous state are contained in the TOKEN_PRIVILEGES structure referenced by PreviousState. If the PrivilegeCount member of TOKEN_PRIVILEGES is zero, then no privileges have been changed by this function. This parameter can be NULL</param>
29+
/// <param name="returnLength">A pointer to a variable that receives the required size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be NULL if PreviousState is NULL</param>
30+
/// <returns>If the function succeeds, the return value is nonzero</returns>
31+
[DllImport("advapi32.dll", SetLastError = true)]
32+
internal static extern bool AdjustTokenPrivileges(IntPtr tokenHandle, bool disableAllPrivileges, ref TokenPrivileges newState, int bufferLength, IntPtr previousState, IntPtr returnLength);
33+
/// <summary>Change Windows System parameters</summary>
34+
/// <param name="infoClass"></param>
35+
/// <param name="info"></param>
36+
/// <param name="length">Allocated bytes for the Info block</param>
37+
/// <returns>Opposite of boolean. Zero means success, non-zero means fail and use GetLastError</returns>
38+
[DllImport("ntdll.dll")]
39+
internal static extern uint NtSetSystemInformation(int infoClass, IntPtr info, int length);
40+
/// <summary>
41+
/// Removes as many pages as possible from the working set of the specified process
42+
/// </summary>
43+
/// <param name="hwProc">A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access right and the PROCESS_SET_QUOTA access right</param>
44+
/// <returns>If the function succeeds, the return value is nonzero</returns>
45+
[DllImport("psapi.dll")]
46+
internal static extern int EmptyWorkingSet(IntPtr hwProc);
47+
}
48+
}

MemPlus/MemPlus.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
<Compile Include="Business\RAM\RamData.cs" />
9191
<Compile Include="Business\RAM\RamSticksExporter.cs" />
9292
<Compile Include="Business\RAM\RamStick.cs" />
93+
<Compile Include="Business\UTILS\NativeMethods.cs" />
9394
<Compile Include="Business\UTILS\Utils.cs" />
9495
<Compile Include="Views\Windows\AnalyzerWindow.xaml.cs">
9596
<DependentUpon>AnalyzerWindow.xaml</DependentUpon>

0 commit comments

Comments
 (0)