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
run_rapps(LPWSTR cmdline)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
wmain(int argc,wchar_t * argv[])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