diff --git a/trunk/ProcessHacker/Components/ProcessList.cs b/trunk/ProcessHacker/Components/ProcessList.cs index 1725f0d97..68bc8f048 100644 --- a/trunk/ProcessHacker/Components/ProcessList.cs +++ b/trunk/ProcessHacker/Components/ProcessList.cs @@ -254,16 +254,19 @@ namespace ProcessHacker public void RefreshColors() { - foreach (ListViewItem litem in listProcesses.Items) + lock (listProcesses) { - try + foreach (ListViewItem litem in listProcesses.Items) { - ProcessItem item = _provider.Dictionary[int.Parse(litem.Name)]; + try + { + ProcessItem item = _provider.Dictionary[int.Parse(litem.Name)]; - (litem as HighlightedListViewItem).NormalColor = this.GetProcessColor(item); + (litem as HighlightedListViewItem).NormalColor = this.GetProcessColor(item); + } + catch + { } } - catch - { } } } diff --git a/trunk/ProcessHacker/Forms/HackerWindow.cs b/trunk/ProcessHacker/Forms/HackerWindow.cs index 3df2186fa..bbfabca08 100644 --- a/trunk/ProcessHacker/Forms/HackerWindow.cs +++ b/trunk/ProcessHacker/Forms/HackerWindow.cs @@ -348,7 +348,7 @@ namespace ProcessHacker try { if (Win32.GetProcessUsername(p.Handle.ToInt32(), true) == "NT AUTHORITY\\SYSTEM" && - Win32.GetProcessSessionId(p.Handle.ToInt32()) == myId) + Win32.GetProcessSessionId(p.Id) == myId) { listProcesses.List.Items[p.Id.ToString()].Selected = true; listProcesses.List.Items[p.Id.ToString()].EnsureVisible(); @@ -802,7 +802,7 @@ namespace ProcessHacker int phandle = Win32.OpenProcess(Win32.PROCESS_RIGHTS.PROCESS_QUERY_INFORMATION, 0, processSelectedPID); if (Win32.GetProcessSessionId(phandle) == - Win32.GetProcessSessionId(Process.GetCurrentProcess().Handle.ToInt32())) + Win32.GetProcessSessionId(Process.GetCurrentProcess().Id)) injectorMenuItem.Enabled = true; else injectorMenuItem.Enabled = false; @@ -2350,7 +2350,7 @@ namespace ProcessHacker { delegate (Process p) { - int id = Win32.GetProcessSessionId(p.Handle.ToInt32()); + int id = Win32.GetProcessSessionId(p.Id); return id == -1 ? "Unknown" : id.ToString(); }, diff --git a/trunk/ProcessHacker/Win32.cs b/trunk/ProcessHacker/Win32.cs index 48de92926..f7b3fffba 100644 --- a/trunk/ProcessHacker/Win32.cs +++ b/trunk/ProcessHacker/Win32.cs @@ -70,6 +70,39 @@ namespace ProcessHacker } } + public class ProcessHandle : IDisposable + { + private int _handle; + + public ProcessHandle(int PID, PROCESS_RIGHTS access) + { + _handle = OpenProcess(access, 0, PID); + + if (_handle == 0) + throw new Exception(GetLastErrorMessage()); + } + + public void Terminate() + { + this.Terminate(0); + } + + public void Terminate(int ExitCode) + { + if (TerminateProcess(_handle, ExitCode) == 0) + throw new Exception(GetLastErrorMessage()); + } + + #region IDisposable Members + + public void Dispose() + { + CloseHandle(_handle); + } + + #endregion + } + public class ServiceHandle : IDisposable { private int _handle; @@ -652,60 +685,94 @@ namespace ProcessHacker TokenImpersonation } + public enum WTS_CONNECTSTATE_CLASS : int + { + WTSActive, + WTSConnected, + WTSConnectQuery, + WTSShadow, + WTSDisconnected, + WTSIdle, + WTSListen, + WTSReset, + WTSDown, + WTSInit + } + #endregion #region Imported Functions + #region Terminal Server + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern int ProcessIdToSessionId(int ProcessId, ref int SessionId); + + [DllImport("wtsapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern int WTSEnumerateSessions(int ServerHandle, int Reserved, + int Version, ref WTS_SESSION_INFO[] SessionInfo, ref int Count); + + [DllImport("wtsapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern int WTSEnumerateProcesses(int ServerHandle, int Reserved, + int Version, ref WTS_PROCESS_INFO[] ProcessInfo, ref int Count); + + [DllImport("wtsapi32.dll", SetLastError = true)] + public static extern int WTSFreeMemory(WTS_PROCESS_INFO[] Memory); + [DllImport("wtsapi32.dll", SetLastError = true)] + public static extern int WTSFreeMemory(WTS_SESSION_INFO[] Memory); + + #endregion + [DllImport("advapi32.dll", SetLastError = true)] public static extern int StartService(int Service, int NumServiceArgs, int Args); - [DllImport("advapi32.dll", SetLastError = true)] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern int ChangeServiceConfig(int Service, SERVICE_TYPE ServiceType, SERVICE_START_TYPE StartType, SERVICE_ERROR_CONTROL ErrorControl, - [MarshalAs(UnmanagedType.LPStr)] string BinaryPath, - [MarshalAs(UnmanagedType.LPStr)] string LoadOrderGroup, + [MarshalAs(UnmanagedType.LPTStr)] string BinaryPath, + [MarshalAs(UnmanagedType.LPTStr)] string LoadOrderGroup, int TagID, int Dependencies, - [MarshalAs(UnmanagedType.LPStr)] string StartName, + [MarshalAs(UnmanagedType.LPTStr)] string StartName, int Password, int DisplayName); [DllImport("advapi32.dll", SetLastError = true)] public static extern int ControlService(int Service, SERVICE_CONTROL Control, ref SERVICE_STATUS ServiceStatus); - [DllImport("advapi32.dll", SetLastError = true)] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern int CreateService(int SCManager, - [MarshalAs(UnmanagedType.LPStr)] string ServiceName, - [MarshalAs(UnmanagedType.LPStr)] string DisplayName, + [MarshalAs(UnmanagedType.LPTStr)] string ServiceName, + [MarshalAs(UnmanagedType.LPTStr)] string DisplayName, SERVICE_RIGHTS DesiredAccess, SERVICE_TYPE ServiceType, SERVICE_START_TYPE StartType, SERVICE_ERROR_CONTROL ErrorControl, - [MarshalAs(UnmanagedType.LPStr)] string BinaryPathName, - [MarshalAs(UnmanagedType.LPStr)] string LoadOrderGroup, + [MarshalAs(UnmanagedType.LPTStr)] string BinaryPathName, + [MarshalAs(UnmanagedType.LPTStr)] string LoadOrderGroup, int TagID, int Dependencies, - [MarshalAs(UnmanagedType.LPStr)] string ServiceStartName, - [MarshalAs(UnmanagedType.LPStr)] string Password); + [MarshalAs(UnmanagedType.LPTStr)] string ServiceStartName, + [MarshalAs(UnmanagedType.LPTStr)] string Password); [DllImport("advapi32.dll", SetLastError = true)] public static extern int DeleteService(int Service); - [DllImport("advapi32.dll", SetLastError = true)] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern int QueryServiceConfig(int Service, int ServiceConfig, int BufSize, ref int BytesNeeded); - [DllImport("advapi32.dll", SetLastError = true)] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern int QueryServiceConfig(int Service, IntPtr ServiceConfig, int BufSize, ref int BytesNeeded); - [DllImport("advapi32.dll", SetLastError = true)] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern int QueryServiceConfig(int Service, [MarshalAs(UnmanagedType.Struct)] ref QUERY_SERVICE_CONFIG ServiceConfig, int BufSize, ref int BytesNeeded); - [DllImport("advapi32.dll", SetLastError = true)] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern int OpenService(int SCManager, - [MarshalAs(UnmanagedType.LPStr)] string ServiceName, SERVICE_RIGHTS DesiredAccess); + [MarshalAs(UnmanagedType.LPTStr)] string ServiceName, SERVICE_RIGHTS DesiredAccess); /// /// Enumerates services in the specified service control manager database. @@ -727,7 +794,7 @@ namespace ProcessHacker /// EnumServicesStatusEx function is called. /// Must be 0 for this definition. /// A non-zero value for success, zero for failure. - [DllImport("advapi32.dll", SetLastError = true)] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern int EnumServicesStatusEx(int SCManager, int InfoLevel, SERVICE_QUERY_TYPE ServiceType, SERVICE_QUERY_STATE ServiceState, ref int Services, int BufSize, ref int BytesNeeded, ref int ServicesReturned, @@ -753,7 +820,7 @@ namespace ProcessHacker /// EnumServicesStatusEx function is called. /// Must be 0 for this definition. /// A non-zero value for success, zero for failure. - [DllImport("advapi32.dll", SetLastError = true)] + [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern int EnumServicesStatusEx(int SCManager, int InfoLevel, SERVICE_QUERY_TYPE ServiceType, SERVICE_QUERY_STATE ServiceState, IntPtr Services, int BufSize, ref int BytesNeeded, ref int ServicesReturned, @@ -1155,10 +1222,10 @@ namespace ProcessHacker [StructLayout(LayoutKind.Sequential)] public struct ENUM_SERVICE_STATUS_PROCESS { - [MarshalAs(UnmanagedType.LPStr)] + [MarshalAs(UnmanagedType.LPTStr)] public string ServiceName; - [MarshalAs(UnmanagedType.LPStr)] + [MarshalAs(UnmanagedType.LPTStr)] public string DisplayName; [MarshalAs(UnmanagedType.Struct)] @@ -1354,19 +1421,19 @@ namespace ProcessHacker public SERVICE_START_TYPE StartType; public SERVICE_ERROR_CONTROL ErrorControl; - [MarshalAs(UnmanagedType.LPStr)] + [MarshalAs(UnmanagedType.LPTStr)] public string BinaryPathName; - [MarshalAs(UnmanagedType.LPStr)] + [MarshalAs(UnmanagedType.LPTStr)] public string LoadOrderGroup; public int TagID; public int Dependencies; // pointer to a string array - [MarshalAs(UnmanagedType.LPStr)] + [MarshalAs(UnmanagedType.LPTStr)] public string ServiceStartName; - [MarshalAs(UnmanagedType.LPStr)] + [MarshalAs(UnmanagedType.LPTStr)] public string DisplayName; } @@ -1618,6 +1685,29 @@ namespace ProcessHacker public string Buffer; } + [StructLayout(LayoutKind.Sequential)] + public struct WTS_PROCESS_INFO + { + public int SessionID; + public int ProcessID; + + [MarshalAs(UnmanagedType.LPTStr)] + public string ProcessName; + + public int SID; + } + + [StructLayout(LayoutKind.Sequential)] + public struct WTS_SESSION_INFO + { + public int SessionID; + + [MarshalAs(UnmanagedType.LPTStr)] + public string WinStationName; + + WTS_CONNECTSTATE_CLASS State; + } + #endregion public static Dictionary EnumServices() @@ -1678,7 +1768,13 @@ namespace ProcessHacker SID_NAME_USE use = SID_NAME_USE.SidTypeUser; if (LookupAccountSid(0, SID, name, ref namelen, domain, ref domainlen, ref use) == 0) - return ""; + { + name.EnsureCapacity(namelen); + domain.EnsureCapacity(domainlen); + + if (LookupAccountSid(0, SID, name, ref namelen, domain, ref domainlen, ref use) == 0) + throw new Exception("Could not lookup account SID: " + Win32.GetLastErrorMessage()); + } if (IncludeDomain) { @@ -1802,25 +1898,41 @@ namespace ProcessHacker } } - public static int GetProcessSessionId(int ProcessHandle) + public static int GetProcessSessionId(int ProcessId) { - int token = 0; - int id = 0; - int retLen = 0; + int sessionId = -1; - if (Win32.OpenProcessToken(ProcessHandle, Win32.TOKEN_RIGHTS.TOKEN_QUERY, - ref token) == 0) - return -1; - - if (Win32.GetTokenInformation(token, Win32.TOKEN_INFORMATION_CLASS.TokenSessionId, - ref id, 4, ref retLen) == 0) + try { - Win32.CloseHandle(token); - return -1; + if (ProcessIdToSessionId(ProcessId, ref sessionId) == 0) + throw new Exception(GetLastErrorMessage()); + } + catch + { + int handle = 0; + int token = 0; + int retLen = 0; + + if ((handle = OpenProcess(PROCESS_RIGHTS.PROCESS_QUERY_INFORMATION, 0, ProcessId)) == 0) + return -1; + + if (OpenProcessToken(handle, TOKEN_RIGHTS.TOKEN_QUERY, + ref token) == 0) + return -1; + + if (GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenSessionId, + ref sessionId, 4, ref retLen) == 0) + { + CloseHandle(token); + return -1; + } + + CloseHandle(token); + + return sessionId; } - Win32.CloseHandle(token); - return id; + return sessionId; } public static int GetProcessSID(int ProcessHandle)