OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/app/google_update_client.h" | |
6 | |
7 #include <shlobj.h> | |
8 #include <strsafe.h> | |
9 | |
10 #include "chrome/app/client_util.h" | |
11 #include "chrome/installer/util/google_update_constants.h" | |
12 #include "chrome/installer/util/install_util.h" | |
13 | |
14 namespace { | |
15 // Allocates the out param on success. | |
16 bool GoogleUpdateEnvQueryStr(const wchar_t* key_name, wchar_t** out) { | |
17 DWORD count = ::GetEnvironmentVariableW(key_name, NULL, 0); | |
18 if (!count) { | |
19 return false; | |
20 } | |
21 wchar_t* value = new wchar_t[count + 1]; | |
22 if (!::GetEnvironmentVariableW(key_name, value, count)) { | |
23 delete[] value; | |
24 return false; | |
25 } | |
26 *out = value; | |
27 return true; | |
28 } | |
29 } // anonymous namespace | |
30 | |
31 namespace google_update { | |
32 | |
33 GoogleUpdateClient::GoogleUpdateClient() : version_(NULL) { | |
34 } | |
35 | |
36 GoogleUpdateClient::~GoogleUpdateClient() { | |
37 delete[] version_; | |
38 } | |
39 | |
40 std::wstring GoogleUpdateClient::GetDLLFullPath() { | |
41 return client_util::GetDLLPath(dll_, dll_path_); | |
42 } | |
43 | |
44 std::wstring GoogleUpdateClient::GetDLLPath() { | |
45 return dll_path_; | |
46 } | |
47 | |
48 const wchar_t* GoogleUpdateClient::GetVersion() const { | |
49 return version_; | |
50 } | |
51 | |
52 bool GoogleUpdateClient::Launch(HINSTANCE instance, | |
53 sandbox::SandboxInterfaceInfo* sandbox, | |
54 wchar_t* command_line, | |
55 const char* entry_name, | |
56 int* ret) { | |
57 if (client_util::FileExists(dll_path_)) { | |
58 // Setting the version on the environment block is a 'best effort' deal. | |
59 // It enables Google Update running on a child to load the same DLL version. | |
60 ::SetEnvironmentVariableW(google_update::kEnvProductVersionKey, version_); | |
61 } | |
62 | |
63 // The dll can be in the exe's directory or in the current directory. | |
64 // Use the alternate search path to be sure that it's not trying to load it | |
65 // calling application's directory. | |
66 HINSTANCE dll_handle = ::LoadLibraryEx(dll_.c_str(), NULL, | |
67 LOAD_WITH_ALTERED_SEARCH_PATH); | |
68 if (NULL == dll_handle) { | |
69 unsigned long err = GetLastError(); | |
70 if (err) { | |
71 WCHAR message[500] = {0}; | |
72 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, | |
73 reinterpret_cast<LPWSTR>(&message), 500, NULL); | |
74 ::OutputDebugStringW(message); | |
75 } | |
76 return false; | |
77 } | |
78 | |
79 bool did_launch = false; | |
80 client_util::DLL_MAIN entry = reinterpret_cast<client_util::DLL_MAIN>( | |
81 ::GetProcAddress(dll_handle, entry_name)); | |
82 if (NULL != entry) { | |
83 // record did_run "dr" in client state | |
84 std::wstring key_path(google_update::kRegPathClientState); | |
85 key_path.append(L"\\" + guid_); | |
86 HKEY reg_key; | |
87 if (::RegCreateKeyEx(HKEY_CURRENT_USER, key_path.c_str(), 0, NULL, | |
88 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, | |
89 ®_key, NULL) == ERROR_SUCCESS) { | |
90 const wchar_t kVal[] = L"1"; | |
91 ::RegSetValueEx(reg_key, google_update::kRegDidRunField, 0, REG_SZ, | |
92 reinterpret_cast<const BYTE *>(kVal), sizeof(kVal)); | |
93 ::RegCloseKey(reg_key); | |
94 } | |
95 | |
96 int rc = (entry)(instance, sandbox, command_line); | |
97 if (ret) { | |
98 *ret = rc; | |
99 } | |
100 did_launch = true; | |
101 } | |
102 #ifdef PURIFY | |
103 // We should never unload the dll. There is only risk and no gain from | |
104 // doing so. The singleton dtors have been already run by AtExitManager. | |
105 ::FreeLibrary(dll_handle); | |
106 #endif | |
107 return did_launch; | |
108 } | |
109 | |
110 bool GoogleUpdateClient::Init(const wchar_t* client_guid, | |
111 const wchar_t* client_dll) { | |
112 dll_path_ = client_util::GetExecutablePath(); | |
113 guid_.assign(client_guid); | |
114 dll_.assign(client_dll); | |
115 bool ret = false; | |
116 if (!guid_.empty()) { | |
117 if (GoogleUpdateEnvQueryStr(google_update::kEnvProductVersionKey, | |
118 &version_)) { | |
119 ret = true; | |
120 } else { | |
121 std::wstring key(google_update::kRegPathClients); | |
122 key.append(L"\\" + guid_); | |
123 if (client_util::GetChromiumVersion(dll_path_.c_str(), | |
124 key.c_str(), | |
125 &version_)) | |
126 ret = true; | |
127 } | |
128 } | |
129 | |
130 if (version_) { | |
131 dll_path_.append(version_); | |
132 } | |
133 return ret; | |
134 } | |
135 } // namespace google_update | |
OLD | NEW |