VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win32/process-win32.cpp@ 1710

最後變更 在這個檔案從1710是 1441,由 vboxsync 提交於 18 年 前

Updated the new command line syntax

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 7.6 KB
 
1/* $Id: process-win32.cpp 1441 2007-03-13 14:20:32Z vboxsync $ */
2/** @file
3 * InnoTek Portable Runtime - Process, Win32.
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP RTLOGGROUP_PROCESS
27
28#include <Windows.h>
29#include <process.h>
30#include <errno.h>
31
32#include <iprt/process.h>
33#include <iprt/assert.h>
34#include <iprt/err.h>
35
36
37/*
38 * This is from Winternl.h. It has been copied here
39 * because the header does not define a calling convention for
40 * its prototypes and just assumes that _stdcall is the standard
41 * calling convention.
42 */
43typedef struct _PEB {
44 BYTE Reserved1[2];
45 BYTE BeingDebugged;
46 BYTE Reserved2[229];
47 PVOID Reserved3[59];
48 ULONG SessionId;
49} PEB, *PPEB;
50
51typedef struct _PROCESS_BASIC_INFORMATION {
52 PVOID Reserved1;
53 PPEB PebBaseAddress;
54 PVOID Reserved2[2];
55 ULONG_PTR UniqueProcessId;
56 PVOID Reserved3;
57} PROCESS_BASIC_INFORMATION;
58
59typedef enum _PROCESSINFOCLASS {
60 ProcessBasicInformation = 0,
61 ProcessWow64Information = 26
62} PROCESSINFOCLASS;
63
64extern "C" LONG WINAPI
65NtQueryInformationProcess (
66 IN HANDLE ProcessHandle,
67 IN PROCESSINFOCLASS ProcessInformationClass,
68 OUT PVOID ProcessInformation,
69 IN ULONG ProcessInformationLength,
70 OUT PULONG ReturnLength OPTIONAL
71 );
72
73/** @todo r=michael This function currently does not work correctly if the arguments
74 contain spaces. */
75RTR3DECL(int) RTProcCreate(const char *pszExec, const char * const *papszArgs, const char * const *papszEnv, unsigned fFlags, PRTPROCESS pProcess)
76{
77 /*
78 * Validate input.
79 */
80 if (!pszExec || !*pszExec)
81 {
82 AssertMsgFailed(("no exec\n"));
83 return VERR_INVALID_PARAMETER;
84 }
85 if (fFlags)
86 {
87 AssertMsgFailed(("invalid flags!\n"));
88 return VERR_INVALID_PARAMETER;
89 }
90 /* later: path searching. */
91
92 /*
93 * Spawn the child.
94 */
95 /** @todo utf-8 considerations! */
96 HANDLE hProcess = (HANDLE)_spawnve(_P_NOWAITO, pszExec, papszArgs, papszEnv);
97 if (hProcess != 0 && hProcess != INVALID_HANDLE_VALUE)
98 {
99 if (pProcess)
100 {
101 /*
102 * GetProcessId requires XP SP1 or later
103 */
104#ifdef __WIN64__
105 *pProcess = GetProcessId(hProcess);
106#else /* !__WIN64__ */
107 static bool fInitialized = false;
108 static DWORD (WINAPI *pfnGetProcessId)(HANDLE Thread) = NULL;
109 if (!fInitialized)
110 {
111 HMODULE hmodKernel32 = GetModuleHandle("KERNEL32.DLL");
112 if (hmodKernel32)
113 pfnGetProcessId = (DWORD (WINAPI*)(HANDLE))GetProcAddress(hmodKernel32, "GetProcessId");
114 fInitialized = true;
115 }
116 if (pfnGetProcessId)
117 {
118 *pProcess = pfnGetProcessId(hProcess);
119 if (!*pProcess)
120 {
121 int rc = RTErrConvertFromWin32(GetLastError());
122 AssertMsgFailed(("failed to get pid from hProcess=%#x rc=%Vrc\n", hProcess, rc));
123 return rc;
124 }
125 }
126 else
127 {
128 /*
129 * Fall back to the NT api for older versions.
130 */
131 PROCESS_BASIC_INFORMATION ProcInfo = {0};
132 ULONG Status = NtQueryInformationProcess(hProcess, ProcessBasicInformation,
133 &ProcInfo, sizeof(ProcInfo), NULL);
134 if (Status != 0)
135 {
136 int rc = ERROR_INTERNAL_ERROR; /* (we don't have a valid conversion here, but this shouldn't happen anyway.) */
137 AssertMsgFailed(("failed to get pid from hProcess=%#x rc=%Vrc Status=%#x\n", hProcess, rc, Status));
138 return rc;
139 }
140 *pProcess = ProcInfo.UniqueProcessId;
141 }
142#endif /* !__WIN64__ */
143 }
144 return VINF_SUCCESS;
145 }
146
147 int rc = RTErrConvertFromErrno(errno);
148 AssertMsgFailed(("spawn/exec failed rc=%Vrc\n", rc)); /* this migth be annoying... */
149 return rc;
150}
151
152
153RTR3DECL(int) RTProcWait(RTPROCESS Process, unsigned fFlags, PRTPROCSTATUS pProcStatus)
154{
155 AssertReturn(!(fFlags & ~(RTPROCWAIT_FLAGS_BLOCK | RTPROCWAIT_FLAGS_NOBLOCK)), VERR_INVALID_PARAMETER);
156
157 /*
158 * Open the process.
159 */
160 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, Process);
161 if (hProcess != NULL)
162 {
163 /*
164 * Wait for it to terminate.
165 */
166 DWORD Millies = fFlags == RTPROCWAIT_FLAGS_BLOCK ? INFINITE : 0;
167 DWORD WaitRc = WaitForSingleObjectEx(hProcess, Millies, TRUE);
168 while (WaitRc == WAIT_IO_COMPLETION)
169 WaitRc = WaitForSingleObjectEx(hProcess, Millies, TRUE);
170 switch (WaitRc)
171 {
172 /*
173 * It has terminated.
174 */
175 case WAIT_OBJECT_0:
176 {
177 DWORD dwExitCode;
178 if (GetExitCodeProcess(hProcess, &dwExitCode))
179 {
180 if (pProcStatus)
181 {
182 pProcStatus->enmReason = RTPROCEXITREASON_NORMAL;
183 pProcStatus->iStatus = (int)dwExitCode;
184 }
185 return VINF_SUCCESS;
186 }
187 break;
188 }
189
190 /*
191 * It hasn't terminated just yet.
192 */
193 case WAIT_TIMEOUT:
194 return VERR_PROCESS_RUNNING;
195
196 /*
197 * Something went wrong...
198 */
199 case WAIT_FAILED:
200 break;
201 case WAIT_ABANDONED:
202 AssertFailed();
203 return VERR_GENERAL_FAILURE;
204 default:
205 AssertMsgFailed(("WaitRc=%RU32\n", WaitRc));
206 return VERR_GENERAL_FAILURE;
207 }
208 }
209 DWORD dwErr = GetLastError();
210 return RTErrConvertFromWin32(dwErr);
211}
212
213
214RTR3DECL(int) RTProcTerminate(RTPROCESS Process)
215{
216 HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, Process);
217 if (hProcess != NULL)
218 {
219 BOOL fRc = TerminateProcess(hProcess, 127);
220 CloseHandle(hProcess);
221 if (fRc)
222 return VINF_SUCCESS;
223 }
224 DWORD dwErr = GetLastError();
225 return RTErrConvertFromWin32(dwErr);
226}
227
228
229RTR3DECL(uint64_t) RTProcGetAffinityMask(void)
230{
231 DWORD_PTR dwProcessAffinityMask = 0xffffffff;
232 DWORD_PTR dwSystemAffinityMask;
233
234 BOOL fRc = GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask);
235 Assert(fRc);
236
237 return dwProcessAffinityMask;
238}
239
240
241RTR3DECL(char *) RTProcGetExecutableName(char *pszExecName, size_t cchExecName)
242{
243 HMODULE hExe = GetModuleHandle(NULL);
244 if (GetModuleFileName(hExe, pszExecName, cchExecName))
245 return pszExecName;
246 return NULL;
247}
248
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette