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 |