1 /* 2 * PROJECT: ReactOS Applications Manager Command-Line Launcher (rapps.com) 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Allow explorer / cmd to wait for rapps.exe when passing commandline arguments 5 * COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include <windef.h> 9 #include <winbase.h> 10 #include <strsafe.h> 11 12 int run_rapps(LPWSTR cmdline) 13 { 14 DWORD dwExit; 15 STARTUPINFOW si = { sizeof(si) }; 16 PROCESS_INFORMATION pi = { 0 }; 17 18 SetLastError(0); 19 if (!CreateProcessW(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) 20 { 21 fprintf(stderr, "Unable to create rapps.exe process...\n"); 22 return -1; 23 } 24 CloseHandle(pi.hThread); 25 WaitForSingleObject(pi.hProcess, INFINITE); 26 GetExitCodeProcess(pi.hProcess, &dwExit); 27 CloseHandle(pi.hProcess); 28 return (int)dwExit; 29 } 30 31 int wmain(int argc, wchar_t* argv[]) 32 { 33 int iRet; 34 int n; 35 size_t arglen; 36 WCHAR RappsExe[MAX_PATH] = { 0 }; 37 wchar_t* cmdline; 38 39 GetModuleFileNameW(NULL, RappsExe, ARRAYSIZE(RappsExe)); 40 arglen = wcslen(RappsExe); 41 if (arglen > 4 && !wcsicmp(RappsExe + arglen - 4, L".com")) 42 { 43 wcscpy(RappsExe + arglen - 4, L".exe"); 44 } 45 else 46 { 47 fprintf(stderr, "Unable to build rapps.exe path...\n"); 48 return -1; 49 } 50 51 arglen += (1 + 2); // NULL terminator + 2 quotes 52 53 for (n = 1; n < argc; ++n) 54 { 55 arglen += wcslen(argv[n]); 56 arglen += 3; // Surrounding quotes + space 57 } 58 59 cmdline = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, arglen * sizeof(WCHAR)); 60 if (cmdline) 61 { 62 wchar_t* ptr = cmdline; 63 size_t cchRemaining = arglen; 64 65 StringCchPrintfExW(ptr, cchRemaining, &ptr, &cchRemaining, 0, L"\"%s\"", RappsExe); 66 67 for (n = 1; n < argc; ++n) 68 { 69 StringCchPrintfExW(ptr, cchRemaining, &ptr, &cchRemaining, 0, L" \"%s\"", argv[n]); 70 } 71 } 72 73 iRet = run_rapps(cmdline); 74 if (cmdline) 75 HeapFree(GetProcessHeap(), 0, cmdline); 76 return iRet; 77 } 78