Chromium Code Reviews| Index: chrome_frame/chrome_frame_helper_main.cc |
| =================================================================== |
| --- chrome_frame/chrome_frame_helper_main.cc (revision 85906) |
| +++ chrome_frame/chrome_frame_helper_main.cc (working copy) |
| @@ -13,9 +13,12 @@ |
| // |
| #include <crtdbg.h> |
| +#include <objbase.h> |
| #include <windows.h> |
| +#include <string> |
| #include "chrome_frame/crash_server_init.h" |
| +#include "chrome_frame/chrome_frame_helper_util.h" |
|
grt (UTC plus 2)
2011/05/25 16:10:07
move this above the previous line
robertshield
2011/05/26 15:14:28
Done.
|
| // Window class and window names. |
|
grt (UTC plus 2)
2011/05/25 16:10:07
nit: wrap as much of this as reasonable in namespa
robertshield
2011/05/26 15:14:28
Done.
|
| const wchar_t kChromeFrameHelperWindowClassName[] = |
| @@ -23,6 +26,15 @@ |
| const wchar_t kChromeFrameHelperWindowName[] = |
| L"ChromeFrameHelperWindowName"; |
| +const wchar_t kChromeFrameClientStateKey[] = |
| + L"Software\\Google\\Update\\ClientState\\" |
| + L"{8BA986DA-5100-405E-AA35-86F34A02ACBF}\\"; |
|
grt (UTC plus 2)
2011/05/25 16:10:07
nit: I don't think we usually have a trailing sepa
robertshield
2011/05/26 15:14:28
Done.
|
| +const wchar_t kChromeFrameUninstallCmdExeValue[] = L"UninstallString"; |
| +const wchar_t kChromeFrameUninstallCmdArgsValue[] = L"UninstallArguments"; |
| + |
| +const wchar_t kFirstRunArg[] = L"--first-run"; |
| +const wchar_t kForceUninstall[] = L"--force-uninstall"; |
| + |
| // Small helper class that assists in loading the DLL that contains code |
| // to register our event hook callback. Automatically removes the hook and |
| // unloads the DLL on destruction. |
| @@ -133,11 +145,79 @@ |
| return hwnd; |
| } |
| + |
| +// This method runs the user-level Chrome Frame uninstall command. This is |
| +// intended to allow it to delegate to an existing system-level install. |
| +bool UninstallUserLevelChromeFrame() { |
| + bool success = false; |
| + HKEY reg_handle = NULL; |
| + wchar_t reg_path_buffer[MAX_PATH] = {0}; |
| + LONG result = RegOpenKeyEx(HKEY_CURRENT_USER, |
| + kChromeFrameClientStateKey, |
| + 0, |
| + KEY_READ, |
|
grt (UTC plus 2)
2011/05/25 16:10:07
KEY_READ -> KEY_QUERY_VALUE
robertshield
2011/05/26 15:14:28
Done.
|
| + ®_handle); |
| + if (result == ERROR_SUCCESS) { |
| + wchar_t exe_buffer[MAX_PATH] = {0}; |
| + wchar_t args_buffer[MAX_PATH] = {0}; |
| + LONG exe_result = ReadValue(reg_handle, |
| + kChromeFrameUninstallCmdExeValue, |
| + MAX_PATH, |
| + exe_buffer); |
| + LONG args_result = ReadValue(reg_handle, |
| + kChromeFrameUninstallCmdArgsValue, |
| + MAX_PATH, |
| + args_buffer); |
| + |
|
grt (UTC plus 2)
2011/05/25 16:10:07
Consider moving RegCloseKey(reg_handle); reg_handl
robertshield
2011/05/26 15:14:28
Done.
|
| + if (exe_result == ERROR_SUCCESS && args_result == ERROR_SUCCESS) { |
| + STARTUPINFO startup_info = {0}; |
| + startup_info.cb = sizeof(startup_info); |
| + startup_info.dwFlags = STARTF_USESHOWWINDOW; |
| + startup_info.wShowWindow = SW_SHOW; |
| + PROCESS_INFORMATION process_info = {0}; |
| + |
| + // Quote the command string in the args. |
| + std::wstring args(L"\""); |
|
amit
2011/05/24 22:36:50
nit: size concern - if we are using std::string ju
grt (UTC plus 2)
2011/05/25 16:10:07
Agreed. The rest of the code seems to bend over t
robertshield
2011/05/26 15:14:28
Done.
robertshield
2011/05/26 15:14:28
Done.
|
| + args += exe_buffer; |
| + args += L"\" "; |
| + args += args_buffer; |
| + // Make sure the uninstall is silent. |
| + args += L"\" "; |
| + args += kForceUninstall; |
| + |
| + if (CreateProcess(exe_buffer, &args[0], |
| + NULL, NULL, FALSE, 0, NULL, NULL, |
| + &startup_info, &process_info)) { |
| + // Close handles. |
| + CloseHandle(process_info.hThread); |
| + CloseHandle(process_info.hProcess); |
| + success = true; |
| + } |
| + } |
| + RegCloseKey(reg_handle); |
| + } |
| + |
| + return success; |
| +} |
| + |
| + |
| int APIENTRY wWinMain(HINSTANCE hinstance, HINSTANCE, wchar_t*, int show_cmd) { |
| const wchar_t* cmd_line = ::GetCommandLine(); |
| google_breakpad::scoped_ptr<google_breakpad::ExceptionHandler> breakpad( |
| InitializeCrashReporting(cmd_line)); |
| + if (IsSystemLevelChromeFrameInstalled()) { |
| + // If we're running at startup, check for system-level Chrome Frame |
| + // installations. If we have one, time |
| + // to bail, also schedule user-level CF to be uninstalled at next logon. |
| + const wchar_t* cmd_line = ::GetCommandLine(); |
| + if (cmd_line && wcsstr(cmd_line, kFirstRunArg) != NULL) { |
| + bool uninstalled = UninstallUserLevelChromeFrame(); |
| + _ASSERTE(uninstalled); |
| + } |
| + return 0; |
| + } |
| + |
| // Create a window with a known class and title just to listen for WM_CLOSE |
| // messages that will shut us down. |
| HWND hwnd = RegisterAndCreateWindow(hinstance); |