blob: 8eaedae89dc928deea8d71f6e333db0d02b5e936 [file] [log] [blame]
[email protected]2249aeb32009-10-28 10:37:571// 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
3// found in the LICENSE file.
4
5#include <windows.h>
6
7#include "chrome_frame/chrome_launcher.h"
8
9// We want to keep this EXE tiny, so we avoid all dependencies and link to no
10// libraries, and we do not use the C runtime.
11//
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
19// In release builds, we skip the standard library completely to minimize
20// size. This is more work in debug builds, and unnecessary, hence the
21// different signatures.
22#ifndef NDEBUG
23int APIENTRY wWinMain(HINSTANCE, HINSTANCE, wchar_t*, int) {
24#else
25extern "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.
[email protected]ea9ed97d2010-01-05 19:16:2332 const wchar_t kBaseName[] = L"npchrome_frame.dll";
[email protected]2249aeb32009-10-28 10:37:5733 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
37 // Find index of last slash, and null-terminate the string after it.
38 //
39 // Proof for security purposes, since we can't use the safe string
40 // manipulation functions from the runtime:
[email protected]ea9ed97d2010-01-05 19:16:2341 // - File_path is always null-terminated, by us initially and by
[email protected]2249aeb32009-10-28 10:37:5742 // ::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
[email protected]ea9ed97d2010-01-05 19:16:2345 // npchrome_frame.dll.
[email protected]2249aeb32009-10-28 10:37:5746 // - 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;
[email protected]ea9ed97d2010-01-05 19:16:2354 // Invariant: 0 <= slash_index < MAX_PATH and it is either the index of
[email protected]2249aeb32009-10-28 10:37:5755 // 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
62 UINT exit_code = ERROR_FILE_NOT_FOUND;
63 HMODULE chrome_tab = ::LoadLibrary(file_path);
64 CLM_ASSERT(chrome_tab);
65 if (chrome_tab) {
[email protected]ea9ed97d2010-01-05 19:16:2366 chrome_launcher::CfLaunchChromeProc proc =
[email protected]2249aeb32009-10-28 10:37:5767 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
76 ::FreeLibrary(chrome_tab);
77 }
78 ::ExitProcess(exit_code);
79}