michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: // Linker options michael@0: #pragma comment(lib, "User32.lib") michael@0: #pragma comment(lib, "shlwapi.lib") michael@0: #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:wmainCRTStartup") michael@0: michael@0: #define NUM_MAX_PATH_BYTES sizeof(wchar_t) * MAX_PATH + 1 michael@0: #define PROFILE_ARG L" -profile " michael@0: michael@0: // Options that can be overridden at build time with -D michael@0: #ifndef B2G_NAME michael@0: #define B2G_NAME L"b2g.exe" michael@0: #endif michael@0: #ifndef GAIA_PATH michael@0: #define GAIA_PATH L"gaia\\profile" michael@0: #endif michael@0: michael@0: void error(wchar_t* msg){ michael@0: MessageBoxW(nullptr, msg, L"Error starting program", MB_OK | MB_ICONERROR); michael@0: } michael@0: michael@0: /* This function takes a string which represents a windows path, orig. michael@0: * The file portion of the path is stripped off and replaced with the michael@0: * path component, file. This function returns a string which represents michael@0: * a windows path with the modifications requested and needs to be freed michael@0: * explicitly by the calling function. michael@0: */ michael@0: wchar_t* make_path_with_leaf_file_name(wchar_t* orig, wchar_t* file){ michael@0: wchar_t* buffer = (wchar_t*) malloc(NUM_MAX_PATH_BYTES); michael@0: if (!buffer) { michael@0: return nullptr; michael@0: } michael@0: if (FAILED(StringCchCopyW(buffer, NUM_MAX_PATH_BYTES, orig))) { michael@0: error(L"Error copying string"); michael@0: free(buffer); michael@0: buffer = nullptr; michael@0: } michael@0: PathRemoveFileSpecW(buffer); michael@0: if (!PathAppendW(buffer, file)) { michael@0: error(L"Unable to append file to directory"); michael@0: free(buffer); michael@0: buffer = nullptr; michael@0: } michael@0: return buffer; michael@0: } michael@0: michael@0: BOOL execute(wchar_t* binary_path, wchar_t* args, int cp_flags) { michael@0: STARTUPINFOW si; michael@0: PROCESS_INFORMATION pi; michael@0: michael@0: ZeroMemory(&si, sizeof(si)); michael@0: si.cb = sizeof(si); michael@0: ZeroMemory(&pi, sizeof(pi)); michael@0: michael@0: if (!CreateProcessW( michael@0: binary_path, michael@0: args, michael@0: nullptr, michael@0: nullptr, michael@0: FALSE, michael@0: cp_flags, michael@0: nullptr, michael@0: nullptr, michael@0: &si, michael@0: &pi)){ michael@0: error(L"Could not execute program"); michael@0: return FALSE; michael@0: } michael@0: michael@0: WaitForInputIdle(pi.hProcess, 0); michael@0: CloseHandle(pi.hProcess); michael@0: CloseHandle(pi.hThread); michael@0: return true; michael@0: } michael@0: michael@0: int wmain(int argc, wchar_t *argv[], wchar_t *envp[]){ michael@0: int cp_flags; michael@0: wchar_t* b2g_path = make_path_with_leaf_file_name(argv[0], B2G_NAME); michael@0: wchar_t* profile_path = make_path_with_leaf_file_name(argv[0], GAIA_PATH); michael@0: // 10 chars for the ' -profile ' portion of the argument michael@0: wchar_t* args = (wchar_t*) malloc(2 * NUM_MAX_PATH_BYTES + wcslen(PROFILE_ARG)); michael@0: if (FAILED(StringCchPrintfW(args, NUM_MAX_PATH_BYTES, L"\"%ws\"%ws\"%ws\"", b2g_path, PROFILE_ARG, profile_path))) { michael@0: error(L"Could not create argument string"); michael@0: ExitProcess(1); michael@0: } michael@0: #ifdef SHOW_CONSOLE michael@0: cp_flags = 0; michael@0: #else michael@0: cp_flags = DETACHED_PROCESS; michael@0: #endif michael@0: if (!execute(b2g_path, args, cp_flags)) { michael@0: error(L"Failed to launch program"); michael@0: } michael@0: free(profile_path); michael@0: free(b2g_path); michael@0: free(args); michael@0: profile_path = b2g_path = args = nullptr; michael@0: michael@0: }