1 //
2 // Process_WINCE.cpp
3 //
4 // Library: Foundation
5 // Package: Processes
6 // Module: Process
7 //
8 // Copyright (c) 2004-2010, Applied Informatics Software Engineering GmbH.
9 // and Contributors.
10 //
11 // SPDX-License-Identifier: BSL-1.0
12 //
13
14
15 #include "Poco/Process_WINCE.h"
16 #include "Poco/Exception.h"
17 #include "Poco/NumberFormatter.h"
18 #include "Poco/NamedEvent.h"
19 #include "Poco/UnicodeConverter.h"
20 #include "Poco/Pipe.h"
21
22
23 namespace Poco {
24
25
26 //
27 // ProcessHandleImpl
28 //
ProcessHandleImpl(HANDLE hProcess,UInt32 pid)29 ProcessHandleImpl::ProcessHandleImpl(HANDLE hProcess, UInt32 pid):
30 _hProcess(hProcess),
31 _pid(pid)
32 {
33 }
34
35
~ProcessHandleImpl()36 ProcessHandleImpl::~ProcessHandleImpl()
37 {
38 closeHandle();
39 }
40
closeHandle()41 void ProcessHandleImpl::closeHandle()
42 {
43 if (_hProcess)
44 {
45 CloseHandle(_hProcess);
46 _hProcess = NULL;
47 }
48 }
49
id() const50 UInt32 ProcessHandleImpl::id() const
51 {
52 return _pid;
53 }
54
55
process() const56 HANDLE ProcessHandleImpl::process() const
57 {
58 return _hProcess;
59 }
60
61
wait() const62 int ProcessHandleImpl::wait() const
63 {
64 DWORD rc = WaitForSingleObject(_hProcess, INFINITE);
65 if (rc != WAIT_OBJECT_0)
66 throw SystemException("Wait failed for process", NumberFormatter::format(_pid));
67
68 DWORD exitCode;
69 if (GetExitCodeProcess(_hProcess, &exitCode) == 0)
70 throw SystemException("Cannot get exit code for process", NumberFormatter::format(_pid));
71
72 return exitCode;
73 }
74
75
tryWait() const76 int ProcessHandleImpl::tryWait() const
77 {
78 DWORD exitCode;
79 if (GetExitCodeProcess(_hProcess, &exitCode) == 0)
80 throw SystemException("Cannot get exit code for process", NumberFormatter::format(_pid));
81 if (exitCode == STILL_ACTIVE)
82 return -1;
83 else
84 return exitCode;
85 }
86
87
88 //
89 // ProcessImpl
90 //
idImpl()91 ProcessImpl::PIDImpl ProcessImpl::idImpl()
92 {
93 return GetCurrentProcessId();
94 }
95
96
timesImpl(long & userTime,long & kernelTime)97 void ProcessImpl::timesImpl(long& userTime, long& kernelTime)
98 {
99 FILETIME ftCreation;
100 FILETIME ftExit;
101 FILETIME ftKernel;
102 FILETIME ftUser;
103
104 if (GetThreadTimes(GetCurrentThread(), &ftCreation, &ftExit, &ftKernel, &ftUser) != 0)
105 {
106 ULARGE_INTEGER time;
107 time.LowPart = ftKernel.dwLowDateTime;
108 time.HighPart = ftKernel.dwHighDateTime;
109 kernelTime = long(time.QuadPart/10000000L);
110 time.LowPart = ftUser.dwLowDateTime;
111 time.HighPart = ftUser.dwHighDateTime;
112 userTime = long(time.QuadPart/10000000L);
113 }
114 else
115 {
116 userTime = kernelTime = -1;
117 }
118 }
119
120
launchImpl(const std::string & command,const ArgsImpl & args,const std::string & initialDirectory,Pipe * inPipe,Pipe * outPipe,Pipe * errPipe,const EnvImpl & env)121 ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const ArgsImpl& args, const std::string& initialDirectory, Pipe* inPipe, Pipe* outPipe, Pipe* errPipe, const EnvImpl& env)
122 {
123 std::wstring ucommand;
124 UnicodeConverter::toUTF16(command, ucommand);
125
126 std::string commandLine;
127 for (ArgsImpl::const_iterator it = args.begin(); it != args.end(); ++it)
128 {
129 if (it != args.begin()) commandLine.append(" ");
130 commandLine.append(*it);
131 }
132
133 std::wstring ucommandLine;
134 UnicodeConverter::toUTF16(commandLine, ucommandLine);
135
136 PROCESS_INFORMATION processInfo;
137 BOOL rc = CreateProcessW(
138 ucommand.c_str(),
139 const_cast<wchar_t*>(ucommandLine.c_str()),
140 NULL,
141 NULL,
142 FALSE,
143 0,
144 NULL,
145 NULL,
146 NULL/*&startupInfo*/,
147 &processInfo
148 );
149
150 if (rc)
151 {
152 CloseHandle(processInfo.hThread);
153 return new ProcessHandleImpl(processInfo.hProcess, processInfo.dwProcessId);
154 }
155 else throw SystemException("Cannot launch process", command);
156 }
157
158
killImpl(ProcessHandleImpl & handle)159 void ProcessImpl::killImpl(ProcessHandleImpl& handle)
160 {
161 if (handle.process())
162 {
163 if (TerminateProcess(handle.process(), 0) == 0)
164 {
165 handle.closeHandle();
166 throw SystemException("cannot kill process");
167 }
168 handle.closeHandle();
169 }
170 }
171
172
killImpl(PIDImpl pid)173 void ProcessImpl::killImpl(PIDImpl pid)
174 {
175 HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
176 if (hProc)
177 {
178 if (TerminateProcess(hProc, 0) == 0)
179 {
180 CloseHandle(hProc);
181 throw SystemException("cannot kill process");
182 }
183 CloseHandle(hProc);
184 }
185 else
186 {
187 switch (GetLastError())
188 {
189 case ERROR_ACCESS_DENIED:
190 throw NoPermissionException("cannot kill process");
191 case ERROR_NOT_FOUND:
192 throw NotFoundException("cannot kill process");
193 default:
194 throw SystemException("cannot kill process");
195 }
196 }
197 }
198
199
isRunningImpl(const ProcessHandleImpl & handle)200 bool ProcessImpl::isRunningImpl(const ProcessHandleImpl& handle)
201 {
202 bool result = true;
203 DWORD exitCode;
204 BOOL rc = GetExitCodeProcess(handle.process(), &exitCode);
205 if (!rc || exitCode != STILL_ACTIVE) result = false;
206 return result;
207 }
208
209
isRunningImpl(PIDImpl pid)210 bool ProcessImpl::isRunningImpl(PIDImpl pid)
211 {
212 HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
213 bool result = true;
214 DWORD exitCode;
215 BOOL rc = GetExitCodeProcess(hProc, &exitCode);
216 if (!rc || exitCode != STILL_ACTIVE) result = false;
217 return result;}
218
219
requestTerminationImpl(PIDImpl pid)220 void ProcessImpl::requestTerminationImpl(PIDImpl pid)
221 {
222 NamedEvent ev(terminationEventName(pid));
223 ev.set();
224 }
225
226
terminationEventName(PIDImpl pid)227 std::string ProcessImpl::terminationEventName(PIDImpl pid)
228 {
229 std::string evName("POCOTRM");
230 NumberFormatter::appendHex(evName, pid, 8);
231 return evName;
232 }
233
234
235 } // namespace Poco
236