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 Registry access.
33
34 @group Instrumentation:
35 Registry, RegistryKey
36 """
37
38 from __future__ import with_statement
39
40 __revision__ = "$Id: registry.py 1299 2013-12-20 09:30:55Z qvasimodo $"
41
42 __all__ = ['Registry']
43
44 import win32
45 import collections
46 import warnings
79
83 """
84 Exposes a single Windows Registry key as a dictionary-like object.
85
86 @see: L{Registry}
87
88 @type path: str
89 @ivar path: Registry key path.
90
91 @type handle: L{win32.RegistryKeyHandle}
92 @ivar handle: Registry key handle.
93 """
94
96 """
97 @type path: str
98 @param path: Registry key path.
99
100 @type handle: L{win32.RegistryKeyHandle}
101 @param handle: Registry key handle.
102 """
103 super(RegistryKey, self).__init__()
104 if path.endswith('\\'):
105 path = path[:-1]
106 self._path = path
107 self._handle = handle
108
109 @property
112
113 @property
115
116
117
118 return self._handle
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
155
163
166
169
179
189
199
212
225
238
240 """
241 Retrieves the low-level data type for the given value.
242
243 @type name: str
244 @param name: Registry value name.
245
246 @rtype: int
247 @return: One of the following constants:
248 - L{win32.REG_NONE} (0)
249 - L{win32.REG_SZ} (1)
250 - L{win32.REG_EXPAND_SZ} (2)
251 - L{win32.REG_BINARY} (3)
252 - L{win32.REG_DWORD} (4)
253 - L{win32.REG_DWORD_BIG_ENDIAN} (5)
254 - L{win32.REG_LINK} (6)
255 - L{win32.REG_MULTI_SZ} (7)
256 - L{win32.REG_RESOURCE_LIST} (8)
257 - L{win32.REG_FULL_RESOURCE_DESCRIPTOR} (9)
258 - L{win32.REG_RESOURCE_REQUIREMENTS_LIST} (10)
259 - L{win32.REG_QWORD} (11)
260
261 @raise KeyError: The specified value could not be found.
262 """
263 try:
264 return win32.RegQueryValueEx(self.handle, name)[1]
265 except WindowsError, e:
266 if e.winerror == win32.ERROR_FILE_NOT_FOUND:
267 raise KeyError(name)
268 raise
269
277
281
285
287 return '<Registry key: "%s">' % self._path
288
290 """
291 Iterates the subkeys for this Registry key.
292
293 @rtype: iter of L{RegistryKey}
294 @return: Iterator of subkeys.
295 """
296 handle = self.handle
297 index = 0
298 while 1:
299 subkey = win32.RegEnumKey(handle, index)
300 if subkey is None:
301 break
302 yield self.child(subkey)
303 index += 1
304
306 """
307 Returns a list of subkeys for this Registry key.
308
309 @rtype: list(L{RegistryKey})
310 @return: List of subkeys.
311 """
312
313 handle = self.handle
314 result = []
315 index = 0
316 while 1:
317 subkey = win32.RegEnumKey(handle, index)
318 if subkey is None:
319 break
320 result.append( self.child(subkey) )
321 index += 1
322 return result
323
324 - def child(self, subkey):
325 """
326 Retrieves a subkey for this Registry key, given its name.
327
328 @type subkey: str
329 @param subkey: Name of the subkey.
330
331 @rtype: L{RegistryKey}
332 @return: Subkey.
333 """
334 path = self._path + '\\' + subkey
335 handle = win32.RegOpenKey(self.handle, subkey)
336 return RegistryKey(path, handle)
337
339 """
340 Flushes changes immediately to disk.
341
342 This method is normally not needed, as the Registry writes changes
343 to disk by itself. This mechanism is provided to ensure the write
344 happens immediately, as opposed to whenever the OS wants to.
345
346 @warn: Calling this method too often may degrade performance.
347 """
348 win32.RegFlushKey(self.handle)
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370 -class Registry (_RegistryContainer):
371 """
372 Exposes the Windows Registry as a Python container.
373
374 @type machine: str or None
375 @ivar machine: For a remote Registry, the machine name.
376 For a local Registry, the value is C{None}.
377 """
378
379 _hives_by_name = {
380
381
382 'HKCR' : win32.HKEY_CLASSES_ROOT,
383 'HKCU' : win32.HKEY_CURRENT_USER,
384 'HKLM' : win32.HKEY_LOCAL_MACHINE,
385 'HKU' : win32.HKEY_USERS,
386 'HKPD' : win32.HKEY_PERFORMANCE_DATA,
387 'HKCC' : win32.HKEY_CURRENT_CONFIG,
388
389
390 'HKEY_CLASSES_ROOT' : win32.HKEY_CLASSES_ROOT,
391 'HKEY_CURRENT_USER' : win32.HKEY_CURRENT_USER,
392 'HKEY_LOCAL_MACHINE' : win32.HKEY_LOCAL_MACHINE,
393 'HKEY_USERS' : win32.HKEY_USERS,
394 'HKEY_PERFORMANCE_DATA' : win32.HKEY_PERFORMANCE_DATA,
395 'HKEY_CURRENT_CONFIG' : win32.HKEY_CURRENT_CONFIG,
396 }
397
398 _hives_by_value = {
399 win32.HKEY_CLASSES_ROOT : 'HKEY_CLASSES_ROOT',
400 win32.HKEY_CURRENT_USER : 'HKEY_CURRENT_USER',
401 win32.HKEY_LOCAL_MACHINE : 'HKEY_LOCAL_MACHINE',
402 win32.HKEY_USERS : 'HKEY_USERS',
403 win32.HKEY_PERFORMANCE_DATA : 'HKEY_PERFORMANCE_DATA',
404 win32.HKEY_CURRENT_CONFIG : 'HKEY_CURRENT_CONFIG',
405 }
406
407 _hives = sorted(_hives_by_value.itervalues())
408
410 """
411 Opens a local or remote registry.
412
413 @type machine: str
414 @param machine: Optional machine name. If C{None} it opens the local
415 registry.
416 """
417 self._machine = machine
418 self._remote_hives = {}
419
420 @property
423
425 """
426 Splits a Registry path and returns the hive and key.
427
428 @type path: str
429 @param path: Registry path.
430
431 @rtype: tuple( int, str )
432 @return: Tuple containing the hive handle and the subkey path.
433 The hive handle is always one of the following integer constants:
434 - L{win32.HKEY_CLASSES_ROOT}
435 - L{win32.HKEY_CURRENT_USER}
436 - L{win32.HKEY_LOCAL_MACHINE}
437 - L{win32.HKEY_USERS}
438 - L{win32.HKEY_PERFORMANCE_DATA}
439 - L{win32.HKEY_CURRENT_CONFIG}
440 """
441 if '\\' in path:
442 p = path.find('\\')
443 hive = path[:p]
444 path = path[p+1:]
445 else:
446 hive = path
447 path = None
448 handle = self._hives_by_name[ hive.upper() ]
449 return handle, path
450
452 """
453 Parses a Registry path and returns the hive and key.
454
455 @type path: str
456 @param path: Registry path.
457
458 @rtype: tuple( int, str )
459 @return: Tuple containing the hive handle and the subkey path.
460 For a local Registry, the hive handle is an integer.
461 For a remote Registry, the hive handle is a L{RegistryKeyHandle}.
462 """
463 handle, path = self._split_path(path)
464 if self._machine is not None:
465 handle = self._connect_hive(handle)
466 return handle, path
467
469 """
470 Joins the hive and key to make a Registry path.
471
472 @type hive: int
473 @param hive: Registry hive handle.
474 The hive handle must be one of the following integer constants:
475 - L{win32.HKEY_CLASSES_ROOT}
476 - L{win32.HKEY_CURRENT_USER}
477 - L{win32.HKEY_LOCAL_MACHINE}
478 - L{win32.HKEY_USERS}
479 - L{win32.HKEY_PERFORMANCE_DATA}
480 - L{win32.HKEY_CURRENT_CONFIG}
481
482 @type subkey: str
483 @param subkey: Subkey path.
484
485 @rtype: str
486 @return: Registry path.
487 """
488 path = self._hives_by_value[hive]
489 if subkey:
490 path = path + '\\' + subkey
491 return path
492
494 """
495 Sanitizes the given Registry path.
496
497 @type path: str
498 @param path: Registry path.
499
500 @rtype: str
501 @return: Registry path.
502 """
503 return self._join_path( *self._split_path(path) )
504
506 """
507 Connect to the specified hive of a remote Registry.
508
509 @note: The connection will be cached, to close all connections and
510 erase this cache call the L{close} method.
511
512 @type hive: int
513 @param hive: Hive to connect to.
514
515 @rtype: L{win32.RegistryKeyHandle}
516 @return: Open handle to the remote Registry hive.
517 """
518 try:
519 handle = self._remote_hives[hive]
520 except KeyError:
521 handle = win32.RegConnectRegistry(self._machine, hive)
522 self._remote_hives[hive] = handle
523 return handle
524
526 """
527 Closes all open connections to the remote Registry.
528
529 No exceptions are raised, even if an error occurs.
530
531 This method has no effect when opening the local Registry.
532
533 The remote Registry will still be accessible after calling this method
534 (new connections will be opened automatically on access).
535 """
536 while self._remote_hives:
537 hive = self._remote_hives.popitem()[1]
538 try:
539 hive.close()
540 except Exception, e:
541 try:
542 msg = "Cannot close registry hive handle %s, reason: %s"
543 msg %= (hive.value, str(e))
544 warnings.warn(msg)
545 except Exception:
546 pass
547
550
551 - def __exit__(self, exc_type, exc_value, traceback):
553
555 if self._machine:
556 return '<Remote Registry at "%s">' % self._machine
557 return '<Local Registry>'
558
568
579
581 do_copy = isinstance(value, RegistryKey)
582 if not do_copy and not isinstance(value, str) \
583 and not isinstance(value, unicode):
584 if isinstance(value, object):
585 t = value.__class__.__name__
586 else:
587 t = type(value)
588 raise TypeError("Expected string or RegistryKey, got %s" % t)
589 hive, subpath = self._parse_path(path)
590 with win32.RegCreateKey(hive, subpath) as handle:
591 if do_copy:
592 win32.RegCopyTree(value.handle, None, handle)
593 else:
594 win32.RegSetValueEx(handle, None, value)
595
596
597
599 hive, subpath = self._parse_path(path)
600 if not subpath:
601 raise TypeError(
602 "Are you SURE you want to wipe out an entire hive?!"
603 " Call win32.RegDeleteTree() directly if you must...")
604 try:
605 win32.RegDeleteTree(hive, subpath)
606 except WindowsError, e:
607 if e.winerror == win32.ERROR_FILE_NOT_FOUND:
608 raise KeyError(path)
609 raise
610
625
627 """
628 Returns a list of subkeys for the given Registry key.
629
630 @type path: str
631 @param path: Registry key path.
632
633 @rtype: list(str)
634 @return: List of subkey names.
635 """
636 result = list()
637 hive, subpath = self._parse_path(path)
638 with win32.RegOpenKey(hive, subpath) as handle:
639 index = 0
640 while 1:
641 name = win32.RegEnumKey(handle, index)
642 if name is None:
643 break
644 result.append(name)
645 index += 1
646 return result
647
649 """
650 Returns a recursive iterator on the specified key and its subkeys.
651
652 @type path: str
653 @param path: Registry key path.
654
655 @rtype: iterator
656 @return: Recursive iterator that returns Registry key paths.
657
658 @raise KeyError: The specified path does not exist.
659 """
660 if path.endswith('\\'):
661 path = path[:-1]
662 if not self.has_key(path):
663 raise KeyError(path)
664 stack = collections.deque()
665 stack.appendleft(path)
666 return self.__iterate(stack)
667
669 """
670 Returns an iterator that crawls the entire Windows Registry.
671 """
672 stack = collections.deque(self._hives)
673 stack.reverse()
674 return self.__iterate(stack)
675
687