Chromium Code Reviews| 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 ScopedRegKeyHANDLE::ScopedRegKeyHANDLE() : handle_(INVALID_HANDLE_VALUE) {} | |
| 569 | |
| 570 ScopedRegKeyHANDLE::ScopedRegKeyHANDLE(HANDLE handle) : handle_(handle) {} | |
| 571 | |
| 572 ScopedRegKeyHANDLE::~ScopedRegKeyHANDLE() { | |
| 573 if (!g_initialized) | |
|
penny
2016/11/21 21:35:46
Let's first add a check for is_valid(). I'd rathe
scottmg
2016/11/22 22:47:36
Good catch! Done.
| |
| 574 InitNativeRegApi(); | |
| 575 g_nt_close(handle_); | |
| 576 } | |
| 577 | |
| 578 HANDLE ScopedRegKeyHANDLE::release() { | |
| 579 HANDLE result = handle_; | |
| 580 handle_ = INVALID_HANDLE_VALUE; | |
| 581 return result; | |
| 582 } | |
| 583 | |
| 568 //------------------------------------------------------------------------------ | 584 //------------------------------------------------------------------------------ |
| 569 // Create, open, delete, close functions | 585 // Create, open, delete, close functions |
| 570 //------------------------------------------------------------------------------ | 586 //------------------------------------------------------------------------------ |
| 571 | 587 |
| 572 bool CreateRegKey(ROOT_KEY root, | 588 ScopedRegKeyHANDLE CreateRegKey(ROOT_KEY root, |
| 573 const wchar_t* key_path, | 589 const wchar_t* key_path, |
| 574 ACCESS_MASK access, | 590 ACCESS_MASK access) { |
| 575 HANDLE* out_handle OPTIONAL) { | |
| 576 // |key_path| can be null or empty, but it can't be longer than | 591 // |key_path| can be null or empty, but it can't be longer than |
| 577 // |g_kRegMaxPathLen| at this point. | 592 // |g_kRegMaxPathLen| at this point. |
| 578 if (key_path != nullptr && | 593 if (key_path != nullptr && |
| 579 ::wcsnlen(key_path, g_kRegMaxPathLen + 1) == g_kRegMaxPathLen + 1) | 594 ::wcsnlen(key_path, g_kRegMaxPathLen + 1) == g_kRegMaxPathLen + 1) |
| 580 return false; | 595 return ScopedRegKeyHANDLE(); |
| 581 | 596 |
| 582 if (!g_initialized) | 597 if (!g_initialized) |
| 583 InitNativeRegApi(); | 598 InitNativeRegApi(); |
| 584 | 599 |
| 585 if (root == nt::AUTO) | 600 if (root == nt::AUTO) |
| 586 root = g_system_install ? nt::HKLM : nt::HKCU; | 601 root = g_system_install ? nt::HKLM : nt::HKCU; |
| 587 | 602 |
| 588 std::wstring redirected_key_path; | 603 std::wstring redirected_key_path; |
| 589 if (key_path) { | 604 if (key_path) { |
| 590 redirected_key_path = key_path; | 605 redirected_key_path = key_path; |
| 591 SanitizeSubkeyPath(&redirected_key_path); | 606 SanitizeSubkeyPath(&redirected_key_path); |
| 592 ProcessRedirection(root, access, &redirected_key_path); | 607 ProcessRedirection(root, access, &redirected_key_path); |
| 593 } | 608 } |
| 594 | 609 |
| 595 std::wstring current_path; | 610 std::wstring current_path; |
| 596 std::vector<std::wstring> subkeys; | 611 std::vector<std::wstring> subkeys; |
| 597 if (!ParseFullRegPath(ConvertRootKey(root), redirected_key_path, | 612 if (!ParseFullRegPath(ConvertRootKey(root), redirected_key_path, |
| 598 ¤t_path, &subkeys)) | 613 ¤t_path, &subkeys)) |
| 599 return false; | 614 return ScopedRegKeyHANDLE(); |
| 600 | 615 |
| 601 // Open the base hive first. It should always exist already. | 616 // Open the base hive first. It should always exist already. |
| 602 HANDLE last_handle = INVALID_HANDLE_VALUE; | 617 HANDLE last_handle = INVALID_HANDLE_VALUE; |
| 603 NTSTATUS status = | 618 NTSTATUS status = |
| 604 CreateKeyWrapper(current_path, access, &last_handle, nullptr); | 619 CreateKeyWrapper(current_path, access, &last_handle, nullptr); |
| 605 if (!NT_SUCCESS(status)) | 620 if (!NT_SUCCESS(status)) |
| 606 return false; | 621 return ScopedRegKeyHANDLE(); |
| 607 | 622 |
| 608 size_t subkeys_size = subkeys.size(); | 623 size_t subkeys_size = subkeys.size(); |
| 609 if (subkeys_size != 0) | 624 if (subkeys_size != 0) |
| 610 g_nt_close(last_handle); | 625 g_nt_close(last_handle); |
| 611 | 626 |
| 612 // Recursively open/create each subkey. | 627 // Recursively open/create each subkey. |
| 613 std::vector<HANDLE> rollback; | 628 std::vector<HANDLE> rollback; |
| 614 bool success = true; | 629 bool success = true; |
| 615 for (size_t i = 0; i < subkeys_size; i++) { | 630 for (size_t i = 0; i < subkeys_size; i++) { |
| 616 current_path.append(subkeys[i]); | 631 current_path.append(subkeys[i]); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 641 // Delete any subkeys created. | 656 // Delete any subkeys created. |
| 642 for (HANDLE handle : rollback) { | 657 for (HANDLE handle : rollback) { |
| 643 g_nt_delete_key(handle); | 658 g_nt_delete_key(handle); |
| 644 } | 659 } |
| 645 } | 660 } |
| 646 for (HANDLE handle : rollback) { | 661 for (HANDLE handle : rollback) { |
| 647 // Close the rollback handles, on success or failure. | 662 // Close the rollback handles, on success or failure. |
| 648 g_nt_close(handle); | 663 g_nt_close(handle); |
| 649 } | 664 } |
| 650 if (!success) | 665 if (!success) |
| 651 return false; | 666 return ScopedRegKeyHANDLE(); |
| 652 | 667 |
| 653 // See if caller wants the handle left open. | 668 return ScopedRegKeyHANDLE(last_handle); |
| 654 if (out_handle) | |
| 655 *out_handle = last_handle; | |
| 656 else | |
| 657 g_nt_close(last_handle); | |
| 658 | |
| 659 return true; | |
| 660 } | 669 } |
| 661 | 670 |
| 662 bool OpenRegKey(ROOT_KEY root, | 671 ScopedRegKeyHANDLE OpenRegKey(ROOT_KEY root, |
| 663 const wchar_t* key_path, | 672 const wchar_t* key_path, |
| 664 ACCESS_MASK access, | 673 ACCESS_MASK access, |
| 665 HANDLE* out_handle, | 674 NTSTATUS* error_code OPTIONAL) { |
| 666 NTSTATUS* error_code OPTIONAL) { | |
| 667 // |key_path| can be null or empty, but it can't be longer than | 675 // |key_path| can be null or empty, but it can't be longer than |
|
penny
2016/11/21 21:35:47
Above this, let's set a default error code (for if
scottmg
2016/11/22 22:47:36
Done.
| |
| 668 // |g_kRegMaxPathLen| at this point. | 676 // |g_kRegMaxPathLen| at this point. |
| 669 if (key_path != nullptr && | 677 if (key_path != nullptr && |
| 670 ::wcsnlen(key_path, g_kRegMaxPathLen + 1) == g_kRegMaxPathLen + 1) | 678 ::wcsnlen(key_path, g_kRegMaxPathLen + 1) == g_kRegMaxPathLen + 1) |
| 671 return false; | 679 return ScopedRegKeyHANDLE(); |
| 672 | 680 |
| 673 if (!g_initialized) | 681 if (!g_initialized) |
| 674 InitNativeRegApi(); | 682 InitNativeRegApi(); |
| 675 | 683 |
| 676 NTSTATUS status = STATUS_UNSUCCESSFUL; | 684 NTSTATUS status = STATUS_UNSUCCESSFUL; |
|
penny
2016/11/21 21:35:46
Delete this initialization.
scottmg
2016/11/22 22:47:36
Done.
| |
| 677 UNICODE_STRING key_path_uni = {}; | 685 UNICODE_STRING key_path_uni = {}; |
| 678 OBJECT_ATTRIBUTES obj = {}; | 686 OBJECT_ATTRIBUTES obj = {}; |
| 679 *out_handle = INVALID_HANDLE_VALUE; | 687 HANDLE result_handle = INVALID_HANDLE_VALUE; |
|
penny
2016/11/21 21:35:47
Move initialization of HANDLE result_handle down t
scottmg
2016/11/22 22:47:35
Done.
| |
| 680 | 688 |
| 681 if (root == nt::AUTO) | 689 if (root == nt::AUTO) |
| 682 root = g_system_install ? nt::HKLM : nt::HKCU; | 690 root = g_system_install ? nt::HKLM : nt::HKCU; |
| 683 | 691 |
| 684 std::wstring full_path; | 692 std::wstring full_path; |
| 685 if (key_path) { | 693 if (key_path) { |
| 686 full_path = key_path; | 694 full_path = key_path; |
| 687 SanitizeSubkeyPath(&full_path); | 695 SanitizeSubkeyPath(&full_path); |
| 688 ProcessRedirection(root, access, &full_path); | 696 ProcessRedirection(root, access, &full_path); |
| 689 } | 697 } |
| 690 full_path.insert(0, ConvertRootKey(root)); | 698 full_path.insert(0, ConvertRootKey(root)); |
| 691 | 699 |
| 692 g_rtl_init_unicode_string(&key_path_uni, full_path.c_str()); | 700 g_rtl_init_unicode_string(&key_path_uni, full_path.c_str()); |
| 693 InitializeObjectAttributes(&obj, &key_path_uni, OBJ_CASE_INSENSITIVE, NULL, | 701 InitializeObjectAttributes(&obj, &key_path_uni, OBJ_CASE_INSENSITIVE, NULL, |
| 694 NULL); | 702 NULL); |
| 695 | 703 |
| 696 status = g_nt_open_key_ex(out_handle, access, &obj, 0); | 704 status = g_nt_open_key_ex(&result_handle, access, &obj, 0); |
|
penny
2016/11/21 21:35:47
NTSTATUS status = ...
scottmg
2016/11/22 22:47:36
Done.
| |
| 697 // See if caller wants the NTSTATUS. | 705 // See if caller wants the NTSTATUS. |
| 698 if (error_code) | 706 if (error_code) |
|
penny
2016/11/21 21:35:46
Let's move this down a tad, so that we only set |e
scottmg
2016/11/22 22:47:35
Done.
| |
| 699 *error_code = status; | 707 *error_code = status; |
| 700 | 708 |
| 701 if (NT_SUCCESS(status)) | 709 if (NT_SUCCESS(status)) |
| 702 return true; | 710 return ScopedRegKeyHANDLE(result_handle); |
| 703 | 711 |
| 704 return false; | 712 return ScopedRegKeyHANDLE(); |
| 705 } | 713 } |
| 706 | 714 |
| 707 bool DeleteRegKey(HANDLE key) { | 715 bool DeleteRegKey(HANDLE key) { |
| 708 if (!g_initialized) | 716 if (!g_initialized) |
| 709 InitNativeRegApi(); | 717 InitNativeRegApi(); |
| 710 | 718 return NT_SUCCESS(g_nt_delete_key(key)); |
|
penny
2016/11/21 21:35:47
Do my ocd a favour and add an empty line above thi
scottmg
2016/11/22 22:47:36
Ugly! If you insist.
| |
| 711 NTSTATUS status = STATUS_UNSUCCESSFUL; | |
| 712 | |
| 713 status = g_nt_delete_key(key); | |
| 714 | |
| 715 if (NT_SUCCESS(status)) | |
| 716 return true; | |
| 717 | |
| 718 return false; | |
| 719 } | 719 } |
| 720 | 720 |
| 721 // wrapper function | 721 // wrapper function |
| 722 bool DeleteRegKey(ROOT_KEY root, | 722 bool DeleteRegKey(ROOT_KEY root, |
| 723 WOW64_OVERRIDE wow64_override, | 723 WOW64_OVERRIDE wow64_override, |
| 724 const wchar_t* key_path) { | 724 const wchar_t* key_path) { |
| 725 HANDLE key = INVALID_HANDLE_VALUE; | 725 ScopedRegKeyHANDLE key = |
| 726 | 726 OpenRegKey(root, key_path, DELETE | wow64_override, nullptr); |
| 727 if (!OpenRegKey(root, key_path, DELETE | wow64_override, &key, nullptr)) | 727 if (!key.is_valid()) |
| 728 return false; | 728 return false; |
| 729 | 729 return DeleteRegKey(key.get()); |
|
penny
2016/11/21 21:35:47
Do my ocd a favour and add an empty line above thi
scottmg
2016/11/22 22:47:35
Done.
| |
| 730 if (!DeleteRegKey(key)) { | |
| 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 } | 730 } |
| 744 | 731 |
| 745 //------------------------------------------------------------------------------ | 732 //------------------------------------------------------------------------------ |
| 746 // Getter functions | 733 // Getter functions |
| 747 //------------------------------------------------------------------------------ | 734 //------------------------------------------------------------------------------ |
| 748 | 735 |
| 749 bool QueryRegKeyValue(HANDLE key, | 736 bool QueryRegKeyValue(HANDLE key, |
| 750 const wchar_t* value_name, | 737 const wchar_t* value_name, |
| 751 ULONG* out_type, | 738 ULONG* out_type, |
| 752 BYTE** out_buffer, | 739 BYTE** out_buffer, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 delete[] value_bytes; | 790 delete[] value_bytes; |
| 804 return true; | 791 return true; |
| 805 } | 792 } |
| 806 | 793 |
| 807 // wrapper function | 794 // wrapper function |
| 808 bool QueryRegValueDWORD(ROOT_KEY root, | 795 bool QueryRegValueDWORD(ROOT_KEY root, |
| 809 WOW64_OVERRIDE wow64_override, | 796 WOW64_OVERRIDE wow64_override, |
| 810 const wchar_t* key_path, | 797 const wchar_t* key_path, |
| 811 const wchar_t* value_name, | 798 const wchar_t* value_name, |
| 812 DWORD* out_dword) { | 799 DWORD* out_dword) { |
| 813 HANDLE key = INVALID_HANDLE_VALUE; | 800 ScopedRegKeyHANDLE key = |
| 814 | 801 OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, nullptr); |
| 815 if (!OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, &key, NULL)) | 802 if (!key.is_valid()) |
| 816 return false; | 803 return false; |
| 817 | 804 return QueryRegValueDWORD(key.get(), value_name, out_dword); |
|
penny
2016/11/21 21:35:47
Do my ocd a favour and add an empty line above thi
scottmg
2016/11/22 22:47:35
Done.
| |
| 818 if (!QueryRegValueDWORD(key, value_name, out_dword)) { | |
| 819 CloseRegKey(key); | |
| 820 return false; | |
| 821 } | |
| 822 | |
| 823 CloseRegKey(key); | |
| 824 return true; | |
| 825 } | 805 } |
| 826 | 806 |
| 827 // wrapper function | 807 // wrapper function |
| 828 bool QueryRegValueSZ(HANDLE key, | 808 bool QueryRegValueSZ(HANDLE key, |
| 829 const wchar_t* value_name, | 809 const wchar_t* value_name, |
| 830 std::wstring* out_sz) { | 810 std::wstring* out_sz) { |
| 831 BYTE* value_bytes = nullptr; | 811 BYTE* value_bytes = nullptr; |
| 832 DWORD ret_size = 0; | 812 DWORD ret_size = 0; |
| 833 ULONG type = REG_NONE; | 813 ULONG type = REG_NONE; |
| 834 | 814 |
| 835 if (!QueryRegKeyValue(key, value_name, &type, &value_bytes, &ret_size) || | 815 if (!QueryRegKeyValue(key, value_name, &type, &value_bytes, &ret_size) || |
| 836 type != REG_SZ) | 816 type != REG_SZ) { |
| 837 return false; | 817 return false; |
| 818 } | |
| 838 | 819 |
| 839 *out_sz = reinterpret_cast<wchar_t*>(value_bytes); | 820 *out_sz = reinterpret_cast<wchar_t*>(value_bytes); |
| 840 | 821 |
| 841 delete[] value_bytes; | 822 delete[] value_bytes; |
| 842 return true; | 823 return true; |
| 843 } | 824 } |
| 844 | 825 |
| 845 // wrapper function | 826 // wrapper function |
| 846 bool QueryRegValueSZ(ROOT_KEY root, | 827 bool QueryRegValueSZ(ROOT_KEY root, |
| 847 WOW64_OVERRIDE wow64_override, | 828 WOW64_OVERRIDE wow64_override, |
| 848 const wchar_t* key_path, | 829 const wchar_t* key_path, |
| 849 const wchar_t* value_name, | 830 const wchar_t* value_name, |
| 850 std::wstring* out_sz) { | 831 std::wstring* out_sz) { |
| 851 HANDLE key = INVALID_HANDLE_VALUE; | 832 ScopedRegKeyHANDLE key = |
| 852 | 833 OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, nullptr); |
| 853 if (!OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, &key, NULL)) | 834 if (!key.is_valid()) |
| 854 return false; | 835 return false; |
| 855 | 836 return QueryRegValueSZ(key.get(), value_name, out_sz); |
|
penny
2016/11/21 21:35:47
Do my ocd a favour and add an empty line above thi
scottmg
2016/11/22 22:47:36
Done.
| |
| 856 if (!QueryRegValueSZ(key, value_name, out_sz)) { | |
| 857 CloseRegKey(key); | |
| 858 return false; | |
| 859 } | |
| 860 | |
| 861 CloseRegKey(key); | |
| 862 return true; | |
| 863 } | 837 } |
| 864 | 838 |
| 865 // wrapper function | 839 // wrapper function |
| 866 bool QueryRegValueMULTISZ(HANDLE key, | 840 bool QueryRegValueMULTISZ(HANDLE key, |
| 867 const wchar_t* value_name, | 841 const wchar_t* value_name, |
| 868 std::vector<std::wstring>* out_multi_sz) { | 842 std::vector<std::wstring>* out_multi_sz) { |
| 869 BYTE* value_bytes = nullptr; | 843 BYTE* value_bytes = nullptr; |
| 870 DWORD ret_size = 0; | 844 DWORD ret_size = 0; |
| 871 ULONG type = REG_NONE; | 845 ULONG type = REG_NONE; |
| 872 | 846 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 895 delete[] value_bytes; | 869 delete[] value_bytes; |
| 896 return true; | 870 return true; |
| 897 } | 871 } |
| 898 | 872 |
| 899 // wrapper function | 873 // wrapper function |
| 900 bool QueryRegValueMULTISZ(ROOT_KEY root, | 874 bool QueryRegValueMULTISZ(ROOT_KEY root, |
| 901 WOW64_OVERRIDE wow64_override, | 875 WOW64_OVERRIDE wow64_override, |
| 902 const wchar_t* key_path, | 876 const wchar_t* key_path, |
| 903 const wchar_t* value_name, | 877 const wchar_t* value_name, |
| 904 std::vector<std::wstring>* out_multi_sz) { | 878 std::vector<std::wstring>* out_multi_sz) { |
| 905 HANDLE key = INVALID_HANDLE_VALUE; | 879 ScopedRegKeyHANDLE key = |
| 906 | 880 OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, nullptr); |
| 907 if (!OpenRegKey(root, key_path, KEY_QUERY_VALUE | wow64_override, &key, NULL)) | 881 if (!key.is_valid()) |
| 908 return false; | 882 return false; |
| 909 | 883 return QueryRegValueMULTISZ(key.get(), value_name, out_multi_sz); |
|
penny
2016/11/21 21:35:47
Do my ocd a favour and add an empty line above thi
scottmg
2016/11/22 22:47:36
Done.
| |
| 910 if (!QueryRegValueMULTISZ(key, value_name, out_multi_sz)) { | |
| 911 CloseRegKey(key); | |
| 912 return false; | |
| 913 } | |
| 914 | |
| 915 CloseRegKey(key); | |
| 916 return true; | |
| 917 } | 884 } |
| 918 | 885 |
| 919 //------------------------------------------------------------------------------ | 886 //------------------------------------------------------------------------------ |
| 920 // Setter functions | 887 // Setter functions |
| 921 //------------------------------------------------------------------------------ | 888 //------------------------------------------------------------------------------ |
| 922 | 889 |
| 923 bool SetRegKeyValue(HANDLE key, | 890 bool SetRegKeyValue(HANDLE key, |
| 924 const wchar_t* value_name, | 891 const wchar_t* value_name, |
| 925 ULONG type, | 892 ULONG type, |
| 926 const BYTE* data, | 893 const BYTE* data, |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 947 return SetRegKeyValue(key, value_name, REG_DWORD, | 914 return SetRegKeyValue(key, value_name, REG_DWORD, |
| 948 reinterpret_cast<BYTE*>(&value), sizeof(value)); | 915 reinterpret_cast<BYTE*>(&value), sizeof(value)); |
| 949 } | 916 } |
| 950 | 917 |
| 951 // wrapper function | 918 // wrapper function |
| 952 bool SetRegValueDWORD(ROOT_KEY root, | 919 bool SetRegValueDWORD(ROOT_KEY root, |
| 953 WOW64_OVERRIDE wow64_override, | 920 WOW64_OVERRIDE wow64_override, |
| 954 const wchar_t* key_path, | 921 const wchar_t* key_path, |
| 955 const wchar_t* value_name, | 922 const wchar_t* value_name, |
| 956 DWORD value) { | 923 DWORD value) { |
| 957 HANDLE key = INVALID_HANDLE_VALUE; | 924 ScopedRegKeyHANDLE key = |
| 958 | 925 OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, nullptr); |
| 959 if (!OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, &key, NULL)) | 926 if (!key.is_valid()) |
| 960 return false; | 927 return false; |
| 961 | 928 return SetRegValueDWORD(key.get(), value_name, value); |
|
penny
2016/11/21 21:35:47
Do my ocd a favour and add an empty line above thi
scottmg
2016/11/22 22:47:35
Done.
| |
| 962 if (!SetRegValueDWORD(key, value_name, value)) { | |
| 963 CloseRegKey(key); | |
| 964 return false; | |
| 965 } | |
| 966 | |
| 967 return true; | |
| 968 } | 929 } |
| 969 | 930 |
| 970 // wrapper function | 931 // wrapper function |
| 971 bool SetRegValueSZ(HANDLE key, | 932 bool SetRegValueSZ(HANDLE key, |
| 972 const wchar_t* value_name, | 933 const wchar_t* value_name, |
| 973 const std::wstring& value) { | 934 const std::wstring& value) { |
| 974 // Make sure the number of bytes in |value|, including EoS, fits in a DWORD. | 935 // Make sure the number of bytes in |value|, including EoS, fits in a DWORD. |
| 975 if (std::numeric_limits<DWORD>::max() < | 936 if (std::numeric_limits<DWORD>::max() < |
| 976 ((value.length() + 1) * sizeof(wchar_t))) | 937 ((value.length() + 1) * sizeof(wchar_t))) |
| 977 return false; | 938 return false; |
| 978 | 939 |
| 979 DWORD size = (static_cast<DWORD>((value.length() + 1) * sizeof(wchar_t))); | 940 DWORD size = (static_cast<DWORD>((value.length() + 1) * sizeof(wchar_t))); |
| 980 return SetRegKeyValue(key, value_name, REG_SZ, | 941 return SetRegKeyValue(key, value_name, REG_SZ, |
| 981 reinterpret_cast<const BYTE*>(value.c_str()), size); | 942 reinterpret_cast<const BYTE*>(value.c_str()), size); |
| 982 } | 943 } |
| 983 | 944 |
| 984 // wrapper function | 945 // wrapper function |
| 985 bool SetRegValueSZ(ROOT_KEY root, | 946 bool SetRegValueSZ(ROOT_KEY root, |
| 986 WOW64_OVERRIDE wow64_override, | 947 WOW64_OVERRIDE wow64_override, |
| 987 const wchar_t* key_path, | 948 const wchar_t* key_path, |
| 988 const wchar_t* value_name, | 949 const wchar_t* value_name, |
| 989 const std::wstring& value) { | 950 const std::wstring& value) { |
| 990 HANDLE key = INVALID_HANDLE_VALUE; | 951 ScopedRegKeyHANDLE key = |
| 991 | 952 OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, nullptr); |
| 992 if (!OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, &key, NULL)) | 953 if (!key.is_valid()) |
| 993 return false; | 954 return false; |
| 994 | 955 return SetRegValueSZ(key.get(), value_name, value); |
|
penny
2016/11/21 21:35:46
Do my ocd a favour and add an empty line above thi
scottmg
2016/11/22 22:47:36
Done.
| |
| 995 if (!SetRegValueSZ(key, value_name, value)) { | |
| 996 CloseRegKey(key); | |
| 997 return false; | |
| 998 } | |
| 999 | |
| 1000 return true; | |
| 1001 } | 956 } |
| 1002 | 957 |
| 1003 // wrapper function | 958 // wrapper function |
| 1004 bool SetRegValueMULTISZ(HANDLE key, | 959 bool SetRegValueMULTISZ(HANDLE key, |
| 1005 const wchar_t* value_name, | 960 const wchar_t* value_name, |
| 1006 const std::vector<std::wstring>& values) { | 961 const std::vector<std::wstring>& values) { |
| 1007 std::vector<wchar_t> builder; | 962 std::vector<wchar_t> builder; |
| 1008 | 963 |
| 1009 for (auto& string : values) { | 964 for (auto& string : values) { |
| 1010 // Just in case someone is passing in an illegal empty string | 965 // Just in case someone is passing in an illegal empty string |
| 1011 // (not allowed in REG_MULTI_SZ), ignore it. | 966 // (not allowed in REG_MULTI_SZ), ignore it. |
| 1012 if (!string.empty()) { | 967 if (!string.empty()) { |
| 1013 for (const wchar_t& w : string) { | 968 for (const wchar_t& w : string) { |
| 1014 builder.push_back(w); | 969 builder.push_back(w); |
| 1015 } | 970 } |
| 1016 builder.push_back(L'\0'); | 971 builder.push_back(L'\0'); |
| 1017 } | 972 } |
| 1018 } | 973 } |
| 1019 // Add second null terminator to end REG_MULTI_SZ. | 974 // Add second null terminator to end REG_MULTI_SZ. |
| 1020 builder.push_back(L'\0'); | 975 builder.push_back(L'\0'); |
| 1021 // Handle rare case where the vector passed in was empty, | 976 // Handle rare case where the vector passed in was empty, |
| 1022 // or only had an empty string. | 977 // or only had an empty string. |
| 1023 if (builder.size() == 1) | 978 if (builder.size() == 1) |
| 1024 builder.push_back(L'\0'); | 979 builder.push_back(L'\0'); |
| 1025 | 980 |
| 1026 if (std::numeric_limits<DWORD>::max() < builder.size()) | 981 if (std::numeric_limits<DWORD>::max() < builder.size()) |
| 1027 return false; | 982 return false; |
| 1028 | 983 |
| 1029 return SetRegKeyValue( | 984 return SetRegKeyValue( |
| 1030 key, value_name, REG_MULTI_SZ, reinterpret_cast<BYTE*>(builder.data()), | 985 key, value_name, REG_MULTI_SZ, |
| 986 reinterpret_cast<BYTE*>(builder.data()), | |
|
penny
2016/11/21 21:35:47
I'm just curious why this got moved down... it was
scottmg
2016/11/22 22:47:36
Forgot to reformat, done.
| |
| 1031 (static_cast<DWORD>(builder.size()) + 1) * sizeof(wchar_t)); | 987 (static_cast<DWORD>(builder.size()) + 1) * sizeof(wchar_t)); |
| 1032 } | 988 } |
| 1033 | 989 |
| 1034 // wrapper function | 990 // wrapper function |
| 1035 bool SetRegValueMULTISZ(ROOT_KEY root, | 991 bool SetRegValueMULTISZ(ROOT_KEY root, |
| 1036 WOW64_OVERRIDE wow64_override, | 992 WOW64_OVERRIDE wow64_override, |
| 1037 const wchar_t* key_path, | 993 const wchar_t* key_path, |
| 1038 const wchar_t* value_name, | 994 const wchar_t* value_name, |
| 1039 const std::vector<std::wstring>& values) { | 995 const std::vector<std::wstring>& values) { |
| 1040 HANDLE key = INVALID_HANDLE_VALUE; | 996 ScopedRegKeyHANDLE key = |
| 1041 | 997 OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, nullptr); |
| 1042 if (!OpenRegKey(root, key_path, KEY_SET_VALUE | wow64_override, &key, NULL)) | 998 if (!key.is_valid()) |
| 1043 return false; | 999 return false; |
| 1044 | 1000 return SetRegValueMULTISZ(key.get(), value_name, values); |
|
penny
2016/11/21 21:35:46
Do my ocd a favour and add an empty line above thi
scottmg
2016/11/22 22:47:35
Done.
| |
| 1045 if (!SetRegValueMULTISZ(key, value_name, values)) { | |
| 1046 CloseRegKey(key); | |
| 1047 return false; | |
| 1048 } | |
| 1049 | |
| 1050 return true; | |
| 1051 } | 1001 } |
| 1052 | 1002 |
| 1053 //------------------------------------------------------------------------------ | 1003 //------------------------------------------------------------------------------ |
| 1054 // Utils | 1004 // Utils |
| 1055 //------------------------------------------------------------------------------ | 1005 //------------------------------------------------------------------------------ |
| 1056 | 1006 |
| 1057 const wchar_t* GetCurrentUserSidString() { | 1007 const wchar_t* GetCurrentUserSidString() { |
| 1058 if (!g_initialized) | 1008 if (!g_initialized) |
| 1059 InitNativeRegApi(); | 1009 InitNativeRegApi(); |
| 1060 | 1010 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1089 if (!g_initialized) | 1039 if (!g_initialized) |
| 1090 InitNativeRegApi(); | 1040 InitNativeRegApi(); |
| 1091 | 1041 |
| 1092 if (root == HKCU || (root == AUTO && !g_system_install)) | 1042 if (root == HKCU || (root == AUTO && !g_system_install)) |
| 1093 return g_HKCU_override; | 1043 return g_HKCU_override; |
| 1094 | 1044 |
| 1095 return g_HKLM_override; | 1045 return g_HKLM_override; |
| 1096 } | 1046 } |
| 1097 | 1047 |
| 1098 }; // namespace nt | 1048 }; // namespace nt |
| OLD | NEW |