xref: /reactos/base/applications/rapps_com/main.c (revision 3adf4508)
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