OLD | NEW |
| (Empty) |
1 // Copyright 2004-2010 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 // | |
16 // system functions for checking disk space / memory usage / etc. | |
17 | |
18 #ifndef OMAHA_BASE_SYSTEM_H_ | |
19 #define OMAHA_BASE_SYSTEM_H_ | |
20 | |
21 #include <atlstr.h> | |
22 #include <base/basictypes.h> | |
23 | |
24 namespace omaha { | |
25 | |
26 #define kMaxRegistryBackupWaitMs 3000 | |
27 #define kMaxRegistryRestoreWaitMs 30000 | |
28 | |
29 // amount of time the user must have no input before we declare them idle | |
30 // used by outlook addin, outlook_cap, and filecap. | |
31 #define kUserIdleThresholdMs 30000 | |
32 | |
33 // The user is busy typing or interacting with another application | |
34 // if the user is below the minimum threshold. | |
35 #define kUserIdleMinThresholdMs 30000 | |
36 | |
37 // The user is probably not paying attention | |
38 // if the user is above the maximum threshold. | |
39 #define kUserIdleMaxThresholdMs 600000 | |
40 | |
41 const DWORD kInvalidSessionId = 0xFFFFFFFF; | |
42 | |
43 class System { | |
44 public: | |
45 | |
46 // disk activity. | |
47 | |
48 // waits up to specified time for disk activity to occur; sleeps in | |
49 // increments of sleep_time. | |
50 static HRESULT WaitForDiskActivity(uint32 max_delay_milliseconds, | |
51 uint32 sleep_time_ms, | |
52 uint32 *time_waited); | |
53 // disk activity counters; may require admin on some machines? should return | |
54 // E_FAIL if so. | |
55 static HRESULT GetDiskActivityCounters(uint64 *reads, | |
56 uint64 *writes, | |
57 uint64 *bytes_read, | |
58 uint64 *bytes_written); | |
59 | |
60 // disk statistics. | |
61 | |
62 // disk total and free space. | |
63 // Path is either the root of a drive or an existing folder on a drive; the | |
64 // statistics are for that drive. | |
65 static HRESULT GetDiskStatistics(const TCHAR* path, | |
66 uint64 *free_bytes_current_user, | |
67 uint64 *total_bytes_current_user, | |
68 uint64 *free_bytes_all_users); | |
69 | |
70 enum Priority { | |
71 LOW, | |
72 HIGH, | |
73 NORMAL, | |
74 IDLE | |
75 }; | |
76 | |
77 // functions to alter process/thread priority. | |
78 static HRESULT SetThreadPriority(enum Priority priority); | |
79 static HRESULT SetProcessPriority(enum Priority priority); | |
80 | |
81 // The three functions below start background processes via ::CreateProcess. | |
82 // Use the ShellExecuteProcessXXX functions when starting foreground | |
83 // processes. | |
84 static HRESULT StartProcessWithArgs(const TCHAR *process_name, | |
85 const TCHAR *cmd_line_arguments); | |
86 static HRESULT StartProcessWithArgsAndInfo(const TCHAR *process_name, | |
87 const TCHAR *cmd_line_arguments, | |
88 PROCESS_INFORMATION *pi); | |
89 static HRESULT StartCommandLine(const TCHAR* command_line_to_execute); | |
90 static HRESULT StartProcess(const TCHAR *process_name, | |
91 TCHAR *command_line, | |
92 PROCESS_INFORMATION *pi); | |
93 | |
94 // Start the process with the provided token, in the specified desktop of | |
95 // the token's session. The caller needs to be SYSTEM. | |
96 static HRESULT StartProcessAsUser(HANDLE user_token, | |
97 const CString& executable_path, | |
98 const CString& parameters, | |
99 LPWSTR desktop, | |
100 PROCESS_INFORMATION* pi); | |
101 | |
102 // start another process painlessly via ::ShellExecuteEx. Use this method | |
103 // instead of the StartProcessXXX methods that use ::CreateProcess where | |
104 // possible, since ::ShellExecuteEx has better behavior on Vista. | |
105 static HRESULT ShellExecuteProcess(const TCHAR* file_name_to_execute, | |
106 const TCHAR* command_line_parameters, | |
107 HWND hwnd, | |
108 HANDLE* process_handle); | |
109 | |
110 // start another process painlessly via ::ShellExecuteEx. Use this method | |
111 // instead of the StartProcessXXX methods that use ::CreateProcess where | |
112 // possible, since ::ShellExecuteEx has better behavior on Vista. | |
113 static HRESULT ShellExecuteCommandLine(const TCHAR* command_line_to_execute, | |
114 HWND hwnd, | |
115 HANDLE* process_handle); | |
116 | |
117 // memory statistics. | |
118 | |
119 // max amount of memory that can be allocated without paging. | |
120 static HRESULT MaxPhysicalMemoryAvailable(uint64 *max_bytes); | |
121 | |
122 // global memory stats | |
123 static HRESULT GetGlobalMemoryStatistics( | |
124 uint32 *memory_load_percentage, | |
125 uint64 *free_physical_memory, | |
126 uint64 *total_physical_memory, | |
127 uint64 *free_paged_memory, | |
128 uint64 *total_paged_memory, | |
129 uint64 *process_free_virtual_memory, | |
130 uint64 *process_total_virtual_memory); | |
131 | |
132 // process memory stats | |
133 static HRESULT GetProcessMemoryStatistics(uint64 *current_working_set, | |
134 uint64 *peak_working_set, | |
135 uint64 *min_working_set_size, | |
136 uint64 *max_working_set_size); | |
137 | |
138 // TODO(omaha): determine if using this where we do with machines | |
139 // with slow disks causes noticeable slowdown | |
140 | |
141 // reduce process working set - beware of possible negative performance | |
142 // implications - this function frees (to the page cache) all used pages, | |
143 // minimizing the working set - but could lead to additional page faults | |
144 // when the process continues. If the process continues soon enough the | |
145 // pages will still be in the page cache so they'll be relatively cheap | |
146 // soft page faults. This function is best used to reduce memory footprint | |
147 // when a component is about to go idle for "awhile". | |
148 static void FreeProcessWorkingSet(); | |
149 | |
150 // returns the number of ms the system has had no user input. | |
151 static int GetUserIdleTime(); | |
152 | |
153 // from ntddk.h, used as a parameter to get the process handle count. | |
154 static const int kProcessHandleCount = 20; | |
155 static uint32 GetProcessHandleCount(); | |
156 static uint32 GetProcessHandleCountOld(); | |
157 | |
158 static void GetGuiObjectCount(uint32 *gdi, uint32 *user); | |
159 | |
160 static bool IsUserIdle(); | |
161 static bool IsUserBusy(); | |
162 static bool IsScreensaverRunning(); | |
163 static bool IsWorkstationLocked(); | |
164 static bool IsUserAway(); | |
165 | |
166 // Is the system requiring reboot. | |
167 static bool IsRebooted(const TCHAR* base_file); | |
168 | |
169 // Mark the system as reboot required. | |
170 static HRESULT MarkAsRebootRequired(const TCHAR* base_file); | |
171 | |
172 // Unmark the system as reboot required. | |
173 static HRESULT UnmarkAsRebootRequired(const TCHAR* base_file); | |
174 | |
175 // Restart the computer. | |
176 static HRESULT RestartComputer(); | |
177 | |
178 // Get the full path name of the screen saver program currently selected. | |
179 // If no screen saver is selected then "fileName" is empty. | |
180 static HRESULT GetCurrentScreenSaver(CString* fileName); | |
181 | |
182 // Create an instance of a COM Local Server class using either plain vanilla | |
183 // CoCreateInstance, or using the Elevation moniker if Vista or later and | |
184 // the user is not an elevated admin. | |
185 static HRESULT CoCreateInstanceAsAdmin(HWND hwnd, | |
186 REFCLSID rclsid, | |
187 REFIID riid, | |
188 void** ppv); | |
189 | |
190 // Attempts to adjust current process privileges. | |
191 // Only process running with administrator privileges will succeed. | |
192 static HRESULT AdjustPrivilege(const TCHAR* privilege, bool enable); | |
193 | |
194 // Checks if the given privilege is enabled for the current process. | |
195 static HRESULT IsPrivilegeEnabled(const TCHAR* privilege, bool* present); | |
196 | |
197 // Dynamically links and calls ::WTSGetActiveConsoleSessionId(). Returns | |
198 // kInvalidSessionId if it cannot find the export in kernel32.dll. | |
199 static DWORD WTSGetActiveConsoleSessionId(); | |
200 | |
201 // Get the session the current process is running under. | |
202 static DWORD GetCurrentSessionId(); | |
203 | |
204 // Get the best guess as to the currently active session, | |
205 // or kInvalidSessionId if there is no active session. | |
206 static DWORD GetActiveSessionId(); | |
207 | |
208 // Is there a user logged on and active in the specified session? | |
209 static bool IsSessionActive(DWORD session_id); | |
210 | |
211 // Is the current process running under WinSta0. | |
212 static bool IsCurrentProcessInteractive(); | |
213 | |
214 // is the current process running under WinSta0 for the currently active | |
215 // session. | |
216 static bool IsCurrentProcessActiveAndInteractive(); | |
217 | |
218 // Returns true if a system battery is detected and the AC line | |
219 // status is 'offline', otherwise it returns false. | |
220 static bool IsRunningOnBatteries(); | |
221 | |
222 private: | |
223 static HRESULT GetRebootCheckDummyFileName(const TCHAR* base_file, | |
224 CString* dummy_file); | |
225 DISALLOW_EVIL_CONSTRUCTORS(System); | |
226 }; | |
227 | |
228 } // namespace omaha | |
229 | |
230 #endif // OMAHA_BASE_SYSTEM_H_ | |
231 | |
OLD | NEW |