Reactos

[SETUPLIB] Add support for removing sections and key values, and remove some hacks (#6815)

- Use LIST_ENTRY instead of custom list pointers;
- Fix key/section unlinking before freeing.

+201 -199
+31 -41
base/setup/lib/utils/bldrsup.c
··· 1006 1006 IN OUT PBOOT_STORE_OPTIONS BootOptions 1007 1007 /* , IN PULONG BootOptionsLength */ ) 1008 1008 { 1009 - NTSTATUS Status = STATUS_SUCCESS; 1010 1009 PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; 1011 - PWCHAR TimeoutStr; 1010 + PCWSTR TimeoutStr; 1012 1011 1013 1012 if (!BootStore || !BootOptions) 1014 1013 return STATUS_INVALID_PARAMETER; ··· 1036 1035 { 1037 1036 BootOptions->Version = FreeLdr; 1038 1037 1039 - Status = IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, 1040 - L"DefaultOS", (PWCHAR*)&BootOptions->CurrentBootEntryKey); 1041 - if (!NT_SUCCESS(Status)) 1042 - BootOptions->CurrentBootEntryKey = 0; 1038 + BootOptions->CurrentBootEntryKey = 0; 1039 + IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, 1040 + L"DefaultOS", (PCWSTR*)&BootOptions->CurrentBootEntryKey); 1043 1041 1044 - Status = IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, 1045 - L"TimeOut", &TimeoutStr); 1046 - if (NT_SUCCESS(Status) && TimeoutStr) 1042 + BootOptions->Timeout = 0; 1043 + if (IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, 1044 + L"TimeOut", &TimeoutStr) && TimeoutStr) 1045 + { 1047 1046 BootOptions->Timeout = _wtoi(TimeoutStr); 1048 - else 1049 - BootOptions->Timeout = 0; 1047 + } 1050 1048 } 1051 1049 else if (BootStore->Type == NtLdr) 1052 1050 { 1053 1051 BootOptions->Version = NtLdr; 1054 1052 1055 - Status = IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, 1056 - L"default", (PWCHAR*)&BootOptions->CurrentBootEntryKey); 1057 - if (!NT_SUCCESS(Status)) 1058 - BootOptions->CurrentBootEntryKey = 0; 1053 + BootOptions->CurrentBootEntryKey = 0; 1054 + IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, 1055 + L"default", (PCWSTR*)&BootOptions->CurrentBootEntryKey); 1059 1056 1060 - Status = IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, 1061 - L"timeout", &TimeoutStr); 1062 - if (NT_SUCCESS(Status) && TimeoutStr) 1057 + BootOptions->Timeout = 0; 1058 + if (IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, 1059 + L"timeout", &TimeoutStr) && TimeoutStr) 1060 + { 1063 1061 BootOptions->Timeout = _wtoi(TimeoutStr); 1064 - else 1065 - BootOptions->Timeout = 0; 1062 + } 1066 1063 } 1067 1064 1068 - return STATUS_SUCCESS; // FIXME: use Status; instead? 1065 + return STATUS_SUCCESS; 1069 1066 } 1070 1067 1071 1068 NTSTATUS ··· 1110 1107 L"DefaultOS", (PCWSTR)BootOptions->CurrentBootEntryKey); 1111 1108 1112 1109 RtlStringCchPrintfW(TimeoutStr, ARRAYSIZE(TimeoutStr), L"%d", BootOptions->Timeout); 1113 - IniInsertKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, 1114 - NULL, INSERT_FIRST, // INSERT_LAST, // FIXME!! There is a bug in the INI parser where a given key can be inserted twice in the same section... 1115 - L"TimeOut", TimeoutStr); 1110 + IniAddKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, 1111 + L"TimeOut", TimeoutStr); 1116 1112 1117 1113 return STATUS_SUCCESS; 1118 1114 } ··· 1129 1125 NTSTATUS Status = STATUS_SUCCESS; 1130 1126 PINICACHEITERATOR Iterator; 1131 1127 PINI_SECTION OsIniSection; 1132 - PWCHAR SectionName, KeyData; 1128 + PCWSTR SectionName, KeyData; 1133 1129 UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + 1134 1130 max(sizeof(NTOS_OPTIONS), sizeof(BOOT_SECTOR_OPTIONS))]; 1135 1131 PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry; ··· 1140 1136 if (!Iterator) return STATUS_SUCCESS; 1141 1137 do 1142 1138 { 1143 - PWCHAR InstallName; 1139 + PCWSTR InstallName; 1144 1140 ULONG InstallNameLength; 1145 1141 1146 1142 /* Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni) */ ··· 1195 1191 if (!OsIniSection) 1196 1192 goto DoEnum; 1197 1193 1198 - /* Check for supported boot type "Windows2003" */ 1199 - Status = IniGetKey(OsIniSection, L"BootType", &KeyData); 1200 - if (!NT_SUCCESS(Status) || !KeyData) 1194 + /* Check for supported boot type */ 1195 + if (!IniGetKey(OsIniSection, L"BootType", &KeyData) || !KeyData) 1201 1196 { 1202 1197 /* Certainly not a ReactOS installation */ 1203 1198 DPRINT1("No BootType value present!\n"); ··· 1222 1217 1223 1218 /* Check its SystemPath */ 1224 1219 Options->OsLoadPath = NULL; 1225 - Status = IniGetKey(OsIniSection, L"SystemPath", &KeyData); 1226 - if (NT_SUCCESS(Status)) 1220 + if (IniGetKey(OsIniSection, L"SystemPath", &KeyData)) 1227 1221 Options->OsLoadPath = KeyData; 1228 1222 // KeyData == SystemRoot; 1229 1223 1230 1224 /* Check the optional Options */ 1231 1225 Options->OsLoadOptions = NULL; 1232 - Status = IniGetKey(OsIniSection, L"Options", &KeyData); 1233 - if (NT_SUCCESS(Status)) 1226 + if (IniGetKey(OsIniSection, L"Options", &KeyData)) 1234 1227 Options->OsLoadOptions = KeyData; 1235 1228 } 1236 1229 else ··· 1251 1244 1252 1245 /* Check its BootDrive */ 1253 1246 Options->Drive = NULL; 1254 - Status = IniGetKey(OsIniSection, L"BootDrive", &KeyData); 1255 - if (NT_SUCCESS(Status)) 1247 + if (IniGetKey(OsIniSection, L"BootDrive", &KeyData)) 1256 1248 Options->Drive = KeyData; 1257 1249 1258 1250 /* Check its BootPartition */ 1259 1251 Options->Partition = NULL; 1260 - Status = IniGetKey(OsIniSection, L"BootPartition", &KeyData); 1261 - if (NT_SUCCESS(Status)) 1252 + if (IniGetKey(OsIniSection, L"BootPartition", &KeyData)) 1262 1253 Options->Partition = KeyData; 1263 1254 1264 1255 /* Check its BootSector */ 1265 1256 Options->BootSectorFileName = NULL; 1266 - Status = IniGetKey(OsIniSection, L"BootSectorFile", &KeyData); 1267 - if (NT_SUCCESS(Status)) 1257 + if (IniGetKey(OsIniSection, L"BootSectorFile", &KeyData)) 1268 1258 Options->BootSectorFileName = KeyData; 1269 1259 } 1270 1260 else ··· 1300 1290 { 1301 1291 NTSTATUS Status = STATUS_SUCCESS; 1302 1292 PINICACHEITERATOR Iterator; 1303 - PWCHAR SectionName, KeyData; 1293 + PCWSTR SectionName, KeyData; 1304 1294 UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; 1305 1295 PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry; 1306 1296 PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; ··· 1312 1302 if (!Iterator) return STATUS_SUCCESS; 1313 1303 do 1314 1304 { 1315 - PWCHAR InstallName, OsOptions; 1305 + PCWSTR InstallName, OsOptions; 1316 1306 ULONG InstallNameLength, OsOptionsLength; 1317 1307 1318 1308 /* Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni) */
+140 -135
base/setup/lib/utils/inicache.c
··· 16 16 17 17 /* PRIVATE FUNCTIONS ********************************************************/ 18 18 19 - static 20 - PINI_KEYWORD 19 + static VOID 21 20 IniCacheFreeKey( 22 - PINI_KEYWORD Key) 21 + _In_ PINI_KEYWORD Key) 23 22 { 24 - PINI_KEYWORD Next; 25 - 26 - if (Key == NULL) 27 - return NULL; 23 + /* Unlink the key */ 24 + RemoveEntryList(&Key->ListEntry); 28 25 29 - Next = Key->Next; 30 - if (Key->Name != NULL) 31 - { 26 + /* Free its data */ 27 + if (Key->Name) 32 28 RtlFreeHeap(ProcessHeap, 0, Key->Name); 33 - Key->Name = NULL; 34 - } 35 - 36 - if (Key->Data != NULL) 37 - { 29 + if (Key->Data) 38 30 RtlFreeHeap(ProcessHeap, 0, Key->Data); 39 - Key->Data = NULL; 40 - } 41 - 42 31 RtlFreeHeap(ProcessHeap, 0, Key); 43 - 44 - return Next; 45 32 } 46 33 47 - static 48 - PINI_SECTION 34 + static VOID 49 35 IniCacheFreeSection( 50 - PINI_SECTION Section) 36 + _In_ PINI_SECTION Section) 51 37 { 52 - PINI_SECTION Next; 38 + /* Unlink the section */ 39 + RemoveEntryList(&Section->ListEntry); 53 40 54 - if (Section == NULL) 55 - return NULL; 56 - 57 - Next = Section->Next; 58 - while (Section->FirstKey != NULL) 41 + /* Free its data */ 42 + while (!IsListEmpty(&Section->KeyList)) 59 43 { 60 - Section->FirstKey = IniCacheFreeKey(Section->FirstKey); 44 + PLIST_ENTRY Entry = RemoveHeadList(&Section->KeyList); 45 + PINI_KEYWORD Key = CONTAINING_RECORD(Entry, INI_KEYWORD, ListEntry); 46 + IniCacheFreeKey(Key); 61 47 } 62 - Section->LastKey = NULL; 63 - 64 - if (Section->Name != NULL) 65 - { 48 + if (Section->Name) 66 49 RtlFreeHeap(ProcessHeap, 0, Section->Name); 67 - Section->Name = NULL; 68 - } 69 - 70 50 RtlFreeHeap(ProcessHeap, 0, Section); 71 - 72 - return Next; 73 51 } 74 52 75 53 static ··· 78 56 _In_ PINICACHE Cache, 79 57 _In_ PCWSTR Name) 80 58 { 81 - PINI_SECTION Section; 59 + PLIST_ENTRY Entry; 82 60 83 - for (Section = Cache->FirstSection; Section; Section = Section->Next) 61 + for (Entry = Cache->SectionList.Flink; 62 + Entry != &Cache->SectionList; 63 + Entry = Entry->Flink) 84 64 { 65 + PINI_SECTION Section = CONTAINING_RECORD(Entry, INI_SECTION, ListEntry); 85 66 if (_wcsicmp(Section->Name, Name) == 0) 86 67 return Section; 87 68 } ··· 94 75 _In_ PINI_SECTION Section, 95 76 _In_ PCWSTR Name) 96 77 { 97 - PINI_KEYWORD Key; 78 + PLIST_ENTRY Entry; 98 79 99 - for (Key = Section->FirstKey; Key; Key = Key->Next) 80 + for (Entry = Section->KeyList.Flink; 81 + Entry != &Section->KeyList; 82 + Entry = Entry->Flink) 100 83 { 84 + PINI_KEYWORD Key = CONTAINING_RECORD(Entry, INI_KEYWORD, ListEntry); 101 85 if (_wcsicmp(Key->Name, Name) == 0) 102 86 return Key; 103 87 } ··· 208 192 Key->Data = DataU; 209 193 210 194 /* Insert the key into section */ 211 - if (Section->FirstKey == NULL) 195 + if (IsListEmpty(&Section->KeyList)) 212 196 { 213 - Section->FirstKey = Key; 214 - Section->LastKey = Key; 197 + InsertHeadList(&Section->KeyList, &Key->ListEntry); 215 198 } 216 199 else if ((InsertionType == INSERT_FIRST) || 217 200 ((InsertionType == INSERT_BEFORE) && 218 - ((AnchorKey == NULL) || (AnchorKey == Section->FirstKey)))) 201 + (!AnchorKey || (&AnchorKey->ListEntry == Section->KeyList.Flink)))) 219 202 { 220 203 /* Insert at the head of the list */ 221 - Section->FirstKey->Prev = Key; 222 - Key->Next = Section->FirstKey; 223 - Section->FirstKey = Key; 204 + InsertHeadList(&Section->KeyList, &Key->ListEntry); 224 205 } 225 - else if ((InsertionType == INSERT_BEFORE) && (AnchorKey != NULL)) 206 + else if ((InsertionType == INSERT_BEFORE) && AnchorKey) 226 207 { 227 208 /* Insert before the anchor key */ 228 - Key->Next = AnchorKey; 229 - Key->Prev = AnchorKey->Prev; 230 - AnchorKey->Prev->Next = Key; 231 - AnchorKey->Prev = Key; 209 + InsertTailList(&AnchorKey->ListEntry, &Key->ListEntry); 232 210 } 233 211 else if ((InsertionType == INSERT_LAST) || 234 212 ((InsertionType == INSERT_AFTER) && 235 - ((AnchorKey == NULL) || (AnchorKey == Section->LastKey)))) 213 + (!AnchorKey || (&AnchorKey->ListEntry == Section->KeyList.Blink)))) 236 214 { 237 - Section->LastKey->Next = Key; 238 - Key->Prev = Section->LastKey; 239 - Section->LastKey = Key; 215 + /* Insert at the tail of the list */ 216 + InsertTailList(&Section->KeyList, &Key->ListEntry); 240 217 } 241 - else if ((InsertionType == INSERT_AFTER) && (AnchorKey != NULL)) 218 + else if ((InsertionType == INSERT_AFTER) && AnchorKey) 242 219 { 243 220 /* Insert after the anchor key */ 244 - Key->Next = AnchorKey->Next; 245 - Key->Prev = AnchorKey; 246 - AnchorKey->Next->Prev = Key; 247 - AnchorKey->Next = Key; 221 + InsertHeadList(&AnchorKey->ListEntry, &Key->ListEntry); 248 222 } 249 223 250 224 return Key; ··· 305 279 return NULL; 306 280 } 307 281 Section->Name = NameU; 282 + InitializeListHead(&Section->KeyList); 308 283 309 284 /* Append the section */ 310 - if (Cache->FirstSection == NULL) 311 - { 312 - Cache->FirstSection = Section; 313 - Cache->LastSection = Section; 314 - } 315 - else 316 - { 317 - Cache->LastSection->Next = Section; 318 - Section->Prev = Cache->LastSection; 319 - Cache->LastSection = Section; 320 - } 285 + InsertTailList(&Cache->SectionList, &Section->ListEntry); 321 286 322 287 return Section; 323 288 } ··· 540 505 ULONG KeyValueSize; 541 506 542 507 /* Allocate inicache header */ 543 - *Cache = (PINICACHE)RtlAllocateHeap(ProcessHeap, 544 - HEAP_ZERO_MEMORY, 545 - sizeof(INICACHE)); 546 - if (*Cache == NULL) 547 - { 548 - DPRINT("RtlAllocateHeap() failed\n"); 508 + *Cache = IniCacheCreate(); 509 + if (!*Cache) 549 510 return STATUS_INSUFFICIENT_RESOURCES; 550 - } 551 511 552 512 /* Parse ini file */ 553 513 Section = NULL; ··· 737 697 738 698 VOID 739 699 IniCacheDestroy( 740 - PINICACHE Cache) 700 + _In_ PINICACHE Cache) 741 701 { 742 - if (Cache == NULL) 702 + if (!Cache) 743 703 return; 744 704 745 - while (Cache->FirstSection != NULL) 705 + while (!IsListEmpty(&Cache->SectionList)) 746 706 { 747 - Cache->FirstSection = IniCacheFreeSection(Cache->FirstSection); 707 + PLIST_ENTRY Entry = RemoveHeadList(&Cache->SectionList); 708 + PINI_SECTION Section = CONTAINING_RECORD(Entry, INI_SECTION, ListEntry); 709 + IniCacheFreeSection(Section); 748 710 } 749 - Cache->LastSection = NULL; 750 711 751 712 RtlFreeHeap(ProcessHeap, 0, Cache); 752 713 } ··· 765 726 return IniCacheFindSection(Cache, Name); 766 727 } 767 728 768 - NTSTATUS 729 + PINI_KEYWORD 769 730 IniGetKey( 770 - PINI_SECTION Section, 771 - PWCHAR KeyName, 772 - PWCHAR *KeyData) 731 + _In_ PINI_SECTION Section, 732 + _In_ PCWSTR KeyName, 733 + _Out_ PCWSTR* KeyData) 773 734 { 774 735 PINI_KEYWORD Key; 775 736 776 - if (Section == NULL || KeyName == NULL || KeyData == NULL) 737 + if (!Section || !KeyName || !KeyData) 777 738 { 778 739 DPRINT("Invalid parameter\n"); 779 - return STATUS_INVALID_PARAMETER; 740 + return NULL; 780 741 } 781 742 782 743 *KeyData = NULL; 783 744 784 745 Key = IniCacheFindKey(Section, KeyName); 785 - if (Key == NULL) 786 - { 787 - return STATUS_INVALID_PARAMETER; 788 - } 746 + if (!Key) 747 + return NULL; 789 748 790 749 *KeyData = Key->Data; 791 750 792 - return STATUS_SUCCESS; 751 + return Key; 793 752 } 794 753 795 754 796 755 PINICACHEITERATOR 797 756 IniFindFirstValue( 798 - PINI_SECTION Section, 799 - PWCHAR *KeyName, 800 - PWCHAR *KeyData) 757 + _In_ PINI_SECTION Section, 758 + _Out_ PCWSTR* KeyName, 759 + _Out_ PCWSTR* KeyData) 801 760 { 802 761 PINICACHEITERATOR Iterator; 762 + PLIST_ENTRY Entry; 803 763 PINI_KEYWORD Key; 804 764 805 - if (Section == NULL || KeyName == NULL || KeyData == NULL) 765 + if (!Section || !KeyName || !KeyData) 806 766 { 807 767 DPRINT("Invalid parameter\n"); 808 768 return NULL; 809 769 } 810 770 811 - Key = Section->FirstKey; 812 - if (Key == NULL) 771 + Entry = Section->KeyList.Flink; 772 + if (Entry == &Section->KeyList) 813 773 { 814 774 DPRINT("Invalid parameter\n"); 815 775 return NULL; 816 776 } 817 - 818 - *KeyName = Key->Name; 819 - *KeyData = Key->Data; 777 + Key = CONTAINING_RECORD(Entry, INI_KEYWORD, ListEntry); 820 778 821 779 Iterator = (PINICACHEITERATOR)RtlAllocateHeap(ProcessHeap, 822 780 0, 823 781 sizeof(INICACHEITERATOR)); 824 - if (Iterator == NULL) 782 + if (!Iterator) 825 783 { 826 784 DPRINT("RtlAllocateHeap() failed\n"); 827 785 return NULL; 828 786 } 829 - 830 787 Iterator->Section = Section; 831 788 Iterator->Key = Key; 789 + 790 + *KeyName = Key->Name; 791 + *KeyData = Key->Data; 832 792 833 793 return Iterator; 834 794 } 835 795 836 796 BOOLEAN 837 797 IniFindNextValue( 838 - PINICACHEITERATOR Iterator, 839 - PWCHAR *KeyName, 840 - PWCHAR *KeyData) 798 + _In_ PINICACHEITERATOR Iterator, 799 + _Out_ PCWSTR* KeyName, 800 + _Out_ PCWSTR* KeyData) 841 801 { 802 + PLIST_ENTRY Entry; 842 803 PINI_KEYWORD Key; 843 804 844 - if (Iterator == NULL || KeyName == NULL || KeyData == NULL) 805 + if (!Iterator || !KeyName || !KeyData) 845 806 { 846 807 DPRINT("Invalid parameter\n"); 847 808 return FALSE; 848 809 } 849 810 850 - Key = Iterator->Key->Next; 851 - if (Key == NULL) 811 + Entry = Iterator->Key->ListEntry.Flink; 812 + if (Entry == &Iterator->Section->KeyList) 852 813 { 853 814 DPRINT("No more entries\n"); 854 815 return FALSE; 855 816 } 817 + Key = CONTAINING_RECORD(Entry, INI_KEYWORD, ListEntry); 818 + 819 + Iterator->Key = Key; 856 820 857 821 *KeyName = Key->Name; 858 822 *KeyData = Key->Data; 859 823 860 - Iterator->Key = Key; 861 - 862 824 return TRUE; 863 825 } 864 826 865 827 VOID 866 828 IniFindClose( 867 - PINICACHEITERATOR Iterator) 829 + _In_ PINICACHEITERATOR Iterator) 868 830 { 869 - if (Iterator == NULL) 831 + if (!Iterator) 870 832 return; 871 - 872 833 RtlFreeHeap(ProcessHeap, 0, Iterator); 873 834 } 874 835 ··· 886 847 return IniCacheAddSectionAorW(Cache, Name, wcslen(Name), TRUE); 887 848 } 888 849 850 + VOID 851 + IniRemoveSection( 852 + _In_ PINI_SECTION Section) 853 + { 854 + if (!Section) 855 + { 856 + DPRINT("Invalid parameter\n"); 857 + return; 858 + } 859 + IniCacheFreeSection(Section); 860 + } 861 + 889 862 PINI_KEYWORD 890 863 IniInsertKey( 891 864 _In_ PINI_SECTION Section, ··· 915 888 return IniInsertKey(Section, NULL, INSERT_LAST, Name, Data); 916 889 } 917 890 891 + VOID 892 + IniRemoveKeyByName( 893 + _In_ PINI_SECTION Section, 894 + _In_ PCWSTR KeyName) 895 + { 896 + PINI_KEYWORD Key; 897 + UNREFERENCED_PARAMETER(Section); 898 + 899 + Key = IniCacheFindKey(Section, KeyName); 900 + if (Key) 901 + IniCacheFreeKey(Key); 902 + } 903 + 904 + VOID 905 + IniRemoveKey( 906 + _In_ PINI_SECTION Section, 907 + _In_ PINI_KEYWORD Key) 908 + { 909 + UNREFERENCED_PARAMETER(Section); 910 + if (!Key) 911 + { 912 + DPRINT("Invalid parameter\n"); 913 + return; 914 + } 915 + IniCacheFreeKey(Key); 916 + } 918 917 919 918 PINICACHE 920 919 IniCacheCreate(VOID) ··· 925 924 Cache = (PINICACHE)RtlAllocateHeap(ProcessHeap, 926 925 HEAP_ZERO_MEMORY, 927 926 sizeof(INICACHE)); 928 - if (Cache == NULL) 927 + if (!Cache) 929 928 { 930 929 DPRINT("RtlAllocateHeap() failed\n"); 931 930 return NULL; 932 931 } 932 + InitializeListHead(&Cache->SectionList); 933 933 934 934 return Cache; 935 935 } ··· 940 940 HANDLE FileHandle) 941 941 { 942 942 NTSTATUS Status; 943 + PLIST_ENTRY Entry1, Entry2; 943 944 PINI_SECTION Section; 944 945 PINI_KEYWORD Key; 945 946 ULONG BufferSize; ··· 951 952 952 953 /* Calculate required buffer size */ 953 954 BufferSize = 0; 954 - Section = Cache->FirstSection; 955 - while (Section != NULL) 955 + Entry1 = Cache->SectionList.Flink; 956 + while (Entry1 != &Cache->SectionList) 956 957 { 958 + Section = CONTAINING_RECORD(Entry1, INI_SECTION, ListEntry); 957 959 BufferSize += (Section->Name ? wcslen(Section->Name) : 0) 958 960 + 4; /* "[]\r\n" */ 959 961 960 - Key = Section->FirstKey; 961 - while (Key != NULL) 962 + Entry2 = Section->KeyList.Flink; 963 + while (Entry2 != &Section->KeyList) 962 964 { 965 + Key = CONTAINING_RECORD(Entry2, INI_KEYWORD, ListEntry); 963 966 BufferSize += wcslen(Key->Name) 964 967 + (Key->Data ? wcslen(Key->Data) : 0) 965 968 + 3; /* "=\r\n" */ 966 - Key = Key->Next; 969 + Entry2 = Entry2->Flink; 967 970 } 968 971 969 - Section = Section->Next; 970 - if (Section != NULL) 972 + Entry1 = Entry1->Flink; 973 + if (Entry1 != &Cache->SectionList) 971 974 BufferSize += 2; /* Extra "\r\n" at end of each section */ 972 975 } 973 976 ··· 985 988 986 989 /* Fill file buffer */ 987 990 Ptr = Buffer; 988 - Section = Cache->FirstSection; 989 - while (Section != NULL) 991 + Entry1 = Cache->SectionList.Flink; 992 + while (Entry1 != &Cache->SectionList) 990 993 { 994 + Section = CONTAINING_RECORD(Entry1, INI_SECTION, ListEntry); 991 995 Len = sprintf(Ptr, "[%S]\r\n", Section->Name); 992 996 Ptr += Len; 993 997 994 - Key = Section->FirstKey; 995 - while (Key != NULL) 998 + Entry2 = Section->KeyList.Flink; 999 + while (Entry2 != &Section->KeyList) 996 1000 { 1001 + Key = CONTAINING_RECORD(Entry2, INI_KEYWORD, ListEntry); 997 1002 Len = sprintf(Ptr, "%S=%S\r\n", Key->Name, Key->Data); 998 1003 Ptr += Len; 999 - Key = Key->Next; 1004 + Entry2 = Entry2->Flink; 1000 1005 } 1001 1006 1002 - Section = Section->Next; 1003 - if (Section != NULL) 1007 + Entry1 = Entry1->Flink; 1008 + if (Entry1 != &Cache->SectionList) 1004 1009 { 1005 1010 Len = sprintf(Ptr, "\r\n"); 1006 1011 Ptr += Len;
+30 -23
base/setup/lib/utils/inicache.h
··· 11 11 { 12 12 PWSTR Name; 13 13 PWSTR Data; 14 - 15 - struct _INI_KEYWORD *Next; 16 - struct _INI_KEYWORD *Prev; 14 + LIST_ENTRY ListEntry; 17 15 } INI_KEYWORD, *PINI_KEYWORD; 18 16 19 17 typedef struct _INI_SECTION 20 18 { 21 19 PWSTR Name; 22 - 23 - PINI_KEYWORD FirstKey; 24 - PINI_KEYWORD LastKey; 25 - 26 - struct _INI_SECTION *Next; 27 - struct _INI_SECTION *Prev; 20 + LIST_ENTRY KeyList; 21 + LIST_ENTRY ListEntry; 28 22 } INI_SECTION, *PINI_SECTION; 29 23 30 24 typedef struct _INICACHE 31 25 { 32 - PINI_SECTION FirstSection; 33 - PINI_SECTION LastSection; 26 + LIST_ENTRY SectionList; 34 27 } INICACHE, *PINICACHE; 35 28 36 29 typedef struct _PINICACHEITERATOR ··· 70 63 71 64 VOID 72 65 IniCacheDestroy( 73 - PINICACHE Cache); 66 + _In_ PINICACHE Cache); 74 67 75 68 PINI_SECTION 76 69 IniGetSection( 77 70 _In_ PINICACHE Cache, 78 71 _In_ PCWSTR Name); 79 72 80 - NTSTATUS 73 + PINI_KEYWORD 81 74 IniGetKey( 82 - PINI_SECTION Section, 83 - PWCHAR KeyName, 84 - PWCHAR *KeyData); 75 + _In_ PINI_SECTION Section, 76 + _In_ PCWSTR KeyName, 77 + _Out_ PCWSTR* KeyData); 85 78 86 79 PINICACHEITERATOR 87 80 IniFindFirstValue( 88 - PINI_SECTION Section, 89 - PWCHAR *KeyName, 90 - PWCHAR *KeyData); 81 + _In_ PINI_SECTION Section, 82 + _Out_ PCWSTR* KeyName, 83 + _Out_ PCWSTR* KeyData); 91 84 92 85 BOOLEAN 93 86 IniFindNextValue( 94 - PINICACHEITERATOR Iterator, 95 - PWCHAR *KeyName, 96 - PWCHAR *KeyData); 87 + _In_ PINICACHEITERATOR Iterator, 88 + _Out_ PCWSTR* KeyName, 89 + _Out_ PCWSTR* KeyData); 97 90 98 91 VOID 99 92 IniFindClose( 100 - PINICACHEITERATOR Iterator); 93 + _In_ PINICACHEITERATOR Iterator); 101 94 102 95 PINI_SECTION 103 96 IniAddSection( 104 97 _In_ PINICACHE Cache, 105 98 _In_ PCWSTR Name); 106 99 100 + VOID 101 + IniRemoveSection( 102 + _In_ PINI_SECTION Section); 103 + 107 104 PINI_KEYWORD 108 105 IniInsertKey( 109 106 _In_ PINI_SECTION Section, ··· 117 114 _In_ PINI_SECTION Section, 118 115 _In_ PCWSTR Name, 119 116 _In_ PCWSTR Data); 117 + 118 + VOID 119 + IniRemoveKeyByName( 120 + _In_ PINI_SECTION Section, 121 + _In_ PCWSTR KeyName); 122 + 123 + VOID 124 + IniRemoveKey( 125 + _In_ PINI_SECTION Section, 126 + _In_ PINI_KEYWORD Key); 120 127 121 128 PINICACHE 122 129 IniCacheCreate(VOID);