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

Side by Side Diff: chrome_frame/chrome_frame_helper_main.cc

Issue 7065024: Add a self-destruct mechanism to user-level Chrome Frame when it detects that system-level Chrome... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // chrome_frame_helper_main.cc : The .exe that bootstraps the 5 // chrome_frame_helper_main.cc : The .exe that bootstraps the
6 // chrome_frame_helper.dll. 6 // chrome_frame_helper.dll.
7 // 7 //
8 // This is a small exe that loads the hook dll to set the event hooks and then 8 // This is a small exe that loads the hook dll to set the event hooks and then
9 // waits in a message loop. It is intended to be shut down by looking for a 9 // waits in a message loop. It is intended to be shut down by looking for a
10 // window with the class and title 10 // window with the class and title
11 // kChromeFrameHelperWindowClassName and kChromeFrameHelperWindowName and then 11 // kChromeFrameHelperWindowClassName and kChromeFrameHelperWindowName and then
12 // sending that window a WM_CLOSE message. 12 // sending that window a WM_CLOSE message.
13 // 13 //
14 14
15 #include <crtdbg.h> 15 #include <crtdbg.h>
16 #include <objbase.h>
16 #include <windows.h> 17 #include <windows.h>
17 18
19 #include "chrome_frame/chrome_frame_helper_util.h"
18 #include "chrome_frame/crash_server_init.h" 20 #include "chrome_frame/crash_server_init.h"
21 #include "chrome_frame/registry_watcher.h"
19 22
23 namespace {
20 // Window class and window names. 24 // Window class and window names.
grt (UTC plus 2) 2011/05/26 17:08:58 nit: newline before this
robertshield 2011/05/27 03:34:59 Done.
21 const wchar_t kChromeFrameHelperWindowClassName[] = 25 const wchar_t kChromeFrameHelperWindowClassName[] =
22 L"ChromeFrameHelperWindowClass"; 26 L"ChromeFrameHelperWindowClass";
23 const wchar_t kChromeFrameHelperWindowName[] = 27 const wchar_t kChromeFrameHelperWindowName[] =
24 L"ChromeFrameHelperWindowName"; 28 L"ChromeFrameHelperWindowName";
25 29
30 const wchar_t kChromeFrameClientStateKey[] =
31 L"Software\\Google\\Update\\ClientState\\"
32 L"{8BA986DA-5100-405E-AA35-86F34A02ACBF}";
33 const wchar_t kChromeFrameUninstallCmdExeValue[] = L"UninstallString";
34 const wchar_t kChromeFrameUninstallCmdArgsValue[] = L"UninstallArguments";
35
36 const wchar_t kBHORegistrationPath[] =
37 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer"
38 L"\\Browser Helper Objects";
39
40 const wchar_t kStartupArg[] = L"--startup";
41 const wchar_t kForceUninstall[] = L"--force-uninstall";
42
43 HWND g_hwnd = NULL;
44 const UINT kRegistryWatcherChangeMessage = WM_USER + 42;
45
46 } // namespace
47
26 // Small helper class that assists in loading the DLL that contains code 48 // Small helper class that assists in loading the DLL that contains code
27 // to register our event hook callback. Automatically removes the hook and 49 // to register our event hook callback. Automatically removes the hook and
28 // unloads the DLL on destruction. 50 // unloads the DLL on destruction.
29 class HookDllLoader { 51 class HookDllLoader {
30 public: 52 public:
31 HookDllLoader() : dll_(NULL), start_proc_(NULL), stop_proc_(NULL) {} 53 HookDllLoader() : dll_(NULL), start_proc_(NULL), stop_proc_(NULL) {}
32 ~HookDllLoader() { 54 ~HookDllLoader() {
33 if (dll_) { 55 if (dll_) {
34 Unload(); 56 Unload();
35 } 57 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 } 123 }
102 124
103 LRESULT CALLBACK ChromeFrameHelperWndProc(HWND hwnd, 125 LRESULT CALLBACK ChromeFrameHelperWndProc(HWND hwnd,
104 UINT message, 126 UINT message,
105 WPARAM wparam, 127 WPARAM wparam,
106 LPARAM lparam) { 128 LPARAM lparam) {
107 switch (message) { 129 switch (message) {
108 case WM_CREATE: 130 case WM_CREATE:
109 CloseAllHelperWindowsApartFrom(hwnd); 131 CloseAllHelperWindowsApartFrom(hwnd);
110 break; 132 break;
133 case kRegistryWatcherChangeMessage:
134 // A system level Chrome appeared. Fall through:
111 case WM_DESTROY: 135 case WM_DESTROY:
112 PostQuitMessage(0); 136 PostQuitMessage(0);
113 break; 137 break;
114 default: 138 default:
115 return ::DefWindowProc(hwnd, message, wparam, lparam); 139 return ::DefWindowProc(hwnd, message, wparam, lparam);
116 } 140 }
117 return 0; 141 return 0;
118 } 142 }
119 143
120 HWND RegisterAndCreateWindow(HINSTANCE hinstance) { 144 HWND RegisterAndCreateWindow(HINSTANCE hinstance) {
121 WNDCLASSEX wcex = {0}; 145 WNDCLASSEX wcex = {0};
122 wcex.cbSize = sizeof(WNDCLASSEX); 146 wcex.cbSize = sizeof(WNDCLASSEX);
123 wcex.lpfnWndProc = ChromeFrameHelperWndProc; 147 wcex.lpfnWndProc = ChromeFrameHelperWndProc;
124 wcex.hInstance = GetModuleHandle(NULL); 148 wcex.hInstance = GetModuleHandle(NULL);
125 wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1); 149 wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
126 wcex.lpszClassName = kChromeFrameHelperWindowClassName; 150 wcex.lpszClassName = kChromeFrameHelperWindowClassName;
127 RegisterClassEx(&wcex); 151 RegisterClassEx(&wcex);
128 152
129 HWND hwnd = CreateWindow(kChromeFrameHelperWindowClassName, 153 HWND hwnd = CreateWindow(kChromeFrameHelperWindowClassName,
130 kChromeFrameHelperWindowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 154 kChromeFrameHelperWindowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
131 CW_USEDEFAULT, 0, NULL, NULL, hinstance, NULL); 155 CW_USEDEFAULT, 0, NULL, NULL, hinstance, NULL);
132 156
133 return hwnd; 157 return hwnd;
134 } 158 }
135 159
160
161 // This method runs the user-level Chrome Frame uninstall command. This is
162 // intended to allow it to delegate to an existing system-level install.
163 bool UninstallUserLevelChromeFrame() {
164 bool success = false;
165 HKEY reg_handle = NULL;
166 wchar_t reg_path_buffer[MAX_PATH] = {0};
167 LONG result = RegOpenKeyEx(HKEY_CURRENT_USER,
168 kChromeFrameClientStateKey,
169 0,
170 KEY_QUERY_VALUE,
171 &reg_handle);
172 if (result == ERROR_SUCCESS) {
173 wchar_t exe_buffer[MAX_PATH] = {0};
174 wchar_t args_buffer[MAX_PATH] = {0};
175 LONG exe_result = ReadValue(reg_handle,
176 kChromeFrameUninstallCmdExeValue,
177 MAX_PATH,
178 exe_buffer);
179 LONG args_result = ReadValue(reg_handle,
180 kChromeFrameUninstallCmdArgsValue,
181 MAX_PATH,
182 args_buffer);
183 RegCloseKey(reg_handle);
184 reg_handle = NULL;
185
186 if (exe_result == ERROR_SUCCESS && args_result == ERROR_SUCCESS) {
187 STARTUPINFO startup_info = {0};
188 startup_info.cb = sizeof(startup_info);
189 startup_info.dwFlags = STARTF_USESHOWWINDOW;
190 startup_info.wShowWindow = SW_SHOW;
191 PROCESS_INFORMATION process_info = {0};
192
193 // Quote the command string in the args.
194 wchar_t argument_string[MAX_PATH * 3] = {0};
195 _snwprintf(argument_string,
grt (UTC plus 2) 2011/05/26 17:08:58 int argument_string_len = _snwprintf(...); if (arg
robertshield 2011/05/27 03:34:59 Done.
196 MAX_PATH * 3,
grt (UTC plus 2) 2011/05/26 17:08:58 _countof(argument_string) would be more safe, no?
robertshield 2011/05/27 03:34:59 _countof() - 1, just to ensure that the string rem
grt (UTC plus 2) 2011/05/27 14:07:58 Good call.
197 L"\"%s\" %s %s",
198 exe_buffer,
199 args_buffer,
200 kForceUninstall);
201
202 if (CreateProcess(exe_buffer, argument_string,
203 NULL, NULL, FALSE, 0, NULL, NULL,
204 &startup_info, &process_info)) {
205 // Close handles.
206 CloseHandle(process_info.hThread);
207 CloseHandle(process_info.hProcess);
208 success = true;
209 }
210 }
211 }
212
213 return success;
214 }
215
216 void CALLBACK WaitCallback(void* param, BOOLEAN wait_fired) {
217 RegistryWatcher* watcher = reinterpret_cast<RegistryWatcher*>(param);
218 if (watcher->stopping())
219 return;
220
221 // Check if the Chrome Frame BHO is now in the list of registered BHOs:
222 if (IsBHOLoadingPolicyRegistered()) {
223 // Post message.
grt (UTC plus 2) 2011/05/26 17:08:58 This comment adds nothing. Please either make it
robertshield 2011/05/27 03:34:59 Done.
224 PostMessage(g_hwnd, kRegistryWatcherChangeMessage, 0, 0);
225 }
226 }
227
136 int APIENTRY wWinMain(HINSTANCE hinstance, HINSTANCE, wchar_t*, int show_cmd) { 228 int APIENTRY wWinMain(HINSTANCE hinstance, HINSTANCE, wchar_t*, int show_cmd) {
137 const wchar_t* cmd_line = ::GetCommandLine(); 229 const wchar_t* cmd_line = ::GetCommandLine();
138 google_breakpad::scoped_ptr<google_breakpad::ExceptionHandler> breakpad( 230 google_breakpad::scoped_ptr<google_breakpad::ExceptionHandler> breakpad(
139 InitializeCrashReporting(cmd_line)); 231 InitializeCrashReporting(cmd_line));
140 232
233 if (IsSystemLevelChromeFrameInstalled()) {
234 // If we're running at startup, check for system-level Chrome Frame
235 // installations. If we have one, time
236 // to bail, also schedule user-level CF to be uninstalled at next logon.
237 const wchar_t* cmd_line = ::GetCommandLine();
238 if (cmd_line && wcsstr(cmd_line, kStartupArg) != NULL) {
239 bool uninstalled = UninstallUserLevelChromeFrame();
240 _ASSERTE(uninstalled);
241 }
242 return 0;
243 }
244
141 // Create a window with a known class and title just to listen for WM_CLOSE 245 // Create a window with a known class and title just to listen for WM_CLOSE
142 // messages that will shut us down. 246 // messages that will shut us down.
143 HWND hwnd = RegisterAndCreateWindow(hinstance); 247 g_hwnd = RegisterAndCreateWindow(hinstance);
144 _ASSERTE(hwnd); 248 _ASSERTE(IsWindow(g_hwnd));
145 249
146 // Load the hook dll, and set the event hooks. 250 // Load the hook dll, and set the event hooks.
147 HookDllLoader loader; 251 HookDllLoader loader;
148 bool loaded = loader.Load(); 252 bool loaded = loader.Load();
149 _ASSERTE(loaded); 253 _ASSERTE(loaded);
150 254
255 // Start up the registry watcher
256 RegistryWatcher registry_watcher(HKEY_LOCAL_MACHINE, kBHORegistrationPath,
257 WaitCallback);
258 bool watching = registry_watcher.StartWatching();
259 _ASSERTE(watching);
260
151 if (loaded) { 261 if (loaded) {
152 MSG msg; 262 MSG msg;
153 BOOL ret; 263 BOOL ret;
154 // Main message loop: 264 // Main message loop:
155 while ((ret = GetMessage(&msg, NULL, 0, 0))) { 265 while ((ret = GetMessage(&msg, NULL, 0, 0))) {
156 if (ret == -1) { 266 if (ret == -1) {
157 break; 267 break;
158 } else { 268 } else {
159 TranslateMessage(&msg); 269 TranslateMessage(&msg);
160 DispatchMessage(&msg); 270 DispatchMessage(&msg);
161 } 271 }
162 } 272 }
163 } 273 }
164 274
165 UnregisterClass(kChromeFrameHelperWindowClassName, hinstance); 275 UnregisterClass(kChromeFrameHelperWindowClassName, hinstance);
166 return 0; 276 return 0;
167 } 277 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698