SmartPDF - lightweight pdf viewer app for rosapps
[reactos.git] / rosapps / smartpdf / baseutils / WinUtil.cpp
1 /* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
2 The author disclaims copyright to this source code. */
3
4 #include "base_util.h"
5
6 #include "WinUtil.hpp"
7
8 #include "str_util.h"
9
10 // TODO: exe name might be unicode so to support everything cmd or args
11 // should be unicode or we can assume that cmd and args are utf8 and
12 // convert them to utf16 and call CreateProcessW
13 #define DONT_INHERIT_HANDLES FALSE
14
15 // Given name of the command to exececute 'cmd', and its arguments 'args'
16 // return WinProcess object that makes it easier to handle the process
17 // Returns NULL if failed to create the process. Caller can use GetLastError()
18 // for detailed error information.
19 WinProcess * WinProcess::Create(const char* cmd, char* args)
20 {
21 UINT res;
22 HANDLE stdOut = INVALID_HANDLE_VALUE;
23 HANDLE stdErr = INVALID_HANDLE_VALUE;
24 STARTUPINFOA siStartupInfo;
25 PROCESS_INFORMATION piProcessInfo;
26 SECURITY_ATTRIBUTES sa;
27
28 sa.nLength = sizeof(sa);
29 sa.lpSecurityDescriptor = 0;
30 sa.bInheritHandle = 1;
31
32 memzero(&siStartupInfo, sizeof(siStartupInfo));
33 memzero(&piProcessInfo, sizeof(piProcessInfo));
34 siStartupInfo.cb = sizeof(siStartupInfo);
35
36 char stdoutTempName[MAX_PATH] = {0};
37 char stderrTempName[MAX_PATH] = {0};
38 char *stdoutTempNameCopy = NULL;
39 char *stderrTempNameCopy = NULL;
40
41 char buf[MAX_PATH] = {0};
42 int len = GetTempPathA(sizeof(buf), buf);
43 assert(len < sizeof(buf));
44 // create temporary files for capturing stdout and stderr or the command
45 res = GetTempFileNameA(buf, "stdout", 0, stdoutTempName);
46 if (0 == res)
47 goto Error;
48
49 res = GetTempFileNameA(buf, "stderr", 0, stderrTempName);
50 if (0 == res)
51 goto Error;
52
53 stdoutTempNameCopy = str_dup(stdoutTempName);
54 stderrTempNameCopy = str_dup(stderrTempName);
55
56 stdOut = CreateFileA(stdoutTempNameCopy,
57 GENERIC_READ|GENERIC_WRITE,
58 FILE_SHARE_WRITE|FILE_SHARE_READ,
59 &sa, CREATE_ALWAYS,
60 FILE_ATTRIBUTE_NORMAL, 0);
61 if (INVALID_HANDLE_VALUE == stdOut)
62 goto Error;
63
64 stdErr = CreateFileA(stderrTempNameCopy,
65 GENERIC_READ|GENERIC_WRITE,
66 FILE_SHARE_WRITE|FILE_SHARE_READ,
67 &sa, CREATE_ALWAYS,
68 FILE_ATTRIBUTE_NORMAL, 0);
69 if (INVALID_HANDLE_VALUE == stdErr)
70 goto Error;
71
72 siStartupInfo.hStdOutput = stdOut;
73 siStartupInfo.hStdError = stdErr;
74
75 BOOL ok = CreateProcessA(cmd, args, NULL, NULL, DONT_INHERIT_HANDLES,
76 CREATE_DEFAULT_ERROR_MODE, NULL /*env*/, NULL /*curr dir*/,
77 &siStartupInfo, &piProcessInfo);
78
79 if (!ok)
80 goto Error;
81
82 // TODO: pass stdoutTempNameCopy and stderrTempNameCopy so upon
83 // WinProcess destruction the files can be deleted and their memory freed
84 WinProcess *wp = new WinProcess(&piProcessInfo);
85 return wp;
86
87 Error:
88 if (INVALID_HANDLE_VALUE != stdOut) {
89 CloseHandle(stdOut);
90 }
91
92 if (INVALID_HANDLE_VALUE != stdErr) {
93 CloseHandle(stdErr);
94 }
95
96 if (stdoutTempName[0]) {
97 // TODO: delete stdoutTempName
98 }
99 if (stderrTempName[0]) {
100 // TODO: delete stderrTempName
101 }
102 free(stdoutTempNameCopy);
103 free(stderrTempNameCopy);
104 return NULL;
105 }
106
107 WinProcess::WinProcess(PROCESS_INFORMATION *pi)
108 {
109 memcpy(&m_processInfo, pi, sizeof(PROCESS_INFORMATION));
110 }
111
112