Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
michael@0 | 1 | #include <Windows.h> |
michael@0 | 2 | #include <Shlwapi.h> |
michael@0 | 3 | #include <strsafe.h> |
michael@0 | 4 | |
michael@0 | 5 | // Linker options |
michael@0 | 6 | #pragma comment(lib, "User32.lib") |
michael@0 | 7 | #pragma comment(lib, "shlwapi.lib") |
michael@0 | 8 | #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:wmainCRTStartup") |
michael@0 | 9 | |
michael@0 | 10 | #define NUM_MAX_PATH_BYTES sizeof(wchar_t) * MAX_PATH + 1 |
michael@0 | 11 | #define PROFILE_ARG L" -profile " |
michael@0 | 12 | |
michael@0 | 13 | // Options that can be overridden at build time with -D |
michael@0 | 14 | #ifndef B2G_NAME |
michael@0 | 15 | #define B2G_NAME L"b2g.exe" |
michael@0 | 16 | #endif |
michael@0 | 17 | #ifndef GAIA_PATH |
michael@0 | 18 | #define GAIA_PATH L"gaia\\profile" |
michael@0 | 19 | #endif |
michael@0 | 20 | |
michael@0 | 21 | void error(wchar_t* msg){ |
michael@0 | 22 | MessageBoxW(nullptr, msg, L"Error starting program", MB_OK | MB_ICONERROR); |
michael@0 | 23 | } |
michael@0 | 24 | |
michael@0 | 25 | /* This function takes a string which represents a windows path, orig. |
michael@0 | 26 | * The file portion of the path is stripped off and replaced with the |
michael@0 | 27 | * path component, file. This function returns a string which represents |
michael@0 | 28 | * a windows path with the modifications requested and needs to be freed |
michael@0 | 29 | * explicitly by the calling function. |
michael@0 | 30 | */ |
michael@0 | 31 | wchar_t* make_path_with_leaf_file_name(wchar_t* orig, wchar_t* file){ |
michael@0 | 32 | wchar_t* buffer = (wchar_t*) malloc(NUM_MAX_PATH_BYTES); |
michael@0 | 33 | if (!buffer) { |
michael@0 | 34 | return nullptr; |
michael@0 | 35 | } |
michael@0 | 36 | if (FAILED(StringCchCopyW(buffer, NUM_MAX_PATH_BYTES, orig))) { |
michael@0 | 37 | error(L"Error copying string"); |
michael@0 | 38 | free(buffer); |
michael@0 | 39 | buffer = nullptr; |
michael@0 | 40 | } |
michael@0 | 41 | PathRemoveFileSpecW(buffer); |
michael@0 | 42 | if (!PathAppendW(buffer, file)) { |
michael@0 | 43 | error(L"Unable to append file to directory"); |
michael@0 | 44 | free(buffer); |
michael@0 | 45 | buffer = nullptr; |
michael@0 | 46 | } |
michael@0 | 47 | return buffer; |
michael@0 | 48 | } |
michael@0 | 49 | |
michael@0 | 50 | BOOL execute(wchar_t* binary_path, wchar_t* args, int cp_flags) { |
michael@0 | 51 | STARTUPINFOW si; |
michael@0 | 52 | PROCESS_INFORMATION pi; |
michael@0 | 53 | |
michael@0 | 54 | ZeroMemory(&si, sizeof(si)); |
michael@0 | 55 | si.cb = sizeof(si); |
michael@0 | 56 | ZeroMemory(&pi, sizeof(pi)); |
michael@0 | 57 | |
michael@0 | 58 | if (!CreateProcessW( |
michael@0 | 59 | binary_path, |
michael@0 | 60 | args, |
michael@0 | 61 | nullptr, |
michael@0 | 62 | nullptr, |
michael@0 | 63 | FALSE, |
michael@0 | 64 | cp_flags, |
michael@0 | 65 | nullptr, |
michael@0 | 66 | nullptr, |
michael@0 | 67 | &si, |
michael@0 | 68 | &pi)){ |
michael@0 | 69 | error(L"Could not execute program"); |
michael@0 | 70 | return FALSE; |
michael@0 | 71 | } |
michael@0 | 72 | |
michael@0 | 73 | WaitForInputIdle(pi.hProcess, 0); |
michael@0 | 74 | CloseHandle(pi.hProcess); |
michael@0 | 75 | CloseHandle(pi.hThread); |
michael@0 | 76 | return true; |
michael@0 | 77 | } |
michael@0 | 78 | |
michael@0 | 79 | int wmain(int argc, wchar_t *argv[], wchar_t *envp[]){ |
michael@0 | 80 | int cp_flags; |
michael@0 | 81 | wchar_t* b2g_path = make_path_with_leaf_file_name(argv[0], B2G_NAME); |
michael@0 | 82 | wchar_t* profile_path = make_path_with_leaf_file_name(argv[0], GAIA_PATH); |
michael@0 | 83 | // 10 chars for the ' -profile ' portion of the argument |
michael@0 | 84 | wchar_t* args = (wchar_t*) malloc(2 * NUM_MAX_PATH_BYTES + wcslen(PROFILE_ARG)); |
michael@0 | 85 | if (FAILED(StringCchPrintfW(args, NUM_MAX_PATH_BYTES, L"\"%ws\"%ws\"%ws\"", b2g_path, PROFILE_ARG, profile_path))) { |
michael@0 | 86 | error(L"Could not create argument string"); |
michael@0 | 87 | ExitProcess(1); |
michael@0 | 88 | } |
michael@0 | 89 | #ifdef SHOW_CONSOLE |
michael@0 | 90 | cp_flags = 0; |
michael@0 | 91 | #else |
michael@0 | 92 | cp_flags = DETACHED_PROCESS; |
michael@0 | 93 | #endif |
michael@0 | 94 | if (!execute(b2g_path, args, cp_flags)) { |
michael@0 | 95 | error(L"Failed to launch program"); |
michael@0 | 96 | } |
michael@0 | 97 | free(profile_path); |
michael@0 | 98 | free(b2g_path); |
michael@0 | 99 | free(args); |
michael@0 | 100 | profile_path = b2g_path = args = nullptr; |
michael@0 | 101 | |
michael@0 | 102 | } |