Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(356)

Side by Side Diff: base/utils.h

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/user_rights_unittest.cc ('k') | base/utils.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2003-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 #ifndef OMAHA_BASE_UTILS_H_
17 #define OMAHA_BASE_UTILS_H_
18
19 #include <windows.h>
20 #include <accctrl.h>
21 #include <aclapi.h>
22 #include <sddl.h>
23 #include <shellapi.h>
24 #include <shlobj.h>
25 #include <atlstr.h>
26 #include <atlsecurity.h>
27 #include <atlwin.h>
28 #include <memory.h>
29 #include <map>
30 #include <vector>
31 #include "base/basictypes.h"
32 #include "omaha/base/constants.h"
33 #include "omaha/base/debug.h"
34 #include "omaha/base/logging.h"
35 #include "omaha/base/reg_key.h"
36 #include "omaha/base/scoped_any.h"
37 #include "omaha/base/static_assert.h"
38 #include "omaha/base/user_info.h"
39
40 namespace omaha {
41
42 // These definitions are not in any current Microsoft SDK header file. Taken
43 // from platformsdk/v6_1/files/Include/ObjIdl.h.
44 MIDL_INTERFACE("0000015B-0000-0000-C000-000000000046")
45 IGlobalOptions : public IUnknown {
46 public:
47 virtual HRESULT STDMETHODCALLTYPE Set(
48 /* [in] */ DWORD dwProperty,
49 /* [in] */ ULONG_PTR dwValue) = 0;
50
51 virtual HRESULT STDMETHODCALLTYPE Query(
52 /* [in] */ DWORD dwProperty,
53 /* [out] */ ULONG_PTR *pdwValue) = 0;
54 };
55
56 enum __MIDL___MIDL_itf_objidl_0000_0047_0001 {
57 COMGLB_EXCEPTION_HANDLING = 1,
58 COMGLB_APPID = 2
59 };
60
61 enum __MIDL___MIDL_itf_objidl_0000_0047_0002 {
62 COMGLB_EXCEPTION_HANDLE = 0,
63 COMGLB_EXCEPTION_DONOT_HANDLE = 1
64 };
65
66 // Determines whether to run ClickOnce components. This constant is not defined
67 // in the SDK headers.
68 #ifndef URLACTION_MANAGED_UNSIGNED
69 #define URLACTION_MANAGED_UNSIGNED (0x00002004)
70 #endif
71
72 ULONGLONG VersionFromString(const CString& s);
73
74 CString StringFromVersion(ULONGLONG version);
75
76 // Gets current directory
77 CString GetCurrentDir();
78
79 // Creates a unique file name using a new guid. Does not check for
80 // presence of this file in the directory.
81 HRESULT GetNewFileNameInDirectory(const CString& dir, CString* file_name);
82
83 // Gets security descriptor with a DACL that grants the admin_access_mask to
84 // Admins and System, and the non_admin_access_mask to Interactive.
85 void GetEveryoneDaclSecurityDescriptor(CSecurityDesc* sd,
86 ACCESS_MASK admin_access_mask,
87 ACCESS_MASK non_admin_access_mask);
88
89 // Get security descriptor containing a DACL that grants the ACCESS_MASK access
90 // to admins and system.
91 void GetAdminDaclSecurityDescriptor(CSecurityDesc* sd, ACCESS_MASK accessmask);
92
93 // Get security attributes containing a DACL that grant the ACCESS_MASK access
94 // to admins and system.
95 void GetAdminDaclSecurityAttributes(CSecurityAttributes* sec_attr,
96 ACCESS_MASK accessmask);
97
98 // This method is intended to be called by same or lower integrity COM clients.
99 // Calls ::CoInitializeSecurity with the default DACL. Servers are allowed to
100 // impersonate the client.
101 HRESULT InitializeClientSecurity();
102
103 // This method calls ::CoInitializeSecurity with security settings and ACLs of
104 // callers that are allowed access to the COM server. Clients can only identify
105 // the server, and custom marshaling as well as activate-as-activator are
106 // disallowed.
107 // * If the bool is set, a DACL that provides COM_RIGHTS_EXECUTE access
108 // for medium-integrity callers is set.
109 // * If the bool is not set, but the caller is Local System, the function will
110 // set a security descriptor that also allows the Administrators group access to
111 // the COM server.
112 HRESULT InitializeServerSecurity(bool allow_calls_from_medium);
113
114 // Ensures that the COM marshaling machinery does not eat crashes.
115 HRESULT DisableCOMExceptionHandling();
116
117 // Merges an Allowed ACE into a named object. If the ACE already exists in the
118 // DACL with the same permissions (or a superset) and the same ACE flags, the
119 // merge is skipped.
120 HRESULT AddAllowedAce(const TCHAR* object_name,
121 SE_OBJECT_TYPE object_type,
122 const CSid& sid,
123 ACCESS_MASK required_permissions,
124 uint8 required_ace_flags);
125
126 struct NamedObjectAttributes {
127 CString name;
128 CSecurityAttributes sa;
129 };
130
131 // For machine and local system, the prefix would be "Global\G{obj_name}".
132 // For user, the prefix would be "Global\G{user_sid}{obj_name}".
133 // For machine objects, returns a security attributes that gives permissions to
134 // both Admins and SYSTEM. This allows for cases where SYSTEM creates the named
135 // object first. The default DACL for SYSTEM will not allow Admins access.
136 void GetNamedObjectAttributes(const TCHAR* base_name,
137 bool is_machine,
138 NamedObjectAttributes* attr);
139
140 // Returns true if the current process is running as SYSTEM.
141 HRESULT IsSystemProcess(bool* is_system_process);
142
143 // Returns true if the user of the current process is Local System or it has an
144 // interactive session: console, terminal services, or fast user switching.
145 HRESULT IsUserLoggedOn(bool* is_logged_on);
146
147 // Returns true if URLACTION_MANAGED_UNSIGNED is disabled for the Internet zone
148 // for the current user.
149 bool IsClickOnceDisabled();
150
151 // Wrapper around ::GetProcAddress().
152 template <typename T>
153 bool GPA(HMODULE module, const char* function_name, T* function_pointer) {
154 ASSERT1(module);
155 ASSERT1(function_name);
156 ASSERT1(function_pointer);
157
158 *function_pointer = reinterpret_cast<T>(::GetProcAddress(module,
159 function_name));
160 if (NULL == *function_pointer) {
161 UTIL_LOG(LW, (_T("GetProcAddress failed [%s]"), CA2T(function_name)));
162 }
163 return NULL != *function_pointer;
164 }
165
166 #define GPA_WRAP(module, \
167 function, \
168 proto, \
169 call, \
170 calling_convention, \
171 result_type, \
172 result_error) \
173 typedef result_type (calling_convention *function##_pointer) proto; \
174 inline result_type function##Wrap proto { \
175 HINSTANCE module_instance = ::GetModuleHandle(_T(#module)); \
176 ASSERT1(module_instance); \
177 if (!module_instance) { \
178 return result_error; \
179 } \
180 function##_pointer fn = NULL; \
181 return GPA(module_instance, #function, &fn) ? (*fn) call : result_error; \
182 }
183
184 GPA_WRAP(kernel32.dll,
185 AttachConsole,
186 (DWORD process_id),
187 (process_id),
188 WINAPI,
189 BOOL,
190 0);
191
192 // Private Object Namespaces for Vista and above. More information here:
193 // http://msdn2.microsoft.com/en-us/library/ms684295(VS.85).aspx
194 GPA_WRAP(kernel32.dll,
195 CreateBoundaryDescriptorW,
196 (LPCWSTR boundary_name, ULONG flags),
197 (boundary_name, flags),
198 WINAPI,
199 HANDLE,
200 NULL);
201 GPA_WRAP(kernel32.dll,
202 AddSIDToBoundaryDescriptor,
203 (HANDLE* boundary_descriptor, PSID required_sid),
204 (boundary_descriptor, required_sid),
205 WINAPI,
206 BOOL,
207 FALSE);
208 GPA_WRAP(kernel32.dll,
209 CreatePrivateNamespaceW,
210 (LPSECURITY_ATTRIBUTES private_namespace_attributes, LPVOID boundary_de scriptor, LPCWSTR alias_prefix), // NOLINT
211 (private_namespace_attributes, boundary_descriptor, alias_prefix),
212 WINAPI,
213 HANDLE,
214 NULL);
215 GPA_WRAP(kernel32.dll,
216 OpenPrivateNamespaceW,
217 (LPVOID boundary_descriptor, LPCWSTR alias_prefix),
218 (boundary_descriptor, alias_prefix),
219 WINAPI,
220 HANDLE,
221 NULL);
222
223 bool IsPrivateNamespaceAvailable();
224
225
226 HRESULT PinModuleIntoProcess(const CString& module_name);
227
228 // Creates a directory with default security.
229 // S_OK: Created directory
230 // S_FALSE: Directory already existed
231 // E_FAIL: Couldn't create
232 HRESULT CreateDir(const TCHAR* dirname, LPSECURITY_ATTRIBUTES security_attr);
233
234 // Gets the path for the specified special folder.
235 HRESULT GetFolderPath(int csidl, CString* path);
236
237 // Returns true if this directory name is 'safe' for deletion:
238 // - it doesn't contain ".."
239 // - it doesn't specify a drive root
240 bool SafeDirectoryNameForDeletion(const TCHAR* dir_name);
241
242 // Deletes a directory and its files.
243 HRESULT DeleteDirectory(const TCHAR* ir_name);
244
245 // Deletes all files in a directory.
246 HRESULT DeleteDirectoryFiles(const TCHAR* dir_name);
247
248 // Deletes all files in a directory matching a wildcard.
249 HRESULT DeleteWildcardFiles(const TCHAR* dir_name, const TCHAR* wildcard_name);
250
251 // Deletes either a file or directory before or after reboot.
252 HRESULT DeleteBeforeOrAfterReboot(const TCHAR* targetname);
253
254 // Gets the size of all files in a directory.
255 // Aborts counting if one of the maximum criteria is reached.
256 HRESULT SafeGetDirectorySize(const TCHAR* dir_name,
257 uint64* size,
258 HANDLE shutdown_event,
259 uint64 max_size,
260 int max_depth,
261 int max_file_count,
262 int max_running_time_ms);
263
264 // Gets size of all files in a directory.
265 HRESULT GetDirectorySize(const TCHAR* dir_name, uint64* size);
266
267 enum TimeCategory {
268 PAST = 0, // older than 40 years from now
269 FUTURE, // in the future by > 1 day
270 PRESENT, // neither ANCIENT nor FUTURE
271 };
272
273 TimeCategory GetTimeCategory(time64 t);
274
275 // Returns true if a given time is likely to be valid.
276 bool IsValidTime(time64 t);
277
278 // Gets a time64 value.
279 // If the value is greater than the
280 // max value, then SetValue will be called using the max_value.
281 //
282 // Args:
283 // full_key_name: the reg keyto read to get the time value.
284 // value_name: the name for the reg key value to be read.
285 // (may be NULL to get the default value)
286 // max_time: the maximum value for the reg key.
287 // value: the time value read. May not be set on failure.
288 // limited_value: true iff will be set if the value was
289 // changed (and resaved). (NULL is allowable.)
290 HRESULT GetLimitedTimeValue(const TCHAR* full_key_name,
291 const TCHAR* value_name,
292 time64 max_time,
293 time64* value,
294 bool* limited_value);
295
296 // Gets a time64 value trying reg keys successively if there is a
297 // failure in getting a value.
298 //
299 // Typically used when there is a user value and a default value if the
300 // user has none.
301 //
302 // Args:
303 // full_key_names: a list of reg keys to try successively (starting
304 // with index 0) to read to get the time value. The
305 // attempts stops as soon as there is a successful read or
306 // when all keys have been tried.
307 // key_names_length: number of keys in full_key_names.
308 // value_name: the name for the reg key value to be read.
309 // (may be NULL to get the default value)
310 // max_time: the maximum value for the reg key.
311 // value: the time value read. May not be set on failure.
312 // limited_value: true iff will be set if the value was
313 // changed (and resaved). (NULL is allowable.)
314 HRESULT GetLimitedTimeValues(const TCHAR* full_key_names[],
315 int key_names_length,
316 const TCHAR* value_name,
317 time64 max_time,
318 time64* value,
319 bool* limited_value);
320
321 // Convert milliseconds to a relative time in units of 100ns, suitable for use
322 // with waitable timers
323 LARGE_INTEGER MSto100NSRelative(DWORD ms);
324
325 // TODO(omaha): remove from public interface.
326 inline void WINAPI NullAPCFunc(ULONG_PTR) {}
327
328 // Forces rasman.dll load to avoid a crash in wininet.
329 void EnsureRasmanLoaded();
330
331 // Returns if the HRESULT argument is a COM error
332 // TODO(omaha): use an ANONYMOUS_VARIABLE to avoid the situation in which the
333 // macro gets called like RET_IF_FAILED(hr);
334 // For now, use a quick fix hr -> __hr. Leading underscore names are not to be
335 // used in application code.
336 #define RET_IF_FAILED(x) \
337 do { \
338 HRESULT __hr(x); \
339 if (FAILED(__hr)) { \
340 return __hr; \
341 } \
342 } while (false)
343
344 // return error if the first argument evaluates to false
345 #define RET_IF_FALSE(x, err) \
346 do { \
347 if (!(x)) { \
348 return err; \
349 } \
350 } while (false)
351
352 // return false if the HRESULT argument is a COM error
353 #define RET_FALSE_IF_FAILED(x) \
354 do { \
355 if (FAILED(x)) { \
356 return false; \
357 } \
358 } while (false)
359
360 // return true if the HRESULT argument is a COM error
361 #define RET_TRUE_IF_FAILED(x) \
362 do { \
363 if (FAILED(x)) { \
364 return true; \
365 } \
366 } while (false)
367
368 // return if the HRESULT argument evaluates to FAILED - but also assert
369 // if failed
370 #define RET_IF_FAILED_ASSERT(x, msg) \
371 do { \
372 HRESULT hr(x); \
373 if (FAILED(hr)) { \
374 ASSERT(false, msg); \
375 return hr; \
376 } \
377 } while (false)
378
379
380 // return if the HRESULT argument evaluates to FAILED - but also log an error
381 // message if failed
382 #define RET_IF_FAILED_LOG(x, cat, msg) \
383 do { \
384 HRESULT hr(x); \
385 if (FAILED(hr)) { \
386 LC_LOG(cat, LEVEL_ERROR, msg); \
387 return hr; \
388 } \
389 } while (false)
390
391 // return if the HRESULT argument evaluates to FAILED - but also REPORT an error
392 // message if failed
393 #define RET_IF_FAILED_REPORT(x, msg, n) \
394 do { \
395 HRESULT hr(x); \
396 if (FAILED(hr)) { \
397 REPORT(false, R_ERROR, msg, n); \
398 return hr; \
399 } \
400 } while (false)
401
402 // Initializes a POD to zero.
403 // Using this function requires discipline. Don't use for types that have a
404 // v-table or virtual bases.
405 template <typename T>
406 inline void SetZero(T& p) { // NOLINT
407 // Guard against the easy mistake of
408 // foo(int *p) { SetZero(p); } instead of
409 // SetZero(*p);
410 // which it should be.
411 STATIC_ASSERT(sizeof(p) != sizeof(void*)); // NOLINT
412
413 // A POD (plain old data) object has one of these data types:
414 // a fundamental type, union, struct, array,
415 // or class--with no constructor. PODs don't have virtual functions or
416 // virtual bases.
417
418 // Test to see if the type has constructors.
419 union CtorTest {
420 T t;
421 int i;
422 };
423
424 // TODO(omaha): There might be a way to test if the type has virtuals
425 // For now, if we zero a type with virtuals by mistake, it is going to crash
426 // predictable at run-time when the virtuals are called.
427
428 memset(&p, 0, sizeof(T));
429 }
430
431 inline void SecureSetZero(CString* p) {
432 ASSERT1(p);
433 if (!p->IsEmpty()) {
434 ::SecureZeroMemory(p->GetBufferSetLength(p->GetLength()),
435 p->GetLength() * sizeof(TCHAR));
436 p->ReleaseBuffer();
437 }
438 }
439
440 inline void SecureSetZero(CComVariant* p) {
441 ASSERT1(p);
442 ASSERT1(V_VT(p) == VT_BSTR);
443 uint32 byte_len = ::SysStringByteLen(V_BSTR(p));
444 if (byte_len > 0) {
445 ::SecureZeroMemory(V_BSTR(p), byte_len);
446 }
447 }
448
449 // CreateForegroundParentWindowForUAC creates a WS_POPUP | WS_VISIBLE with zero
450 // size, of the STATIC WNDCLASS. It uses the default running EXE module
451 // handle for creation.
452 //
453 // A visible centered foreground window is needed as the parent in Windows 7 and
454 // above, to allow the UAC prompt to come up in the foreground, centered.
455 // Otherwise, the elevation prompt will be minimized on the taskbar. A zero size
456 // window works. A plain vanilla WS_POPUP allows the window to be free of
457 // adornments. WS_EX_TOOLWINDOW prevents the task bar from showing the
458 // zero-sized window.
459 //
460 // Returns NULL on failure. Call ::GetLastError() to get extended error
461 // information on failure.
462 inline HWND CreateForegroundParentWindowForUAC() {
463 CWindow foreground_parent;
464 if (foreground_parent.Create(_T("STATIC"), NULL, NULL, NULL,
465 WS_POPUP | WS_VISIBLE, WS_EX_TOOLWINDOW)) {
466 foreground_parent.CenterWindow(NULL);
467 ::SetForegroundWindow(foreground_parent);
468 }
469 return foreground_parent.Detach();
470 }
471
472 // TODO(omaha): move the definition and ShellExecuteExEnsureParent function
473 // below into shell.h
474
475 #if (NTDDI_VERSION < NTDDI_WINXPSP1)
476 // This value is not defined in the header, but has no effect on older OSes.
477 #define SEE_MASK_NOZONECHECKS 0x00800000
478 #endif
479
480 // ShellExecuteExEnsureParent is a wrapper around ::ShellExecuteEx.
481 // It ensures that we always have a parent window. In elevation scenarios, we
482 // need to use the HWND property to be acknowledged as a foreground application
483 // on Windows Vista. Otherwise, the elevation prompt will appear minimized on
484 // the taskbar The UAC elevation mechanism uses the HWND as part of determining
485 // whether the elevation is a foreground elevation.
486 //
487 // A better place for this might be in the Process class. However, to
488 // reduce dependencies for the stub, placing this in utils.
489 //
490 // Return values:
491 // ShellExecuteExEnsureParent returns TRUE on success, and FALSE on failure.
492 // Call ::GetLastError() to get the extended error information on failure.
493 //
494 // Args:
495 // shell_exec_info structure pointer, filled in, with an optional HWND.
496 // The structure is not validated. If the HWND is NULL, it creates one.
497 bool ShellExecuteExEnsureParent(LPSHELLEXECUTEINFO shell_exec_info);
498
499 //
500 // Wait with a message loop.
501 // Returns true if the wait completed successfully and false in case of an
502 // error.
503 //
504
505 // Waits with a message loop until any of the synchronization objects is
506 // signaled. Return the index of the object that satisfied the wait.
507 bool WaitWithMessageLoopAny(const std::vector<HANDLE>& handles, uint32* pos);
508
509 // Waits with message loop until all the synchronization objects are signaled.
510 bool WaitWithMessageLoopAll(const std::vector<HANDLE>& handles);
511
512 // Waits with message loop until the synchronization object is signaled.
513 bool WaitWithMessageLoop(HANDLE h);
514
515 // Waits with message loop for a certain period of time
516 bool WaitWithMessageLoopTimed(DWORD ms);
517
518 //
519 // TODO(omaha): message handler classes should go in other module.
520 //
521 // Handles windows messages
522 class MessageHandlerInterface {
523 public:
524 virtual ~MessageHandlerInterface() {}
525 // Does the translate/dispatch for one window message
526 // msg is never NULL.
527 virtual void Process(MSG* msg) = 0;
528 };
529
530 // The simplest working implementation of a message handler.
531 // It does TranslateMessage/DispatchMessage.
532 class BasicMessageHandler : public MessageHandlerInterface {
533 public:
534 BasicMessageHandler() {}
535 virtual void Process(MSG* msg);
536 private:
537 DISALLOW_EVIL_CONSTRUCTORS(BasicMessageHandler);
538 };
539
540 // An internal detail (used to handle messages
541 // and adjust the handles/cnt as needed).
542 class MessageHandlerInternalInterface {
543 public:
544 virtual ~MessageHandlerInternalInterface() {}
545 // Does the translate/dispatch for one window message
546 // msg is never NULL and may change the handles and cnt (which are
547 // never NULL).
548 virtual void Process(MSG* msg, const HANDLE** handles, uint32* cnt) = 0;
549 };
550
551 // The callback for MessageLoopInterface::RegisterWaitForSingleObject
552 class WaitCallbackInterface {
553 public:
554 virtual ~WaitCallbackInterface() {}
555 // Return false from this method to terminate the message loop.
556 virtual bool HandleSignaled(HANDLE handle) = 0;
557 };
558
559 // This is similar to a threadpool interface
560 // but this is done on the main message loop instead.
561 //
562 // Important: These method calls are *not* threadsafe and
563 // should only be done on the message loop thread.
564 class MessageLoopInterface {
565 public:
566 virtual ~MessageLoopInterface() {}
567 // sets-up a callback for when the handle becomes signaled
568 // * the callback happens on the main thread.
569 // * the handle/callback is removed when
570 // the callback is made.
571 // * If the handle becomes invalid while it is being waited on,
572 // the message loop will exit.
573 // * If the handle has already been registered,
574 // then adding it again will essentially replace the
575 // previous callback with the new one.
576 virtual bool RegisterWaitForSingleObject(HANDLE handle,
577 WaitCallbackInterface* callback) = 0;
578
579 // stops watching for the handle to be signaled
580 virtual bool UnregisterWait(HANDLE handle) = 0;
581 };
582
583 // An implementation of the MessageLoopInterface
584 class MessageLoopWithWait : public MessageLoopInterface,
585 private MessageHandlerInternalInterface {
586 public:
587 MessageLoopWithWait();
588
589 // This method needs to be called before the "Process()"
590 // method or else "Process()" will crash.
591 //
592 // Args:
593 // message_handler: handles any messages that occur
594 // *Note* It is the callers responsibility to keep
595 // message_handler around while this class exists
596 // and the *caller* should free message_handler
597 // after that.
598 void set_message_handler(MessageHandlerInterface* message_handler);
599
600 // sets-up a callback for when the handle becomes signaled
601 virtual bool RegisterWaitForSingleObject(HANDLE handle,
602 WaitCallbackInterface* callback);
603
604 // stops watching for the handle to be signaled
605 virtual bool UnregisterWait(HANDLE handle);
606
607 // The message loop and handle callback routine
608 HRESULT Process();
609
610 private:
611 // Handles one messgae and adjus tthe handles and cnt as appropriate after
612 // handling the message
613 virtual void Process(MSG* msg, const HANDLE** handles, uint32* cnt);
614
615 void RemoveHandleAt(uint32 pos);
616
617 MessageHandlerInterface* message_handler_;
618
619 // Handles that are checked for being signaled.
620 std::vector<HANDLE> callback_handles_;
621
622 // What to call when a handle is signaled.
623 std::vector<WaitCallbackInterface*> callbacks_;
624 DISALLOW_EVIL_CONSTRUCTORS(MessageLoopWithWait);
625 };
626
627 // Calls an entry point that may be exposed from a DLL
628 // It is an error if the DLL is missing or can't be loaded
629 // If the entry point is missing the error returned is
630 // ERROR_INVALID_FUNCTION (as an HRESULT).
631 // Otherwise, if the function is called successfully then
632 // CallEntryPoint0 return S_OK and the result parameter is set to the
633 // return value from the function call.
634 HRESULT CallEntryPoint0(const TCHAR* dll_path,
635 const char* function_name,
636 HRESULT* result);
637
638 // (Un)Registers a COM DLL with the system. Returns S_FALSE if entry
639 // point missing (so that it you can call (Un)RegisterDll on any DLL
640 // without worrying whether the DLL is actually a COM server or not).
641 HRESULT RegisterDll(const TCHAR* dll_path);
642 HRESULT UnregisterDll(const TCHAR* dll_path);
643
644 // (Un)Registers a COM Local Server with the system.
645 HRESULT RegisterServer(const TCHAR* exe_path);
646 HRESULT UnregisterServer(const TCHAR* exe_path);
647 HRESULT RegisterOrUnregisterExe(const TCHAR* exe_path, const TCHAR* cmd_line);
648
649 // (Un)Registers a COM Service with the system.
650 HRESULT RegisterService(const TCHAR* exe_path);
651 HRESULT UnregisterService(const TCHAR* exe_path);
652
653 // Starts a service.
654 HRESULT RunService(const TCHAR* service_name);
655
656 // Read an entire file into a memory buffer. Use this function when you need
657 // exclusive access to the file.
658 // Returns MEM_E_INVALID_SIZE if the file size is larger than max_len (unless
659 // max_len == 0, in which case it is ignored)
660 HRESULT ReadEntireFile(const TCHAR* filepath,
661 uint32 max_len,
662 std::vector<byte>* buffer_out);
663
664 // Allows specifying a sharing mode such as FILE_SHARE_READ. Otherwise,
665 // this is identical to ReadEntireFile.
666 HRESULT ReadEntireFileShareMode(const TCHAR* filepath,
667 uint32 max_len,
668 DWORD share_mode,
669 std::vector<byte>* buffer_out);
670
671 // Writes an entire file from a memory buffer
672 HRESULT WriteEntireFile(const TCHAR * filepath,
673 const std::vector<byte>& buffer_in);
674
675 // Conversions between a byte stream and a std::string
676 HRESULT BufferToString(const std::vector<byte>& buffer_in, CStringA* str_out);
677 HRESULT BufferToString(const std::vector<byte>& buffer_in, CString* str_out);
678 HRESULT StringToBuffer(const CStringA& str_in, std::vector<byte>* buffer_out);
679 HRESULT StringToBuffer(const CString& str_in, std::vector<byte>* buffer_out);
680
681 // Splits a "full regkey name" into a key name part and a value name part.
682 // Handles "(default)" as a value name. Treats a trailing "/" as "(default)".
683 HRESULT RegSplitKeyvalueName(const CString& keyvalue_name,
684 CString* key_name,
685 CString* value_name);
686
687 // Expands string with embedded special variables which are enclosed
688 // in '%' pair. For example, "%PROGRAMFILES%\Google" expands to
689 // "C:\Program Files\Google".
690 // If any of the embedded variable can not be expanded, we will leave it intact
691 // and return HRESULT_FROM_WIN32(ERROR_NOT_FOUND)
692 HRESULT ExpandEnvLikeStrings(const TCHAR* src,
693 const std::map<CString, CString>& keywords,
694 CString* dest);
695
696 // Returns true if the path represents a registry path.
697 bool IsRegistryPath(const TCHAR* path);
698
699 // Returns true if the path is a URL.
700 bool IsUrl(const TCHAR* path);
701
702 // Converts GUID to string.
703 CString GuidToString(const GUID& guid);
704
705 // Converts string to GUID.
706 HRESULT StringToGuidSafe(const CString& str, GUID* guid);
707
708 // Converts a variant containing a list of strings.
709 void VariantToStringList(VARIANT var, std::vector<CString>* list);
710
711 // Appends two registry key paths, takes care of extra separators in the
712 // beginning or end of the key.
713 CString AppendRegKeyPath(const CString& one, const CString& two);
714 CString AppendRegKeyPath(const CString& one,
715 const CString& two,
716 const CString& three);
717
718 // Returns the list of user keys that are present within the HKEY_USERS key
719 // the method only returns the keys of the users and takes care of,
720 // removing the well known sids. The returned values are the complete values
721 // from the root of the registry
722 HRESULT GetUserKeysFromHkeyUsers(std::vector<CString>* key_names);
723
724 // Use when a function should be able to
725 // be replaced with another implementation. Usually,
726 // this is done for testing code only.
727 //
728 // Typical usage:
729 //
730 // typedef bool BoolPreferenceFunctionType();
731 // CallInterceptor<BoolPreferenceFunctionType> should_send_stats_interceptor;
732 // BoolPreferenceFunctionType* ReplaceShouldSendStatsFunction(
733 // BoolPreferenceFunctionType* replacement) {
734 // return should_send_stats_interceptor.ReplaceFunction(replacement);
735 // }
736 template <typename R>
737 class CallInterceptor {
738 public:
739 CallInterceptor() {
740 interceptor_ = NULL;
741 }
742
743 R* ReplaceFunction(R* replacement) {
744 R* old = interceptor_;
745 interceptor_ = replacement;
746 return old;
747 }
748
749 R* interceptor() {
750 return interceptor_;
751 }
752
753 private:
754 R* interceptor_;
755 DISALLOW_EVIL_CONSTRUCTORS(CallInterceptor);
756 };
757
758 // Gets a handle of the current process. The handle is a real handle
759 // and the caller must close it
760 HRESULT GetCurrentProcessHandle(HANDLE* handle);
761
762 // Duplicates the given token from the source_process into the current process.
763 HRESULT DuplicateTokenIntoCurrentProcess(HANDLE source_process,
764 HANDLE token_to_duplicate,
765 CAccessToken* duplicated_token);
766
767 // Helper class for an ATL module that registers a custom AccessPermission
768 // to allow local calls from interactive users and the system account.
769 // Derive from this class as well as CAtlModuleT (or a derivative).
770 // Override RegisterAppId() and UnregisterAppId(), and delegate to the
771 // corresponding functions in this class.
772 template <class T>
773 class LocalCallAccessPermissionHelper {
774 public:
775 HRESULT RegisterAppId() throw() {
776 // Local call permissions allowed for Interactive Users and Local System
777 static LPCTSTR ALLOW_LOCAL_CALL_SDDL =
778 _T("O:BAG:BAD:(A;;0x3;;;IU)(A;;0x3;;;SY)");
779
780 UTIL_LOG(L1, (_T("[LocalCallAccessPermissionHelper::RegisterAppId]")));
781
782 // First call the base ATL module implementation, so the AppId is registered
783 RET_IF_FAILED(T::UpdateRegistryAppId(TRUE));
784
785 // Next, write the AccessPermission value
786 RegKey key_app_id;
787 RET_IF_FAILED(key_app_id.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE));
788
789 RegKey key;
790 RET_IF_FAILED(key.Create(key_app_id.Key(), T::GetAppIdT()));
791 CSecurityDesc sd;
792 RET_IF_FALSE(sd.FromString(ALLOW_LOCAL_CALL_SDDL), HRESULTFromLastError());
793 RET_IF_FAILED(key.SetValue(
794 _T("AccessPermission"),
795 reinterpret_cast<const byte*>(sd.GetPSECURITY_DESCRIPTOR()),
796 sd.GetLength()));
797
798 UTIL_LOG(L1, (_T("[LocalCallAccessPermissionHelper::RegisterAppId]")
799 _T("[succeeded]")));
800 return S_OK;
801 }
802
803 HRESULT UnregisterAppId() throw() {
804 // First remove the AccesPermission entry.
805 RegKey key_app_id;
806 RET_IF_FAILED(key_app_id.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE));
807
808 RegKey key;
809 RET_IF_FAILED(key.Open(key_app_id.Key(), T::GetAppIdT(), KEY_WRITE));
810 VERIFY1(SUCCEEDED(key.DeleteValue(_T("AccessPermission"))));
811
812 // Now, call the base ATL module implementation to unregister the AppId
813 RET_IF_FAILED(T::UpdateRegistryAppId(FALSE));
814
815 UTIL_LOG(L1, (_T("[LocalCallAccessPermissionHelper::UnregisterAppId'")
816 _T("[succeeded]")));
817 return S_OK;
818 }
819 };
820
821 // Returns true if the argument is a guid.
822 inline bool IsGuid(const TCHAR* s) {
823 if (!s) return false;
824 GUID guid = {0};
825 return SUCCEEDED(StringToGuidSafe(s, &guid));
826 }
827
828 inline bool IsLocalSystemSid(const TCHAR* sid) {
829 ASSERT1(sid);
830 return _tcsicmp(sid, kLocalSystemSid) == 0;
831 }
832
833 // Fills a buffer with cryptographically random bytes.
834 bool GenRandom(void* buffer, size_t buffer_length);
835
836 // Deletes an object. The functor is useful in for_each algorithms.
837 struct DeleteFun {
838 template <class T> void operator()(T ptr) { delete ptr; }
839 };
840
841 // Sets or clears the specified value in the Run key to the specified command.
842 HRESULT ConfigureRunAtStartup(const CString& root_key_name,
843 const CString& run_value_name,
844 const CString& command,
845 bool install);
846
847 // Cracks a command line and returns the program name, which is the first
848 // whitespace separated token.
849 HRESULT GetExePathFromCommandLine(const TCHAR* command_line,
850 CString* exe_path);
851
852 // Waits for MSI to complete, if MSI is busy installing or uninstalling apps.
853 HRESULT WaitForMSIExecute(int timeout_ms);
854
855 // Returns the value of the specified environment variable.
856 CString GetEnvironmentVariableAsString(const TCHAR* name);
857
858 // Returns true if the OS is installing (e.g., Audit Mode at an OEM factory).
859 // NOTE: This is unreliable on Windows Vista and later. Some computers remain in
860 // one of the incomplete states even after OOBE. See http://b/1690617.
861 bool IsWindowsInstalling();
862
863 // TODO(omaha): unit test.
864 inline uint64 GetGuidMostSignificantUint64(const GUID& guid) {
865 return (static_cast<uint64>(guid.Data1) << 32) +
866 (static_cast<uint64>(guid.Data2) << 16) +
867 static_cast<uint64>(guid.Data3);
868 }
869
870 // Calls either ATL::InterlockedExchangePointer if ATL headers are included,
871 // or ::InterlockedExchangePointer. ATL slightly redefines the SDK function
872 // with the same name.
873 template <typename T>
874 inline T* interlocked_exchange_pointer(T* volatile * target,
875 const T* value) {
876 return static_cast<T*>(InterlockedExchangePointer(
877 reinterpret_cast<void**>(const_cast<T**>(target)),
878 const_cast<T*>(value)));
879 }
880
881 // Gets a guid from the system (for user id, etc.)
882 // The guid will be of the form: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
883 HRESULT GetGuid(CString* guid);
884
885 // Returns the message for an error code in the user's language or an
886 // empty string if an error occurs. The function does not support
887 // "insert sequences". The sequence will be returned in the string.
888 CString GetMessageForSystemErrorCode(DWORD error_code);
889
890 // Ceil function for integer types. Returns the quotient of the two
891 // numbers (m/n) rounded upwards to the nearest integer.
892 // T should be unsigned integer type, such as unsigned short, unsigned long,
893 // unsigned int etc.
894 template <typename T>
895 inline T CeilingDivide(T m, T n) {
896 ASSERT1(n != 0);
897
898 return (m + n - 1) / n;
899 }
900
901 } // namespace omaha
902
903 #endif // OMAHA_BASE_UTILS_H_
OLDNEW
« no previous file with comments | « base/user_rights_unittest.cc ('k') | base/utils.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698