1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "osProcess.h"
17 #include <windows.h>
18 #include <string>
19 #include <stdlib.h>
20 #include <psapi.h>
21 
22 namespace osUtils {
23 
24 childProcess *
create(const char * p_cmdLine,const char * p_startdir)25 childProcess::create(const char *p_cmdLine, const char *p_startdir)
26 {
27     childProcess *child = new childProcess();
28     if (!child) {
29         return NULL;
30     }
31 
32     STARTUPINFOA        si;
33     ZeroMemory(&si, sizeof(si));
34 
35     ZeroMemory(&child->m_proc, sizeof(child->m_proc));
36     BOOL ret = CreateProcessA(
37                     NULL ,
38                     (LPSTR)p_cmdLine,
39                     NULL,
40                     NULL,
41                     FALSE,
42                     CREATE_DEFAULT_ERROR_MODE,
43                     NULL,
44                     (p_startdir != NULL ? p_startdir : ".\\"),
45                     &si,
46                     &child->m_proc);
47     if (ret == 0) {
48         delete child;
49         return NULL;
50     }
51 
52     // close the thread handle we do not need it,
53     // keep the process handle for wait/trywait operations, will
54     // be closed on destruction
55     CloseHandle(child->m_proc.hThread);
56 
57     return child;
58 }
59 
~childProcess()60 childProcess::~childProcess()
61 {
62     if (m_proc.hProcess) {
63         CloseHandle(m_proc.hProcess);
64     }
65 }
66 
67 bool
wait(int * exitStatus)68 childProcess::wait(int *exitStatus)
69 {
70 DWORD _exitStatus;
71 
72     if (WaitForSingleObject(m_proc.hProcess, INFINITE) == WAIT_FAILED) {
73         return false;
74     }
75 
76     if (!GetExitCodeProcess(m_proc.hProcess, &_exitStatus))
77     {
78         return false;
79     }
80 
81     if (exitStatus) {
82         *exitStatus = _exitStatus;
83     }
84 
85     return true;
86 }
87 
88 int
tryWait(bool & isAlive)89 childProcess::tryWait(bool& isAlive)
90 {
91     DWORD status = WaitForSingleObject(m_proc.hProcess, 0);
92 
93     if(status == WAIT_OBJECT_0)
94     {
95         // process has exited
96         isAlive = false;
97         GetExitCodeProcess(m_proc.hProcess, &status);
98     }
99     else if (status == WAIT_TIMEOUT)
100     {
101         isAlive = true;
102         status = 0;
103     }
104 
105     return status;
106 
107 }
108 
ProcessGetPID()109 int ProcessGetPID()
110 {
111     return GetCurrentProcessId();
112 }
113 
ProcessGetTID()114 int ProcessGetTID()
115 {
116     return GetCurrentThreadId();
117 }
118 
ProcessGetName(char * p_outName,int p_outNameLen)119 bool ProcessGetName(char *p_outName, int p_outNameLen)
120 {
121     return 0 != GetModuleFileNameEx( GetCurrentProcess(), NULL, p_outName, p_outNameLen);
122 }
123 
KillProcess(int pid,bool wait)124 int KillProcess(int pid, bool wait)
125 {
126     DWORD exitStatus = 1;
127     HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
128 
129     if (NULL == hProc) {
130         return 0;
131     }
132 
133     //
134     // Terminate the process
135     //
136     TerminateProcess(hProc, 0x55);
137 
138     if (wait) {
139         //
140         // Wait for it to be terminated
141         //
142         if(WaitForSingleObject(hProc, INFINITE) == WAIT_FAILED) {
143             CloseHandle(hProc);
144             return 0;
145         }
146 
147         if (!GetExitCodeProcess(hProc, &exitStatus)) {
148             CloseHandle(hProc);
149             return 0;
150         }
151     }
152 
153     CloseHandle(hProc);
154 
155     return exitStatus;
156 }
157 
isProcessRunning(int pid)158 bool isProcessRunning(int pid)
159 {
160     bool isRunning = false;
161 
162     HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
163     if (NULL != process) {
164         DWORD ret = WaitForSingleObject(process, 0);
165         CloseHandle(process);
166         isRunning = (ret == WAIT_TIMEOUT);
167     }
168     return isRunning;
169 }
170 
171 } // of namespace osUtils
172