OLD | NEW |
(Empty) | |
| 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 |
| 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 |
| 23 int APIENTRY wWinMain(HINSTANCE, HINSTANCE, wchar_t*, int) { |
| 24 #else |
| 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_tab.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 |
| 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: |
| 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_tab.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 |
| 62 UINT exit_code = ERROR_FILE_NOT_FOUND; |
| 63 HMODULE chrome_tab = ::LoadLibrary(file_path); |
| 64 CLM_ASSERT(chrome_tab); |
| 65 if (chrome_tab) { |
| 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 |
| 76 ::FreeLibrary(chrome_tab); |
| 77 } |
| 78 ::ExitProcess(exit_code); |
| 79 } |
OLD | NEW |