62
62
# pulling in win32com.shell is a bit of overhead, and normally we don't need
63
63
# it as ctypes is preferred and common. lazy_imports and "optional"
64
64
# modules don't work well, so we do our own lazy thing...
65
has_win32com_shell = None # Set to True or False once we know for sure...
65
has_win32com_shell = None # Set to True or False once we know for sure...
67
67
# Special Win32 API constants
68
68
# Handles of std streams
73
73
# CSIDL constants (from MSDN 2003)
74
74
CSIDL_APPDATA = 0x001A # Application Data folder
75
CSIDL_LOCAL_APPDATA = 0x001c# <user name>\Local Settings\Application Data (non roaming)
75
# <user name>\Local Settings\Application Data (non roaming)
76
CSIDL_LOCAL_APPDATA = 0x001c
76
77
CSIDL_PERSONAL = 0x0005 # My Documents folder
78
79
# from winapi C headers
102
103
('PagefileUsage', ctypes.c_size_t),
103
104
('PeakPagefileUsage', ctypes.c_size_t),
104
105
('PrivateUsage', ctypes.c_size_t),
106
107
cur_process = ctypes.windll.kernel32.GetCurrentProcess()
107
108
mem_struct = PROCESS_MEMORY_COUNTERS_EX()
108
ret = ctypes.windll.psapi.GetProcessMemoryInfo(cur_process,
109
ctypes.byref(mem_struct),
110
ctypes.sizeof(mem_struct))
109
ret = ctypes.windll.psapi.GetProcessMemoryInfo(
110
cur_process, ctypes.byref(mem_struct), ctypes.sizeof(mem_struct))
112
112
trace.note(gettext('Failed to GetProcessMemoryInfo()'))
122
122
'PagefileUsage': mem_struct.PagefileUsage,
123
123
'PeakPagefileUsage': mem_struct.PeakPagefileUsage,
124
124
'PrivateUsage': mem_struct.PrivateUsage,
126
126
elif has_win32api:
127
127
import win32process
128
128
# win32process does not return PrivateUsage, because it doesn't use
131
131
info = win32process.GetProcessMemoryInfo(proc)
133
133
trace.note(gettext('Cannot debug memory on win32 without ctypes'
137
137
# using base-2 units (see HACKING.txt).
138
138
trace.note(gettext('WorkingSize {0:>7}KiB'
139
'\tPeakWorking {1:>7}KiB\t{2}').format(
139
'\tPeakWorking {1:>7}KiB\t{2}').format(
140
140
info['WorkingSetSize'] / 1024,
141
141
info['PeakWorkingSetSize'] / 1024,
145
145
trace.note('%s', message)
146
trace.note(gettext('WorkingSize %8d KiB'), info['WorkingSetSize'] / 1024)
147
trace.note(gettext('PeakWorking %8d KiB'), info['PeakWorkingSetSize'] / 1024)
148
trace.note(gettext('PagefileUsage %8d KiB'), info.get('PagefileUsage', 0) / 1024)
146
trace.note(gettext('WorkingSize %8d KiB'),
147
info['WorkingSetSize'] / 1024)
148
trace.note(gettext('PeakWorking %8d KiB'),
149
info['PeakWorkingSetSize'] / 1024)
150
trace.note(gettext('PagefileUsage %8d KiB'),
151
info.get('PagefileUsage', 0) / 1024)
149
152
trace.note(gettext('PeakPagefileUsage %8d KiB'),
150
153
info.get('PeakPagefileUsage', 0) / 1024)
151
trace.note(gettext('PrivateUsage %8d KiB'), info.get('PrivateUsage', 0) / 1024)
154
trace.note(gettext('PrivateUsage %8d KiB'),
155
info.get('PrivateUsage', 0) / 1024)
152
156
trace.note(gettext('PageFaultCount %8d'), info.get('PageFaultCount', 0))
173
177
(bufx, bufy, curx, cury, wattr,
174
left, top, right, bottom, maxx, maxy) = struct.unpack(
178
left, top, right, bottom, maxx, maxy) = struct.unpack(
175
179
"hhhhHhhhhhh", csbi.raw)
176
180
sizex = right - left + 1
177
181
sizey = bottom - top + 1
283
287
advapi32 = ctypes.windll.advapi32
284
GetUserName = getattr(advapi32, 'GetUserName'+suffix)
288
GetUserName = getattr(advapi32, 'GetUserName' + suffix)
285
289
except AttributeError:
288
buf = create_buffer(UNLEN+1)
289
n = ctypes.c_int(UNLEN+1)
292
buf = create_buffer(UNLEN + 1)
293
n = ctypes.c_int(UNLEN + 1)
290
294
if GetUserName(buf, ctypes.byref(n)):
291
295
return extract_buffer(buf)
292
296
# otherwise try env variables
314
319
kernel32 = ctypes.windll.kernel32
315
320
except AttributeError:
316
pass # Missing the module we need
321
pass # Missing the module we need
318
buf = create_buffer(MAX_COMPUTERNAME_LENGTH+1)
319
n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
323
buf = create_buffer(MAX_COMPUTERNAME_LENGTH + 1)
324
n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH + 1)
321
326
# Try GetComputerNameEx which gives a proper Unicode hostname
322
GetComputerNameEx = getattr(kernel32, 'GetComputerNameEx'+suffix,
327
GetComputerNameEx = getattr(kernel32, 'GetComputerNameEx' + suffix,
324
329
if (GetComputerNameEx is not None
325
330
and GetComputerNameEx(_WIN32_ComputerNameDnsHostname,
329
334
# Try GetComputerName in case GetComputerNameEx wasn't found
330
335
# It returns the NETBIOS name, which isn't as good, but still ok.
331
336
# The first GetComputerNameEx might have changed 'n', so reset it
332
n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
333
GetComputerName = getattr(kernel32, 'GetComputerName'+suffix,
337
n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH + 1)
338
GetComputerName = getattr(kernel32, 'GetComputerName' + suffix,
335
340
if (GetComputerName is not None
336
and GetComputerName(buf, ctypes.byref(n))):
341
and GetComputerName(buf, ctypes.byref(n))):
337
342
return extract_buffer(buf)
338
343
return get_environ_unicode('COMPUTERNAME')
341
346
def _ensure_with_dir(path):
342
347
if (not os.path.split(path)[0] or path.startswith(u'*')
343
or path.startswith(u'?')):
348
or path.startswith(u'?')):
344
349
return u'./' + path, True
346
351
return path, False
348
354
def _undo_ensure_with_dir(path, corrected):
457
463
:return: A list of unicode strings.
459
465
# First, split the command line
460
s = cmdline.Splitter(command_line, single_quotes_allowed=single_quotes_allowed)
462
# Bug #587868 Now make sure that the length of s agrees with sys.argv
463
# we do this by simply counting the number of arguments in each. The counts should
464
# agree no matter what encoding sys.argv is in (AFAIK)
465
# len(arguments) < len(sys.argv) should be an impossibility since python gets
466
s = cmdline.Splitter(
467
command_line, single_quotes_allowed=single_quotes_allowed)
469
# Bug #587868 Now make sure that the length of s agrees with sys.argv
470
# we do this by simply counting the number of arguments in each. The counts should
471
# agree no matter what encoding sys.argv is in (AFAIK)
472
# len(arguments) < len(sys.argv) should be an impossibility since python gets
466
473
# args from the very same PEB as does GetCommandLineW
467
474
arguments = list(s)
469
476
# Now shorten the command line we get from GetCommandLineW to match sys.argv
470
477
if len(arguments) < len(argv):
471
478
raise AssertionError("Split command line can't be shorter than argv")
472
479
arguments = arguments[len(arguments) - len(argv):]
474
481
# Carry on to process globs (metachars) in the command line
475
482
# expand globs if necessary
476
483
# TODO: Use 'globbing' instead of 'glob.glob', this gives us stuff like
516
522
cfunc = ctypes.WINFUNCTYPE(DWORD, LPCWSTR, LPWSTR, DWORD)(
517
523
("GetEnvironmentVariableW", ctypes.windll.kernel32))
518
524
get_environ_unicode._c_function = cfunc
519
buffer_size = 256 # heuristic, 256 characters often enough
525
buffer_size = 256 # heuristic, 256 characters often enough
521
527
buffer = ctypes.create_unicode_buffer(buffer_size)
522
528
length = cfunc(key, buffer, buffer_size)
524
530
code = ctypes.GetLastError()
525
if code == 203: # ERROR_ENVVAR_NOT_FOUND
531
if code == 203: # ERROR_ENVVAR_NOT_FOUND
527
533
raise ctypes.WinError(code)
528
534
if buffer_size > length:
534
540
def _pywin32_is_local_pid_dead(pid):
535
541
"""True if pid doesn't correspond to live process on this machine"""
537
handle = win32api.OpenProcess(1, False, pid) # PROCESS_TERMINATE
543
handle = win32api.OpenProcess(1, False, pid) # PROCESS_TERMINATE
538
544
except pywintypes.error as e:
539
if e[0] == 5: # ERROR_ACCESS_DENIED
545
if e[0] == 5: # ERROR_ACCESS_DENIED
540
546
# Probably something alive we're not allowed to kill
542
elif e[0] == 87: # ERROR_INVALID_PARAMETER
548
elif e[0] == 87: # ERROR_INVALID_PARAMETER
552
558
("CloseHandle", _kernel32))
553
559
_OpenProcess = ctypes.WINFUNCTYPE(HANDLE, DWORD, BOOL, DWORD)(
554
560
("OpenProcess", _kernel32))
555
562
def _ctypes_is_local_pid_dead(pid):
556
563
"""True if pid doesn't correspond to live process on this machine"""
557
handle = _OpenProcess(1, False, pid) # PROCESS_TERMINATE
564
handle = _OpenProcess(1, False, pid) # PROCESS_TERMINATE
559
566
errorcode = ctypes.GetLastError()
560
if errorcode == 5: # ERROR_ACCESS_DENIED
567
if errorcode == 5: # ERROR_ACCESS_DENIED
561
568
# Probably something alive we're not allowed to kill
563
elif errorcode == 87: # ERROR_INVALID_PARAMETER
570
elif errorcode == 87: # ERROR_INVALID_PARAMETER
565
572
raise ctypes.WinError(errorcode)
566
573
_CloseHandle(handle)