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