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 |