inicache.c
来自「一个类似windows」· C语言 代码 · 共 1,188 行 · 第 1/2 页
C
1,188 行
&IoStatusBlock,
FileBuffer,
FileLength,
&FileOffset,
NULL);
/* Append string terminator */
FileBuffer[FileLength] = 0;
NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT("NtReadFile() failed (Status %lx)\n", Status);
RtlFreeHeap(ProcessHeap,
0,
FileBuffer);
return(Status);
}
/* Allocate inicache header */
*Cache = (PINICACHE)RtlAllocateHeap(ProcessHeap,
0,
sizeof(INICACHE));
if (*Cache == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
/* Initialize inicache header */
RtlZeroMemory(*Cache,
sizeof(INICACHE));
/* Parse ini file */
Section = NULL;
Ptr = FileBuffer;
while (Ptr != NULL && *Ptr != 0)
{
Ptr = IniCacheSkipWhitespace(Ptr);
if (Ptr == NULL)
continue;
if (*Ptr == '[')
{
Section = NULL;
Ptr++;
Ptr = IniCacheGetSectionName(Ptr,
&SectionName,
&SectionNameSize);
DPRINT1("[%.*s]\n", SectionNameSize, SectionName);
Section = IniCacheAddSection(*Cache,
SectionName,
SectionNameSize);
if (Section == NULL)
{
DPRINT("IniCacheAddSection() failed\n");
Ptr = IniCacheSkipToNextSection(Ptr);
continue;
}
}
else
{
if (Section == NULL)
{
Ptr = IniCacheSkipToNextSection(Ptr);
continue;
}
Ptr = IniCacheGetKeyName(Ptr,
&KeyName,
&KeyNameSize);
Ptr = IniCacheGetKeyValue(Ptr,
&KeyValue,
&KeyValueSize,
String);
DPRINT1("'%.*s' = '%.*s'\n", KeyNameSize, KeyName, KeyValueSize, KeyValue);
Key = IniCacheAddKey(Section,
KeyName,
KeyNameSize,
KeyValue,
KeyValueSize);
if (Key == NULL)
{
DPRINT("IniCacheAddKey() failed\n");
}
}
}
/* Free file buffer */
RtlFreeHeap(ProcessHeap,
0,
FileBuffer);
return(Status);
}
VOID
IniCacheDestroy(PINICACHE Cache)
{
if (Cache == NULL)
{
return;
}
while (Cache->FirstSection != NULL)
{
Cache->FirstSection = IniCacheFreeSection(Cache->FirstSection);
}
Cache->LastSection = NULL;
RtlFreeHeap(ProcessHeap,
0,
Cache);
}
PINICACHESECTION
IniCacheGetSection(PINICACHE Cache,
PWCHAR Name)
{
PINICACHESECTION Section = NULL;
if (Cache == NULL || Name == NULL)
{
DPRINT("Invalid parameter\n");
return(NULL);
}
/* Iterate through list of sections */
Section = Cache->FirstSection;
while (Section != NULL)
{
DPRINT("Comparing '%S' and '%S'\n", Section->Name, Name);
/* Are the section names the same? */
if (_wcsicmp(Section->Name, Name) == 0)
return(Section);
/* Get the next section */
Section = Section->Next;
}
DPRINT("Section not found\n");
return(NULL);
}
NTSTATUS
IniCacheGetKey(PINICACHESECTION Section,
PWCHAR KeyName,
PWCHAR *KeyData)
{
PINICACHEKEY Key;
if (Section == NULL || KeyName == NULL || KeyData == NULL)
{
DPRINT("Invalid parameter\n");
return(STATUS_INVALID_PARAMETER);
}
*KeyData = NULL;
Key = IniCacheFindKey(Section, KeyName, wcslen(KeyName));
if (Key == NULL)
{
return(STATUS_INVALID_PARAMETER);
}
*KeyData = Key->Data;
return(STATUS_SUCCESS);
}
PINICACHEITERATOR
IniCacheFindFirstValue(PINICACHESECTION Section,
PWCHAR *KeyName,
PWCHAR *KeyData)
{
PINICACHEITERATOR Iterator;
PINICACHEKEY Key;
if (Section == NULL || KeyName == NULL || KeyData == NULL)
{
DPRINT("Invalid parameter\n");
return(NULL);
}
Key = Section->FirstKey;
if (Key == NULL)
{
DPRINT("Invalid parameter\n");
return(NULL);
}
*KeyName = Key->Name;
*KeyData = Key->Data;
Iterator = (PINICACHEITERATOR)RtlAllocateHeap(ProcessHeap,
0,
sizeof(INICACHEITERATOR));
if (Iterator == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
return(NULL);
}
Iterator->Section = Section;
Iterator->Key = Key;
return(Iterator);
}
BOOLEAN
IniCacheFindNextValue(PINICACHEITERATOR Iterator,
PWCHAR *KeyName,
PWCHAR *KeyData)
{
PINICACHEKEY Key;
if (Iterator == NULL || KeyName == NULL || KeyData == NULL)
{
DPRINT("Invalid parameter\n");
return(FALSE);
}
Key = Iterator->Key->Next;
if (Key == NULL)
{
DPRINT("No more entries\n");
return(FALSE);
}
*KeyName = Key->Name;
*KeyData = Key->Data;
Iterator->Key = Key;
return(TRUE);
}
VOID
IniCacheFindClose(PINICACHEITERATOR Iterator)
{
if (Iterator == NULL)
return;
RtlFreeHeap(ProcessHeap,
0,
Iterator);
}
PINICACHEKEY
IniCacheInsertKey(PINICACHESECTION Section,
PINICACHEKEY AnchorKey,
INSERTATION_TYPE InsertationType,
PWCHAR Name,
PWCHAR Data)
{
PINICACHEKEY Key;
Key = NULL;
if (Section == NULL ||
Name == NULL ||
*Name == 0 ||
Data == NULL ||
*Data == 0)
{
DPRINT("Invalid parameter\n");
return(NULL);
}
/* Allocate key buffer */
Key = (PINICACHEKEY)RtlAllocateHeap(ProcessHeap,
0,
sizeof(INICACHEKEY));
if (Key == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
return(NULL);
}
RtlZeroMemory(Key,
sizeof(INICACHEKEY));
/* Allocate name buffer */
Key->Name = RtlAllocateHeap(ProcessHeap,
0,
(wcslen(Name) + 1) * sizeof(WCHAR));
if (Key->Name == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
RtlFreeHeap(ProcessHeap,
0,
Key);
return(NULL);
}
/* Copy value name */
wcscpy(Key->Name, Name);
/* Allocate data buffer */
Key->Data = RtlAllocateHeap(ProcessHeap,
0,
(wcslen(Data) + 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 */
wcscpy(Key->Data, Data);
/* Insert key into section */
if (Section->FirstKey == NULL)
{
Section->FirstKey = Key;
Section->LastKey = Key;
}
else if ((InsertationType == INSERT_FIRST) ||
((InsertationType == INSERT_BEFORE) && ((AnchorKey == NULL) || (AnchorKey == Section->FirstKey))))
{
/* Insert at the head of the list */
Section->FirstKey->Prev = Key;
Key->Next = Section->FirstKey;
Section->FirstKey = Key;
}
else if ((InsertationType == INSERT_BEFORE) && (AnchorKey != NULL))
{
/* Insert before the anchor key */
Key->Next = AnchorKey;
Key->Prev = AnchorKey->Prev;
AnchorKey->Prev->Next = Key;
AnchorKey->Prev = Key;
}
else if ((InsertationType == INSERT_LAST) ||
((InsertationType == INSERT_AFTER) && ((AnchorKey == NULL) || (AnchorKey == Section->LastKey))))
{
Section->LastKey->Next = Key;
Key->Prev = Section->LastKey;
Section->LastKey = Key;
}
else if ((InsertationType == INSERT_AFTER) && (AnchorKey != NULL))
{
/* Insert before the anchor key */
Key->Next = AnchorKey->Next;
Key->Prev = AnchorKey;
AnchorKey->Next->Prev = Key;
AnchorKey->Next = Key;
}
return(Key);
}
PINICACHE
IniCacheCreate(VOID)
{
PINICACHE Cache;
/* Allocate inicache header */
Cache = (PINICACHE)RtlAllocateHeap(ProcessHeap,
0,
sizeof(INICACHE));
if (Cache == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
return(NULL);
}
/* Initialize inicache header */
RtlZeroMemory(Cache,
sizeof(INICACHE));
return(Cache);
}
NTSTATUS
IniCacheSave(PINICACHE Cache,
PWCHAR FileName)
{
UNICODE_STRING Name;
PINICACHESECTION Section;
PINICACHEKEY Key;
ULONG BufferSize;
PCHAR Buffer;
PCHAR Ptr;
ULONG Len;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER Offset;
HANDLE FileHandle;
/* Calculate required buffer size */
BufferSize = 0;
Section = Cache->FirstSection;
while (Section != NULL)
{
BufferSize += (Section->Name ? wcslen(Section->Name) : 0)
+ 4; /* "[]\r\n" */
Key = Section->FirstKey;
while (Key != NULL)
{
BufferSize += wcslen(Key->Name)
+ (Key->Data ? wcslen(Key->Data) : 0)
+ 3; /* "=\r\n" */
Key = Key->Next;
}
Section = Section->Next;
if (Section != NULL)
BufferSize += 2; /* extra "\r\n" at end of each section */
}
BufferSize++; /* Null-terminator */
DPRINT1("BufferSize: %lu\n", BufferSize);
/* Allocate file buffer */
Buffer = RtlAllocateHeap(ProcessHeap,
0,
BufferSize);
if (Buffer == NULL)
{
DPRINT1("RtlAllocateHeap() failed\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
RtlZeroMemory(Buffer, BufferSize);
/* Fill file buffer */
Ptr = Buffer;
Section = Cache->FirstSection;
while (Section != NULL)
{
Len = sprintf(Ptr, "[%S]\r\n", Section->Name);
Ptr += Len;
Key = Section->FirstKey;
while (Key != NULL)
{
Len = sprintf(Ptr, "%S=%S\r\n", Key->Name, Key->Data);
Ptr += Len;
Key = Key->Next;
}
Section = Section->Next;
if (Section != NULL)
{
Len = sprintf(Ptr, "\r\n");
Ptr += Len;
}
}
/* Create ini file */
RtlInitUnicodeString(&Name,
FileName);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
0,
NULL,
NULL);
Status = NtCreateFile(&FileHandle,
GENERIC_WRITE,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_SUPERSEDE,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
NULL,
0);
if (!NT_SUCCESS(Status))
{
DPRINT("NtCreateFile() failed (Status %lx)\n", Status);
RtlFreeHeap(ProcessHeap,
0,
Buffer);
return(Status);
}
Offset.QuadPart = 0LL;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
Buffer,
BufferSize,
&Offset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap,
0,
Buffer);
return(Status);
}
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap,
0,
Buffer);
return(STATUS_SUCCESS);
}
PINICACHESECTION
IniCacheAppendSection(PINICACHE Cache,
PWCHAR Name)
{
PINICACHESECTION Section = NULL;
if (Cache == NULL || Name == NULL || *Name == 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,
(wcslen(Name) + 1) * sizeof(WCHAR));
if (Section->Name == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
RtlFreeHeap(ProcessHeap,
0,
Section);
return(NULL);
}
/* Copy section name */
wcscpy(Section->Name, Name);
/* 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);
}
/* EOF */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?