VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/testdriver/winbase.py@ 70521

最後變更 在這個檔案從70521是 70521,由 vboxsync 提交於 7 年 前

ValidationKit: More python 3 adjustments.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 10.8 KB
 
1# -*- coding: utf-8 -*-
2# $Id: winbase.py 70521 2018-01-10 15:49:10Z vboxsync $
3
4"""
5This module is here to externalize some Windows specifics that gives pychecker
6a hard time when running on non-Windows systems.
7"""
8
9__copyright__ = \
10"""
11Copyright (C) 2010-2017 Oracle Corporation
12
13This file is part of VirtualBox Open Source Edition (OSE), as
14available from http://www.alldomusa.eu.org. This file is free software;
15you can redistribute it and/or modify it under the terms of the GNU
16General Public License (GPL) as published by the Free Software
17Foundation, in version 2 as it comes in the "COPYING" file of the
18VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20
21The contents of this file may alternatively be used under the terms
22of the Common Development and Distribution License Version 1.0
23(CDDL) only, as it comes in the "COPYING.CDDL" file of the
24VirtualBox OSE distribution, in which case the provisions of the
25CDDL are applicable instead of those of the GPL.
26
27You may elect to license modified versions of this file under the
28terms and conditions of either the GPL or the CDDL or both.
29"""
30__version__ = "$Revision: 70521 $"
31
32
33# Standard Python imports.
34import ctypes;
35import os;
36import sys;
37
38# Windows specific imports.
39import win32api; # pylint: disable=import-error
40import win32con; # pylint: disable=import-error
41import win32console; # pylint: disable=import-error
42import win32event; # pylint: disable=import-error
43import win32process; # pylint: disable=import-error
44import winerror; # pylint: disable=import-error
45import pywintypes; # pylint: disable=import-error
46
47# Validation Kit imports.
48from testdriver import reporter;
49
50# Python 3 hacks:
51if sys.version_info[0] >= 3:
52 long = int; # pylint: disable=redefined-builtin,invalid-name
53
54
55#
56# Windows specific implementation of base functions.
57#
58
59def processInterrupt(uPid):
60 """
61 The Windows version of base.processInterrupt
62
63 Note! This doesn't work terribly well with a lot of processes.
64 """
65 try:
66 # pylint: disable=no-member
67 win32console.GenerateConsoleCtrlEvent(win32con.CTRL_BREAK_EVENT, uPid);
68 #GenerateConsoleCtrlEvent = ctypes.windll.kernel32.GenerateConsoleCtrlEvent
69 #rc = GenerateConsoleCtrlEvent(1, uPid);
70 #reporter.log('GenerateConsoleCtrlEvent -> %s' % (rc,));
71 fRc = True;
72 except:
73 reporter.logXcpt('uPid=%s' % (uPid,));
74 fRc = False;
75 return fRc;
76
77def postThreadMesssageClose(uTid):
78 """ Posts a WM_CLOSE message to the specified thread."""
79 fRc = False;
80 try:
81 win32api.PostThreadMessage(uTid, win32con.WM_CLOSE, 0, 0); # pylint: disable=no-member
82 fRc = True;
83 except:
84 reporter.logXcpt('uTid=%s' % (uTid,));
85 return fRc;
86
87def postThreadMesssageQuit(uTid):
88 """ Posts a WM_QUIT message to the specified thread."""
89 fRc = False;
90 try:
91 win32api.PostThreadMessage(uTid, win32con.WM_QUIT, 0x40010004, 0); # DBG_TERMINATE_PROCESS # pylint: disable=no-member
92 fRc = True;
93 except:
94 reporter.logXcpt('uTid=%s' % (uTid,));
95 return fRc;
96
97def processTerminate(uPid):
98 """ The Windows version of base.processTerminate """
99 # pylint: disable=no-member
100 fRc = False;
101 try:
102 hProcess = win32api.OpenProcess(win32con.PROCESS_TERMINATE, False, uPid);
103 except:
104 reporter.logXcpt('uPid=%s' % (uPid,));
105 else:
106 try:
107 win32process.TerminateProcess(hProcess, 0x40010004); # DBG_TERMINATE_PROCESS
108 fRc = True;
109 except:
110 reporter.logXcpt('uPid=%s' % (uPid,));
111 hProcess.Close(); #win32api.CloseHandle(hProcess)
112 return fRc;
113
114def processKill(uPid):
115 """ The Windows version of base.processKill """
116 return processTerminate(uPid);
117
118def processExists(uPid):
119 """ The Windows version of base.processExists """
120 # We try open the process for waiting since this is generally only forbidden in a very few cases.
121 try:
122 hProcess = win32api.OpenProcess(win32con.SYNCHRONIZE, False, uPid); # pylint: disable=no-member
123 except pywintypes.error as oXcpt: # pylint: disable=no-member
124 if oXcpt.winerror == winerror.ERROR_INVALID_PARAMETER:
125 return False;
126 if oXcpt.winerror != winerror.ERROR_ACCESS_DENIED:
127 reporter.logXcpt('uPid=%s oXcpt=%s' % (uPid, oXcpt));
128 return False;
129 reporter.logXcpt('uPid=%s oXcpt=%s' % (uPid, oXcpt));
130 except Exception as oXcpt:
131 reporter.logXcpt('uPid=%s' % (uPid,));
132 return False;
133 else:
134 hProcess.Close(); #win32api.CloseHandle(hProcess)
135 return True;
136
137def processCheckPidAndName(uPid, sName):
138 """ The Windows version of base.processCheckPidAndName """
139 fRc = processExists(uPid);
140 if fRc is True:
141 try:
142 from win32com.client import GetObject; # pylint: disable=F0401
143 oWmi = GetObject('winmgmts:');
144 aoProcesses = oWmi.InstancesOf('Win32_Process');
145 for oProcess in aoProcesses:
146 if long(oProcess.Properties_("ProcessId").Value) == uPid:
147 sCurName = oProcess.Properties_("Name").Value;
148 reporter.log2('uPid=%s sName=%s sCurName=%s' % (uPid, sName, sCurName));
149 sName = sName.lower();
150 sCurName = sCurName.lower();
151 if os.path.basename(sName) == sName:
152 sCurName = os.path.basename(sCurName);
153
154 if sCurName == sName \
155 or sCurName + '.exe' == sName \
156 or sCurName == sName + '.exe':
157 fRc = True;
158 break;
159 except:
160 reporter.logXcpt('uPid=%s sName=%s' % (uPid, sName));
161 return fRc;
162
163#
164# Some helper functions.
165#
166def processCreate(sName, asArgs):
167 """
168 Returns a (pid, handle, tid) tuple on success. (-1, None) on failure (logged).
169 """
170
171 # Construct a command line.
172 sCmdLine = '';
173 for sArg in asArgs:
174 if sCmdLine == '':
175 sCmdLine += '"';
176 else:
177 sCmdLine += ' "';
178 sCmdLine += sArg;
179 sCmdLine += '"';
180
181 # Try start the process.
182 # pylint: disable=no-member
183 dwCreationFlags = win32con.CREATE_NEW_PROCESS_GROUP;
184 oStartupInfo = win32process.STARTUPINFO();
185 try:
186 (hProcess, hThread, uPid, uTid) = win32process.CreateProcess(sName,
187 sCmdLine, # CommandLine
188 None, # ProcessAttributes
189 None, # ThreadAttibutes
190 1, # fInheritHandles
191 dwCreationFlags,
192 None, # Environment
193 None, # CurrentDirectory.
194 oStartupInfo);
195 except:
196 reporter.logXcpt('sName="%s" sCmdLine="%s"' % (sName, sCmdLine));
197 return (-1, None, -1);
198
199 # Dispense with the thread handle.
200 try:
201 hThread.Close(); # win32api.CloseHandle(hThread);
202 except:
203 reporter.logXcpt();
204
205 # Try get full access to the process.
206 try:
207 hProcessFullAccess = win32api.DuplicateHandle(
208 win32api.GetCurrentProcess(),
209 hProcess,
210 win32api.GetCurrentProcess(),
211 win32con.PROCESS_TERMINATE
212 | win32con.PROCESS_QUERY_INFORMATION
213 | win32con.SYNCHRONIZE
214 | win32con.DELETE,
215 False,
216 0);
217 hProcess.Close(); # win32api.CloseHandle(hProcess);
218 hProcess = hProcessFullAccess;
219 except:
220 reporter.logXcpt();
221 reporter.log2('processCreate -> %#x, hProcess=%s %#x' % (uPid, hProcess, hProcess.handle,));
222 return (uPid, hProcess, uTid);
223
224def processPollByHandle(hProcess):
225 """
226 Polls the process handle to see if it has finished (True) or not (False).
227 """
228 try:
229 dwWait = win32event.WaitForSingleObject(hProcess, 0); # pylint: disable=no-member
230 except:
231 reporter.logXcpt('hProcess=%s %#x' % (hProcess, hProcess.handle,));
232 return True;
233 return dwWait != win32con.WAIT_TIMEOUT; #0x102; #
234
235
236def processTerminateByHandle(hProcess):
237 """
238 Terminates the process.
239 """
240 try:
241 win32api.TerminateProcess(hProcess, 0x40010004); # DBG_TERMINATE_PROCESS # pylint: disable=no-member
242 except:
243 reporter.logXcpt('hProcess=%s %#x' % (hProcess, hProcess.handle,));
244 return False;
245 return True;
246
247#
248# Misc
249#
250
251def logMemoryStats():
252 """
253 Logs windows memory stats.
254 """
255 class MemoryStatusEx(ctypes.Structure):
256 """ MEMORYSTATUSEX """
257 kaFields = [
258 ( 'dwLength', ctypes.c_ulong ),
259 ( 'dwMemoryLoad', ctypes.c_ulong ),
260 ( 'ullTotalPhys', ctypes.c_ulonglong ),
261 ( 'ullAvailPhys', ctypes.c_ulonglong ),
262 ( 'ullTotalPageFile', ctypes.c_ulonglong ),
263 ( 'ullAvailPageFile', ctypes.c_ulonglong ),
264 ( 'ullTotalVirtual', ctypes.c_ulonglong ),
265 ( 'ullAvailVirtual', ctypes.c_ulonglong ),
266 ( 'ullAvailExtendedVirtual', ctypes.c_ulonglong ),
267 ];
268 _fields_ = kaFields; # pylint: disable=invalid-name
269
270 def __init__(self):
271 super(MemoryStatusEx, self).__init__();
272 self.dwLength = ctypes.sizeof(self);
273
274 try:
275 oStats = MemoryStatusEx();
276 ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(oStats));
277 except:
278 reporter.logXcpt();
279 return False;
280
281 reporter.log('Memory statistics:');
282 for sField, _ in MemoryStatusEx.kaFields:
283 reporter.log(' %32s: %s' % (sField, getattr(oStats, sField)));
284 return True;
285
286def checkProcessHeap():
287 """
288 Calls HeapValidate(GetProcessHeap(), 0, NULL);
289 """
290
291 # Get the process heap.
292 try:
293 hHeap = ctypes.windll.kernel32.GetProcessHeap();
294 except:
295 reporter.logXcpt();
296 return False;
297
298 # Check it.
299 try:
300 fIsOkay = ctypes.windll.kernel32.HeapValidate(hHeap, 0, None);
301 except:
302 reporter.logXcpt();
303 return False;
304
305 if fIsOkay == 0:
306 reporter.log('HeapValidate failed!');
307
308 # Try trigger a dump using c:\utils\procdump64.exe.
309 from common import utils;
310
311 iPid = os.getpid();
312 asArgs = [ 'e:\\utils\\procdump64.exe', '-ma', '%s' % (iPid,), 'c:\\CrashDumps\\python.exe-%u-heap.dmp' % (iPid,)];
313 if utils.getHostArch() != 'amd64':
314 asArgs[0] = 'c:\\utils\\procdump.exe'
315 reporter.log('Trying to dump this process using: %s' % (asArgs,));
316 utils.processCall(asArgs);
317
318 # Generate a crash exception.
319 ctypes.windll.msvcrt.strcpy(None, None, 1024);
320
321 return True;
322
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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