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

Side by Side Diff: chrome_frame/chrome_launcher_main.cc

Issue 2278003: Rewrite of chrome_launcher.exe. ETW-based perf tests suggest that this is on ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 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
« no previous file with comments | « chrome_frame/chrome_launcher.cc ('k') | chrome_frame/chrome_launcher_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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
5 #include <windows.h> 6 #include <windows.h>
7 #include <DbgHelp.h>
8 #include <string>
6 9
7 #include "chrome_frame/chrome_launcher.h" 10 #include "chrome_frame/chrome_launcher.h"
11 #include "breakpad/src/client/windows/handler/exception_handler.h"
8 12
9 // We want to keep this EXE tiny, so we avoid all dependencies and link to no 13 // TODO(robertshield): Much of the crash report init code is shared with CF and
10 // libraries, and we do not use the C runtime. 14 // probably Chrome too. If this pans out, consider refactoring it into a
11 // 15 // common lib.
12 // To catch errors in debug builds, we define an extremely simple assert macro.
13 #ifndef NDEBUG
14 #define CLM_ASSERT(x) do { if (!(x)) { ::DebugBreak(); } } while (false)
15 #else
16 #define CLM_ASSERT(x)
17 #endif // NDEBUG
18 16
19 // In release builds, we skip the standard library completely to minimize 17 namespace {
20 // size. This is more work in debug builds, and unnecessary, hence the 18
21 // different signatures. 19 // Possible names for Pipes:
22 #ifndef NDEBUG 20 // Headless (testing) mode: "NamedPipe\ChromeCrashServices"
21 // System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18"
22 // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>"
23 const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices";
24 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
25 const wchar_t kSystemPrincipalSid[] = L"S-1-5-18";
26
27 // Assume this implies headless mode and use kChromePipeName if it shows
28 // up in the command line.
29 const wchar_t kFullMemoryCrashReport[] = L"full-memory-crash-report";
30
31 const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>(
32 MiniDumpWithProcessThreadData | // Get PEB and TEB.
33 MiniDumpWithUnloadedModules | // Get unloaded modules when available.
34 MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by stack.
35
36 } // namespace
37
38 google_breakpad::CustomClientInfo* GetCustomInfo() {
39 // TODO(robertshield): Populate this with actual data.
40 std::wstring product(L"ChromeFrame");
41 std::wstring version(L"0.1.0.0");
42 static google_breakpad::CustomInfoEntry ver_entry(L"ver", version.c_str());
43 static google_breakpad::CustomInfoEntry prod_entry(L"prod", product.c_str());
44 static google_breakpad::CustomInfoEntry plat_entry(L"plat", L"Win32");
45 static google_breakpad::CustomInfoEntry type_entry(L"ptype", L"chrome_frame");
46 static google_breakpad::CustomInfoEntry entries[] = {
47 ver_entry, prod_entry, plat_entry, type_entry };
48 static google_breakpad::CustomClientInfo custom_info = {
49 entries, arraysize(entries) };
50 return &custom_info;
51 }
52
53 google_breakpad::ExceptionHandler* InitializeCrashReporting(
54 const wchar_t* cmd_line) {
55 if (cmd_line == NULL) {
56 return NULL;
57 }
58
59 wchar_t temp_path[MAX_PATH + 1] = {0};
60 DWORD path_len = ::GetTempPath(MAX_PATH, temp_path);
61
62 std::wstring pipe_name;
63 if (wcsstr(cmd_line, kFullMemoryCrashReport) != NULL) {
64 pipe_name = kChromePipeName;
65 } else {
66 // TODO(robertshield): Figure out if we're a per-user install and connect
67 // to the per-user named pipe instead.
68 pipe_name = kGoogleUpdatePipeName;
69 pipe_name += kSystemPrincipalSid;
70 }
71
72 google_breakpad::ExceptionHandler* breakpad =
73 new google_breakpad::ExceptionHandler(
74 temp_path, NULL, NULL, NULL,
75 google_breakpad::ExceptionHandler::HANDLER_ALL, kLargerDumpType,
76 pipe_name.c_str(), GetCustomInfo());
77
78 return breakpad;
79 }
80
23 int APIENTRY wWinMain(HINSTANCE, HINSTANCE, wchar_t*, int) { 81 int APIENTRY wWinMain(HINSTANCE, HINSTANCE, wchar_t*, int) {
24 #else 82 const wchar_t* cmd_line = ::GetCommandLine();
25 extern "C" void __cdecl WinMainCRTStartup() {
26 #endif // NDEBUG
27 // This relies on the chrome_launcher.exe residing in the same directory
28 // as our DLL. We build a full path to avoid loading it from any other
29 // directory in the DLL search path.
30 //
31 // The code is a bit verbose because we can't use the standard library.
32 const wchar_t kBaseName[] = L"npchrome_frame.dll";
33 wchar_t file_path[MAX_PATH + (sizeof(kBaseName) / sizeof(kBaseName[0])) + 1];
34 file_path[0] = L'\0';
35 ::GetModuleFileName(::GetModuleHandle(NULL), file_path, MAX_PATH);
36 83
37 // Find index of last slash, and null-terminate the string after it. 84 google_breakpad::scoped_ptr<google_breakpad::ExceptionHandler> breakpad(
38 // 85 InitializeCrashReporting(cmd_line));
39 // Proof for security purposes, since we can't use the safe string
40 // manipulation functions from the runtime:
41 // - File_path is always null-terminated, by us initially and by
42 // ::GetModuleFileName if it puts anything into the buffer.
43 // - If there is no slash in the path then it's a relative path, not an
44 // absolute one, and the code ends up creating a relative path to
45 // npchrome_frame.dll.
46 // - It's safe to use lstrcatW since we know the maximum length of both
47 // parts we are concatenating, and we know the buffer will fit them in
48 // the worst case.
49 int slash_index = lstrlenW(file_path);
50 // Invariant: 0 <= slash_index < MAX_PATH
51 CLM_ASSERT(slash_index > 0);
52 while (slash_index > 0 && file_path[slash_index] != L'\\')
53 --slash_index;
54 // Invariant: 0 <= slash_index < MAX_PATH and it is either the index of
55 // the last \ in the path, or 0.
56 if (slash_index != 0)
57 ++slash_index; // don't remove the last '\'
58 file_path[slash_index] = L'\0';
59
60 lstrcatW(file_path, kBaseName);
61 86
62 UINT exit_code = ERROR_FILE_NOT_FOUND; 87 UINT exit_code = ERROR_FILE_NOT_FOUND;
63 HMODULE chrome_tab = ::LoadLibrary(file_path); 88 if (chrome_launcher::SanitizeAndLaunchChrome(::GetCommandLine())) {
64 CLM_ASSERT(chrome_tab); 89 exit_code = ERROR_SUCCESS;
65 if (chrome_tab) { 90 }
66 chrome_launcher::CfLaunchChromeProc proc =
67 reinterpret_cast<chrome_launcher::CfLaunchChromeProc>(
68 ::GetProcAddress(chrome_tab, "CfLaunchChrome"));
69 CLM_ASSERT(proc);
70 if (proc) {
71 exit_code = proc();
72 } else {
73 exit_code = ERROR_INVALID_FUNCTION;
74 }
75 91
76 ::FreeLibrary(chrome_tab); 92 return exit_code;
77 }
78 ::ExitProcess(exit_code);
79 } 93 }
OLDNEW
« no previous file with comments | « chrome_frame/chrome_launcher.cc ('k') | chrome_frame/chrome_launcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698