ReactOS 0.4.15-dev-8039-g69ebfd6
inicache.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Setup Library
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: INI file parser that caches contents of INI file in memory.
5 * COPYRIGHT: Copyright 2002-2018 Royce Mitchell III
6 */
7
8/* INCLUDES *****************************************************************/
9
10#include "precomp.h"
11
12#include "inicache.h"
13
14#define NDEBUG
15#include <debug.h>
16
17/* PRIVATE FUNCTIONS ********************************************************/
18
19static VOID
22{
23 /* Unlink the key */
24 RemoveEntryList(&Key->ListEntry);
25
26 /* Free its data */
27 if (Key->Name)
28 RtlFreeHeap(ProcessHeap, 0, Key->Name);
29 if (Key->Data)
30 RtlFreeHeap(ProcessHeap, 0, Key->Data);
32}
33
34static VOID
36 _In_ PINI_SECTION Section)
37{
38 /* Unlink the section */
39 RemoveEntryList(&Section->ListEntry);
40
41 /* Free its data */
42 while (!IsListEmpty(&Section->KeyList))
43 {
44 PLIST_ENTRY Entry = RemoveHeadList(&Section->KeyList);
47 }
48 if (Section->Name)
49 RtlFreeHeap(ProcessHeap, 0, Section->Name);
50 RtlFreeHeap(ProcessHeap, 0, Section);
51}
52
53static
58{
60
61 for (Entry = Cache->SectionList.Flink;
62 Entry != &Cache->SectionList;
63 Entry = Entry->Flink)
64 {
65 PINI_SECTION Section = CONTAINING_RECORD(Entry, INI_SECTION, ListEntry);
66 if (_wcsicmp(Section->Name, Name) == 0)
67 return Section;
68 }
69 return NULL;
70}
71
72static
75 _In_ PINI_SECTION Section,
77{
79
80 for (Entry = Section->KeyList.Flink;
81 Entry != &Section->KeyList;
82 Entry = Entry->Flink)
83 {
85 if (_wcsicmp(Key->Name, Name) == 0)
86 return Key;
87 }
88 return NULL;
89}
90
91static
94 _In_ PINI_SECTION Section,
95 _In_ PINI_KEYWORD AnchorKey,
96 _In_ INSERTION_TYPE InsertionType,
97 _In_ const VOID* Name,
98 _In_ ULONG NameLength,
99 _In_ const VOID* Data,
101 _In_ BOOLEAN IsUnicode)
102{
104 PWSTR NameU, DataU;
105
106 if (!Section || !Name || NameLength == 0 || !Data || DataLength == 0)
107 {
108 DPRINT("Invalid parameter\n");
109 return NULL;
110 }
111
112 /* Allocate the UNICODE key name */
114 0,
115 (NameLength + 1) * sizeof(WCHAR));
116 if (!NameU)
117 {
118 DPRINT("RtlAllocateHeap() failed\n");
119 return NULL;
120 }
121 /* Copy the value name (ANSI or UNICODE) */
122 if (IsUnicode)
123 wcsncpy(NameU, (PCWCH)Name, NameLength);
124 else
125 _snwprintf(NameU, NameLength, L"%.*S", NameLength, (PCCH)Name);
126 NameU[NameLength] = UNICODE_NULL;
127
128 /*
129 * Find whether a key with the given name already exists in the section.
130 * If so, modify the data and return it; otherwise create a new one.
131 */
132 Key = IniCacheFindKey(Section, NameU);
133 if (Key)
134 {
135 RtlFreeHeap(ProcessHeap, 0, NameU);
136
137 /* Modify the existing data */
138
139 /* Allocate the UNICODE data buffer */
141 0,
142 (DataLength + 1) * sizeof(WCHAR));
143 if (!DataU)
144 {
145 DPRINT("RtlAllocateHeap() failed\n");
146 return NULL; // We failed, don't modify the original key.
147 }
148 /* Copy the data (ANSI or UNICODE) */
149 if (IsUnicode)
150 wcsncpy(DataU, (PCWCH)Data, DataLength);
151 else
152 _snwprintf(DataU, DataLength, L"%.*S", DataLength, (PCCH)Data);
153 DataU[DataLength] = UNICODE_NULL;
154
155 /* Swap the old key data with the new one */
156 RtlFreeHeap(ProcessHeap, 0, Key->Data);
157 Key->Data = DataU;
158
159 /* Return the modified key */
160 return Key;
161 }
162
163 /* Allocate the key buffer and name */
166 sizeof(INI_KEYWORD));
167 if (!Key)
168 {
169 DPRINT("RtlAllocateHeap() failed\n");
170 RtlFreeHeap(ProcessHeap, 0, NameU);
171 return NULL;
172 }
173 Key->Name = NameU;
174
175 /* Allocate the UNICODE data buffer */
177 0,
178 (DataLength + 1) * sizeof(WCHAR));
179 if (!DataU)
180 {
181 DPRINT("RtlAllocateHeap() failed\n");
182 RtlFreeHeap(ProcessHeap, 0, NameU);
184 return NULL;
185 }
186 /* Copy the data (ANSI or UNICODE) */
187 if (IsUnicode)
188 wcsncpy(DataU, (PCWCH)Data, DataLength);
189 else
190 _snwprintf(DataU, DataLength, L"%.*S", DataLength, (PCCH)Data);
191 DataU[DataLength] = UNICODE_NULL;
192 Key->Data = DataU;
193
194 /* Insert the key into section */
195 if (IsListEmpty(&Section->KeyList))
196 {
197 InsertHeadList(&Section->KeyList, &Key->ListEntry);
198 }
199 else if ((InsertionType == INSERT_FIRST) ||
200 ((InsertionType == INSERT_BEFORE) &&
201 (!AnchorKey || (&AnchorKey->ListEntry == Section->KeyList.Flink))))
202 {
203 /* Insert at the head of the list */
204 InsertHeadList(&Section->KeyList, &Key->ListEntry);
205 }
206 else if ((InsertionType == INSERT_BEFORE) && AnchorKey)
207 {
208 /* Insert before the anchor key */
209 InsertTailList(&AnchorKey->ListEntry, &Key->ListEntry);
210 }
211 else if ((InsertionType == INSERT_LAST) ||
212 ((InsertionType == INSERT_AFTER) &&
213 (!AnchorKey || (&AnchorKey->ListEntry == Section->KeyList.Blink))))
214 {
215 /* Insert at the tail of the list */
216 InsertTailList(&Section->KeyList, &Key->ListEntry);
217 }
218 else if ((InsertionType == INSERT_AFTER) && AnchorKey)
219 {
220 /* Insert after the anchor key */
221 InsertHeadList(&AnchorKey->ListEntry, &Key->ListEntry);
222 }
223
224 return Key;
225}
226
227static
231 _In_ const VOID* Name,
232 _In_ ULONG NameLength,
233 _In_ BOOLEAN IsUnicode)
234{
235 PINI_SECTION Section;
236 PWSTR NameU;
237
238 if (!Cache || !Name || NameLength == 0)
239 {
240 DPRINT("Invalid parameter\n");
241 return NULL;
242 }
243
244 /* Allocate the UNICODE section name */
246 0,
247 (NameLength + 1) * sizeof(WCHAR));
248 if (!NameU)
249 {
250 DPRINT("RtlAllocateHeap() failed\n");
251 return NULL;
252 }
253 /* Copy the section name (ANSI or UNICODE) */
254 if (IsUnicode)
255 wcsncpy(NameU, (PCWCH)Name, NameLength);
256 else
257 _snwprintf(NameU, NameLength, L"%.*S", NameLength, (PCCH)Name);
258 NameU[NameLength] = UNICODE_NULL;
259
260 /*
261 * Find whether a section with the given name already exists.
262 * If so, just return it; otherwise create a new one.
263 */
264 Section = IniCacheFindSection(Cache, NameU);
265 if (Section)
266 {
267 RtlFreeHeap(ProcessHeap, 0, NameU);
268 return Section;
269 }
270
271 /* Allocate the section buffer and name */
274 sizeof(INI_SECTION));
275 if (!Section)
276 {
277 DPRINT("RtlAllocateHeap() failed\n");
278 RtlFreeHeap(ProcessHeap, 0, NameU);
279 return NULL;
280 }
281 Section->Name = NameU;
282 InitializeListHead(&Section->KeyList);
283
284 /* Append the section */
285 InsertTailList(&Cache->SectionList, &Section->ListEntry);
286
287 return Section;
288}
289
290static
291PCHAR
293 PCHAR Ptr)
294{
295 while (*Ptr != 0 && isspace(*Ptr))
296 Ptr++;
297
298 return (*Ptr == 0) ? NULL : Ptr;
299}
300
301static
302PCHAR
304 PCHAR Ptr)
305{
306 while (*Ptr != 0 && *Ptr != '[')
307 {
308 while (*Ptr != 0 && *Ptr != L'\n')
309 {
310 Ptr++;
311 }
312
313 Ptr++;
314 }
315
316 return (*Ptr == 0) ? NULL : Ptr;
317}
318
319static
320PCHAR
322 PCHAR Ptr,
323 PCHAR *NamePtr,
324 PULONG NameSize)
325{
326 ULONG Size = 0;
327
328 *NamePtr = NULL;
329 *NameSize = 0;
330
331 /* Skip whitespace */
332 while (*Ptr != 0 && isspace(*Ptr))
333 {
334 Ptr++;
335 }
336
337 *NamePtr = Ptr;
338
339 while (*Ptr != 0 && *Ptr != ']')
340 {
341 Size++;
342 Ptr++;
343 }
344 Ptr++;
345
346 while (*Ptr != 0 && *Ptr != L'\n')
347 {
348 Ptr++;
349 }
350 Ptr++;
351
352 *NameSize = Size;
353
354 DPRINT("SectionName: '%.*s'\n", Size, *NamePtr);
355
356 return Ptr;
357}
358
359static
360PCHAR
362 PCHAR Ptr,
363 PCHAR *NamePtr,
364 PULONG NameSize)
365{
366 ULONG Size = 0;
367
368 *NamePtr = NULL;
369 *NameSize = 0;
370
371 while (Ptr && *Ptr)
372 {
373 *NamePtr = NULL;
374 *NameSize = 0;
375 Size = 0;
376
377 /* Skip whitespace and empty lines */
378 while (isspace(*Ptr) || *Ptr == '\n' || *Ptr == '\r')
379 {
380 Ptr++;
381 }
382 if (*Ptr == 0)
383 {
384 continue;
385 }
386
387 *NamePtr = Ptr;
388
389 while (*Ptr != 0 && !isspace(*Ptr) && *Ptr != '=' && *Ptr != ';')
390 {
391 Size++;
392 Ptr++;
393 }
394 if (*Ptr == ';')
395 {
396 while (*Ptr != 0 && *Ptr != '\r' && *Ptr != '\n')
397 {
398 Ptr++;
399 }
400 }
401 else
402 {
403 *NameSize = Size;
404 break;
405 }
406 }
407
408 return Ptr;
409}
410
411static
412PCHAR
414 PCHAR Ptr,
415 PCHAR *DataPtr,
418{
419 ULONG Size = 0;
420
421 *DataPtr = NULL;
422 *DataSize = 0;
423
424 /* Skip whitespace */
425 while (*Ptr != 0 && isspace(*Ptr))
426 {
427 Ptr++;
428 }
429
430 /* Check and skip '=' */
431 if (*Ptr != '=')
432 {
433 return NULL;
434 }
435 Ptr++;
436
437 /* Skip whitespace */
438 while (*Ptr != 0 && isspace(*Ptr))
439 {
440 Ptr++;
441 }
442
443 if (*Ptr == '"' && String)
444 {
445 Ptr++;
446
447 /* Get data */
448 *DataPtr = Ptr;
449 while (*Ptr != '"')
450 {
451 Ptr++;
452 Size++;
453 }
454 Ptr++;
455
456 while (*Ptr && *Ptr != '\r' && *Ptr != '\n')
457 {
458 Ptr++;
459 }
460 }
461 else
462 {
463 /* Get data */
464 *DataPtr = Ptr;
465 while (*Ptr != 0 && *Ptr != '\r' && *Ptr != ';')
466 {
467 Ptr++;
468 Size++;
469 }
470 }
471
472 /* Skip to next line */
473 if (*Ptr == '\r')
474 Ptr++;
475 if (*Ptr == '\n')
476 Ptr++;
477
478 *DataSize = Size;
479
480 return Ptr;
481}
482
483
484/* PUBLIC FUNCTIONS *********************************************************/
485
489 PCHAR FileBuffer,
492{
493 PCHAR Ptr;
494
495 PINI_SECTION Section;
497
498 PCHAR SectionName;
499 ULONG SectionNameSize;
500
502 ULONG KeyNameSize;
503
504 PCHAR KeyValue;
505 ULONG KeyValueSize;
506
507 /* Allocate inicache header */
509 if (!*Cache)
511
512 /* Parse ini file */
513 Section = NULL;
514 Ptr = FileBuffer;
515 while (Ptr != NULL && *Ptr != 0)
516 {
518 if (Ptr == NULL)
519 continue;
520
521 if (*Ptr == '[')
522 {
523 Section = NULL;
524 Ptr++;
525
527 &SectionName,
528 &SectionNameSize);
529
530 DPRINT("[%.*s]\n", SectionNameSize, SectionName);
531
532 Section = IniCacheAddSectionAorW(*Cache,
533 SectionName,
534 SectionNameSize,
535 FALSE);
536 if (Section == NULL)
537 {
538 DPRINT("IniCacheAddSectionAorW() failed\n");
540 continue;
541 }
542 }
543 else
544 {
545 if (Section == NULL)
546 {
548 continue;
549 }
550
552 &KeyName,
553 &KeyNameSize);
554
556 &KeyValue,
557 &KeyValueSize,
558 String);
559
560 DPRINT("'%.*s' = '%.*s'\n", KeyNameSize, KeyName, KeyValueSize, KeyValue);
561
562 Key = IniCacheAddKeyAorW(Section,
563 NULL,
565 KeyName,
566 KeyNameSize,
567 KeyValue,
568 KeyValueSize,
569 FALSE);
570 if (Key == NULL)
571 {
572 DPRINT("IniCacheAddKeyAorW() failed\n");
573 }
574 }
575 }
576
577 return STATUS_SUCCESS;
578}
579
585{
589 PCHAR FileBuffer;
592
593 *Cache = NULL;
594
595 /* Query file size */
598 &FileInfo,
601 if (!NT_SUCCESS(Status))
602 {
603 DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
604 return Status;
605 }
606
607 FileLength = FileInfo.EndOfFile.u.LowPart;
608
609 DPRINT("File size: %lu\n", FileLength);
610
611 /* Allocate file buffer with NULL-terminator */
612 FileBuffer = (PCHAR)RtlAllocateHeap(ProcessHeap,
613 0,
614 FileLength + 1);
615 if (FileBuffer == NULL)
616 {
617 DPRINT1("RtlAllocateHeap() failed\n");
619 }
620
621 /* Read file */
622 FileOffset.QuadPart = 0ULL;
624 NULL,
625 NULL,
626 NULL,
628 FileBuffer,
630 &FileOffset,
631 NULL);
632
633 /* Append NULL-terminator */
634 FileBuffer[FileLength] = 0;
635
636 if (!NT_SUCCESS(Status))
637 {
638 DPRINT("NtReadFile() failed (Status %lx)\n", Status);
639 goto Quit;
640 }
641
643 if (!NT_SUCCESS(Status))
644 {
645 DPRINT1("IniCacheLoadFromMemory() failed (Status %lx)\n", Status);
646 }
647
648Quit:
649 /* Free the file buffer, and return */
650 RtlFreeHeap(ProcessHeap, 0, FileBuffer);
651 return Status;
652}
653
659{
665
666 *Cache = NULL;
667
668 /* Open the INI file */
670
672 &Name,
674 NULL,
675 NULL);
676
683 if (!NT_SUCCESS(Status))
684 {
685 DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
686 return Status;
687 }
688
689 DPRINT("NtOpenFile() successful\n");
690
692
693 /* Close the INI file */
695 return Status;
696}
697
698VOID
701{
702 if (!Cache)
703 return;
704
705 while (!IsListEmpty(&Cache->SectionList))
706 {
707 PLIST_ENTRY Entry = RemoveHeadList(&Cache->SectionList);
708 PINI_SECTION Section = CONTAINING_RECORD(Entry, INI_SECTION, ListEntry);
709 IniCacheFreeSection(Section);
710 }
711
713}
714
715
720{
721 if (!Cache || !Name)
722 {
723 DPRINT("Invalid parameter\n");
724 return NULL;
725 }
727}
728
731 _In_ PINI_SECTION Section,
733 _Out_ PCWSTR* KeyData)
734{
736
737 if (!Section || !KeyName || !KeyData)
738 {
739 DPRINT("Invalid parameter\n");
740 return NULL;
741 }
742
743 *KeyData = NULL;
744
745 Key = IniCacheFindKey(Section, KeyName);
746 if (!Key)
747 return NULL;
748
749 *KeyData = Key->Data;
750
751 return Key;
752}
753
754
757 _In_ PINI_SECTION Section,
759 _Out_ PCWSTR* KeyData)
760{
764
765 if (!Section || !KeyName || !KeyData)
766 {
767 DPRINT("Invalid parameter\n");
768 return NULL;
769 }
770
771 Entry = Section->KeyList.Flink;
772 if (Entry == &Section->KeyList)
773 {
774 DPRINT("Invalid parameter\n");
775 return NULL;
776 }
777 Key = CONTAINING_RECORD(Entry, INI_KEYWORD, ListEntry);
778
780 0,
781 sizeof(INICACHEITERATOR));
782 if (!Iterator)
783 {
784 DPRINT("RtlAllocateHeap() failed\n");
785 return NULL;
786 }
787 Iterator->Section = Section;
788 Iterator->Key = Key;
789
790 *KeyName = Key->Name;
791 *KeyData = Key->Data;
792
793 return Iterator;
794}
795
800 _Out_ PCWSTR* KeyData)
801{
804
805 if (!Iterator || !KeyName || !KeyData)
806 {
807 DPRINT("Invalid parameter\n");
808 return FALSE;
809 }
810
811 Entry = Iterator->Key->ListEntry.Flink;
812 if (Entry == &Iterator->Section->KeyList)
813 {
814 DPRINT("No more entries\n");
815 return FALSE;
816 }
817 Key = CONTAINING_RECORD(Entry, INI_KEYWORD, ListEntry);
818
819 Iterator->Key = Key;
820
821 *KeyName = Key->Name;
822 *KeyData = Key->Data;
823
824 return TRUE;
825}
826
827VOID
830{
831 if (!Iterator)
832 return;
834}
835
836
841{
842 if (!Cache || !Name || !*Name)
843 {
844 DPRINT("Invalid parameter\n");
845 return NULL;
846 }
848}
849
850VOID
852 _In_ PINI_SECTION Section)
853{
854 if (!Section)
855 {
856 DPRINT("Invalid parameter\n");
857 return;
858 }
859 IniCacheFreeSection(Section);
860}
861
864 _In_ PINI_SECTION Section,
865 _In_ PINI_KEYWORD AnchorKey,
866 _In_ INSERTION_TYPE InsertionType,
869{
870 if (!Section || !Name || !*Name || !Data || !*Data)
871 {
872 DPRINT("Invalid parameter\n");
873 return NULL;
874 }
875 return IniCacheAddKeyAorW(Section,
876 AnchorKey, InsertionType,
877 Name, wcslen(Name),
878 Data, wcslen(Data),
879 TRUE);
880}
881
884 _In_ PINI_SECTION Section,
887{
888 return IniInsertKey(Section, NULL, INSERT_LAST, Name, Data);
889}
890
891VOID
893 _In_ PINI_SECTION Section,
895{
897 UNREFERENCED_PARAMETER(Section);
898
899 Key = IniCacheFindKey(Section, KeyName);
900 if (Key)
902}
903
904VOID
906 _In_ PINI_SECTION Section,
908{
909 UNREFERENCED_PARAMETER(Section);
910 if (!Key)
911 {
912 DPRINT("Invalid parameter\n");
913 return;
914 }
916}
917
920{
922
923 /* Allocate inicache header */
926 sizeof(INICACHE));
927 if (!Cache)
928 {
929 DPRINT("RtlAllocateHeap() failed\n");
930 return NULL;
931 }
932 InitializeListHead(&Cache->SectionList);
933
934 return Cache;
935}
936
941{
943 PLIST_ENTRY Entry1, Entry2;
944 PINI_SECTION Section;
948 PCHAR Ptr;
949 ULONG Len;
952
953 /* Calculate required buffer size */
954 BufferSize = 0;
955 Entry1 = Cache->SectionList.Flink;
956 while (Entry1 != &Cache->SectionList)
957 {
958 Section = CONTAINING_RECORD(Entry1, INI_SECTION, ListEntry);
959 BufferSize += (Section->Name ? wcslen(Section->Name) : 0)
960 + 4; /* "[]\r\n" */
961
962 Entry2 = Section->KeyList.Flink;
963 while (Entry2 != &Section->KeyList)
964 {
965 Key = CONTAINING_RECORD(Entry2, INI_KEYWORD, ListEntry);
966 BufferSize += wcslen(Key->Name)
967 + (Key->Data ? wcslen(Key->Data) : 0)
968 + 3; /* "=\r\n" */
969 Entry2 = Entry2->Flink;
970 }
971
972 Entry1 = Entry1->Flink;
973 if (Entry1 != &Cache->SectionList)
974 BufferSize += 2; /* Extra "\r\n" at end of each section */
975 }
976
977 DPRINT("BufferSize: %lu\n", BufferSize);
978
979 /* Allocate file buffer with NULL-terminator */
982 BufferSize + 1);
983 if (Buffer == NULL)
984 {
985 DPRINT1("RtlAllocateHeap() failed\n");
987 }
988
989 /* Fill file buffer */
990 Ptr = Buffer;
991 Entry1 = Cache->SectionList.Flink;
992 while (Entry1 != &Cache->SectionList)
993 {
994 Section = CONTAINING_RECORD(Entry1, INI_SECTION, ListEntry);
995 Len = sprintf(Ptr, "[%S]\r\n", Section->Name);
996 Ptr += Len;
997
998 Entry2 = Section->KeyList.Flink;
999 while (Entry2 != &Section->KeyList)
1000 {
1001 Key = CONTAINING_RECORD(Entry2, INI_KEYWORD, ListEntry);
1002 Len = sprintf(Ptr, "%S=%S\r\n", Key->Name, Key->Data);
1003 Ptr += Len;
1004 Entry2 = Entry2->Flink;
1005 }
1006
1007 Entry1 = Entry1->Flink;
1008 if (Entry1 != &Cache->SectionList)
1009 {
1010 Len = sprintf(Ptr, "\r\n");
1011 Ptr += Len;
1012 }
1013 }
1014
1015 /* Write to the INI file */
1016 Offset.QuadPart = 0LL;
1018 NULL,
1019 NULL,
1020 NULL,
1022 Buffer,
1023 BufferSize,
1024 &Offset,
1025 NULL);
1026 if (!NT_SUCCESS(Status))
1027 {
1028 DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
1030 return Status;
1031 }
1032
1034 return STATUS_SUCCESS;
1035}
1036
1041{
1047
1048 /* Create the INI file */
1050
1052 &Name,
1054 NULL,
1055 NULL);
1056
1061 NULL,
1063 0,
1066 NULL,
1067 0);
1068 if (!NT_SUCCESS(Status))
1069 {
1070 DPRINT("NtCreateFile() failed (Status %lx)\n", Status);
1071 return Status;
1072 }
1073
1075
1076 /* Close the INI file */
1078 return Status;
1079}
1080
1081/* EOF */
unsigned char BOOLEAN
#define isspace(c)
Definition: acclib.h:69
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
HANDLE ProcessHeap
Definition: servman.c:15
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define Len
Definition: deflate.h:82
#define BufferSize
Definition: mmc.h:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
Status
Definition: gdiplustypes.h:25
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID IniCacheDestroy(_In_ PINICACHE Cache)
Definition: inicache.c:699
NTSTATUS IniCacheLoad(PINICACHE *Cache, PWCHAR FileName, BOOLEAN String)
Definition: inicache.c:655
NTSTATUS IniCacheLoadFromMemory(PINICACHE *Cache, PCHAR FileBuffer, ULONG FileLength, BOOLEAN String)
Definition: inicache.c:487
VOID IniRemoveSection(_In_ PINI_SECTION Section)
Definition: inicache.c:851
static VOID IniCacheFreeKey(_In_ PINI_KEYWORD Key)
Definition: inicache.c:20
VOID IniRemoveKeyByName(_In_ PINI_SECTION Section, _In_ PCWSTR KeyName)
Definition: inicache.c:892
static PINI_KEYWORD IniCacheFindKey(_In_ PINI_SECTION Section, _In_ PCWSTR Name)
Definition: inicache.c:74
PINI_SECTION IniAddSection(_In_ PINICACHE Cache, _In_ PCWSTR Name)
Definition: inicache.c:838
NTSTATUS IniCacheSaveByHandle(PINICACHE Cache, HANDLE FileHandle)
Definition: inicache.c:938
VOID IniRemoveKey(_In_ PINI_SECTION Section, _In_ PINI_KEYWORD Key)
Definition: inicache.c:905
static PCHAR IniCacheGetKeyName(PCHAR Ptr, PCHAR *NamePtr, PULONG NameSize)
Definition: inicache.c:361
PINICACHEITERATOR IniFindFirstValue(_In_ PINI_SECTION Section, _Out_ PCWSTR *KeyName, _Out_ PCWSTR *KeyData)
Definition: inicache.c:756
PINI_SECTION IniGetSection(_In_ PINICACHE Cache, _In_ PCWSTR Name)
Definition: inicache.c:717
static PINI_SECTION IniCacheAddSectionAorW(_In_ PINICACHE Cache, _In_ const VOID *Name, _In_ ULONG NameLength, _In_ BOOLEAN IsUnicode)
Definition: inicache.c:229
PINI_KEYWORD IniGetKey(_In_ PINI_SECTION Section, _In_ PCWSTR KeyName, _Out_ PCWSTR *KeyData)
Definition: inicache.c:730
static PINI_SECTION IniCacheFindSection(_In_ PINICACHE Cache, _In_ PCWSTR Name)
Definition: inicache.c:55
static VOID IniCacheFreeSection(_In_ PINI_SECTION Section)
Definition: inicache.c:35
static PCHAR IniCacheGetKeyValue(PCHAR Ptr, PCHAR *DataPtr, PULONG DataSize, BOOLEAN String)
Definition: inicache.c:413
static PCHAR IniCacheSkipToNextSection(PCHAR Ptr)
Definition: inicache.c:303
static PCHAR IniCacheGetSectionName(PCHAR Ptr, PCHAR *NamePtr, PULONG NameSize)
Definition: inicache.c:321
NTSTATUS IniCacheSave(PINICACHE Cache, PWCHAR FileName)
Definition: inicache.c:1038
PINICACHE IniCacheCreate(VOID)
Definition: inicache.c:919
static PINI_KEYWORD IniCacheAddKeyAorW(_In_ PINI_SECTION Section, _In_ PINI_KEYWORD AnchorKey, _In_ INSERTION_TYPE InsertionType, _In_ const VOID *Name, _In_ ULONG NameLength, _In_ const VOID *Data, _In_ ULONG DataLength, _In_ BOOLEAN IsUnicode)
Definition: inicache.c:93
VOID IniFindClose(_In_ PINICACHEITERATOR Iterator)
Definition: inicache.c:828
NTSTATUS IniCacheLoadByHandle(PINICACHE *Cache, HANDLE FileHandle, BOOLEAN String)
Definition: inicache.c:581
BOOLEAN IniFindNextValue(_In_ PINICACHEITERATOR Iterator, _Out_ PCWSTR *KeyName, _Out_ PCWSTR *KeyData)
Definition: inicache.c:797
static PCHAR IniCacheSkipWhitespace(PCHAR Ptr)
Definition: inicache.c:292
PINI_KEYWORD IniAddKey(_In_ PINI_SECTION Section, _In_ PCWSTR Name, _In_ PCWSTR Data)
Definition: inicache.c:883
PINI_KEYWORD IniInsertKey(_In_ PINI_SECTION Section, _In_ PINI_KEYWORD AnchorKey, _In_ INSERTION_TYPE InsertionType, _In_ PCWSTR Name, _In_ PCWSTR Data)
Definition: inicache.c:863
struct _PINICACHEITERATOR * PINICACHEITERATOR
INSERTION_TYPE
Definition: inicache.h:36
@ INSERT_BEFORE
Definition: inicache.h:38
@ INSERT_AFTER
Definition: inicache.h:39
@ INSERT_LAST
Definition: inicache.h:40
@ INSERT_FIRST
Definition: inicache.h:37
struct _INI_SECTION * PINI_SECTION
struct _INI_KEYWORD * PINI_KEYWORD
struct _INICACHE * PINICACHE
#define PCHAR
Definition: match.c:90
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define ULL(a, b)
Definition: format_msg.c:27
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
_Out_ PNDIS_HANDLE _Out_ PUINT FileLength
Definition: ndis.h:3228
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTATUS NTAPI NtCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
CONST WCHAR * PCWCH
Definition: ntbasedef.h:411
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
CONST CHAR * PCCH
Definition: ntbasedef.h:392
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define L(x)
Definition: ntvdm.h:50
#define FileStandardInformation
Definition: propsheet.cpp:61
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
#define DPRINT
Definition: sndvol32.h:71
Definition: fatfs.h:173
base of all file and directory entries
Definition: entries.h:83
PWSTR Name
Definition: inicache.h:19
LIST_ENTRY ListEntry
Definition: inicache.h:21
LIST_ENTRY KeyList
Definition: inicache.h:20
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define LL
Definition: tui.h:167
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR Iterator
Definition: wdfchildlist.h:656
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
__wchar_t WCHAR
Definition: xmlstorage.h:180