1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 """
32 System settings.
33
34 @group Instrumentation:
35 System
36 """
37
38 from __future__ import with_statement
39
40 __revision__ = "$Id: system.py 1299 2013-12-20 09:30:55Z qvasimodo $"
41
42 __all__ = ['System']
43
44 import win32
45 import win32.version
46 from registry import Registry
47 from textio import HexInput, HexDump
48 from util import Regenerator, PathOperations, MemoryAddresses, DebugRegister, \
49 classproperty
50 from process import _ProcessContainer
51 from window import Window
52
53 import os
54 import ctypes
55 import warnings
56
57 from os import path, getenv
58
59
60
61 -class System (_ProcessContainer):
62 """
63 Interface to a batch of processes, plus some system wide settings.
64 Contains a snapshot of processes.
65
66 @group Platform settings:
67 arch, bits, os, wow64, pageSize
68
69 @group Instrumentation:
70 find_window, get_window_at, get_foreground_window,
71 get_desktop_window, get_shell_window
72
73 @group Debugging:
74 load_dbghelp, fix_symbol_store_path,
75 request_debug_privileges, drop_debug_privileges
76
77 @group Postmortem debugging:
78 get_postmortem_debugger, set_postmortem_debugger,
79 get_postmortem_exclusion_list, add_to_postmortem_exclusion_list,
80 remove_from_postmortem_exclusion_list
81
82 @group System services:
83 get_services, get_active_services,
84 start_service, stop_service,
85 pause_service, resume_service,
86 get_service_display_name, get_service_from_display_name
87
88 @group Permissions and privileges:
89 request_privileges, drop_privileges, adjust_privileges, is_admin
90
91 @group Miscellaneous global settings:
92 set_kill_on_exit_mode, read_msr, write_msr, enable_step_on_branch_mode,
93 get_last_branch_location
94
95 @type arch: str
96 @cvar arch: Name of the processor architecture we're running on.
97 For more details see L{win32.version._get_arch}.
98
99 @type bits: int
100 @cvar bits: Size of the machine word in bits for the current architecture.
101 For more details see L{win32.version._get_bits}.
102
103 @type os: str
104 @cvar os: Name of the Windows version we're runing on.
105 For more details see L{win32.version._get_os}.
106
107 @type wow64: bool
108 @cvar wow64: C{True} if the debugger is a 32 bits process running in a 64
109 bits version of Windows, C{False} otherwise.
110
111 @type pageSize: int
112 @cvar pageSize: Page size in bytes. Defaults to 0x1000 but it's
113 automatically updated on runtime when importing the module.
114
115 @type registry: L{Registry}
116 @cvar registry: Windows Registry for this machine.
117 """
118
119 arch = win32.arch
120 bits = win32.bits
121 os = win32.os
122 wow64 = win32.wow64
123
124 @classproperty
129
130 registry = Registry()
131
132
133
134 @staticmethod
136 """
137 Find the first top-level window in the current desktop to match the
138 given class name and/or window name. If neither are provided any
139 top-level window will match.
140
141 @see: L{get_window_at}
142
143 @type className: str
144 @param className: (Optional) Class name of the window to find.
145 If C{None} or not used any class name will match the search.
146
147 @type windowName: str
148 @param windowName: (Optional) Caption text of the window to find.
149 If C{None} or not used any caption text will match the search.
150
151 @rtype: L{Window} or None
152 @return: A window that matches the request. There may be more matching
153 windows, but this method only returns one. If no matching window
154 is found, the return value is C{None}.
155
156 @raise WindowsError: An error occured while processing this request.
157 """
158
159
160 hWnd = win32.FindWindow(className, windowName)
161 if hWnd:
162 return Window(hWnd)
163
164 @staticmethod
166 """
167 Get the window located at the given coordinates in the desktop.
168 If no such window exists an exception is raised.
169
170 @see: L{find_window}
171
172 @type x: int
173 @param x: Horizontal coordinate.
174 @type y: int
175 @param y: Vertical coordinate.
176
177 @rtype: L{Window}
178 @return: Window at the requested position. If no such window
179 exists a C{WindowsError} exception is raised.
180
181 @raise WindowsError: An error occured while processing this request.
182 """
183 return Window( win32.WindowFromPoint( (x, y) ) )
184
185 @staticmethod
187 """
188 @rtype: L{Window}
189 @return: Returns the foreground window.
190 @raise WindowsError: An error occured while processing this request.
191 """
192 return Window( win32.GetForegroundWindow() )
193
194 @staticmethod
196 """
197 @rtype: L{Window}
198 @return: Returns the desktop window.
199 @raise WindowsError: An error occured while processing this request.
200 """
201 return Window( win32.GetDesktopWindow() )
202
203 @staticmethod
205 """
206 @rtype: L{Window}
207 @return: Returns the shell window.
208 @raise WindowsError: An error occured while processing this request.
209 """
210 return Window( win32.GetShellWindow() )
211
212
213
214 @classmethod
216 """
217 Requests debug privileges.
218
219 This may be needed to debug processes running as SYSTEM
220 (such as services) since Windows XP.
221
222 @type bIgnoreExceptions: bool
223 @param bIgnoreExceptions: C{True} to ignore any exceptions that may be
224 raised when requesting debug privileges.
225
226 @rtype: bool
227 @return: C{True} on success, C{False} on failure.
228
229 @raise WindowsError: Raises an exception on error, unless
230 C{bIgnoreExceptions} is C{True}.
231 """
232 try:
233 cls.request_privileges(win32.SE_DEBUG_NAME)
234 return True
235 except Exception, e:
236 if not bIgnoreExceptions:
237 raise
238 return False
239
240 @classmethod
242 """
243 Drops debug privileges.
244
245 This may be needed to avoid being detected
246 by certain anti-debug tricks.
247
248 @type bIgnoreExceptions: bool
249 @param bIgnoreExceptions: C{True} to ignore any exceptions that may be
250 raised when dropping debug privileges.
251
252 @rtype: bool
253 @return: C{True} on success, C{False} on failure.
254
255 @raise WindowsError: Raises an exception on error, unless
256 C{bIgnoreExceptions} is C{True}.
257 """
258 try:
259 cls.drop_privileges(win32.SE_DEBUG_NAME)
260 return True
261 except Exception, e:
262 if not bIgnoreExceptions:
263 raise
264 return False
265
266 @classmethod
268 """
269 Requests privileges.
270
271 @type privileges: int...
272 @param privileges: Privileges to request.
273
274 @raise WindowsError: Raises an exception on error.
275 """
276 cls.adjust_privileges(True, privileges)
277
278 @classmethod
280 """
281 Drops privileges.
282
283 @type privileges: int...
284 @param privileges: Privileges to drop.
285
286 @raise WindowsError: Raises an exception on error.
287 """
288 cls.adjust_privileges(False, privileges)
289
290 @staticmethod
307
308 @staticmethod
310 """
311 @rtype: bool
312 @return: C{True} if the current user as Administrator privileges,
313 C{False} otherwise. Since Windows Vista and above this means if
314 the current process is running with UAC elevation or not.
315 """
316 return win32.IsUserAnAdmin()
317
318
319
320 __binary_types = {
321 win32.VFT_APP: "application",
322 win32.VFT_DLL: "dynamic link library",
323 win32.VFT_STATIC_LIB: "static link library",
324 win32.VFT_FONT: "font",
325 win32.VFT_DRV: "driver",
326 win32.VFT_VXD: "legacy driver",
327 }
328
329 __driver_types = {
330 win32.VFT2_DRV_COMM: "communications driver",
331 win32.VFT2_DRV_DISPLAY: "display driver",
332 win32.VFT2_DRV_INSTALLABLE: "installable driver",
333 win32.VFT2_DRV_KEYBOARD: "keyboard driver",
334 win32.VFT2_DRV_LANGUAGE: "language driver",
335 win32.VFT2_DRV_MOUSE: "mouse driver",
336 win32.VFT2_DRV_NETWORK: "network driver",
337 win32.VFT2_DRV_PRINTER: "printer driver",
338 win32.VFT2_DRV_SOUND: "sound driver",
339 win32.VFT2_DRV_SYSTEM: "system driver",
340 win32.VFT2_DRV_VERSIONED_PRINTER: "versioned printer driver",
341 }
342
343 __font_types = {
344 win32.VFT2_FONT_RASTER: "raster font",
345 win32.VFT2_FONT_TRUETYPE: "TrueType font",
346 win32.VFT2_FONT_VECTOR: "vector font",
347 }
348
349 __months = (
350 "January",
351 "February",
352 "March",
353 "April",
354 "May",
355 "June",
356 "July",
357 "August",
358 "September",
359 "October",
360 "November",
361 "December",
362 )
363
364 __days_of_the_week = (
365 "Sunday",
366 "Monday",
367 "Tuesday",
368 "Wednesday",
369 "Thursday",
370 "Friday",
371 "Saturday",
372 )
373
374 @classmethod
376 """
377 Get the program version from an executable file, if available.
378
379 @type filename: str
380 @param filename: Pathname to the executable file to query.
381
382 @rtype: tuple(str, str, bool, bool, str, str)
383 @return: Tuple with version information extracted from the executable
384 file metadata, containing the following:
385 - File version number (C{"major.minor"}).
386 - Product version number (C{"major.minor"}).
387 - C{True} for debug builds, C{False} for production builds.
388 - C{True} for legacy OS builds (DOS, OS/2, Win16),
389 C{False} for modern OS builds.
390 - Binary file type.
391 May be one of the following values:
392 - "application"
393 - "dynamic link library"
394 - "static link library"
395 - "font"
396 - "raster font"
397 - "TrueType font"
398 - "vector font"
399 - "driver"
400 - "communications driver"
401 - "display driver"
402 - "installable driver"
403 - "keyboard driver"
404 - "language driver"
405 - "legacy driver"
406 - "mouse driver"
407 - "network driver"
408 - "printer driver"
409 - "sound driver"
410 - "system driver"
411 - "versioned printer driver"
412 - Binary creation timestamp.
413 Any of the fields may be C{None} if not available.
414
415 @raise WindowsError: Raises an exception on error.
416 """
417
418
419 pBlock = win32.GetFileVersionInfo(filename)
420 pBuffer, dwLen = win32.VerQueryValue(pBlock, "\\")
421 if dwLen != ctypes.sizeof(win32.VS_FIXEDFILEINFO):
422 raise ctypes.WinError(win32.ERROR_BAD_LENGTH)
423 pVersionInfo = ctypes.cast(pBuffer,
424 ctypes.POINTER(win32.VS_FIXEDFILEINFO))
425 VersionInfo = pVersionInfo.contents
426 if VersionInfo.dwSignature != 0xFEEF04BD:
427 raise ctypes.WinError(win32.ERROR_BAD_ARGUMENTS)
428
429
430 FileVersion = "%d.%d" % (VersionInfo.dwFileVersionMS,
431 VersionInfo.dwFileVersionLS)
432 ProductVersion = "%d.%d" % (VersionInfo.dwProductVersionMS,
433 VersionInfo.dwProductVersionLS)
434
435
436 if VersionInfo.dwFileFlagsMask & win32.VS_FF_DEBUG:
437 DebugBuild = (VersionInfo.dwFileFlags & win32.VS_FF_DEBUG) != 0
438 else:
439 DebugBuild = None
440
441
442 LegacyBuild = (VersionInfo.dwFileOS != win32.VOS_NT_WINDOWS32)
443
444
445 FileType = cls.__binary_types.get(VersionInfo.dwFileType)
446 if VersionInfo.dwFileType == win32.VFT_DRV:
447 FileType = cls.__driver_types.get(VersionInfo.dwFileSubtype)
448 elif VersionInfo.dwFileType == win32.VFT_FONT:
449 FileType = cls.__font_types.get(VersionInfo.dwFileSubtype)
450
451
452
453 FileDate = (VersionInfo.dwFileDateMS << 32) + VersionInfo.dwFileDateLS
454 if FileDate:
455 CreationTime = win32.FileTimeToSystemTime(FileDate)
456 CreationTimestamp = "%s, %s %d, %d (%d:%d:%d.%d)" % (
457 cls.__days_of_the_week[CreationTime.wDayOfWeek],
458 cls.__months[CreationTime.wMonth],
459 CreationTime.wDay,
460 CreationTime.wYear,
461 CreationTime.wHour,
462 CreationTime.wMinute,
463 CreationTime.wSecond,
464 CreationTime.wMilliseconds,
465 )
466 else:
467 CreationTimestamp = None
468
469
470 return (
471 FileVersion,
472 ProductVersion,
473 DebugBuild,
474 LegacyBuild,
475 FileType,
476 CreationTimestamp,
477 )
478
479
480
481
482
483
484
485 __dbghelp_locations = {
486
487
488 win32.ARCH_AMD64: set([
489
490
491 path.join(
492 getenv("ProgramFiles", "C:\\Program Files"),
493 "Windows Kits",
494 "8.0",
495 "Debuggers",
496 "x64",
497 "dbghelp.dll"),
498 path.join(
499 getenv("ProgramW6432", getenv("ProgramFiles",
500 "C:\\Program Files")),
501 "Windows Kits",
502 "8.0",
503 "Debuggers",
504 "x64",
505 "dbghelp.dll"),
506
507
508 path.join(
509 getenv("ProgramFiles", "C:\\Program Files"),
510 "Debugging Tools for Windows (x64)",
511 "dbghelp.dll"),
512 ]),
513
514
515 win32.ARCH_I386 : set([
516
517
518 path.join(
519 getenv("ProgramFiles", "C:\\Program Files"),
520 "Windows Kits",
521 "8.0",
522 "Debuggers",
523 "x86",
524 "dbghelp.dll"),
525 path.join(
526 getenv("ProgramW6432", getenv("ProgramFiles",
527 "C:\\Program Files")),
528 "Windows Kits",
529 "8.0",
530 "Debuggers",
531 "x86",
532 "dbghelp.dll"),
533
534
535 path.join(
536 getenv("ProgramFiles", "C:\\Program Files"),
537 "Debugging Tools for Windows (x86)",
538 "dbghelp.dll"),
539
540
541 path.join(
542 getenv("ProgramFiles", "C:\\Program Files"),
543 "Debugging Tools for Windows (x86)",
544 "dbghelp.dll"),
545 ]),
546 }
547
548 @classmethod
550 """
551 Load the specified version of the C{dbghelp.dll} library.
552
553 This library is shipped with the Debugging Tools for Windows, and it's
554 required to load debug symbols.
555
556 Normally you don't need to call this method, as WinAppDbg already tries
557 to load the latest version automatically - but it may come in handy if
558 the Debugging Tools are installed in a non standard folder.
559
560 Example::
561 from winappdbg import Debug
562
563 def simple_debugger( argv ):
564
565 # Instance a Debug object, passing it the event handler callback
566 debug = Debug( my_event_handler )
567 try:
568
569 # Load a specific dbghelp.dll file
570 debug.system.load_dbghelp("C:\Some folder\dbghelp.dll")
571
572 # Start a new process for debugging
573 debug.execv( argv )
574
575 # Wait for the debugee to finish
576 debug.loop()
577
578 # Stop the debugger
579 finally:
580 debug.stop()
581
582 @see: U{http://msdn.microsoft.com/en-us/library/ms679294(VS.85).aspx}
583
584 @type pathname: str
585 @param pathname:
586 (Optional) Full pathname to the C{dbghelp.dll} library.
587 If not provided this method will try to autodetect it.
588
589 @rtype: ctypes.WinDLL
590 @return: Loaded instance of C{dbghelp.dll}.
591
592 @raise NotImplementedError: This feature was not implemented for the
593 current architecture.
594
595 @raise WindowsError: An error occured while processing this request.
596 """
597
598
599 if not pathname:
600
601
602 arch = win32.arch
603 if arch == win32.ARCH_AMD64 and win32.bits == 32:
604 arch = win32.ARCH_I386
605
606
607 if not arch in cls.__dbghelp_locations:
608 msg = "Architecture %s is not currently supported."
609 raise NotImplementedError(msg % arch)
610
611
612 found = []
613 for pathname in cls.__dbghelp_locations[arch]:
614 if path.isfile(pathname):
615 try:
616 f_ver, p_ver = cls.get_file_version_info(pathname)[:2]
617 except WindowsError:
618 msg = "Failed to parse file version metadata for: %s"
619 warnings.warn(msg % pathname)
620 if not f_ver:
621 f_ver = p_ver
622 elif p_ver and p_ver > f_ver:
623 f_ver = p_ver
624 found.append( (f_ver, pathname) )
625
626
627 if found:
628 found.sort()
629 pathname = found.pop()[1]
630
631
632 else:
633 pathname = "dbghelp.dll"
634
635
636 dbghelp = ctypes.windll.LoadLibrary(pathname)
637
638
639 ctypes.windll.dbghelp = dbghelp
640
641
642 return dbghelp
643
644 @staticmethod
648 """
649 Fix the symbol store path. Equivalent to the C{.symfix} command in
650 Microsoft WinDbg.
651
652 If the symbol store path environment variable hasn't been set, this
653 method will provide a default one.
654
655 @type symbol_store_path: str or None
656 @param symbol_store_path: (Optional) Symbol store path to set.
657
658 @type remote: bool
659 @param remote: (Optional) Defines the symbol store path to set when the
660 C{symbol_store_path} is C{None}.
661
662 If C{True} the default symbol store path is set to the Microsoft
663 symbol server. Debug symbols will be downloaded through HTTP.
664 This gives the best results but is also quite slow.
665
666 If C{False} the default symbol store path is set to the local
667 cache only. This prevents debug symbols from being downloaded and
668 is faster, but unless you've installed the debug symbols on this
669 machine or downloaded them in a previous debugging session, some
670 symbols may be missing.
671
672 If the C{symbol_store_path} argument is not C{None}, this argument
673 is ignored entirely.
674
675 @type force: bool
676 @param force: (Optional) If C{True} the new symbol store path is set
677 always. If C{False} the new symbol store path is only set if
678 missing.
679
680 This allows you to call this method preventively to ensure the
681 symbol server is always set up correctly when running your script,
682 but without messing up whatever configuration the user has.
683
684 Example::
685 from winappdbg import Debug, System
686
687 def simple_debugger( argv ):
688
689 # Instance a Debug object
690 debug = Debug( MyEventHandler() )
691 try:
692
693 # Make sure the remote symbol store is set
694 System.fix_symbol_store_path(remote = True,
695 force = False)
696
697 # Start a new process for debugging
698 debug.execv( argv )
699
700 # Wait for the debugee to finish
701 debug.loop()
702
703 # Stop the debugger
704 finally:
705 debug.stop()
706
707 @rtype: str or None
708 @return: The previously set symbol store path if any,
709 otherwise returns C{None}.
710 """
711 try:
712 if symbol_store_path is None:
713 local_path = "C:\\SYMBOLS"
714 if not path.isdir(local_path):
715 local_path = "C:\\Windows\\Symbols"
716 if not path.isdir(local_path):
717 local_path = path.abspath(".")
718 if remote:
719 symbol_store_path = (
720 "cache*;SRV*"
721 + local_path +
722 "*"
723 "http://msdl.microsoft.com/download/symbols"
724 )
725 else:
726 symbol_store_path = "cache*;SRV*" + local_path
727 previous = os.environ.get("_NT_SYMBOL_PATH", None)
728 if not previous or force:
729 os.environ["_NT_SYMBOL_PATH"] = symbol_store_path
730 return previous
731 except Exception, e:
732 warnings.warn("Cannot fix symbol path, reason: %s" % str(e),
733 RuntimeWarning)
734
735
736
737 @staticmethod
739 """
740 Defines the behavior of the debugged processes when the debugging
741 thread dies. This method only affects the calling thread.
742
743 Works on the following platforms:
744
745 - Microsoft Windows XP and above.
746 - Wine (Windows Emulator).
747
748 Fails on the following platforms:
749
750 - Microsoft Windows 2000 and below.
751 - ReactOS.
752
753 @type bKillOnExit: bool
754 @param bKillOnExit: C{True} to automatically kill processes when the
755 debugger thread dies. C{False} to automatically detach from
756 processes when the debugger thread dies.
757
758 @rtype: bool
759 @return: C{True} on success, C{False} on error.
760
761 @note:
762 This call will fail if a debug port was not created. That is, if
763 the debugger isn't attached to at least one process. For more info
764 see: U{http://msdn.microsoft.com/en-us/library/ms679307.aspx}
765 """
766 try:
767
768 win32.DebugSetProcessKillOnExit(bKillOnExit)
769 except (AttributeError, WindowsError):
770 return False
771 return True
772
773 @staticmethod
775 """
776 Read the contents of the specified MSR (Machine Specific Register).
777
778 @type address: int
779 @param address: MSR to read.
780
781 @rtype: int
782 @return: Value of the specified MSR.
783
784 @raise WindowsError:
785 Raises an exception on error.
786
787 @raise NotImplementedError:
788 Current architecture is not C{i386} or C{amd64}.
789
790 @warning:
791 It could potentially brick your machine.
792 It works on my machine, but your mileage may vary.
793 """
794 if win32.arch not in (win32.ARCH_I386, win32.ARCH_AMD64):
795 raise NotImplementedError(
796 "MSR reading is only supported on i386 or amd64 processors.")
797 msr = win32.SYSDBG_MSR()
798 msr.Address = address
799 msr.Data = 0
800 win32.NtSystemDebugControl(win32.SysDbgReadMsr,
801 InputBuffer = msr,
802 OutputBuffer = msr)
803 return msr.Data
804
805 @staticmethod
807 """
808 Set the contents of the specified MSR (Machine Specific Register).
809
810 @type address: int
811 @param address: MSR to write.
812
813 @type value: int
814 @param value: Contents to write on the MSR.
815
816 @raise WindowsError:
817 Raises an exception on error.
818
819 @raise NotImplementedError:
820 Current architecture is not C{i386} or C{amd64}.
821
822 @warning:
823 It could potentially brick your machine.
824 It works on my machine, but your mileage may vary.
825 """
826 if win32.arch not in (win32.ARCH_I386, win32.ARCH_AMD64):
827 raise NotImplementedError(
828 "MSR writing is only supported on i386 or amd64 processors.")
829 msr = win32.SYSDBG_MSR()
830 msr.Address = address
831 msr.Data = value
832 win32.NtSystemDebugControl(win32.SysDbgWriteMsr, InputBuffer = msr)
833
834 @classmethod
836 """
837 When tracing, call this on every single step event
838 for step on branch mode.
839
840 @raise WindowsError:
841 Raises C{ERROR_DEBUGGER_INACTIVE} if the debugger is not attached
842 to least one process.
843
844 @raise NotImplementedError:
845 Current architecture is not C{i386} or C{amd64}.
846
847 @warning:
848 This method uses the processor's machine specific registers (MSR).
849 It could potentially brick your machine.
850 It works on my machine, but your mileage may vary.
851
852 @note:
853 It doesn't seem to work in VMWare or VirtualBox machines.
854 Maybe it fails in other virtualization/emulation environments,
855 no extensive testing was made so far.
856 """
857 cls.write_msr(DebugRegister.DebugCtlMSR,
858 DebugRegister.BranchTrapFlag | DebugRegister.LastBranchRecord)
859
860 @classmethod
862 """
863 Returns the source and destination addresses of the last taken branch.
864
865 @rtype: tuple( int, int )
866 @return: Source and destination addresses of the last taken branch.
867
868 @raise WindowsError:
869 Raises an exception on error.
870
871 @raise NotImplementedError:
872 Current architecture is not C{i386} or C{amd64}.
873
874 @warning:
875 This method uses the processor's machine specific registers (MSR).
876 It could potentially brick your machine.
877 It works on my machine, but your mileage may vary.
878
879 @note:
880 It doesn't seem to work in VMWare or VirtualBox machines.
881 Maybe it fails in other virtualization/emulation environments,
882 no extensive testing was made so far.
883 """
884 LastBranchFromIP = cls.read_msr(DebugRegister.LastBranchFromIP)
885 LastBranchToIP = cls.read_msr(DebugRegister.LastBranchToIP)
886 return ( LastBranchFromIP, LastBranchToIP )
887
888
889
890 @classmethod
891 - def get_postmortem_debugger(cls, bits = None):
892 """
893 Returns the postmortem debugging settings from the Registry.
894
895 @see: L{set_postmortem_debugger}
896
897 @type bits: int
898 @param bits: Set to C{32} for the 32 bits debugger, or C{64} for the
899 64 bits debugger. Set to {None} for the default (L{System.bits}.
900
901 @rtype: tuple( str, bool, int )
902 @return: A tuple containing the command line string to the postmortem
903 debugger, a boolean specifying if user interaction is allowed
904 before attaching, and an integer specifying a user defined hotkey.
905 Any member of the tuple may be C{None}.
906 See L{set_postmortem_debugger} for more details.
907
908 @raise WindowsError:
909 Raises an exception on error.
910 """
911 if bits is None:
912 bits = cls.bits
913 elif bits not in (32, 64):
914 raise NotImplementedError("Unknown architecture (%r bits)" % bits)
915
916 if bits == 32 and cls.bits == 64:
917 keyname = 'HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug'
918 else:
919 keyname = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug'
920
921 key = cls.registry[keyname]
922
923 debugger = key.get('Debugger')
924 auto = key.get('Auto')
925 hotkey = key.get('UserDebuggerHotkey')
926
927 if auto is not None:
928 auto = bool(auto)
929
930 return (debugger, auto, hotkey)
931
932 @classmethod
934 """
935 Returns the exclusion list for the postmortem debugger.
936
937 @see: L{get_postmortem_debugger}
938
939 @type bits: int
940 @param bits: Set to C{32} for the 32 bits debugger, or C{64} for the
941 64 bits debugger. Set to {None} for the default (L{System.bits}).
942
943 @rtype: list( str )
944 @return: List of excluded application filenames.
945
946 @raise WindowsError:
947 Raises an exception on error.
948 """
949 if bits is None:
950 bits = cls.bits
951 elif bits not in (32, 64):
952 raise NotImplementedError("Unknown architecture (%r bits)" % bits)
953
954 if bits == 32 and cls.bits == 64:
955 keyname = 'HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList'
956 else:
957 keyname = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList'
958
959 try:
960 key = cls.registry[keyname]
961 except KeyError:
962 return []
963
964 return [name for (name, enabled) in key.items() if enabled]
965
966 @classmethod
967 - def set_postmortem_debugger(cls, cmdline,
968 auto = None, hotkey = None, bits = None):
969 """
970 Sets the postmortem debugging settings in the Registry.
971
972 @warning: This method requires administrative rights.
973
974 @see: L{get_postmortem_debugger}
975
976 @type cmdline: str
977 @param cmdline: Command line to the new postmortem debugger.
978 When the debugger is invoked, the first "%ld" is replaced with the
979 process ID and the second "%ld" is replaced with the event handle.
980 Don't forget to enclose the program filename in double quotes if
981 the path contains spaces.
982
983 @type auto: bool
984 @param auto: Set to C{True} if no user interaction is allowed, C{False}
985 to prompt a confirmation dialog before attaching.
986 Use C{None} to leave this value unchanged.
987
988 @type hotkey: int
989 @param hotkey: Virtual key scan code for the user defined hotkey.
990 Use C{0} to disable the hotkey.
991 Use C{None} to leave this value unchanged.
992
993 @type bits: int
994 @param bits: Set to C{32} for the 32 bits debugger, or C{64} for the
995 64 bits debugger. Set to {None} for the default (L{System.bits}).
996
997 @rtype: tuple( str, bool, int )
998 @return: Previously defined command line and auto flag.
999
1000 @raise WindowsError:
1001 Raises an exception on error.
1002 """
1003 if bits is None:
1004 bits = cls.bits
1005 elif bits not in (32, 64):
1006 raise NotImplementedError("Unknown architecture (%r bits)" % bits)
1007
1008 if bits == 32 and cls.bits == 64:
1009 keyname = 'HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug'
1010 else:
1011 keyname = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug'
1012
1013 key = cls.registry[keyname]
1014
1015 if cmdline is not None:
1016 key['Debugger'] = cmdline
1017 if auto is not None:
1018 key['Auto'] = int(bool(auto))
1019 if hotkey is not None:
1020 key['UserDebuggerHotkey'] = int(hotkey)
1021
1022 @classmethod
1023 - def add_to_postmortem_exclusion_list(cls, pathname, bits = None):
1024 """
1025 Adds the given filename to the exclusion list for postmortem debugging.
1026
1027 @warning: This method requires administrative rights.
1028
1029 @see: L{get_postmortem_exclusion_list}
1030
1031 @type pathname: str
1032 @param pathname:
1033 Application pathname to exclude from postmortem debugging.
1034
1035 @type bits: int
1036 @param bits: Set to C{32} for the 32 bits debugger, or C{64} for the
1037 64 bits debugger. Set to {None} for the default (L{System.bits}).
1038
1039 @raise WindowsError:
1040 Raises an exception on error.
1041 """
1042 if bits is None:
1043 bits = cls.bits
1044 elif bits not in (32, 64):
1045 raise NotImplementedError("Unknown architecture (%r bits)" % bits)
1046
1047 if bits == 32 and cls.bits == 64:
1048 keyname = 'HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList'
1049 else:
1050 keyname = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList'
1051
1052 try:
1053 key = cls.registry[keyname]
1054 except KeyError:
1055 key = cls.registry.create(keyname)
1056
1057 key[pathname] = 1
1058
1059 @classmethod
1060 - def remove_from_postmortem_exclusion_list(cls, pathname, bits = None):
1061 """
1062 Removes the given filename to the exclusion list for postmortem
1063 debugging from the Registry.
1064
1065 @warning: This method requires administrative rights.
1066
1067 @warning: Don't ever delete entries you haven't created yourself!
1068 Some entries are set by default for your version of Windows.
1069 Deleting them might deadlock your system under some circumstances.
1070
1071 For more details see:
1072 U{http://msdn.microsoft.com/en-us/library/bb204634(v=vs.85).aspx}
1073
1074 @see: L{get_postmortem_exclusion_list}
1075
1076 @type pathname: str
1077 @param pathname: Application pathname to remove from the postmortem
1078 debugging exclusion list.
1079
1080 @type bits: int
1081 @param bits: Set to C{32} for the 32 bits debugger, or C{64} for the
1082 64 bits debugger. Set to {None} for the default (L{System.bits}).
1083
1084 @raise WindowsError:
1085 Raises an exception on error.
1086 """
1087 if bits is None:
1088 bits = cls.bits
1089 elif bits not in (32, 64):
1090 raise NotImplementedError("Unknown architecture (%r bits)" % bits)
1091
1092 if bits == 32 and cls.bits == 64:
1093 keyname = 'HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList'
1094 else:
1095 keyname = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList'
1096
1097 try:
1098 key = cls.registry[keyname]
1099 except KeyError:
1100 return
1101
1102 try:
1103 del key[pathname]
1104 except KeyError:
1105 return
1106
1107
1108
1109 @staticmethod
1111 """
1112 Retrieve a list of all system services.
1113
1114 @see: L{get_active_services},
1115 L{start_service}, L{stop_service},
1116 L{pause_service}, L{resume_service}
1117
1118 @rtype: list( L{win32.ServiceStatusProcessEntry} )
1119 @return: List of service status descriptors.
1120 """
1121 with win32.OpenSCManager(
1122 dwDesiredAccess = win32.SC_MANAGER_ENUMERATE_SERVICE
1123 ) as hSCManager:
1124 try:
1125 return win32.EnumServicesStatusEx(hSCManager)
1126 except AttributeError:
1127 return win32.EnumServicesStatus(hSCManager)
1128
1129 @staticmethod
1148
1149 @staticmethod
1151 """
1152 Get the service descriptor for the given service name.
1153
1154 @see: L{start_service}, L{stop_service},
1155 L{pause_service}, L{resume_service}
1156
1157 @type name: str
1158 @param name: Service unique name. You can get this value from the
1159 C{ServiceName} member of the service descriptors returned by
1160 L{get_services} or L{get_active_services}.
1161
1162 @rtype: L{win32.ServiceStatusProcess}
1163 @return: Service status descriptor.
1164 """
1165 with win32.OpenSCManager(
1166 dwDesiredAccess = win32.SC_MANAGER_ENUMERATE_SERVICE
1167 ) as hSCManager:
1168 with win32.OpenService(hSCManager, name,
1169 dwDesiredAccess = win32.SERVICE_QUERY_STATUS
1170 ) as hService:
1171 try:
1172 return win32.QueryServiceStatusEx(hService)
1173 except AttributeError:
1174 return win32.QueryServiceStatus(hService)
1175
1176 @staticmethod
1178 """
1179 Get the service display name for the given service name.
1180
1181 @see: L{get_service}
1182
1183 @type name: str
1184 @param name: Service unique name. You can get this value from the
1185 C{ServiceName} member of the service descriptors returned by
1186 L{get_services} or L{get_active_services}.
1187
1188 @rtype: str
1189 @return: Service display name.
1190 """
1191 with win32.OpenSCManager(
1192 dwDesiredAccess = win32.SC_MANAGER_ENUMERATE_SERVICE
1193 ) as hSCManager:
1194 return win32.GetServiceDisplayName(hSCManager, name)
1195
1196 @staticmethod
1198 """
1199 Get the service unique name given its display name.
1200
1201 @see: L{get_service}
1202
1203 @type displayName: str
1204 @param displayName: Service display name. You can get this value from
1205 the C{DisplayName} member of the service descriptors returned by
1206 L{get_services} or L{get_active_services}.
1207
1208 @rtype: str
1209 @return: Service unique name.
1210 """
1211 with win32.OpenSCManager(
1212 dwDesiredAccess = win32.SC_MANAGER_ENUMERATE_SERVICE
1213 ) as hSCManager:
1214 return win32.GetServiceKeyName(hSCManager, displayName)
1215
1216 @staticmethod
1218 """
1219 Start the service given by name.
1220
1221 @warn: This method requires UAC elevation in Windows Vista and above.
1222
1223 @see: L{stop_service}, L{pause_service}, L{resume_service}
1224
1225 @type name: str
1226 @param name: Service unique name. You can get this value from the
1227 C{ServiceName} member of the service descriptors returned by
1228 L{get_services} or L{get_active_services}.
1229 """
1230 with win32.OpenSCManager(
1231 dwDesiredAccess = win32.SC_MANAGER_CONNECT
1232 ) as hSCManager:
1233 with win32.OpenService(hSCManager, name,
1234 dwDesiredAccess = win32.SERVICE_START
1235 ) as hService:
1236 win32.StartService(hService)
1237
1238 @staticmethod
1255
1256 @staticmethod
1275
1276 @staticmethod
1295
1296
1297