ReactOS  0.4.14-dev-49-gfb4591c
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 
19 static
23 {
24  PINICACHEKEY Next;
25 
26  if (Key == NULL)
27  return NULL;
28 
29  Next = Key->Next;
30  if (Key->Name != NULL)
31  {
32  RtlFreeHeap(ProcessHeap, 0, Key->Name);
33  Key->Name = NULL;
34  }
35 
36  if (Key->Data != NULL)
37  {
38  RtlFreeHeap(ProcessHeap, 0, Key->Data);
39  Key->Data = NULL;
40  }
41 
43 
44  return Next;
45 }
46 
47 
48 static
51  PINICACHESECTION Section)
52 {
53  PINICACHESECTION Next;
54 
55  if (Section == NULL)
56  return NULL;
57 
58  Next = Section->Next;
59  while (Section->FirstKey != NULL)
60  {
61  Section->FirstKey = IniCacheFreeKey(Section->FirstKey);
62  }
63  Section->LastKey = NULL;
64 
65  if (Section->Name != NULL)
66  {
67  RtlFreeHeap(ProcessHeap, 0, Section->Name);
68  Section->Name = NULL;
69  }
70 
71  RtlFreeHeap(ProcessHeap, 0, Section);
72 
73  return Next;
74 }
75 
76 
77 static
80  PINICACHESECTION Section,
81  PWCHAR Name,
82  ULONG NameLength)
83 {
85 
86  Key = Section->FirstKey;
87  while (Key != NULL)
88  {
89  if (NameLength == wcslen(Key->Name))
90  {
91  if (_wcsnicmp(Key->Name, Name, NameLength) == 0)
92  break;
93  }
94 
95  Key = Key->Next;
96  }
97 
98  return Key;
99 }
100 
101 
102 static
105  PINICACHESECTION Section,
106  PCHAR Name,
107  ULONG NameLength,
108  PCHAR Data,
110 {
112  ULONG i;
113 
114  Key = NULL;
115 
116  if (Section == NULL ||
117  Name == NULL ||
118  NameLength == 0 ||
119  Data == NULL ||
120  DataLength == 0)
121  {
122  DPRINT("Invalid parameter\n");
123  return NULL;
124  }
125 
128  sizeof(INICACHEKEY));
129  if (Key == NULL)
130  {
131  DPRINT("RtlAllocateHeap() failed\n");
132  return NULL;
133  }
134 
136  0,
137  (NameLength + 1) * sizeof(WCHAR));
138  if (Key->Name == NULL)
139  {
140  DPRINT("RtlAllocateHeap() failed\n");
142  return NULL;
143  }
144 
145  /* Copy value name */
146  for (i = 0; i < NameLength; i++)
147  {
148  Key->Name[i] = (WCHAR)Name[i];
149  }
150  Key->Name[NameLength] = 0;
151 
153  0,
154  (DataLength + 1) * sizeof(WCHAR));
155  if (Key->Data == NULL)
156  {
157  DPRINT("RtlAllocateHeap() failed\n");
158  RtlFreeHeap(ProcessHeap, 0, Key->Name);
160  return NULL;
161  }
162 
163  /* Copy value data */
164  for (i = 0; i < DataLength; i++)
165  {
166  Key->Data[i] = (WCHAR)Data[i];
167  }
168  Key->Data[DataLength] = 0;
169 
170 
171  if (Section->FirstKey == NULL)
172  {
173  Section->FirstKey = Key;
174  Section->LastKey = Key;
175  }
176  else
177  {
178  Section->LastKey->Next = Key;
179  Key->Prev = Section->LastKey;
180  Section->LastKey = Key;
181  }
182 
183  return Key;
184 }
185 
186 
187 static
191  PCHAR Name,
192  ULONG NameLength)
193 {
194  PINICACHESECTION Section = NULL;
195  ULONG i;
196 
197  if (Cache == NULL || Name == NULL || NameLength == 0)
198  {
199  DPRINT("Invalid parameter\n");
200  return NULL;
201  }
202 
205  sizeof(INICACHESECTION));
206  if (Section == NULL)
207  {
208  DPRINT("RtlAllocateHeap() failed\n");
209  return NULL;
210  }
211 
212  /* Allocate and initialize section name */
213  Section->Name = (WCHAR*)RtlAllocateHeap(ProcessHeap,
214  0,
215  (NameLength + 1) * sizeof(WCHAR));
216  if (Section->Name == NULL)
217  {
218  DPRINT("RtlAllocateHeap() failed\n");
219  RtlFreeHeap(ProcessHeap, 0, Section);
220  return NULL;
221  }
222 
223  /* Copy section name */
224  for (i = 0; i < NameLength; i++)
225  {
226  Section->Name[i] = (WCHAR)Name[i];
227  }
228  Section->Name[NameLength] = 0;
229 
230  /* Append section */
231  if (Cache->FirstSection == NULL)
232  {
233  Cache->FirstSection = Section;
234  Cache->LastSection = Section;
235  }
236  else
237  {
238  Cache->LastSection->Next = Section;
239  Section->Prev = Cache->LastSection;
240  Cache->LastSection = Section;
241  }
242 
243  return Section;
244 }
245 
246 
247 static
248 PCHAR
250  PCHAR Ptr)
251 {
252  while (*Ptr != 0 && isspace(*Ptr))
253  Ptr++;
254 
255  return (*Ptr == 0) ? NULL : Ptr;
256 }
257 
258 
259 static
260 PCHAR
262  PCHAR Ptr)
263 {
264  while (*Ptr != 0 && *Ptr != '[')
265  {
266  while (*Ptr != 0 && *Ptr != L'\n')
267  {
268  Ptr++;
269  }
270 
271  Ptr++;
272  }
273 
274  return (*Ptr == 0) ? NULL : Ptr;
275 }
276 
277 
278 static
279 PCHAR
281  PCHAR Ptr,
282  PCHAR *NamePtr,
283  PULONG NameSize)
284 {
285  ULONG Size = 0;
286  CHAR Name[256];
287 
288  *NamePtr = NULL;
289  *NameSize = 0;
290 
291  /* Skip whitespace */
292  while (*Ptr != 0 && isspace(*Ptr))
293  {
294  Ptr++;
295  }
296 
297  *NamePtr = Ptr;
298 
299  while (*Ptr != 0 && *Ptr != ']')
300  {
301  Size++;
302  Ptr++;
303  }
304  Ptr++;
305 
306  while (*Ptr != 0 && *Ptr != L'\n')
307  {
308  Ptr++;
309  }
310  Ptr++;
311 
312  *NameSize = Size;
313 
314  strncpy(Name, *NamePtr, Size);
315  Name[Size] = 0;
316 
317  DPRINT("SectionName: '%s'\n", Name);
318 
319  return Ptr;
320 }
321 
322 
323 static
324 PCHAR
326  PCHAR Ptr,
327  PCHAR *NamePtr,
328  PULONG NameSize)
329 {
330  ULONG Size = 0;
331 
332  *NamePtr = NULL;
333  *NameSize = 0;
334 
335  while (Ptr && *Ptr)
336  {
337  *NamePtr = NULL;
338  *NameSize = 0;
339  Size = 0;
340 
341  /* Skip whitespace and empty lines */
342  while (isspace(*Ptr) || *Ptr == '\n' || *Ptr == '\r')
343  {
344  Ptr++;
345  }
346  if (*Ptr == 0)
347  {
348  continue;
349  }
350 
351  *NamePtr = Ptr;
352 
353  while (*Ptr != 0 && !isspace(*Ptr) && *Ptr != '=' && *Ptr != ';')
354  {
355  Size++;
356  Ptr++;
357  }
358  if (*Ptr == ';')
359  {
360  while (*Ptr != 0 && *Ptr != '\r' && *Ptr != '\n')
361  {
362  Ptr++;
363  }
364  }
365  else
366  {
367  *NameSize = Size;
368  break;
369  }
370  }
371 
372  return Ptr;
373 }
374 
375 
376 static
377 PCHAR
379  PCHAR Ptr,
380  PCHAR *DataPtr,
382  BOOLEAN String)
383 {
384  ULONG Size = 0;
385 
386  *DataPtr = NULL;
387  *DataSize = 0;
388 
389  /* Skip whitespace */
390  while (*Ptr != 0 && isspace(*Ptr))
391  {
392  Ptr++;
393  }
394 
395  /* Check and skip '=' */
396  if (*Ptr != '=')
397  {
398  return NULL;
399  }
400  Ptr++;
401 
402  /* Skip whitespace */
403  while (*Ptr != 0 && isspace(*Ptr))
404  {
405  Ptr++;
406  }
407 
408  if (*Ptr == '"' && String)
409  {
410  Ptr++;
411 
412  /* Get data */
413  *DataPtr = Ptr;
414  while (*Ptr != '"')
415  {
416  Ptr++;
417  Size++;
418  }
419  Ptr++;
420 
421  while (*Ptr && *Ptr != '\r' && *Ptr != '\n')
422  {
423  Ptr++;
424  }
425  }
426  else
427  {
428  /* Get data */
429  *DataPtr = Ptr;
430  while (*Ptr != 0 && *Ptr != '\r' && *Ptr != ';')
431  {
432  Ptr++;
433  Size++;
434  }
435  }
436 
437  /* Skip to next line */
438  if (*Ptr == '\r')
439  Ptr++;
440  if (*Ptr == '\n')
441  Ptr++;
442 
443  *DataSize = Size;
444 
445  return Ptr;
446 }
447 
448 
449 /* PUBLIC FUNCTIONS *********************************************************/
450 
451 NTSTATUS
453  PINICACHE *Cache,
454  PCHAR FileBuffer,
456  BOOLEAN String)
457 {
458  PCHAR Ptr;
459 
460  PINICACHESECTION Section;
462 
463  PCHAR SectionName;
464  ULONG SectionNameSize;
465 
466  PCHAR KeyName;
467  ULONG KeyNameSize;
468 
469  PCHAR KeyValue;
470  ULONG KeyValueSize;
471 
472  /* Allocate inicache header */
475  sizeof(INICACHE));
476  if (*Cache == NULL)
477  {
478  DPRINT("RtlAllocateHeap() failed\n");
480  }
481 
482  /* Parse ini file */
483  Section = NULL;
484  Ptr = FileBuffer;
485  while (Ptr != NULL && *Ptr != 0)
486  {
488  if (Ptr == NULL)
489  continue;
490 
491  if (*Ptr == '[')
492  {
493  Section = NULL;
494  Ptr++;
495 
497  &SectionName,
498  &SectionNameSize);
499 
500  DPRINT("[%.*s]\n", SectionNameSize, SectionName);
501 
502  Section = IniCacheAddSection(*Cache,
503  SectionName,
504  SectionNameSize);
505  if (Section == NULL)
506  {
507  DPRINT("IniCacheAddSection() failed\n");
509  continue;
510  }
511  }
512  else
513  {
514  if (Section == NULL)
515  {
517  continue;
518  }
519 
521  &KeyName,
522  &KeyNameSize);
523 
525  &KeyValue,
526  &KeyValueSize,
527  String);
528 
529  DPRINT("'%.*s' = '%.*s'\n", KeyNameSize, KeyName, KeyValueSize, KeyValue);
530 
531  Key = IniCacheAddKey(Section,
532  KeyName,
533  KeyNameSize,
534  KeyValue,
535  KeyValueSize);
536  if (Key == NULL)
537  {
538  DPRINT("IniCacheAddKey() failed\n");
539  }
540  }
541  }
542 
543  return STATUS_SUCCESS;
544 }
545 
546 NTSTATUS
548  PINICACHE *Cache,
550  BOOLEAN String)
551 {
555  PCHAR FileBuffer;
558 
559  *Cache = NULL;
560 
561  /* Query file size */
563  &IoStatusBlock,
564  &FileInfo,
567  if (!NT_SUCCESS(Status))
568  {
569  DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
570  return Status;
571  }
572 
573  FileLength = FileInfo.EndOfFile.u.LowPart;
574 
575  DPRINT("File size: %lu\n", FileLength);
576 
577  /* Allocate file buffer with NULL-terminator */
578  FileBuffer = (CHAR*)RtlAllocateHeap(ProcessHeap,
579  0,
580  FileLength + 1);
581  if (FileBuffer == NULL)
582  {
583  DPRINT1("RtlAllocateHeap() failed\n");
585  }
586 
587  /* Read file */
588  FileOffset.QuadPart = 0ULL;
590  NULL,
591  NULL,
592  NULL,
593  &IoStatusBlock,
594  FileBuffer,
595  FileLength,
596  &FileOffset,
597  NULL);
598 
599  /* Append NULL-terminator */
600  FileBuffer[FileLength] = 0;
601 
602  if (!NT_SUCCESS(Status))
603  {
604  DPRINT("NtReadFile() failed (Status %lx)\n", Status);
605  goto Quit;
606  }
607 
609  if (!NT_SUCCESS(Status))
610  {
611  DPRINT1("IniCacheLoadFromMemory() failed (Status %lx)\n", Status);
612  }
613 
614 Quit:
615  /* Free the file buffer, and return */
616  RtlFreeHeap(ProcessHeap, 0, FileBuffer);
617  return Status;
618 }
619 
620 NTSTATUS
622  PINICACHE *Cache,
624  BOOLEAN String)
625 {
631 
632  *Cache = NULL;
633 
634  /* Open the INI file */
636 
638  &Name,
640  NULL,
641  NULL);
642 
646  &IoStatusBlock,
649  if (!NT_SUCCESS(Status))
650  {
651  DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
652  return Status;
653  }
654 
655  DPRINT("NtOpenFile() successful\n");
656 
658 
659  /* Close the INI file */
661  return Status;
662 }
663 
664 
665 VOID
668 {
669  if (Cache == NULL)
670  return;
671 
672  while (Cache->FirstSection != NULL)
673  {
674  Cache->FirstSection = IniCacheFreeSection(Cache->FirstSection);
675  }
676  Cache->LastSection = NULL;
677 
679 }
680 
681 
685  PWCHAR Name)
686 {
687  PINICACHESECTION Section = NULL;
688 
689  if (Cache == NULL || Name == NULL)
690  {
691  DPRINT("Invalid parameter\n");
692  return NULL;
693  }
694 
695  /* Iterate through list of sections */
696  Section = Cache->FirstSection;
697  while (Section != NULL)
698  {
699  DPRINT("Comparing '%S' and '%S'\n", Section->Name, Name);
700 
701  /* Are the section names the same? */
702  if (_wcsicmp(Section->Name, Name) == 0)
703  return Section;
704 
705  /* Get the next section */
706  Section = Section->Next;
707  }
708 
709  DPRINT("Section not found\n");
710 
711  return NULL;
712 }
713 
714 
715 NTSTATUS
717  PINICACHESECTION Section,
718  PWCHAR KeyName,
719  PWCHAR *KeyData)
720 {
722 
723  if (Section == NULL || KeyName == NULL || KeyData == NULL)
724  {
725  DPRINT("Invalid parameter\n");
727  }
728 
729  *KeyData = NULL;
730 
731  Key = IniCacheFindKey(Section, KeyName, wcslen(KeyName));
732  if (Key == NULL)
733  {
735  }
736 
737  *KeyData = Key->Data;
738 
739  return STATUS_SUCCESS;
740 }
741 
742 
745  PINICACHESECTION Section,
746  PWCHAR *KeyName,
747  PWCHAR *KeyData)
748 {
749  PINICACHEITERATOR Iterator;
751 
752  if (Section == NULL || KeyName == NULL || KeyData == NULL)
753  {
754  DPRINT("Invalid parameter\n");
755  return NULL;
756  }
757 
758  Key = Section->FirstKey;
759  if (Key == NULL)
760  {
761  DPRINT("Invalid parameter\n");
762  return NULL;
763  }
764 
765  *KeyName = Key->Name;
766  *KeyData = Key->Data;
767 
769  0,
770  sizeof(INICACHEITERATOR));
771  if (Iterator == NULL)
772  {
773  DPRINT("RtlAllocateHeap() failed\n");
774  return NULL;
775  }
776 
777  Iterator->Section = Section;
778  Iterator->Key = Key;
779 
780  return Iterator;
781 }
782 
783 
784 BOOLEAN
786  PINICACHEITERATOR Iterator,
787  PWCHAR *KeyName,
788  PWCHAR *KeyData)
789 {
791 
792  if (Iterator == NULL || KeyName == NULL || KeyData == NULL)
793  {
794  DPRINT("Invalid parameter\n");
795  return FALSE;
796  }
797 
798  Key = Iterator->Key->Next;
799  if (Key == NULL)
800  {
801  DPRINT("No more entries\n");
802  return FALSE;
803  }
804 
805  *KeyName = Key->Name;
806  *KeyData = Key->Data;
807 
808  Iterator->Key = Key;
809 
810  return TRUE;
811 }
812 
813 
814 VOID
816  PINICACHEITERATOR Iterator)
817 {
818  if (Iterator == NULL)
819  return;
820 
821  RtlFreeHeap(ProcessHeap, 0, Iterator);
822 }
823 
824 
827  PINICACHESECTION Section,
828  PINICACHEKEY AnchorKey,
829  INSERTION_TYPE InsertionType,
830  PWCHAR Name,
831  PWCHAR Data)
832 {
834 
835  Key = NULL;
836 
837  if (Section == NULL ||
838  Name == NULL ||
839  *Name == 0 ||
840  Data == NULL ||
841  *Data == 0)
842  {
843  DPRINT("Invalid parameter\n");
844  return NULL;
845  }
846 
847  /* Allocate key buffer */
850  sizeof(INICACHEKEY));
851  if (Key == NULL)
852  {
853  DPRINT("RtlAllocateHeap() failed\n");
854  return NULL;
855  }
856 
857  /* Allocate name buffer */
859  0,
860  (wcslen(Name) + 1) * sizeof(WCHAR));
861  if (Key->Name == NULL)
862  {
863  DPRINT("RtlAllocateHeap() failed\n");
865  return NULL;
866  }
867 
868  /* Copy value name */
869  wcscpy(Key->Name, Name);
870 
871  /* Allocate data buffer */
873  0,
874  (wcslen(Data) + 1) * sizeof(WCHAR));
875  if (Key->Data == NULL)
876  {
877  DPRINT("RtlAllocateHeap() failed\n");
878  RtlFreeHeap(ProcessHeap, 0, Key->Name);
880  return NULL;
881  }
882 
883  /* Copy value data */
884  wcscpy(Key->Data, Data);
885 
886  /* Insert key into section */
887  if (Section->FirstKey == NULL)
888  {
889  Section->FirstKey = Key;
890  Section->LastKey = Key;
891  }
892  else if ((InsertionType == INSERT_FIRST) ||
893  ((InsertionType == INSERT_BEFORE) && ((AnchorKey == NULL) || (AnchorKey == Section->FirstKey))))
894  {
895  /* Insert at the head of the list */
896  Section->FirstKey->Prev = Key;
897  Key->Next = Section->FirstKey;
898  Section->FirstKey = Key;
899  }
900  else if ((InsertionType == INSERT_BEFORE) && (AnchorKey != NULL))
901  {
902  /* Insert before the anchor key */
903  Key->Next = AnchorKey;
904  Key->Prev = AnchorKey->Prev;
905  AnchorKey->Prev->Next = Key;
906  AnchorKey->Prev = Key;
907  }
908  else if ((InsertionType == INSERT_LAST) ||
909  ((InsertionType == INSERT_AFTER) && ((AnchorKey == NULL) || (AnchorKey == Section->LastKey))))
910  {
911  Section->LastKey->Next = Key;
912  Key->Prev = Section->LastKey;
913  Section->LastKey = Key;
914  }
915  else if ((InsertionType == INSERT_AFTER) && (AnchorKey != NULL))
916  {
917  /* Insert after the anchor key */
918  Key->Next = AnchorKey->Next;
919  Key->Prev = AnchorKey;
920  AnchorKey->Next->Prev = Key;
921  AnchorKey->Next = Key;
922  }
923 
924  return Key;
925 }
926 
927 
928 PINICACHE
930 {
932 
933  /* Allocate inicache header */
936  sizeof(INICACHE));
937  if (Cache == NULL)
938  {
939  DPRINT("RtlAllocateHeap() failed\n");
940  return NULL;
941  }
942 
943  return Cache;
944 }
945 
946 
947 NTSTATUS
951 {
953  PINICACHESECTION Section;
956  PCHAR Buffer;
957  PCHAR Ptr;
958  ULONG Len;
961 
962  /* Calculate required buffer size */
963  BufferSize = 0;
964  Section = Cache->FirstSection;
965  while (Section != NULL)
966  {
967  BufferSize += (Section->Name ? wcslen(Section->Name) : 0)
968  + 4; /* "[]\r\n" */
969 
970  Key = Section->FirstKey;
971  while (Key != NULL)
972  {
973  BufferSize += wcslen(Key->Name)
974  + (Key->Data ? wcslen(Key->Data) : 0)
975  + 3; /* "=\r\n" */
976  Key = Key->Next;
977  }
978 
979  Section = Section->Next;
980  if (Section != NULL)
981  BufferSize += 2; /* Extra "\r\n" at end of each section */
982  }
983 
984  DPRINT("BufferSize: %lu\n", BufferSize);
985 
986  /* Allocate file buffer with NULL-terminator */
989  BufferSize + 1);
990  if (Buffer == NULL)
991  {
992  DPRINT1("RtlAllocateHeap() failed\n");
994  }
995 
996  /* Fill file buffer */
997  Ptr = Buffer;
998  Section = Cache->FirstSection;
999  while (Section != NULL)
1000  {
1001  Len = sprintf(Ptr, "[%S]\r\n", Section->Name);
1002  Ptr += Len;
1003 
1004  Key = Section->FirstKey;
1005  while (Key != NULL)
1006  {
1007  Len = sprintf(Ptr, "%S=%S\r\n", Key->Name, Key->Data);
1008  Ptr += Len;
1009  Key = Key->Next;
1010  }
1011 
1012  Section = Section->Next;
1013  if (Section != NULL)
1014  {
1015  Len = sprintf(Ptr, "\r\n");
1016  Ptr += Len;
1017  }
1018  }
1019 
1020  /* Write to the INI file */
1021  Offset.QuadPart = 0LL;
1023  NULL,
1024  NULL,
1025  NULL,
1026  &IoStatusBlock,
1027  Buffer,
1028  BufferSize,
1029  &Offset,
1030  NULL);
1031  if (!NT_SUCCESS(Status))
1032  {
1033  DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
1035  return Status;
1036  }
1037 
1039  return STATUS_SUCCESS;
1040 }
1041 
1042 NTSTATUS
1044  PINICACHE Cache,
1045  PWCHAR FileName)
1046 {
1047  NTSTATUS Status;
1052 
1053  /* Create the INI file */
1055 
1057  &Name,
1059  NULL,
1060  NULL);
1061 
1065  &IoStatusBlock,
1066  NULL,
1068  0,
1071  NULL,
1072  0);
1073  if (!NT_SUCCESS(Status))
1074  {
1075  DPRINT("NtCreateFile() failed (Status %lx)\n", Status);
1076  return Status;
1077  }
1078 
1080 
1081  /* Close the INI file */
1083  return Status;
1084 }
1085 
1086 
1089  PINICACHE Cache,
1090  PWCHAR Name)
1091 {
1092  PINICACHESECTION Section = NULL;
1093 
1094  if (Cache == NULL || Name == NULL || *Name == 0)
1095  {
1096  DPRINT("Invalid parameter\n");
1097  return NULL;
1098  }
1099 
1102  sizeof(INICACHESECTION));
1103  if (Section == NULL)
1104  {
1105  DPRINT("RtlAllocateHeap() failed\n");
1106  return NULL;
1107  }
1108 
1109  /* Allocate and initialize section name */
1110  Section->Name = (WCHAR*)RtlAllocateHeap(ProcessHeap,
1111  0,
1112  (wcslen(Name) + 1) * sizeof(WCHAR));
1113  if (Section->Name == NULL)
1114  {
1115  DPRINT("RtlAllocateHeap() failed\n");
1116  RtlFreeHeap(ProcessHeap, 0, Section);
1117  return NULL;
1118  }
1119 
1120  /* Copy section name */
1121  wcscpy(Section->Name, Name);
1122 
1123  /* Append section */
1124  if (Cache->FirstSection == NULL)
1125  {
1126  Cache->FirstSection = Section;
1127  Cache->LastSection = Section;
1128  }
1129  else
1130  {
1131  Cache->LastSection->Next = Section;
1132  Section->Prev = Cache->LastSection;
1133  Cache->LastSection = Section;
1134  }
1135 
1136  return Section;
1137 }
1138 
1139 /* EOF */
static PCHAR IniCacheGetSectionName(PCHAR Ptr, PCHAR *NamePtr, PULONG NameSize)
Definition: inicache.c:280
signed char * PCHAR
Definition: retypes.h:7
#define FILE_GENERIC_READ
Definition: nt_native.h:653
PINICACHEKEY FirstKey
Definition: inicache.h:24
struct _INICACHESECTION * Prev
Definition: inicache.h:28
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
PINICACHEKEY IniCacheInsertKey(PINICACHESECTION Section, PINICACHEKEY AnchorKey, INSERTION_TYPE InsertionType, PWCHAR Name, PWCHAR Data)
Definition: inicache.c:826
#define isspace(c)
Definition: acclib.h:69
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
_Out_ PNDIS_HANDLE _Out_ PUINT FileLength
Definition: ndis.h:3227
#define TRUE
Definition: types.h:120
static PINICACHEKEY IniCacheAddKey(PINICACHESECTION Section, PCHAR Name, ULONG NameLength, PCHAR Data, ULONG DataLength)
Definition: inicache.c:104
struct _INICACHEKEY * PINICACHEKEY
#define LL
Definition: tui.h:85
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static PCHAR IniCacheGetKeyValue(PCHAR Ptr, PCHAR *DataPtr, PULONG DataSize, BOOLEAN String)
Definition: inicache.c:378
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG Key
Definition: fatprocs.h:2697
static PINICACHESECTION IniCacheAddSection(PINICACHE Cache, PCHAR Name, ULONG NameLength)
Definition: inicache.c:189
Definition: fatfs.h:173
PINICACHEKEY LastKey
Definition: inicache.h:25
VOID IniCacheDestroy(PINICACHE Cache)
Definition: inicache.c:666
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char CHAR
Definition: xmlstorage.h:175
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
NTSTATUS IniCacheSave(PINICACHE Cache, PWCHAR FileName)
Definition: inicache.c:1043
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
NTSTATUS IniCacheLoadFromMemory(PINICACHE *Cache, PCHAR FileBuffer, ULONG FileLength, BOOLEAN String)
Definition: inicache.c:452
static WCHAR String[]
Definition: stringtable.c:55
PINICACHESECTION IniCacheGetSection(PINICACHE Cache, PWCHAR Name)
Definition: inicache.c:683
uint16_t * PWCHAR
Definition: typedefs.h:54
BOOLEAN IniCacheFindNextValue(PINICACHEITERATOR Iterator, PWCHAR *KeyName, PWCHAR *KeyData)
Definition: inicache.c:785
#define FILE_SHARE_READ
Definition: compat.h:125
PINICACHESECTION Section
Definition: inicache.h:41
#define sprintf(buf, format,...)
Definition: sprintf.c:55
HANDLE FileHandle
Definition: stats.c:38
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static PCHAR IniCacheGetKeyName(PCHAR Ptr, PCHAR *NamePtr, PULONG NameSize)
Definition: inicache.c:325
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
INSERTION_TYPE
Definition: inicache.h:46
struct NameRec_ * Name
Definition: cdprocs.h:464
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static PINICACHEKEY IniCacheFindKey(PINICACHESECTION Section, PWCHAR Name, ULONG NameLength)
Definition: inicache.c:79
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
#define ULL(a, b)
Definition: format_msg.c:27
PINICACHE IniCacheCreate(VOID)
Definition: inicache.c:929
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
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:3951
static PINICACHESECTION IniCacheFreeSection(PINICACHESECTION Section)
Definition: inicache.c:50
NTSTATUS IniCacheGetKey(PINICACHESECTION Section, PWCHAR KeyName, PWCHAR *KeyData)
Definition: inicache.c:716
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)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS IniCacheLoad(PINICACHE *Cache, PWCHAR FileName, BOOLEAN String)
Definition: inicache.c:621
NTSTATUS IniCacheLoadByHandle(PINICACHE *Cache, HANDLE FileHandle, BOOLEAN String)
Definition: inicache.c:547
#define BufferSize
Definition: classpnp.h:419
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
#define Len
Definition: deflate.h:82
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
PINICACHEKEY Key
Definition: inicache.h:42
struct _INICACHEKEY * Prev
Definition: inicache.h:16
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
VOID IniCacheFindClose(PINICACHEITERATOR Iterator)
Definition: inicache.c:815
static const WCHAR L[]
Definition: oid.c:1250
struct _INICACHEKEY * Next
Definition: inicache.h:15
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)
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
struct _PINICACHEITERATOR * PINICACHEITERATOR
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define SYNCHRONIZE
Definition: nt_native.h:61
static PCHAR IniCacheSkipToNextSection(PCHAR Ptr)
Definition: inicache.c:261
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
static PCHAR IniCacheSkipWhitespace(PCHAR Ptr)
Definition: inicache.c:249
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
struct _INICACHESECTION * PINICACHESECTION
#define DPRINT1
Definition: precomp.h:8
#define FileStandardInformation
Definition: propsheet.cpp:61
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
struct _INICACHE * PINICACHE
struct FileInfo FileInfo
unsigned int ULONG
Definition: retypes.h:1
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
struct _INICACHESECTION * Next
Definition: inicache.h:27
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2966
NTSTATUS IniCacheSaveByHandle(PINICACHE Cache, HANDLE FileHandle)
Definition: inicache.c:948
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
PINICACHESECTION IniCacheAppendSection(PINICACHE Cache, PWCHAR Name)
Definition: inicache.c:1088
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static PINICACHEKEY IniCacheFreeKey(PINICACHEKEY Key)
Definition: inicache.c:21
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)
PINICACHEITERATOR IniCacheFindFirstValue(PINICACHESECTION Section, PWCHAR *KeyName, PWCHAR *KeyData)
Definition: inicache.c:744