| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome_elf/nt_registry/nt_registry.h" | 5 #include "chrome_elf/nt_registry/nt_registry.h" |
| 6 | 6 |
| 7 #include <assert.h> | 7 #include <assert.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 | 9 |
| 10 namespace { | 10 namespace { |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 nullptr); | 558 nullptr); |
| 559 | 559 |
| 560 return g_nt_create_key(out_handle, access, &obj, 0, nullptr, | 560 return g_nt_create_key(out_handle, access, &obj, 0, nullptr, |
| 561 REG_OPTION_NON_VOLATILE, create_or_open); | 561 REG_OPTION_NON_VOLATILE, create_or_open); |
| 562 } | 562 } |
| 563 | 563 |
| 564 } // namespace | 564 } // namespace |
| 565 | 565 |
| 566 namespace nt { | 566 namespace nt { |
| 567 | 567 |
| 568 ScopedHANDLE::ScopedHANDLE() : handle_(nullptr) {} |
| 569 |
| 570 ScopedHANDLE::ScopedHANDLE(HANDLE handle) : handle_(handle) {} |
| 571 |
| 572 ScopedHANDLE::~ScopedHANDLE() { |
| 573 if (!g_initialized) |
| 574 InitNativeRegApi(); |
| 575 if (is_valid()) |
| 576 g_nt_close(handle_); |
| 577 } |
| 578 |
| 579 bool ScopedHANDLE::is_valid() const { |
| 580 // This class should only be used for HANDLEs that have an invalid value of |
| 581 // nullptr. |
| 582 assert(handle_ != INVALID_HANDLE_VALUE); |
| 583 |
| 584 return handle_ != nullptr; |
| 585 } |
| 586 |
| 587 HANDLE ScopedHANDLE::release() { |
| 588 HANDLE result = handle_; |
| 589 handle_ = nullptr; |
| 590 return result; |
| 591 } |
| 592 |
| 568 //------------------------------------------------------------------------------ | 593 //------------------------------------------------------------------------------ |
| 569 // Create, open, delete, close functions | 594 // Create, open, delete, close functions |
| 570 //------------------------------------------------------------------------------ | 595 //------------------------------------------------------------------------------ |
| 571 | 596 |
| 572 bool CreateRegKey(ROOT_KEY root, | 597 ScopedHANDLE CreateRegKey(ROOT_KEY root, |
| 573 const wchar_t* key_path, | 598 const wchar_t* key_path, |
| 574 ACCESS_MASK access, | 599 ACCESS_MASK access) { |
| 575 HANDLE* out_handle OPTIONAL) { | |
| 576 // |key_path| can be null or empty, but it can't be longer than | 600 // |key_path| can be null or empty, but it can't be longer than |
| 577 // |g_kRegMaxPathLen| at this point. | 601 // |g_kRegMaxPathLen| at this point. |
| 578 if (key_path != nullptr && | 602 if (key_path != nullptr && |
| 579 ::wcsnlen(key_path, g_kRegMaxPathLen + 1) == g_kRegMaxPathLen + 1) | 603 ::wcsnlen(key_path, g_kRegMaxPathLen + 1) == g_kRegMaxPathLen + 1) |
| 580 return false; | 604 return ScopedHANDLE(); |
| 581 | 605 |
| 582 if (!g_initialized) | 606 if (!g_initialized) |
| 583 InitNativeRegApi(); | 607 InitNativeRegApi(); |
| 584 | 608 |
| 585 if (root == nt::AUTO) | 609 if (root == nt::AUTO) |
| 586 root = g_system_install ? nt::HKLM : nt::HKCU; | 610 root = g_system_install ? nt::HKLM : nt::HKCU; |
| 587 | 611 |
| 588 std::wstring redirected_key_path; | 612 std::wstring redirected_key_path; |
| 589 if (key_path) { | 613 if (key_path) { |
| 590 redirected_key_path = key_path; | 614 redirected_key_path = key_path; |
| 591 SanitizeSubkeyPath(&redirected_key_path); | 615 SanitizeSubkeyPath(&redirected_key_path); |
| 592 ProcessRedirection(root, access, &redirected_key_path); | 616 ProcessRedirection(root, access, &redirected_key_path); |
| 593 } | 617 } |
| 594 | 618 |
| 595 std::wstring current_path; | 619 std::wstring current_path; |
| 596 std::vector<std::wstring> subkeys; | 620 std::vector<std::wstring> subkeys; |
| 597 if (!ParseFullRegPath(ConvertRootKey(root), redirected_key_path, | 621 if (!ParseFullRegPath(ConvertRootKey(root), redirected_key_path, |
| 598 ¤t_path, &subkeys)) | 622 ¤t_path, &subkeys)) |
| 599 return false; | 623 return ScopedHANDLE(); |
| 600 | 624 |
| 601 // Open the base hive first. It should always exist already. | 625 // Open the base hive first. It should always exist already. |
| 602 HANDLE last_handle = INVALID_HANDLE_VALUE; | 626 HANDLE last_handle = nullptr; |
| 603 NTSTATUS status = | 627 NTSTATUS status = |
| 604 CreateKeyWrapper(current_path, access, &last_handle, nullptr); | 628 CreateKeyWrapper(current_path, access, &last_handle, nullptr); |
| 605 if (!NT_SUCCESS(status)) | 629 if (!NT_SUCCESS(status)) |
| 606 return false; | 630 return ScopedHANDLE(); |
| 607 | 631 |
| 608 size_t subkeys_size = subkeys.size(); | 632 size_t subkeys_size = subkeys.size(); |
| 609 if (subkeys_size != 0) | 633 if (subkeys_size != 0) |
| 610 g_nt_close(last_handle); | 634 g_nt_close(last_handle); |
| 611 | 635 |
| 612 // Recursively open/create each subkey. | 636 // Recursively open/create each subkey. |
| 613 std::vector<HANDLE> rollback; | 637 std::vector<HANDLE> rollback; |
| 614 bool success = true; | 638 bool success = true; |
| 615 for (size_t i = 0; i < subkeys_size; i++) { | 639 for (size_t i = 0; i < subkeys_size; i++) { |
| 616 current_path.append(subkeys[i]); | 640 current_path.append(subkeys[i]); |
| 617 current_path.push_back(L'\\'); | 641 current_path.push_back(L'\\'); |
| 618 | 642 |
| 619 // Process the latest subkey. | 643 // Process the latest subkey. |
| 620 ULONG created = 0; | 644 ULONG created = 0; |
| 621 HANDLE key_handle = INVALID_HANDLE_VALUE; | 645 HANDLE key_handle = nullptr; |
| 622 status = | 646 status = |
| 623 CreateKeyWrapper(current_path.c_str(), access, &key_handle, &created); | 647 CreateKeyWrapper(current_path.c_str(), access, &key_handle, &created); |
| 624 if (!NT_SUCCESS(status)) { | 648 if (!NT_SUCCESS(status)) { |
| 625 success = false; | 649 success = false; |
| 626 break; | 650 break; |
| 627 } | 651 } |
| 628 | 652 |
| 629 if (i == subkeys_size - 1) { | 653 if (i == subkeys_size - 1) { |
| 630 last_handle = key_handle; | 654 last_handle = key_handle; |
| 631 } else { | 655 } else { |
| 632 // Save any subkey handle created, in case of rollback. | 656 // Save any subkey handle created, in case of rollback. |
| 633 if (created == REG_CREATED_NEW_KEY) | 657 if (created == REG_CREATED_NEW_KEY) |
| 634 rollback.push_back(key_handle); | 658 rollback.push_back(key_handle); |
| 635 else | 659 else |
| 636 g_nt_close(key_handle); | 660 g_nt_close(key_handle); |
| 637 } | 661 } |
| 638 } | 662 } |
| 639 | 663 |
| 640 if (!success) { | 664 if (!success) { |
| 641 // Delete any subkeys created. | 665 // Delete any subkeys created. |
| 642 for (HANDLE handle : rollback) { | 666 for (HANDLE handle : rollback) { |
| 643 g_nt_delete_key(handle); | 667 g_nt_delete_key(handle); |
| 644 } | 668 } |
| 645 } | 669 } |
| 646 for (HANDLE handle : rollback) { | 670 for (HANDLE handle : rollback) { |
| 647 // Close the rollback handles, on success or failure. | 671 // Close the rollback handles, on success or failure. |
| 648 g_nt_close(handle); | 672 g_nt_close(handle); |
| 649 } | 673 } |
| 650 if (!success) | 674 if (!success) |
| 651 return false; | 675 return ScopedHANDLE(); |
| 652 | 676 |
| 653 // See if caller wants the handle left open. | 677 return ScopedHANDLE(last_handle); |
| 654 if (out_handle) | |
| 655 *out_handle = last_handle; | |
| 656 else | |
| 657 g_nt_close(last_handle); | |
| 658 | |
| 659 return true; | |
| 660 } | 678 } |
| 661 | 679 |
| 662 bool OpenRegKey(ROOT_KEY root, | 680 ScopedHANDLE OpenRegKey(ROOT_KEY root, |
| 663 const wchar_t* key_path, | 681 const wchar_t* key_path, |
| 664 ACCESS_MASK access, | 682 ACCESS_MASK access, |
| 665 HANDLE* out_handle, | 683 NTSTATUS* error_code OPTIONAL) { |
| 666 NTSTATUS* error_code OPTIONAL) { | 684 if (error_code) |
| 685 *error_code = STATUS_UNSUCCESSFUL; |
| 686 |
| 667 // |key_path| can be null or empty, but it can't be longer than | 687 // |key_path| can be null or empty, but it can't be longer than |
| 668 // |g_kRegMaxPathLen| at this point. | 688 // |g_kRegMaxPathLen| at this point. |
| 669 if (key_path != nullptr && | 689 if (key_path != nullptr && |
| 670 ::wcsnlen(key_path, g_kRegMaxPathLen + 1) == g_kRegMaxPathLen + 1) | 690 ::wcsnlen(key_path, g_kRegMaxPathLen + 1) == g_kRegMaxPathLen + 1) |
| 671 return false; | 691 return ScopedHANDLE(); |
| 672 | 692 |
| 673 if (!g_initialized) | 693 if (!g_initialized) |
| 674 InitNativeRegApi(); | 694 InitNativeRegApi(); |
| 675 | 695 |
| 676 NTSTATUS status = STATUS_UNSUCCESSFUL; | |
| 677 UNICODE_STRING key_path_uni = {}; | 696 UNICODE_STRING key_path_uni = {}; |
| 678 OBJECT_ATTRIBUTES obj = {}; | 697 OBJECT_ATTRIBUTES obj = {}; |
| 679 *out_handle = INVALID_HANDLE_VALUE; | |
| 680 | 698 |
| 681 if (root == nt::AUTO) | 699 if (root == nt::AUTO) |
| 682 root = g_system_install ? nt::HKLM : nt::HKCU; | 700 root = g_system_install ? nt::HKLM : nt::HKCU; |
| 683 | 701 |
| 684 std::wstring full_path; | 702 std::wstring full_path; |
| 685 if (key_path) { | 703 if (key_path) { |
| 686 full_path = key_path; | 704 full_path = key_path; |
| 687 SanitizeSubkeyPath(&full_path); | 705 SanitizeSubkeyPath(&full_path); |
| 688 ProcessRedirection(root, access, &full_path); | 706 ProcessRedirection(root, access, &full_path); |
| 689 } | 707 } |
| 690 full_path.insert(0, ConvertRootKey(root)); | 708 full_path.insert(0, ConvertRootKey(root)); |
| 691 | 709 |
| 692 g_rtl_init_unicode_string(&key_path_uni, full_path.c_str()); | 710 g_rtl_init_unicode_string(&key_path_uni, full_path.c_str()); |
| 693 InitializeObjectAttributes(&obj, &key_path_uni, OBJ_CASE_INSENSITIVE, NULL, | 711 InitializeObjectAttributes(&obj, &key_path_uni, OBJ_CASE_INSENSITIVE, NULL, |
| 694 NULL); | 712 NULL); |
| 695 | 713 |
| 696 status = g_nt_open_key_ex(out_handle, access, &obj, 0); | 714 HANDLE result_handle = nullptr; |
| 697 // See if caller wants the NTSTATUS. | 715 NTSTATUS status = g_nt_open_key_ex(&result_handle, access, &obj, 0); |
| 698 if (error_code) | |
| 699 *error_code = status; | |
| 700 | 716 |
| 701 if (NT_SUCCESS(status)) | 717 if (!NT_SUCCESS(status)) { |
| 702 return true; | 718 // See if caller wants the NTSTATUS. |
| 719 if (error_code) |
| 720 *error_code = status; |
| 721 return ScopedHANDLE(); |
| 722 } |
| 703 | 723 |
| 704 return false; | 724 return ScopedHANDLE(result_handle); |
| 705 } | 725 } |
| 706 | 726 |
| 707 bool DeleteRegKey(HANDLE key) { | 727 bool DeleteRegKey(HANDLE key) { |
| 708 if (!g_initialized) | 728 if (!g_initialized) |
| 709 InitNativeRegApi(); | 729 InitNativeRegApi(); |
| 710 | 730 |
| 711 NTSTATUS status = STATUS_UNSUCCESSFUL; | 731 return NT_SUCCESS(g_nt_delete_key(key)); |
| 712 | |
| 713 status = g_nt_delete_key(key); | |
| 714 | |
| 715 if (NT_SUCCESS(status)) | |
| 716 return true; | |
| 717 | |
| 718 return false; | |
| 719 } | 732 } |
| 720 | 733 |
| 721 // wrapper function | 734 // wrapper function |
| 722 bool DeleteRegKey(ROOT_KEY root, | 735 bool DeleteRegKey(ROOT_KEY root, |
| 723 WOW64_OVERRIDE wow64_override, | 736 WOW64_OVERRIDE wow64_override, |
| 724 const wchar_t* key_path) { | 737 const wchar_t* key_path) { |
| 725 HANDLE key = INVALID_HANDLE_VALUE; | 738 ScopedHANDLE key = |
| 726 | 739 OpenRegKey(root, key_path, DELETE | wow64_override, nullptr); |
| 727 if (!OpenRegKey(root, key_path, DELETE | wow64_override, &key, nullptr)) | 740 if (!key.is_valid()) |
| 728 return false; | 741 return false; |
| 729 | 742 |
| 730 if (!DeleteRegKey(key)) { | 743 return DeleteRegKey(key.get()); |
| 731 CloseRegKey(key); | |
| 732 return false; | |
| 733 } | |
| 734 | |
| 735 CloseRegKey(key); | |
| 736 return true; | |
| 737 } | |
| 738 | |
| 739 void CloseRegKey(HANDLE key) { | |
| 740 if (!g_initialized) | |
| 741 InitNativeRegApi(); | |
| 742 g_nt_close(key); | |
| 743 } | 744 } |
| 744 | 745 |
| 745 //------------------------------------------------------------------------------ | 746 //------------------------------------------------------------------------------ |
| 746 // Getter functions | 747 // Getter functions |
| 747 //------------------------------------------------------------------------------ | 748 //------------------------------------------------------------------------------ |
| 748 | 749 |
| 749 bool QueryRegKeyValue(HANDLE key, | 750 bool QueryRegKeyValue(HANDLE key, |
| 750 const wchar_t* value_name, | 751 const wchar_t* value_name, |
| 751 ULONG* out_type, | 752 ULONG* out_type, |
| 752 BYTE** out_buffer, | 753 BYTE** out_buffer, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 delete[] value_bytes; | 804 delete[] value_bytes; |
| 804 return true; | 805 return true; |
| 805 } | 806 } |
| 806 | 807 |
| 807 // wrapper function | 808 // wrapper function |
| 808 bool QueryRegValueDWORD(ROOT_KEY root, | 809 bool QueryRegValueDWORD(ROOT_KEY root, |
| 809 WOW64_OVERRIDE wow64_override, | 810 WOW64_OVERRIDE wow64_override, |
| 810 const wchar_t* key_path, | 811 const wchar_t* key_path, |
| 811 const wchar_t* value_name, | 812 const wchar_t* value_name, |
| 812 DWORD* out_dword) { | 813 DWORD* out_dword) { |
| 813 HANDLE key = INVALID_HANDLE_VALUE; | 814 ScopedHANDLE key = |
| 814 | 815 OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, nullptr); |
| 815 if (!OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, &key, NULL)) | 816 if (!key.is_valid()) |
| 816 return false; | 817 return false; |
| 817 | 818 |
| 818 if (!QueryRegValueDWORD(key, value_name, out_dword)) { | 819 return QueryRegValueDWORD(key.get(), value_name, out_dword); |
| 819 CloseRegKey(key); | |
| 820 return false; | |
| 821 } | |
| 822 | |
| 823 CloseRegKey(key); | |
| 824 return true; | |
| 825 } | 820 } |
| 826 | 821 |
| 827 // wrapper function | 822 // wrapper function |
| 828 bool QueryRegValueSZ(HANDLE key, | 823 bool QueryRegValueSZ(HANDLE key, |
| 829 const wchar_t* value_name, | 824 const wchar_t* value_name, |
| 830 std::wstring* out_sz) { | 825 std::wstring* out_sz) { |
| 831 BYTE* value_bytes = nullptr; | 826 BYTE* value_bytes = nullptr; |
| 832 DWORD ret_size = 0; | 827 DWORD ret_size = 0; |
| 833 ULONG type = REG_NONE; | 828 ULONG type = REG_NONE; |
| 834 | 829 |
| 835 if (!QueryRegKeyValue(key, value_name, &type, &value_bytes, &ret_size) || | 830 if (!QueryRegKeyValue(key, value_name, &type, &value_bytes, &ret_size) || |
| 836 type != REG_SZ) | 831 type != REG_SZ) { |
| 837 return false; | 832 return false; |
| 833 } |
| 838 | 834 |
| 839 *out_sz = reinterpret_cast<wchar_t*>(value_bytes); | 835 *out_sz = reinterpret_cast<wchar_t*>(value_bytes); |
| 840 | 836 |
| 841 delete[] value_bytes; | 837 delete[] value_bytes; |
| 842 return true; | 838 return true; |
| 843 } | 839 } |
| 844 | 840 |
| 845 // wrapper function | 841 // wrapper function |
| 846 bool QueryRegValueSZ(ROOT_KEY root, | 842 bool QueryRegValueSZ(ROOT_KEY root, |
| 847 WOW64_OVERRIDE wow64_override, | 843 WOW64_OVERRIDE wow64_override, |
| 848 const wchar_t* key_path, | 844 const wchar_t* key_path, |
| 849 const wchar_t* value_name, | 845 const wchar_t* value_name, |
| 850 std::wstring* out_sz) { | 846 std::wstring* out_sz) { |
| 851 HANDLE key = INVALID_HANDLE_VALUE; | 847 ScopedHANDLE key = |
| 852 | 848 OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, nullptr); |
| 853 if (!OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, &key, NULL)) | 849 if (!key.is_valid()) |
| 854 return false; | 850 return false; |
| 855 | 851 |
| 856 if (!QueryRegValueSZ(key, value_name, out_sz)) { | 852 return QueryRegValueSZ(key.get(), value_name, out_sz); |
| 857 CloseRegKey(key); | |
| 858 return false; | |
| 859 } | |
| 860 | |
| 861 CloseRegKey(key); | |
| 862 return true; | |
| 863 } | 853 } |
| 864 | 854 |
| 865 // wrapper function | 855 // wrapper function |
| 866 bool QueryRegValueMULTISZ(HANDLE key, | 856 bool QueryRegValueMULTISZ(HANDLE key, |
| 867 const wchar_t* value_name, | 857 const wchar_t* value_name, |
| 868 std::vector<std::wstring>* out_multi_sz) { | 858 std::vector<std::wstring>* out_multi_sz) { |
| 869 BYTE* value_bytes = nullptr; | 859 BYTE* value_bytes = nullptr; |
| 870 DWORD ret_size = 0; | 860 DWORD ret_size = 0; |
| 871 ULONG type = REG_NONE; | 861 ULONG type = REG_NONE; |
| 872 | 862 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 895 delete[] value_bytes; | 885 delete[] value_bytes; |
| 896 return true; | 886 return true; |
| 897 } | 887 } |
| 898 | 888 |
| 899 // wrapper function | 889 // wrapper function |
| 900 bool QueryRegValueMULTISZ(ROOT_KEY root, | 890 bool QueryRegValueMULTISZ(ROOT_KEY root, |
| 901 WOW64_OVERRIDE wow64_override, | 891 WOW64_OVERRIDE wow64_override, |
| 902 const wchar_t* key_path, | 892 const wchar_t* key_path, |
| 903 const wchar_t* value_name, | 893 const wchar_t* value_name, |
| 904 std::vector<std::wstring>* out_multi_sz) { | 894 std::vector<std::wstring>* out_multi_sz) { |
| 905 HANDLE key = INVALID_HANDLE_VALUE; | 895 ScopedHANDLE key = |
| 906 | 896 OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, nullptr); |
| 907 if (!OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, &key, NULL)) | 897 if (!key.is_valid()) |
| 908 return false; | 898 return false; |
| 909 | 899 |
| 910 if (!QueryRegValueMULTISZ(key, value_name, out_multi_sz)) { | 900 return QueryRegValueMULTISZ(key.get(), value_name, out_multi_sz); |
| 911 CloseRegKey(key); | |
| 912 return false; | |
| 913 } | |
| 914 | |
| 915 CloseRegKey(key); | |
| 916 return true; | |
| 917 } | 901 } |
| 918 | 902 |
| 919 //------------------------------------------------------------------------------ | 903 //------------------------------------------------------------------------------ |
| 920 // Setter functions | 904 // Setter functions |
| 921 //------------------------------------------------------------------------------ | 905 //------------------------------------------------------------------------------ |
| 922 | 906 |
| 923 bool SetRegKeyValue(HANDLE key, | 907 bool SetRegKeyValue(HANDLE key, |
| 924 const wchar_t* value_name, | 908 const wchar_t* value_name, |
| 925 ULONG type, | 909 ULONG type, |
| 926 const BYTE* data, | 910 const BYTE* data, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 947 return SetRegKeyValue(key, value_name, REG_DWORD, | 931 return SetRegKeyValue(key, value_name, REG_DWORD, |
| 948 reinterpret_cast<BYTE*>(&value), sizeof(value)); | 932 reinterpret_cast<BYTE*>(&value), sizeof(value)); |
| 949 } | 933 } |
| 950 | 934 |
| 951 // wrapper function | 935 // wrapper function |
| 952 bool SetRegValueDWORD(ROOT_KEY root, | 936 bool SetRegValueDWORD(ROOT_KEY root, |
| 953 WOW64_OVERRIDE wow64_override, | 937 WOW64_OVERRIDE wow64_override, |
| 954 const wchar_t* key_path, | 938 const wchar_t* key_path, |
| 955 const wchar_t* value_name, | 939 const wchar_t* value_name, |
| 956 DWORD value) { | 940 DWORD value) { |
| 957 HANDLE key = INVALID_HANDLE_VALUE; | 941 ScopedHANDLE key = |
| 958 | 942 OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, nullptr); |
| 959 if (!OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, &key, NULL)) | 943 if (!key.is_valid()) |
| 960 return false; | 944 return false; |
| 961 | 945 |
| 962 if (!SetRegValueDWORD(key, value_name, value)) { | 946 return SetRegValueDWORD(key.get(), value_name, value); |
| 963 CloseRegKey(key); | |
| 964 return false; | |
| 965 } | |
| 966 | |
| 967 return true; | |
| 968 } | 947 } |
| 969 | 948 |
| 970 // wrapper function | 949 // wrapper function |
| 971 bool SetRegValueSZ(HANDLE key, | 950 bool SetRegValueSZ(HANDLE key, |
| 972 const wchar_t* value_name, | 951 const wchar_t* value_name, |
| 973 const std::wstring& value) { | 952 const std::wstring& value) { |
| 974 // Make sure the number of bytes in |value|, including EoS, fits in a DWORD. | 953 // Make sure the number of bytes in |value|, including EoS, fits in a DWORD. |
| 975 if (std::numeric_limits<DWORD>::max() < | 954 if (std::numeric_limits<DWORD>::max() < |
| 976 ((value.length() + 1) * sizeof(wchar_t))) | 955 ((value.length() + 1) * sizeof(wchar_t))) |
| 977 return false; | 956 return false; |
| 978 | 957 |
| 979 DWORD size = (static_cast<DWORD>((value.length() + 1) * sizeof(wchar_t))); | 958 DWORD size = (static_cast<DWORD>((value.length() + 1) * sizeof(wchar_t))); |
| 980 return SetRegKeyValue(key, value_name, REG_SZ, | 959 return SetRegKeyValue(key, value_name, REG_SZ, |
| 981 reinterpret_cast<const BYTE*>(value.c_str()), size); | 960 reinterpret_cast<const BYTE*>(value.c_str()), size); |
| 982 } | 961 } |
| 983 | 962 |
| 984 // wrapper function | 963 // wrapper function |
| 985 bool SetRegValueSZ(ROOT_KEY root, | 964 bool SetRegValueSZ(ROOT_KEY root, |
| 986 WOW64_OVERRIDE wow64_override, | 965 WOW64_OVERRIDE wow64_override, |
| 987 const wchar_t* key_path, | 966 const wchar_t* key_path, |
| 988 const wchar_t* value_name, | 967 const wchar_t* value_name, |
| 989 const std::wstring& value) { | 968 const std::wstring& value) { |
| 990 HANDLE key = INVALID_HANDLE_VALUE; | 969 ScopedHANDLE key = |
| 991 | 970 OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, nullptr); |
| 992 if (!OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, &key, NULL)) | 971 if (!key.is_valid()) |
| 993 return false; | 972 return false; |
| 994 | 973 |
| 995 if (!SetRegValueSZ(key, value_name, value)) { | 974 return SetRegValueSZ(key.get(), value_name, value); |
| 996 CloseRegKey(key); | |
| 997 return false; | |
| 998 } | |
| 999 | |
| 1000 return true; | |
| 1001 } | 975 } |
| 1002 | 976 |
| 1003 // wrapper function | 977 // wrapper function |
| 1004 bool SetRegValueMULTISZ(HANDLE key, | 978 bool SetRegValueMULTISZ(HANDLE key, |
| 1005 const wchar_t* value_name, | 979 const wchar_t* value_name, |
| 1006 const std::vector<std::wstring>& values) { | 980 const std::vector<std::wstring>& values) { |
| 1007 std::vector<wchar_t> builder; | 981 std::vector<wchar_t> builder; |
| 1008 | 982 |
| 1009 for (auto& string : values) { | 983 for (auto& string : values) { |
| 1010 // Just in case someone is passing in an illegal empty string | 984 // Just in case someone is passing in an illegal empty string |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1030 key, value_name, REG_MULTI_SZ, reinterpret_cast<BYTE*>(builder.data()), | 1004 key, value_name, REG_MULTI_SZ, reinterpret_cast<BYTE*>(builder.data()), |
| 1031 (static_cast<DWORD>(builder.size()) + 1) * sizeof(wchar_t)); | 1005 (static_cast<DWORD>(builder.size()) + 1) * sizeof(wchar_t)); |
| 1032 } | 1006 } |
| 1033 | 1007 |
| 1034 // wrapper function | 1008 // wrapper function |
| 1035 bool SetRegValueMULTISZ(ROOT_KEY root, | 1009 bool SetRegValueMULTISZ(ROOT_KEY root, |
| 1036 WOW64_OVERRIDE wow64_override, | 1010 WOW64_OVERRIDE wow64_override, |
| 1037 const wchar_t* key_path, | 1011 const wchar_t* key_path, |
| 1038 const wchar_t* value_name, | 1012 const wchar_t* value_name, |
| 1039 const std::vector<std::wstring>& values) { | 1013 const std::vector<std::wstring>& values) { |
| 1040 HANDLE key = INVALID_HANDLE_VALUE; | 1014 ScopedHANDLE key = |
| 1041 | 1015 OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, nullptr); |
| 1042 if (!OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, &key, NULL)) | 1016 if (!key.is_valid()) |
| 1043 return false; | 1017 return false; |
| 1044 | 1018 |
| 1045 if (!SetRegValueMULTISZ(key, value_name, values)) { | 1019 return SetRegValueMULTISZ(key.get(), value_name, values); |
| 1046 CloseRegKey(key); | |
| 1047 return false; | |
| 1048 } | |
| 1049 | |
| 1050 return true; | |
| 1051 } | 1020 } |
| 1052 | 1021 |
| 1053 //------------------------------------------------------------------------------ | 1022 //------------------------------------------------------------------------------ |
| 1054 // Utils | 1023 // Utils |
| 1055 //------------------------------------------------------------------------------ | 1024 //------------------------------------------------------------------------------ |
| 1056 | 1025 |
| 1057 const wchar_t* GetCurrentUserSidString() { | 1026 const wchar_t* GetCurrentUserSidString() { |
| 1058 if (!g_initialized) | 1027 if (!g_initialized) |
| 1059 InitNativeRegApi(); | 1028 InitNativeRegApi(); |
| 1060 | 1029 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1089 if (!g_initialized) | 1058 if (!g_initialized) |
| 1090 InitNativeRegApi(); | 1059 InitNativeRegApi(); |
| 1091 | 1060 |
| 1092 if (root == HKCU || (root == AUTO && !g_system_install)) | 1061 if (root == HKCU || (root == AUTO && !g_system_install)) |
| 1093 return g_HKCU_override; | 1062 return g_HKCU_override; |
| 1094 | 1063 |
| 1095 return g_HKLM_override; | 1064 return g_HKLM_override; |
| 1096 } | 1065 } |
| 1097 | 1066 |
| 1098 }; // namespace nt | 1067 }; // namespace nt |
| OLD | NEW |