inicache.c
来自「一个类似windows」· C语言 代码 · 共 1,188 行 · 第 1/2 页
C
1,188 行
/*
* ReactOS kernel
* Copyright (C) 2002 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: inicache.c 21704 2006-04-22 13:55:01Z tretiakov $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/inicache.c
* PURPOSE: INI file parser that caches contents of INI file in memory
* PROGRAMMER: Royce Mitchell III
* Eric Kohl
*/
/* INCLUDES *****************************************************************/
#include <usetup.h>
#define NDEBUG
#include <debug.h>
/* PRIVATE FUNCTIONS ********************************************************/
static PINICACHEKEY
IniCacheFreeKey(PINICACHEKEY Key)
{
PINICACHEKEY Next;
if (Key == NULL)
{
return(NULL);
}
Next = Key->Next;
if (Key->Name != NULL)
{
RtlFreeHeap(ProcessHeap,
0,
Key->Name);
Key->Name = NULL;
}
if (Key->Data != NULL)
{
RtlFreeHeap(ProcessHeap,
0,
Key->Data);
Key->Data = NULL;
}
RtlFreeHeap(ProcessHeap,
0,
Key);
return(Next);
}
static PINICACHESECTION
IniCacheFreeSection(PINICACHESECTION Section)
{
PINICACHESECTION Next;
if (Section == NULL)
{
return(NULL);
}
Next = Section->Next;
while (Section->FirstKey != NULL)
{
Section->FirstKey = IniCacheFreeKey(Section->FirstKey);
}
Section->LastKey = NULL;
if (Section->Name != NULL)
{
RtlFreeHeap(ProcessHeap,
0,
Section->Name);
Section->Name = NULL;
}
RtlFreeHeap(ProcessHeap,
0,
Section);
return(Next);
}
static PINICACHEKEY
IniCacheFindKey(PINICACHESECTION Section,
PWCHAR Name,
ULONG NameLength)
{
PINICACHEKEY Key;
Key = Section->FirstKey;
while (Key != NULL)
{
if (NameLength == wcslen(Key->Name))
{
if (_wcsnicmp(Key->Name, Name, NameLength) == 0)
break;
}
Key = Key->Next;
}
return(Key);
}
static PINICACHEKEY
IniCacheAddKey(PINICACHESECTION Section,
PCHAR Name,
ULONG NameLength,
PCHAR Data,
ULONG DataLength)
{
PINICACHEKEY Key;
ULONG i;
Key = NULL;
if (Section == NULL ||
Name == NULL ||
NameLength == 0 ||
Data == NULL ||
DataLength == 0)
{
DPRINT("Invalid parameter\n");
return(NULL);
}
Key = (PINICACHEKEY)RtlAllocateHeap(ProcessHeap,
0,
sizeof(INICACHEKEY));
if (Key == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
return(NULL);
}
RtlZeroMemory(Key,
sizeof(INICACHEKEY));
Key->Name = RtlAllocateHeap(ProcessHeap,
0,
(NameLength + 1) * sizeof(WCHAR));
if (Key->Name == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
RtlFreeHeap(ProcessHeap,
0,
Key);
return(NULL);
}
/* Copy value name */
for (i = 0; i < NameLength; i++)
{
Key->Name[i] = (WCHAR)Name[i];
}
Key->Name[NameLength] = 0;
Key->Data = RtlAllocateHeap(ProcessHeap,
0,
(DataLength + 1) * sizeof(WCHAR));
if (Key->Data == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
RtlFreeHeap(ProcessHeap,
0,
Key->Name);
RtlFreeHeap(ProcessHeap,
0,
Key);
return(NULL);
}
/* Copy value data */
for (i = 0; i < DataLength; i++)
{
Key->Data[i] = (WCHAR)Data[i];
}
Key->Data[DataLength] = 0;
if (Section->FirstKey == NULL)
{
Section->FirstKey = Key;
Section->LastKey = Key;
}
else
{
Section->LastKey->Next = Key;
Key->Prev = Section->LastKey;
Section->LastKey = Key;
}
return(Key);
}
#if 0
static PINICACHESECTION
IniCacheFindSection(PINICACHE Cache,
PWCHAR Name,
ULONG NameLength)
{
PINICACHESECTION Section = NULL;
if (Cache == NULL || Name == NULL || NameLength == 0)
{
return(NULL);
}
Section = Cache->FirstSection;
/* iterate through list of sections */
while (Section != NULL)
{
if (NameLength == wcslen(Section->Name))
{
/* are the contents the same too? */
if (_wcsnicmp(Section->Name, Name, NameLength) == 0)
break;
}
/* get the next section*/
Section = Section->Next;
}
return(Section);
}
#endif
static PINICACHESECTION
IniCacheAddSection(PINICACHE Cache,
PCHAR Name,
ULONG NameLength)
{
PINICACHESECTION Section = NULL;
ULONG i;
if (Cache == NULL || Name == NULL || NameLength == 0)
{
DPRINT("Invalid parameter\n");
return(NULL);
}
Section = (PINICACHESECTION)RtlAllocateHeap(ProcessHeap,
0,
sizeof(INICACHESECTION));
if (Section == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
return(NULL);
}
RtlZeroMemory(Section,
sizeof(INICACHESECTION));
/* Allocate and initialize section name */
Section->Name = RtlAllocateHeap(ProcessHeap,
0,
(NameLength + 1) * sizeof(WCHAR));
if (Section->Name == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
RtlFreeHeap(ProcessHeap,
0,
Section);
return(NULL);
}
/* Copy section name */
for (i = 0; i < NameLength; i++)
{
Section->Name[i] = (WCHAR)Name[i];
}
Section->Name[NameLength] = 0;
/* Append section */
if (Cache->FirstSection == NULL)
{
Cache->FirstSection = Section;
Cache->LastSection = Section;
}
else
{
Cache->LastSection->Next = Section;
Section->Prev = Cache->LastSection;
Cache->LastSection = Section;
}
return(Section);
}
static PCHAR
IniCacheSkipWhitespace(PCHAR Ptr)
{
while (*Ptr != 0 && isspace(*Ptr))
Ptr++;
return((*Ptr == 0) ? NULL : Ptr);
}
static PCHAR
IniCacheSkipToNextSection(PCHAR Ptr)
{
while (*Ptr != 0 && *Ptr != '[')
{
while (*Ptr != 0 && *Ptr != L'\n')
{
Ptr++;
}
Ptr++;
}
return((*Ptr == 0) ? NULL : Ptr);
}
static PCHAR
IniCacheGetSectionName(PCHAR Ptr,
PCHAR *NamePtr,
PULONG NameSize)
{
ULONG Size = 0;
CHAR Name[256];
*NamePtr = NULL;
*NameSize = 0;
/* skip whitespace */
while (*Ptr != 0 && isspace(*Ptr))
{
Ptr++;
}
*NamePtr = Ptr;
while (*Ptr != 0 && *Ptr != ']')
{
Size++;
Ptr++;
}
Ptr++;
while (*Ptr != 0 && *Ptr != L'\n')
{
Ptr++;
}
Ptr++;
*NameSize = Size;
strncpy(Name, *NamePtr, Size);
Name[Size] = 0;
DPRINT("SectionName: '%s'\n", Name);
return(Ptr);
}
static PCHAR
IniCacheGetKeyName(PCHAR Ptr,
PCHAR *NamePtr,
PULONG NameSize)
{
ULONG Size = 0;
*NamePtr = NULL;
*NameSize = 0;
while(Ptr && *Ptr)
{
*NamePtr = NULL;
*NameSize = 0;
Size = 0;
/* skip whitespace and empty lines */
while (isspace(*Ptr) || *Ptr == '\n' || *Ptr == '\r')
{
Ptr++;
}
if (*Ptr == 0)
{
continue;
}
*NamePtr = Ptr;
while (*Ptr != 0 && !isspace(*Ptr) && *Ptr != '=' && *Ptr != ';')
{
Size++;
Ptr++;
}
if (*Ptr == ';')
{
while (*Ptr != 0 && *Ptr != '\r' && *Ptr != '\n')
{
Ptr++;
}
}
else
{
*NameSize = Size;
break;
}
}
return(Ptr);
}
static PCHAR
IniCacheGetKeyValue(PCHAR Ptr,
PCHAR *DataPtr,
PULONG DataSize,
BOOLEAN String)
{
ULONG Size = 0;
*DataPtr = NULL;
*DataSize = 0;
/* Skip whitespace */
while (*Ptr != 0 && isspace(*Ptr))
{
Ptr++;
}
/* Check and skip '=' */
if (*Ptr != '=')
{
return(NULL);
}
Ptr++;
/* Skip whitespace */
while (*Ptr != 0 && isspace(*Ptr))
{
Ptr++;
}
if (*Ptr == '"' && String)
{
Ptr++;
/* Get data */
*DataPtr = Ptr;
while (*Ptr != '"')
{
Ptr++;
Size++;
}
Ptr++;
while (*Ptr && *Ptr != '\r' && *Ptr != '\n')
{
Ptr++;
}
}
else
{
/* Get data */
*DataPtr = Ptr;
while (*Ptr != 0 && *Ptr != '\r' && *Ptr != ';')
{
Ptr++;
Size++;
}
}
/* Skip to next line */
if (*Ptr == '\r')
Ptr++;
if (*Ptr == '\n')
Ptr++;
*DataSize = Size;
return(Ptr);
}
/* PUBLIC FUNCTIONS *********************************************************/
NTSTATUS
IniCacheLoad(PINICACHE *Cache,
PUNICODE_STRING FileName,
BOOLEAN String)
{
OBJECT_ATTRIBUTES ObjectAttributes;
FILE_STANDARD_INFORMATION FileInfo;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
NTSTATUS Status;
PCHAR FileBuffer;
ULONG FileLength;
PCHAR Ptr;
LARGE_INTEGER FileOffset;
PINICACHESECTION Section;
PINICACHEKEY Key;
PCHAR SectionName;
ULONG SectionNameSize;
PCHAR KeyName;
ULONG KeyNameSize;
PCHAR KeyValue;
ULONG KeyValueSize;
*Cache = NULL;
/* Open ini file */
InitializeObjectAttributes(&ObjectAttributes,
FileName,
0,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
GENERIC_READ | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
if (!NT_SUCCESS(Status))
{
DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
return(Status);
}
DPRINT("NtOpenFile() successful\n");
/* Query file size */
Status = NtQueryInformationFile(FileHandle,
&IoStatusBlock,
&FileInfo,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
if (!NT_SUCCESS(Status))
{
DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
NtClose(FileHandle);
return(Status);
}
FileLength = FileInfo.EndOfFile.u.LowPart;
DPRINT("File size: %lu\n", FileLength);
/* Allocate file buffer */
FileBuffer = RtlAllocateHeap(ProcessHeap,
0,
FileLength + 1);
if (FileBuffer == NULL)
{
DPRINT1("RtlAllocateHeap() failed\n");
NtClose(FileHandle);
return(STATUS_INSUFFICIENT_RESOURCES);
}
/* Read file */
FileOffset.QuadPart = 0ULL;
Status = NtReadFile(FileHandle,
NULL,
NULL,
NULL,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?