diff options
author | rahulk@google.com <rahulk@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-22 21:16:47 +0000 |
---|---|---|
committer | rahulk@google.com <rahulk@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-22 21:16:47 +0000 |
commit | c9349d08ebc302d91d695f7abef4750d64a5dc31 (patch) | |
tree | 3c1e7a1e47a3efa2e1882230b8e03b118a14366f /chrome/app/google_update_client.cc | |
parent | 2d5cdce4c2389657ad844a2456f00759806c2371 (diff) | |
download | chromium_src-c9349d08ebc302d91d695f7abef4750d64a5dc31.zip chromium_src-c9349d08ebc302d91d695f7abef4750d64a5dc31.tar.gz chromium_src-c9349d08ebc302d91d695f7abef4750d64a5dc31.tar.bz2 |
Make chrome.exe read version from Software\Chromium instead of Google Update keys when running Chromium. With this change
now we can build a Chromium release that gets installed under Application Data\Chromium and actually runs.
- Added a new file that has common functions used by google update client and chromium
- Did some minor cleanup based on readability guidelines (alphabatical order etc).
- We seem to be trying to avoid std::wstring at some places but are using it at other places. In future we should be just able to use std::wstring and get rid of StringCchDup.
BUG=1296800
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1243 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/app/google_update_client.cc')
-rw-r--r-- | chrome/app/google_update_client.cc | 222 |
1 files changed, 64 insertions, 158 deletions
diff --git a/chrome/app/google_update_client.cc b/chrome/app/google_update_client.cc index a8cd8af..8001916 100644 --- a/chrome/app/google_update_client.cc +++ b/chrome/app/google_update_client.cc @@ -32,67 +32,19 @@ #include <shlobj.h> #include <strsafe.h> -namespace google_update { +#include "chrome/app/client_util.h" +namespace { const wchar_t kRegistryClients[] = L"Software\\Google\\Update\\Clients\\"; const wchar_t kRegistryClientState[] = L"Software\\Google\\Update\\ClientState\\"; -const wchar_t kRequestParamProductVersion[] = L"pv"; const wchar_t kRequestParamDidRun[] = L"dr"; const wchar_t kRegistryUpdate[] = L"Software\\Google\\Update\\"; const wchar_t kRegistryValueCrashReportPath[] = L"CrashReportPath"; const wchar_t kEnvProductVersionKey[] = L"CHROME_VERSION"; -// We're using raw wchar_t everywhere rather than relying on CString or wstring -// to reduce dependencies and make it easier for different apps and libraries -// to use this source code. For similar reasons, we're avoiding using msvcrt -// functions. This is also why this is implemented rather than just using -// _tcsdup. -// TODO(erikkay): add unit test for this function -static HRESULT StringCchDup(wchar_t** dst, const wchar_t* src) { - // TODO(erikkay): ASSERT(src), ASSERT(dst) - size_t len = 0; - *dst = NULL; - HRESULT hr = ::StringCchLength(src, STRSAFE_MAX_CCH, &len); - if (SUCCEEDED(hr)) { - len++; - *dst = new wchar_t[len]; - hr = ::StringCchCopy(*dst, len, src); - if (FAILED(hr)) { - delete[] *dst; - *dst = NULL; - } - } - return hr; -} - -static bool FileExists(const wchar_t* filename) { - WIN32_FILE_ATTRIBUTE_DATA attrs; - return ::GetFileAttributesEx(filename, GetFileExInfoStandard, &attrs) != 0; -} - -// Allocates the out param on success. -static bool GoogleUpdateRegQueryStr(HKEY key, const wchar_t* val, - wchar_t** out) { - DWORD size = 0; - LONG ret; - ret = ::RegQueryValueEx(key, val, NULL, NULL, NULL, &size); - if (ERROR_SUCCESS == ret) { - DWORD len = 1 + (size / sizeof(wchar_t)); - *out = new wchar_t[len]; - ret = ::RegQueryValueEx(key, val, NULL, NULL, - reinterpret_cast<BYTE* >(*out), &size); - if (ERROR_SUCCESS == ret) { - return true; - } else { - delete[] *out; - } - } - return false; -} - // Allocates the out param on success. -static bool GoogleUpdateEnvQueryStr(const wchar_t* key_name, wchar_t** out) { +bool GoogleUpdateEnvQueryStr(const wchar_t* key_name, wchar_t** out) { DWORD count = ::GetEnvironmentVariableW(key_name, NULL, 0); if (!count) { return false; @@ -105,57 +57,44 @@ static bool GoogleUpdateEnvQueryStr(const wchar_t* key_name, wchar_t** out) { *out = value; return true; } +} // anonymous namespace -const wchar_t* GoogleUpdateClient::GetVersion() const { - return version_; -} +namespace google_update { -void GoogleUpdateClient::GetExePathAndInstallMode() { - dll_path_[0] = 0; - user_mode_ = true; +GoogleUpdateClient::GoogleUpdateClient() : version_(NULL) { +} - wchar_t buffer[MAX_PATH] = {0}; - DWORD len = ::GetModuleFileName(NULL, dll_path_, MAX_PATH); - if (!FAILED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, - SHGFP_TYPE_CURRENT, buffer))) { - if (dll_path_ == wcsstr(dll_path_, buffer)) { - user_mode_ = false; - } - } - // TODO(erikkay): ASSERT on len == 0 - wchar_t* t = dll_path_ + len - 1; - while (t >= dll_path_ && *t != L'\\') { - t--; - } - if (t > dll_path_) { - t++; - *t = 0; - } +GoogleUpdateClient::~GoogleUpdateClient() { + delete[] version_; } std::wstring GoogleUpdateClient::GetDLLPath() { - if (FileExists(dll_path_)) + if (client_util::FileExists(dll_path_)) return std::wstring(dll_path_) + L"\\" + dll_; // This is not an official build. Find the dll using the default // path order in LoadLibrary. wchar_t path[MAX_PATH] = {0}; wchar_t* file_part = NULL; - DWORD result = ::SearchPath(NULL, dll_, NULL, MAX_PATH, path, &file_part); + DWORD result = ::SearchPath(NULL, dll_.c_str(), NULL, MAX_PATH, + path, &file_part); if (result == 0 || result > MAX_PATH) return std::wstring(); return path; } -bool GoogleUpdateClient::Launch(HINSTANCE instance, HINSTANCE prev_instance, - wchar_t* command_line, int show_command, - const char* entry_name, int* ret) { - // TODO(erikkay): ASSERT(guid_) +const wchar_t* GoogleUpdateClient::GetVersion() const { + return version_; +} - bool did_launch = false; - if (FileExists(dll_path_)) { - const size_t dll_path_len = wcslen(dll_path_); +bool GoogleUpdateClient::Launch(HINSTANCE instance, + sandbox::SandboxInterfaceInfo* sandbox, + wchar_t* command_line, + int show_command, + const char* entry_name, + int* ret) { + if (client_util::FileExists(dll_path_)) { ::SetCurrentDirectory(dll_path_); // Setting the version on the environment block is a 'best effort' deal. // It enables Google Update running on a child to load the same DLL version. @@ -165,46 +104,9 @@ bool GoogleUpdateClient::Launch(HINSTANCE instance, HINSTANCE prev_instance, // The dll can be in the exe's directory or in the current directory. // Use the alternate search path to be sure that it's not trying to load it // calling application's directory. - HINSTANCE dll_handle = ::LoadLibraryEx(dll_, NULL, + HINSTANCE dll_handle = ::LoadLibraryEx(dll_.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - if (NULL != dll_handle) { - GoogleUpdateEntry entry = reinterpret_cast<GoogleUpdateEntry> - (::GetProcAddress(dll_handle, entry_name)); - if (NULL != entry) { - // record did_run in client state - HKEY reg_client_state; - HKEY reg_root = HKEY_LOCAL_MACHINE; - if (user_mode_) { - reg_root = HKEY_CURRENT_USER; - } - - if (::RegOpenKeyEx(reg_root, kRegistryClientState, 0, - KEY_READ, ®_client_state) == ERROR_SUCCESS) { - HKEY reg_client; - if (::RegOpenKeyEx(reg_client_state, guid_, 0, - KEY_WRITE, ®_client) == ERROR_SUCCESS) { - const wchar_t kVal[] = L"1"; - const size_t len = sizeof(kVal); // we want the size in bytes - const BYTE *bytes = reinterpret_cast<const BYTE *>(kVal); - ::RegSetValueEx(reg_client, kRequestParamDidRun, 0, REG_SZ, - bytes, len); - ::RegCloseKey(reg_client); - } - ::RegCloseKey(reg_client_state); - } - - int rc = (entry)(instance, prev_instance, command_line, show_command); - if (ret) { - *ret = rc; - } - did_launch = true; - } -#ifdef PURIFY - // We should never unload the dll. There is only risk and no gain from - // doing so. The singleton dtors have been already run by AtExitManager. - ::FreeLibrary(dll_handle); -#endif - } else { + if (NULL == dll_handle) { unsigned long err = GetLastError(); if (err) { WCHAR message[500] = {0}; @@ -212,40 +114,55 @@ bool GoogleUpdateClient::Launch(HINSTANCE instance, HINSTANCE prev_instance, reinterpret_cast<LPWSTR>(&message), 500, NULL); ::OutputDebugStringW(message); } + return false; + } + + bool did_launch = false; + client_util::DLL_MAIN entry = reinterpret_cast<client_util::DLL_MAIN>( + ::GetProcAddress(dll_handle, entry_name)); + if (NULL != entry) { + // record did_run "dr" in client state + HKEY reg_root = (user_mode_) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; + std::wstring key_path = kRegistryClientState + guid_; + HKEY reg_key; + if (::RegOpenKeyEx(reg_root, key_path.c_str(), 0, + KEY_WRITE, ®_key) == ERROR_SUCCESS) { + const wchar_t kVal[] = L"1"; + ::RegSetValueEx(reg_key, kRequestParamDidRun, 0, REG_SZ, + reinterpret_cast<const BYTE *>(kVal), sizeof(kVal)); + ::RegCloseKey(reg_key); + } + + int rc = (entry)(instance, sandbox, command_line, show_command); + if (ret) { + *ret = rc; + } + did_launch = true; } +#ifdef PURIFY + // We should never unload the dll. There is only risk and no gain from + // doing so. The singleton dtors have been already run by AtExitManager. + ::FreeLibrary(dll_handle); +#endif return did_launch; } -bool GoogleUpdateClient::Init(const wchar_t* client_guid, const wchar_t* client_dll) { - GetExePathAndInstallMode(); +bool GoogleUpdateClient::Init(const wchar_t* client_guid, + const wchar_t* client_dll) { + client_util::GetExecutablePath(dll_path_); + user_mode_ = client_util::IsUserModeInstall(dll_path_); - StringCchDup(&guid_, client_guid); - StringCchDup(&dll_, client_dll); - // TODO(erikkay): ASSERT(guid_) + guid_.assign(client_guid); + dll_.assign(client_dll); bool ret = false; - if (guid_) { + if (!guid_.empty()) { if (GoogleUpdateEnvQueryStr(kEnvProductVersionKey, &version_)) { ret = true; } else { - // Look up the version from Google Update registry. - HKEY reg_clients; - HKEY reg_root = HKEY_LOCAL_MACHINE; - if (user_mode_) { - reg_root = HKEY_CURRENT_USER; - } - if (::RegOpenKeyEx(reg_root, kRegistryClients, 0, - KEY_READ, ®_clients) == ERROR_SUCCESS) { - HKEY reg_client; - if (::RegOpenKeyEx(reg_clients, guid_, 0, KEY_READ, ®_client) == - ERROR_SUCCESS) { - if (GoogleUpdateRegQueryStr(reg_client, kRequestParamProductVersion, - &version_)) { - ret = true; - } - ::RegCloseKey(reg_client); - } - ::RegCloseKey(reg_clients); - } + std::wstring key(kRegistryClients); + key.append(guid_); + if (client_util::GetChromiumVersion(dll_path_, key.c_str(), &version_)) + ret = true; } } @@ -254,15 +171,4 @@ bool GoogleUpdateClient::Init(const wchar_t* client_guid, const wchar_t* client_ } return ret; } - -GoogleUpdateClient::GoogleUpdateClient() - : guid_(NULL), dll_(NULL), version_(NULL) { -} - -GoogleUpdateClient::~GoogleUpdateClient() { - delete[] guid_; - delete[] dll_; - delete[] version_; -} - } // namespace google_update |