VirtualBox

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

最後變更 在這個檔案從402是 1,由 vboxsync 提交於 55 年 前

import

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 7.5 KB
 
1/* $Id: process-win32.cpp 1 1970-01-01 00:00:00Z 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
73RTR3DECL(int) RTProcCreate(const char *pszExec, const char * const *papszArgs, const char * const *papszEnv, unsigned fFlags, PRTPROCESS pProcess)
74{
75 /*
76 * Validate input.
77 */
78 if (!pszExec || !*pszExec)
79 {
80 AssertMsgFailed(("no exec\n"));
81 return VERR_INVALID_PARAMETER;
82 }
83 if (fFlags)
84 {
85 AssertMsgFailed(("invalid flags!\n"));
86 return VERR_INVALID_PARAMETER;
87 }
88 /* later: path searching. */
89
90 /*
91 * Spawn the child.
92 */
93 /** @todo utf-8 considerations! */
94 HANDLE hProcess = (HANDLE)_spawnve(_P_NOWAITO, pszExec, papszArgs, papszEnv);
95 if (hProcess != 0 && hProcess != INVALID_HANDLE_VALUE)
96 {
97 if (pProcess)
98 {
99 /*
100 * GetProcessId requires XP SP1 or later
101 */
102#ifdef __WIN64__
103 *pProcess = GetProcessId(hProcess);
104#else /* !__WIN64__ */
105 static bool fInitialized = false;
106 static DWORD (WINAPI *pfnGetProcessId)(HANDLE Thread) = NULL;
107 if (!fInitialized)
108 {
109 HMODULE hmodKernel32 = GetModuleHandle("KERNEL32.DLL");
110 if (hmodKernel32)
111 pfnGetProcessId = (DWORD (WINAPI*)(HANDLE))GetProcAddress(hmodKernel32, "GetProcessId");
112 fInitialized = true;
113 }
114 if (pfnGetProcessId)
115 {
116 *pProcess = pfnGetProcessId(hProcess);
117 if (!*pProcess)
118 {
119 int rc = RTErrConvertFromWin32(GetLastError());
120 AssertMsgFailed(("failed to get pid from hProcess=%#x rc=%Vrc\n", hProcess, rc));
121 return rc;
122 }
123 }
124 else
125 {
126 /*
127 * Fall back to the NT api for older versions.
128 */
129 PROCESS_BASIC_INFORMATION ProcInfo = {0};
130 ULONG Status = NtQueryInformationProcess(hProcess, ProcessBasicInformation,
131 &ProcInfo, sizeof(ProcInfo), NULL);
132 if (Status != 0)
133 {
134 int rc = ERROR_INTERNAL_ERROR; /* (we don't have a valid conversion here, but this shouldn't happen anyway.) */
135 AssertMsgFailed(("failed to get pid from hProcess=%#x rc=%Vrc Status=%#x\n", hProcess, rc, Status));
136 return rc;
137 }
138 *pProcess = ProcInfo.UniqueProcessId;
139 }
140#endif /* !__WIN64__ */
141 }
142 return VINF_SUCCESS;
143 }
144
145 int rc = RTErrConvertFromErrno(errno);
146 AssertMsgFailed(("spawn/exec failed rc=%Vrc\n", rc)); /* this migth be annoying... */
147 return rc;
148}
149
150
151RTR3DECL(int) RTProcWait(RTPROCESS Process, unsigned fFlags, PRTPROCSTATUS pProcStatus)
152{
153 AssertReturn(!(fFlags & ~(RTPROCWAIT_FLAGS_BLOCK | RTPROCWAIT_FLAGS_NOBLOCK)), VERR_INVALID_PARAMETER);
154
155 /*
156 * Open the process.
157 */
158 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, Process);
159 if (hProcess != NULL)
160 {
161 /*
162 * Wait for it to terminate.
163 */
164 DWORD Millies = fFlags == RTPROCWAIT_FLAGS_BLOCK ? INFINITE : 0;
165 DWORD WaitRc = WaitForSingleObjectEx(hProcess, Millies, TRUE);
166 while (WaitRc == WAIT_IO_COMPLETION)
167 WaitRc = WaitForSingleObjectEx(hProcess, Millies, TRUE);
168 switch (WaitRc)
169 {
170 /*
171 * It has terminated.
172 */
173 case WAIT_OBJECT_0:
174 {
175 DWORD dwExitCode;
176 if (GetExitCodeProcess(hProcess, &dwExitCode))
177 {
178 if (pProcStatus)
179 {
180 pProcStatus->enmReason = RTPROCEXITREASON_NORMAL;
181 pProcStatus->iStatus = (int)dwExitCode;
182 }
183 return VINF_SUCCESS;
184 }
185 break;
186 }
187
188 /*
189 * It hasn't terminated just yet.
190 */
191 case WAIT_TIMEOUT:
192 return VERR_PROCESS_RUNNING;
193
194 /*
195 * Something went wrong...
196 */
197 case WAIT_FAILED:
198 break;
199 case WAIT_ABANDONED:
200 AssertFailed();
201 return VERR_GENERAL_FAILURE;
202 default:
203 AssertMsgFailed(("WaitRc=%RU32\n", WaitRc));
204 return VERR_GENERAL_FAILURE;
205 }
206 }
207 DWORD dwErr = GetLastError();
208 return RTErrConvertFromWin32(dwErr);
209}
210
211
212RTR3DECL(int) RTProcTerminate(RTPROCESS Process)
213{
214 HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, Process);
215 if (hProcess != NULL)
216 {
217 BOOL fRc = TerminateProcess(hProcess, 127);
218 CloseHandle(hProcess);
219 if (fRc)
220 return VINF_SUCCESS;
221 }
222 DWORD dwErr = GetLastError();
223 return RTErrConvertFromWin32(dwErr);
224}
225
226
227RTR3DECL(uint64_t) RTProcGetAffinityMask(void)
228{
229 DWORD_PTR dwProcessAffinityMask = 0xffffffff;
230 DWORD_PTR dwSystemAffinityMask;
231
232 BOOL fRc = GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask);
233 Assert(fRc);
234
235 return dwProcessAffinityMask;
236}
237
238
239RTR3DECL(char *) RTProcGetExecutableName(char *pszExecName, size_t cchExecName)
240{
241 HMODULE hExe = GetModuleHandle(NULL);
242 if (GetModuleFileName(hExe, pszExecName, cchExecName))
243 return pszExecName;
244 return NULL;
245}
246
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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