1""" 2Manage the Windows registry 3 4----- 5Hives 6----- 7Hives are the main sections of the registry and all begin with the word HKEY. 8 9 - HKEY_LOCAL_MACHINE 10 - HKEY_CURRENT_USER 11 - HKEY_USER 12 13---- 14Keys 15---- 16Keys are the folders in the registry. Keys can have many nested subkeys. Keys 17can have a value assigned to them under the (Default) value name 18 19----------------- 20Values or Entries 21----------------- 22Values/Entries are name/data pairs. There can be many values in a key. The 23(Default) value corresponds to the Key itself, the rest are their own name/value 24pairs. 25 26:depends: - PyWin32 27""" 28# When production windows installer is using Python 3, Python 2 code can be removed 29 30import logging 31import sys 32 33import salt.utils.platform 34import salt.utils.stringutils 35from salt.exceptions import CommandExecutionError 36 37try: 38 import win32gui 39 import win32api 40 import win32con 41 42 HAS_WINDOWS_MODULES = True 43except ImportError: 44 HAS_WINDOWS_MODULES = False 45 46 47PY2 = sys.version_info[0] == 2 48log = logging.getLogger(__name__) 49 50# Define the module's virtual name 51__virtualname__ = "reg" 52 53 54def __virtual__(): 55 """ 56 Only works on Windows systems with the PyWin32 57 """ 58 if not salt.utils.platform.is_windows(): 59 return ( 60 False, 61 "reg execution module failed to load: " 62 "The module will only run on Windows systems", 63 ) 64 65 if not HAS_WINDOWS_MODULES: 66 return ( 67 False, 68 "reg execution module failed to load: " 69 "One of the following libraries did not load: " 70 "win32gui, win32con, win32api", 71 ) 72 73 return __virtualname__ 74 75 76def _to_mbcs(vdata): 77 """ 78 Converts unicode to to current users character encoding. Use this for values 79 returned by reg functions 80 """ 81 return salt.utils.stringutils.to_unicode(vdata, "mbcs") 82 83 84def _to_unicode(vdata): 85 """ 86 Converts from current users character encoding to unicode. Use this for 87 parameters being pass to reg functions 88 """ 89 # None does not convert to Unicode 90 if vdata is None: 91 vdata = "" 92 if isinstance(vdata, int): 93 vdata = str(vdata) 94 return salt.utils.stringutils.to_unicode(vdata, "utf-8") 95 96 97class Registry: # pylint: disable=R0903 98 """ 99 This was put in a class to delay usage until this module is actually used 100 This class contains all the lookup dicts for working with the registry 101 """ 102 103 def __init__(self): 104 self.hkeys = { 105 "HKEY_CURRENT_CONFIG": win32con.HKEY_CURRENT_CONFIG, 106 "HKEY_CLASSES_ROOT": win32con.HKEY_CLASSES_ROOT, 107 "HKEY_CURRENT_USER": win32con.HKEY_CURRENT_USER, 108 "HKEY_LOCAL_MACHINE": win32con.HKEY_LOCAL_MACHINE, 109 "HKEY_USERS": win32con.HKEY_USERS, 110 "HKCC": win32con.HKEY_CURRENT_CONFIG, 111 "HKCR": win32con.HKEY_CLASSES_ROOT, 112 "HKCU": win32con.HKEY_CURRENT_USER, 113 "HKLM": win32con.HKEY_LOCAL_MACHINE, 114 "HKU": win32con.HKEY_USERS, 115 } 116 self.vtype = { 117 "REG_BINARY": win32con.REG_BINARY, 118 "REG_DWORD": win32con.REG_DWORD, 119 "REG_EXPAND_SZ": win32con.REG_EXPAND_SZ, 120 "REG_MULTI_SZ": win32con.REG_MULTI_SZ, 121 "REG_SZ": win32con.REG_SZ, 122 "REG_QWORD": win32con.REG_QWORD, 123 } 124 self.opttype = {"REG_OPTION_NON_VOLATILE": 0, "REG_OPTION_VOLATILE": 1} 125 # Return Unicode due to from __future__ import unicode_literals 126 self.vtype_reverse = { 127 win32con.REG_BINARY: "REG_BINARY", 128 win32con.REG_DWORD: "REG_DWORD", 129 win32con.REG_EXPAND_SZ: "REG_EXPAND_SZ", 130 win32con.REG_MULTI_SZ: "REG_MULTI_SZ", 131 win32con.REG_SZ: "REG_SZ", 132 win32con.REG_QWORD: "REG_QWORD", 133 } 134 self.opttype_reverse = {0: "REG_OPTION_NON_VOLATILE", 1: "REG_OPTION_VOLATILE"} 135 # delete_key_recursive uses this to check the subkey contains enough \ 136 # as we do not want to remove all or most of the registry 137 self.subkey_slash_check = { 138 win32con.HKEY_CURRENT_USER: 0, 139 win32con.HKEY_LOCAL_MACHINE: 1, 140 win32con.HKEY_USERS: 1, 141 win32con.HKEY_CURRENT_CONFIG: 1, 142 win32con.HKEY_CLASSES_ROOT: 1, 143 } 144 145 self.registry_32 = { 146 True: win32con.KEY_READ | win32con.KEY_WOW64_32KEY, 147 False: win32con.KEY_READ, 148 } 149 150 def __getattr__(self, k): 151 try: 152 return self.hkeys[k] 153 except KeyError: 154 msg = "No hkey named '{0}. Try one of {1}'" 155 hkeys = ", ".join(self.hkeys) 156 raise CommandExecutionError(msg.format(k, hkeys)) 157 158 159def key_exists(hive, key, use_32bit_registry=False): 160 """ 161 Check that the key is found in the registry. This refers to keys and not 162 value/data pairs. To check value/data pairs, use ``value_exists`` 163 164 Args: 165 166 hive (str): The hive to connect to 167 168 key (str): The key to check 169 170 use_32bit_registry (bool): Look in the 32bit portion of the registry 171 172 Returns: 173 bool: True if exists, otherwise False 174 175 Usage: 176 177 .. code-block:: python 178 179 import salt.utils.win_reg as reg 180 reg.key_exists(hive='HKLM', key='SOFTWARE\\Microsoft') 181 """ 182 local_hive = _to_unicode(hive) 183 local_key = _to_unicode(key) 184 185 registry = Registry() 186 try: 187 hkey = registry.hkeys[local_hive] 188 except KeyError: 189 raise CommandExecutionError("Invalid Hive: {}".format(local_hive)) 190 access_mask = registry.registry_32[use_32bit_registry] 191 192 handle = None 193 try: 194 handle = win32api.RegOpenKeyEx(hkey, local_key, 0, access_mask) 195 return True 196 except win32api.error as exc: 197 if exc.winerror == 2: 198 return False 199 raise 200 finally: 201 if handle: 202 win32api.RegCloseKey(handle) 203 204 205def value_exists(hive, key, vname, use_32bit_registry=False): 206 """ 207 Check that the value/data pair is found in the registry. 208 209 .. versionadded:: 2018.3.4 210 211 Args: 212 213 hive (str): The hive to connect to 214 215 key (str): The key to check in 216 217 vname (str): The name of the value/data pair you're checking 218 219 use_32bit_registry (bool): Look in the 32bit portion of the registry 220 221 Returns: 222 bool: True if exists, otherwise False 223 224 Usage: 225 226 .. code-block:: python 227 228 import salt.utils.win_reg as reg 229 reg.value_exists(hive='HKLM', 230 key='SOFTWARE\\Microsoft\\Windows\\CurrentVersion', 231 vname='CommonFilesDir') 232 """ 233 local_hive = _to_unicode(hive) 234 local_key = _to_unicode(key) 235 local_vname = _to_unicode(vname) 236 237 registry = Registry() 238 try: 239 hkey = registry.hkeys[local_hive] 240 except KeyError: 241 raise CommandExecutionError("Invalid Hive: {}".format(local_hive)) 242 access_mask = registry.registry_32[use_32bit_registry] 243 244 try: 245 handle = win32api.RegOpenKeyEx(hkey, local_key, 0, access_mask) 246 except win32api.error as exc: 247 if exc.winerror == 2: 248 # The key containing the value/data pair does not exist 249 return False 250 raise 251 252 try: 253 # RegQueryValueEx returns and accepts unicode data 254 _, _ = win32api.RegQueryValueEx(handle, local_vname) 255 # value/data pair exists 256 return True 257 except win32api.error as exc: 258 if exc.winerror == 2 and vname is None: 259 # value/data pair exists but is empty 260 return True 261 else: 262 # value/data pair not found 263 return False 264 finally: 265 win32api.RegCloseKey(handle) 266 267 268def broadcast_change(): 269 """ 270 Refresh the windows environment. 271 272 .. note:: 273 This will only effect new processes and windows. Services will not see 274 the change until the system restarts. 275 276 Returns: 277 bool: True if successful, otherwise False 278 279 Usage: 280 281 .. code-block:: python 282 283 import salt.utils.win_reg 284 winreg.broadcast_change() 285 """ 286 # https://msdn.microsoft.com/en-us/library/windows/desktop/ms644952(v=vs.85).aspx 287 _, res = win32gui.SendMessageTimeout( 288 win32con.HWND_BROADCAST, 289 win32con.WM_SETTINGCHANGE, 290 0, 291 0, 292 win32con.SMTO_ABORTIFHUNG, 293 5000, 294 ) 295 return not bool(res) 296 297 298def list_keys(hive, key=None, use_32bit_registry=False): 299 """ 300 Enumerates the subkeys in a registry key or hive. 301 302 Args: 303 304 hive (str): 305 The name of the hive. Can be one of the following: 306 307 - HKEY_LOCAL_MACHINE or HKLM 308 - HKEY_CURRENT_USER or HKCU 309 - HKEY_USERS or HKU 310 - HKEY_CLASSES_ROOT or HKCR 311 - HKEY_CURRENT_CONFIG or HKCC 312 313 key (str): 314 The key (looks like a path) to the value name. If a key is not 315 passed, the keys under the hive will be returned. 316 317 use_32bit_registry (bool): 318 Accesses the 32bit portion of the registry on 64 bit installations. 319 On 32bit machines this is ignored. 320 321 Returns: 322 list: A list of keys/subkeys under the hive or key. 323 324 Usage: 325 326 .. code-block:: python 327 328 import salt.utils.win_reg 329 winreg.list_keys(hive='HKLM', key='SOFTWARE\\Microsoft') 330 """ 331 332 local_hive = _to_unicode(hive) 333 local_key = _to_unicode(key) 334 335 registry = Registry() 336 try: 337 hkey = registry.hkeys[local_hive] 338 except KeyError: 339 raise CommandExecutionError("Invalid Hive: {}".format(local_hive)) 340 access_mask = registry.registry_32[use_32bit_registry] 341 342 subkeys = [] 343 handle = None 344 try: 345 handle = win32api.RegOpenKeyEx(hkey, local_key, 0, access_mask) 346 347 for i in range(win32api.RegQueryInfoKey(handle)[0]): 348 subkey = win32api.RegEnumKey(handle, i) 349 if PY2: 350 subkeys.append(_to_mbcs(subkey)) 351 else: 352 subkeys.append(subkey) 353 354 except win32api.error as exc: 355 if exc.winerror == 2: 356 log.debug(r"Cannot find key: %s\%s", hive, key, exc_info=True) 357 return False, r"Cannot find key: {}\{}".format(hive, key) 358 raise 359 360 finally: 361 if handle: 362 handle.Close() 363 364 return subkeys 365 366 367def list_values(hive, key=None, use_32bit_registry=False): 368 """ 369 Enumerates the values in a registry key or hive. 370 371 .. note:: 372 The ``(Default)`` value will only be returned if it is set, otherwise it 373 will not be returned in the list of values. 374 375 Args: 376 377 hive (str): 378 The name of the hive. Can be one of the following: 379 380 - HKEY_LOCAL_MACHINE or HKLM 381 - HKEY_CURRENT_USER or HKCU 382 - HKEY_USER or HKU 383 - HKEY_CLASSES_ROOT or HKCR 384 - HKEY_CURRENT_CONFIG or HKCC 385 386 key (str): 387 The key (looks like a path) to the value name. If a key is not 388 passed, the values under the hive will be returned. 389 390 use_32bit_registry (bool): 391 Accesses the 32bit portion of the registry on 64 bit installations. 392 On 32bit machines this is ignored. 393 394 Returns: 395 list: A list of values under the hive or key. 396 397 Usage: 398 399 .. code-block:: python 400 401 import salt.utils.win_reg 402 winreg.list_values(hive='HKLM', key='SYSTEM\\CurrentControlSet\\Services\\Tcpip') 403 """ 404 local_hive = _to_unicode(hive) 405 local_key = _to_unicode(key) 406 407 registry = Registry() 408 try: 409 hkey = registry.hkeys[local_hive] 410 except KeyError: 411 raise CommandExecutionError("Invalid Hive: {}".format(local_hive)) 412 access_mask = registry.registry_32[use_32bit_registry] 413 handle = None 414 values = list() 415 416 try: 417 handle = win32api.RegOpenKeyEx(hkey, local_key, 0, access_mask) 418 419 for i in range(win32api.RegQueryInfoKey(handle)[1]): 420 vname, vdata, vtype = win32api.RegEnumValue(handle, i) 421 422 if not vname: 423 vname = "(Default)" 424 425 value = { 426 "hive": local_hive, 427 "key": local_key, 428 "vname": _to_mbcs(vname), 429 "vtype": registry.vtype_reverse[vtype], 430 "success": True, 431 } 432 # Only convert text types to unicode 433 if vtype == win32con.REG_MULTI_SZ: 434 value["vdata"] = [_to_mbcs(i) for i in vdata] 435 elif vtype in [win32con.REG_SZ, win32con.REG_EXPAND_SZ]: 436 value["vdata"] = _to_mbcs(vdata) 437 else: 438 value["vdata"] = vdata 439 values.append(value) 440 441 except win32api.error as exc: 442 if exc.winerror == 2: 443 log.debug(r"Cannot find key: %s\%s", hive, key) 444 return False, r"Cannot find key: {}\{}".format(hive, key) 445 raise 446 447 finally: 448 if handle: 449 handle.Close() 450 return values 451 452 453def read_value(hive, key, vname=None, use_32bit_registry=False): 454 r""" 455 Reads a registry value entry or the default value for a key. To read the 456 default value, don't pass ``vname`` 457 458 Args: 459 460 hive (str): The name of the hive. Can be one of the following: 461 462 - HKEY_LOCAL_MACHINE or HKLM 463 - HKEY_CURRENT_USER or HKCU 464 - HKEY_USER or HKU 465 - HKEY_CLASSES_ROOT or HKCR 466 - HKEY_CURRENT_CONFIG or HKCC 467 468 key (str): 469 The key (looks like a path) to the value name. 470 471 vname (str): 472 The value name. These are the individual name/data pairs under the 473 key. If not passed, the key (Default) value will be returned. 474 475 use_32bit_registry (bool): 476 Accesses the 32bit portion of the registry on 64bit installations. 477 On 32bit machines this is ignored. 478 479 Returns: 480 dict: A dictionary containing the passed settings as well as the 481 value_data if successful. If unsuccessful, sets success to False. 482 483 bool: Returns False if the key is not found 484 485 If vname is not passed: 486 487 - Returns the first unnamed value (Default) as a string. 488 - Returns none if first unnamed value is empty. 489 490 Usage: 491 492 The following will get the value of the ``version`` value name in the 493 ``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt`` key 494 495 .. code-block:: python 496 497 import salt.utils.win_reg as reg 498 reg.read_value(hive='HKLM', key='SOFTWARE\\Salt', vname='version') 499 500 Usage: 501 502 The following will get the default value of the 503 ``HKEY_LOCAL_MACHINE\\SOFTWARE\\Salt`` key 504 505 .. code-block:: python 506 507 import salt.utils.win_reg as reg 508 reg.read_value(hive='HKLM', key='SOFTWARE\\Salt') 509 """ 510 # If no name is passed, the default value of the key will be returned 511 # The value name is Default 512 513 # Setup the return array 514 local_hive = _to_unicode(hive) 515 local_key = _to_unicode(key) 516 local_vname = _to_unicode(vname) 517 518 ret = { 519 "hive": local_hive, 520 "key": local_key, 521 "vname": local_vname, 522 "vdata": None, 523 "success": True, 524 } 525 526 if not vname: 527 ret["vname"] = "(Default)" 528 529 registry = Registry() 530 try: 531 hkey = registry.hkeys[local_hive] 532 except KeyError: 533 raise CommandExecutionError("Invalid Hive: {}".format(local_hive)) 534 access_mask = registry.registry_32[use_32bit_registry] 535 536 try: 537 handle = win32api.RegOpenKeyEx(hkey, local_key, 0, access_mask) 538 try: 539 # RegQueryValueEx returns and accepts unicode data 540 vdata, vtype = win32api.RegQueryValueEx(handle, local_vname) 541 if vdata or vdata in [0, "", []]: 542 # Only convert text types to unicode 543 ret["vtype"] = registry.vtype_reverse[vtype] 544 if vtype == win32con.REG_MULTI_SZ: 545 ret["vdata"] = [_to_mbcs(i) for i in vdata] 546 elif vtype in [win32con.REG_SZ, win32con.REG_EXPAND_SZ]: 547 ret["vdata"] = _to_mbcs(vdata) 548 else: 549 ret["vdata"] = vdata 550 else: 551 ret["comment"] = "Empty Value" 552 except win32api.error as exc: 553 if exc.winerror == 2 and vname is None: 554 ret["vdata"] = "(value not set)" 555 ret["vtype"] = "REG_SZ" 556 elif exc.winerror == 2: 557 msg = "Cannot find {} in {}\\{}".format( 558 local_vname, local_hive, local_key 559 ) 560 log.trace(exc) 561 log.trace(msg) 562 ret["comment"] = msg 563 ret["success"] = False 564 else: 565 raise 566 except win32api.error as exc: 567 if exc.winerror == 2: 568 msg = "Cannot find key: {}\\{}".format(local_hive, local_key) 569 log.trace(exc) 570 log.trace(msg) 571 ret["comment"] = msg 572 ret["success"] = False 573 else: 574 raise 575 return ret 576 577 578def set_value( 579 hive, 580 key, 581 vname=None, 582 vdata=None, 583 vtype="REG_SZ", 584 use_32bit_registry=False, 585 volatile=False, 586): 587 """ 588 Sets a value in the registry. If ``vname`` is passed, it will be the value 589 for that value name, otherwise it will be the default value for the 590 specified key 591 592 Args: 593 594 hive (str): 595 The name of the hive. Can be one of the following 596 597 - HKEY_LOCAL_MACHINE or HKLM 598 - HKEY_CURRENT_USER or HKCU 599 - HKEY_USER or HKU 600 - HKEY_CLASSES_ROOT or HKCR 601 - HKEY_CURRENT_CONFIG or HKCC 602 603 key (str): 604 The key (looks like a path) to the value name. 605 606 vname (str): 607 The value name. These are the individual name/data pairs under the 608 key. If not passed, the key (Default) value will be set. 609 610 vdata (str, int, list, bytes): 611 The value you'd like to set. If a value name (vname) is passed, this 612 will be the data for that value name. If not, this will be the 613 (Default) value for the key. 614 615 The type of data this parameter expects is determined by the value 616 type specified in ``vtype``. The correspondence is as follows: 617 618 - REG_BINARY: Binary data (str in Py2, bytes in Py3) 619 - REG_DWORD: int 620 - REG_EXPAND_SZ: str 621 - REG_MULTI_SZ: list of str 622 - REG_QWORD: int 623 - REG_SZ: str 624 625 .. note:: 626 When setting REG_BINARY, string data will be converted to 627 binary. You can pass base64 encoded using the ``binascii`` 628 built-in module. Use ``binascii.b2a_base64('your data')`` 629 630 .. note:: 631 The type for the (Default) value is always REG_SZ and cannot be 632 changed. 633 634 .. note:: 635 This parameter is optional. If not passed, the Key will be 636 created with no associated item/value pairs. 637 638 vtype (str): 639 The value type. The possible values of the vtype parameter are 640 indicated above in the description of the vdata parameter. 641 642 use_32bit_registry (bool): 643 Sets the 32bit portion of the registry on 64bit installations. On 644 32bit machines this is ignored. 645 646 volatile (bool): 647 When this parameter has a value of True, the registry key will be 648 made volatile (i.e. it will not persist beyond a system reset or 649 shutdown). This parameter only has an effect when a key is being 650 created and at no other time. 651 652 Returns: 653 bool: True if successful, otherwise False 654 655 Usage: 656 657 This will set the version value to 2015.5.2 in the SOFTWARE\\Salt key in 658 the HKEY_LOCAL_MACHINE hive 659 660 .. code-block:: python 661 662 import salt.utils.win_reg 663 winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='version', vdata='2015.5.2') 664 665 Usage: 666 667 This function is strict about the type of vdata. For instance this 668 example will fail because vtype has a value of REG_SZ and vdata has a 669 type of int (as opposed to str as expected). 670 671 .. code-block:: python 672 673 import salt.utils.win_reg 674 winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='str_data', vdata=1.2) 675 676 Usage: 677 678 In this next example vdata is properly quoted and should succeed. 679 680 .. code-block:: python 681 682 import salt.utils.win_reg 683 winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='str_data', vdata='1.2') 684 685 Usage: 686 687 This is an example of using vtype REG_BINARY. Both ``set_value`` 688 commands will set the same value ``Salty Test`` 689 690 .. code-block:: python 691 692 import salt.utils.win_reg 693 winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='bin_data', vdata='Salty Test', vtype='REG_BINARY') 694 695 import binascii 696 bin_data = binascii.b2a_base64('Salty Test') 697 winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='bin_data_encoded', vdata=bin_data, vtype='REG_BINARY') 698 699 Usage: 700 701 An example using vtype REG_MULTI_SZ is as follows: 702 703 .. code-block:: python 704 705 import salt.utils.win_reg 706 winreg.set_value(hive='HKLM', key='SOFTWARE\\Salt', vname='list_data', vdata=['Salt', 'is', 'great'], vtype='REG_MULTI_SZ') 707 """ 708 local_hive = _to_unicode(hive) 709 local_key = _to_unicode(key) 710 local_vname = _to_unicode(vname) 711 local_vtype = _to_unicode(vtype) 712 713 registry = Registry() 714 try: 715 hkey = registry.hkeys[local_hive] 716 except KeyError: 717 raise CommandExecutionError("Invalid Hive: {}".format(local_hive)) 718 vtype_value = registry.vtype[local_vtype] 719 access_mask = registry.registry_32[use_32bit_registry] | win32con.KEY_ALL_ACCESS 720 721 local_vdata = cast_vdata(vdata=vdata, vtype=local_vtype) 722 723 if volatile: 724 create_options = registry.opttype["REG_OPTION_VOLATILE"] 725 else: 726 create_options = registry.opttype["REG_OPTION_NON_VOLATILE"] 727 728 handle = None 729 try: 730 handle, result = win32api.RegCreateKeyEx( 731 hkey, local_key, access_mask, Options=create_options 732 ) 733 msg = ( 734 "Created new key: %s\\%s" if result == 1 else "Opened existing key: %s\\%s" 735 ) 736 log.debug(msg, local_hive, local_key) 737 738 try: 739 win32api.RegSetValueEx(handle, local_vname, 0, vtype_value, local_vdata) 740 win32api.RegFlushKey(handle) 741 broadcast_change() 742 return True 743 except TypeError as exc: 744 log.exception('"vdata" does not match the expected data type.\n%s', exc) 745 return False 746 except (SystemError, ValueError) as exc: 747 log.exception("Encountered error setting registry value.\n%s", exc) 748 return False 749 750 except win32api.error as exc: 751 log.exception( 752 "Error creating/opening key: %s\\%s\n%s", 753 local_hive, 754 local_key, 755 exc.winerror, 756 ) 757 return False 758 759 finally: 760 if handle: 761 win32api.RegCloseKey(handle) 762 763 764def cast_vdata(vdata=None, vtype="REG_SZ"): 765 """ 766 Cast the ``vdata` value to the appropriate data type for the registry type 767 specified in ``vtype`` 768 769 Args: 770 771 vdata (str, int, list, bytes): The data to cast 772 773 vtype (str): 774 The type of data to be written to the registry. Must be one of the 775 following: 776 777 - REG_BINARY 778 - REG_DWORD 779 - REG_EXPAND_SZ 780 - REG_MULTI_SZ 781 - REG_QWORD 782 - REG_SZ 783 784 Returns: 785 The vdata cast to the appropriate type. Will be unicode string, binary, 786 list of unicode strings, or int 787 788 Usage: 789 790 .. code-block:: python 791 792 import salt.utils.win_reg 793 winreg.cast_vdata(vdata='This is the string', vtype='REG_SZ') 794 """ 795 # Check data type and cast to expected type 796 # int will automatically become long on 64bit numbers 797 # https://www.python.org/dev/peps/pep-0237/ 798 799 registry = Registry() 800 vtype_value = registry.vtype[vtype] 801 802 # String Types to Unicode 803 if vtype_value in [win32con.REG_SZ, win32con.REG_EXPAND_SZ]: 804 return _to_unicode(vdata) 805 # Don't touch binary... if it's binary 806 elif vtype_value == win32con.REG_BINARY: 807 if isinstance(vdata, str): 808 # Unicode data must be encoded 809 return vdata.encode("utf-8") 810 return vdata 811 # Make sure REG_MULTI_SZ is a list of strings 812 elif vtype_value == win32con.REG_MULTI_SZ: 813 return [_to_unicode(i) for i in vdata] 814 # Make sure REG_QWORD is a 64 bit integer 815 elif vtype_value == win32con.REG_QWORD: 816 return int(vdata) 817 # Everything else is int 818 else: 819 return int(vdata) 820 821 822def delete_key_recursive(hive, key, use_32bit_registry=False): 823 """ 824 .. versionadded:: 2015.5.4 825 826 Delete a registry key to include all subkeys and value/data pairs. 827 828 Args: 829 830 hive (str): 831 The name of the hive. Can be one of the following 832 833 - HKEY_LOCAL_MACHINE or HKLM 834 - HKEY_CURRENT_USER or HKCU 835 - HKEY_USER or HKU 836 - HKEY_CLASSES_ROOT or HKCR 837 - HKEY_CURRENT_CONFIG or HKCC 838 839 key (str): 840 The key to remove (looks like a path) 841 842 use_32bit_registry (bool): 843 Deletes the 32bit portion of the registry on 64bit 844 installations. On 32bit machines this is ignored. 845 846 Returns: 847 dict: A dictionary listing the keys that deleted successfully as well as 848 those that failed to delete. 849 850 Usage: 851 852 The following example will remove ``salt`` and all its subkeys from the 853 ``SOFTWARE`` key in ``HKEY_LOCAL_MACHINE``: 854 855 .. code-block:: python 856 857 import salt.utils.win_reg 858 winreg.delete_key_recursive(hive='HKLM', key='SOFTWARE\\DeleteMe') 859 """ 860 861 local_hive = _to_unicode(hive) 862 local_key = _to_unicode(key) 863 864 # Instantiate the registry object 865 registry = Registry() 866 try: 867 hkey = registry.hkeys[local_hive] 868 except KeyError: 869 raise CommandExecutionError("Invalid Hive: {}".format(local_hive)) 870 key_path = local_key 871 access_mask = registry.registry_32[use_32bit_registry] | win32con.KEY_ALL_ACCESS 872 873 if not key_exists(local_hive, local_key, use_32bit_registry): 874 log.debug('"%s\\%s" not found', hive, key) 875 return False 876 877 if (len(key) > 1) and (key.count("\\", 1) < registry.subkey_slash_check[hkey]): 878 log.error('"%s\\%s" is too close to root, not safe to remove', hive, key) 879 return False 880 881 # Functions for traversing the registry tree 882 def _subkeys(_key): 883 """ 884 Enumerate keys 885 """ 886 i = 0 887 while True: 888 try: 889 subkey = win32api.RegEnumKey(_key, i) 890 yield _to_mbcs(subkey) 891 i += 1 892 except win32api.error: 893 break 894 895 def _traverse_registry_tree(_hkey, _keypath, _ret, _access_mask): 896 """ 897 Traverse the registry tree i.e. dive into the tree 898 """ 899 _key = win32api.RegOpenKeyEx(_hkey, _keypath, 0, _access_mask) 900 for subkeyname in _subkeys(_key): 901 subkeypath = "{}\\{}".format(_keypath, subkeyname) 902 _ret = _traverse_registry_tree(_hkey, subkeypath, _ret, access_mask) 903 _ret.append(subkeypath) 904 return _ret 905 906 # Get a reverse list of registry keys to be deleted 907 key_list = [] 908 key_list = _traverse_registry_tree(hkey, key_path, key_list, access_mask) 909 # Add the top level key last, all subkeys must be deleted first 910 key_list.append(key_path) 911 912 ret = {"Deleted": [], "Failed": []} 913 914 # Delete all sub_keys 915 for sub_key_path in key_list: 916 key_handle = None 917 try: 918 key_handle = win32api.RegOpenKeyEx(hkey, sub_key_path, 0, access_mask) 919 try: 920 win32api.RegDeleteKey(key_handle, "") 921 ret["Deleted"].append(r"{}\{}".format(hive, sub_key_path)) 922 except OSError as exc: 923 log.error(exc, exc_info=True) 924 ret["Failed"].append(r"{}\{} {}".format(hive, sub_key_path, exc)) 925 except win32api.error as exc: 926 log.error(exc, exc_info=True) 927 ret["Failed"].append(r"{}\{} {}".format(hive, sub_key_path, exc.strerror)) 928 finally: 929 if key_handle: 930 win32api.CloseHandle(key_handle) 931 932 broadcast_change() 933 934 return ret 935 936 937def delete_value(hive, key, vname=None, use_32bit_registry=False): 938 """ 939 Delete a registry value entry or the default value for a key. 940 941 Args: 942 943 hive (str): 944 The name of the hive. Can be one of the following 945 946 - HKEY_LOCAL_MACHINE or HKLM 947 - HKEY_CURRENT_USER or HKCU 948 - HKEY_USER or HKU 949 - HKEY_CLASSES_ROOT or HKCR 950 - HKEY_CURRENT_CONFIG or HKCC 951 952 key (str): 953 The key (looks like a path) to the value name. 954 955 vname (str): 956 The value name. These are the individual name/data pairs under the 957 key. If not passed, the key (Default) value will be deleted. 958 959 use_32bit_registry (bool): 960 Deletes the 32bit portion of the registry on 64bit installations. On 961 32bit machines this is ignored. 962 963 Return: 964 bool: True if successful, otherwise False 965 966 Usage: 967 968 .. code-block:: python 969 970 import salt.utils.win_reg 971 winreg.delete_value(hive='HKLM', key='SOFTWARE\\SaltTest', vname='version') 972 """ 973 local_hive = _to_unicode(hive) 974 local_key = _to_unicode(key) 975 local_vname = _to_unicode(vname) 976 977 registry = Registry() 978 try: 979 hkey = registry.hkeys[local_hive] 980 except KeyError: 981 raise CommandExecutionError("Invalid Hive: {}".format(local_hive)) 982 access_mask = registry.registry_32[use_32bit_registry] | win32con.KEY_ALL_ACCESS 983 984 handle = None 985 try: 986 handle = win32api.RegOpenKeyEx(hkey, local_key, 0, access_mask) 987 win32api.RegDeleteValue(handle, local_vname) 988 broadcast_change() 989 return True 990 except win32api.error as exc: 991 if exc.winerror == 2: 992 return None 993 raise 994 finally: 995 if handle: 996 win32api.RegCloseKey(handle) 997