mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 00:03:00 +00:00
Create a branch for header work.
svn path=/branches/header-work/; revision=45691
This commit is contained in:
parent
14fe274b1c
commit
9ea495ba33
19538 changed files with 0 additions and 1063950 deletions
737
base/applications/rapps/parser.c
Normal file
737
base/applications/rapps/parser.c
Normal file
|
@ -0,0 +1,737 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Applications Manager
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: base/applications/rapps/parser.c
|
||||
* PURPOSE: Parser functions
|
||||
* PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
|
||||
*/
|
||||
|
||||
#include "rapps.h"
|
||||
|
||||
typedef LONG NTSTATUS;
|
||||
|
||||
typedef struct _UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
} UNICODE_STRING, *PUNICODE_STRING;
|
||||
|
||||
void WINAPI RtlInitUnicodeString(PUNICODE_STRING,PCWSTR);
|
||||
NTSTATUS WINAPI RtlUnicodeStringToInteger(const UNICODE_STRING*,ULONG,ULONG*);
|
||||
BOOLEAN WINAPI RtlIsTextUnicode(LPCVOID,INT,INT*);
|
||||
|
||||
static const char bom_utf8[] = {0xEF,0xBB,0xBF};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ENCODING_UTF8 = 1,
|
||||
ENCODING_UTF16LE,
|
||||
ENCODING_UTF16BE
|
||||
} ENCODING;
|
||||
|
||||
typedef struct tagSECTIONKEY
|
||||
{
|
||||
WCHAR *value;
|
||||
struct tagSECTIONKEY *next;
|
||||
WCHAR name[1];
|
||||
} SECTIONKEY;
|
||||
|
||||
typedef struct tagSECTION
|
||||
{
|
||||
struct tagSECTIONKEY *key;
|
||||
struct tagSECTION *next;
|
||||
WCHAR name[1];
|
||||
} SECTION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL changed;
|
||||
SECTION *section;
|
||||
WCHAR *filename;
|
||||
ENCODING encoding;
|
||||
} ITEMS;
|
||||
|
||||
|
||||
#define N_CACHED_ITEMS 10
|
||||
static ITEMS *ItemsArray[N_CACHED_ITEMS] = {NULL};
|
||||
#define CurProfile (ItemsArray[0])
|
||||
#define IS_ENTRY_COMMENT(str) ((str)[0] == ';')
|
||||
#define ParserIsSpace(c) (iswspace(c) || c == 0x1a)
|
||||
|
||||
|
||||
static
|
||||
WCHAR*
|
||||
memchrW(const WCHAR *ptr, WCHAR ch, size_t n)
|
||||
{
|
||||
const WCHAR *end;
|
||||
for (end = ptr + n; ptr < end; ptr++)
|
||||
if (*ptr == ch)
|
||||
return (WCHAR *)(ULONG_PTR)ptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
WCHAR
|
||||
*memrchrW(const WCHAR *ptr, WCHAR ch, size_t n)
|
||||
{
|
||||
const WCHAR *end;
|
||||
WCHAR *ret = NULL;
|
||||
for (end = ptr + n; ptr < end; ptr++)
|
||||
if (*ptr == ch)
|
||||
ret = (WCHAR *)(ULONG_PTR)ptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
ParserCopyEntry(LPWSTR buffer, LPCWSTR value, int len, BOOL strip_quote)
|
||||
{
|
||||
WCHAR quote = '\0';
|
||||
|
||||
if (!buffer) return;
|
||||
|
||||
if (strip_quote && ((*value == '\'') || (*value == '\"')))
|
||||
{
|
||||
if (value[1] && (value[wcslen(value)-1] == *value))
|
||||
quote = *value++;
|
||||
}
|
||||
|
||||
lstrcpynW(buffer, value, len);
|
||||
if (quote && (len >= (int)wcslen(value))) buffer[wcslen(buffer)-1] = '\0';
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
ParserByteSwapShortBuffer(WCHAR * buffer, int len)
|
||||
{
|
||||
int i;
|
||||
USHORT * shortbuffer = buffer;
|
||||
for (i = 0; i < len; i++)
|
||||
shortbuffer[i] = (shortbuffer[i] >> 8) | (shortbuffer[i] << 8);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
ParserWriteMarker(HANDLE hFile, ENCODING encoding)
|
||||
{
|
||||
DWORD dwBytesWritten;
|
||||
WCHAR bom;
|
||||
|
||||
switch (encoding)
|
||||
{
|
||||
case ENCODING_UTF8:
|
||||
WriteFile(hFile, bom_utf8, sizeof(bom_utf8), &dwBytesWritten, NULL);
|
||||
break;
|
||||
|
||||
case ENCODING_UTF16LE:
|
||||
bom = 0xFEFF;
|
||||
WriteFile(hFile, &bom, sizeof(bom), &dwBytesWritten, NULL);
|
||||
break;
|
||||
|
||||
case ENCODING_UTF16BE:
|
||||
bom = 0xFFFE;
|
||||
WriteFile(hFile, &bom, sizeof(bom), &dwBytesWritten, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
ParserWriteLine(HANDLE hFile, WCHAR * szLine, int len, ENCODING encoding)
|
||||
{
|
||||
char * write_buffer;
|
||||
int write_buffer_len;
|
||||
DWORD dwBytesWritten;
|
||||
|
||||
switch (encoding)
|
||||
{
|
||||
case ENCODING_UTF8:
|
||||
write_buffer_len = WideCharToMultiByte(CP_UTF8, 0, szLine, len, NULL, 0, NULL, NULL);
|
||||
write_buffer = HeapAlloc(GetProcessHeap(), 0, write_buffer_len);
|
||||
if (!write_buffer) return;
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, szLine, len, write_buffer, write_buffer_len, NULL, NULL);
|
||||
WriteFile(hFile, write_buffer, len, &dwBytesWritten, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, write_buffer);
|
||||
break;
|
||||
|
||||
case ENCODING_UTF16LE:
|
||||
WriteFile(hFile, szLine, len * sizeof(WCHAR), &dwBytesWritten, NULL);
|
||||
break;
|
||||
|
||||
case ENCODING_UTF16BE:
|
||||
ParserByteSwapShortBuffer(szLine, len);
|
||||
WriteFile(hFile, szLine, len * sizeof(WCHAR), &dwBytesWritten, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
ParserSave(HANDLE hFile, const SECTION *section, ENCODING encoding)
|
||||
{
|
||||
SECTIONKEY *key;
|
||||
WCHAR *buffer, *p;
|
||||
|
||||
ParserWriteMarker(hFile, encoding);
|
||||
|
||||
for ( ; section; section = section->next)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
if (section->name[0]) len += wcslen(section->name) + 4;
|
||||
|
||||
for (key = section->key; key; key = key->next)
|
||||
{
|
||||
len += wcslen(key->name) + 2;
|
||||
if (key->value) len += wcslen(key->value) + 1;
|
||||
}
|
||||
|
||||
buffer = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||
if (!buffer) return;
|
||||
|
||||
p = buffer;
|
||||
if (section->name[0])
|
||||
{
|
||||
*p++ = '[';
|
||||
wcscpy(p, section->name);
|
||||
p += wcslen(p);
|
||||
*p++ = ']';
|
||||
*p++ = '\r';
|
||||
*p++ = '\n';
|
||||
}
|
||||
|
||||
for (key = section->key; key; key = key->next)
|
||||
{
|
||||
wcscpy(p, key->name);
|
||||
p += wcslen(p);
|
||||
if (key->value)
|
||||
{
|
||||
*p++ = '=';
|
||||
wcscpy(p, key->value);
|
||||
p += wcslen(p);
|
||||
}
|
||||
*p++ = '\r';
|
||||
*p++ = '\n';
|
||||
}
|
||||
ParserWriteLine(hFile, buffer, len, encoding);
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
ParserFree(SECTION *section)
|
||||
{
|
||||
SECTION *next_section;
|
||||
SECTIONKEY *key, *next_key;
|
||||
|
||||
for ( ; section; section = next_section)
|
||||
{
|
||||
for (key = section->key; key; key = next_key)
|
||||
{
|
||||
next_key = key->next;
|
||||
HeapFree(GetProcessHeap(), 0, key->value);
|
||||
HeapFree(GetProcessHeap(), 0, key);
|
||||
}
|
||||
next_section = section->next;
|
||||
HeapFree(GetProcessHeap(), 0, section);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
ENCODING
|
||||
ParserDetectTextEncoding(const void * buffer, int * len)
|
||||
{
|
||||
INT flags = IS_TEXT_UNICODE_SIGNATURE |
|
||||
IS_TEXT_UNICODE_REVERSE_SIGNATURE |
|
||||
IS_TEXT_UNICODE_ODD_LENGTH;
|
||||
|
||||
if (*len >= sizeof(bom_utf8) && !memcmp(buffer, bom_utf8, sizeof(bom_utf8)))
|
||||
{
|
||||
*len = sizeof(bom_utf8);
|
||||
return ENCODING_UTF8;
|
||||
}
|
||||
|
||||
RtlIsTextUnicode((void *)buffer, *len, &flags);
|
||||
|
||||
if (flags & IS_TEXT_UNICODE_SIGNATURE)
|
||||
{
|
||||
*len = sizeof(WCHAR);
|
||||
return ENCODING_UTF16LE;
|
||||
}
|
||||
|
||||
if (flags & IS_TEXT_UNICODE_REVERSE_SIGNATURE)
|
||||
{
|
||||
*len = sizeof(WCHAR);
|
||||
return ENCODING_UTF16BE;
|
||||
}
|
||||
|
||||
*len = 0;
|
||||
|
||||
return ENCODING_UTF8;
|
||||
}
|
||||
|
||||
static
|
||||
SECTION
|
||||
*ParserLoad(HANDLE hFile, ENCODING * pEncoding)
|
||||
{
|
||||
void *buffer_base, *pBuffer;
|
||||
WCHAR * szFile;
|
||||
const WCHAR *szLineStart, *szLineEnd;
|
||||
const WCHAR *szValueStart, *szEnd, *next_line;
|
||||
int line = 0, len;
|
||||
SECTION *section, *first_section;
|
||||
SECTION **next_section;
|
||||
SECTIONKEY *key, *prev_key, **next_key;
|
||||
DWORD dwFileSize;
|
||||
|
||||
dwFileSize = GetFileSize(hFile, NULL);
|
||||
if (dwFileSize == INVALID_FILE_SIZE || dwFileSize == 0)
|
||||
return NULL;
|
||||
|
||||
buffer_base = HeapAlloc(GetProcessHeap(), 0 , dwFileSize);
|
||||
if (!buffer_base)
|
||||
return NULL;
|
||||
|
||||
if (!ReadFile(hFile, buffer_base, dwFileSize, &dwFileSize, NULL))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, buffer_base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = dwFileSize;
|
||||
*pEncoding = ParserDetectTextEncoding(buffer_base, &len);
|
||||
|
||||
pBuffer = (char *)buffer_base + len;
|
||||
dwFileSize -= len;
|
||||
|
||||
switch (*pEncoding)
|
||||
{
|
||||
case ENCODING_UTF8:
|
||||
len = MultiByteToWideChar(CP_UTF8, 0, pBuffer, dwFileSize, NULL, 0);
|
||||
szFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||
if (!szFile)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, buffer_base);
|
||||
return NULL;
|
||||
}
|
||||
MultiByteToWideChar(CP_UTF8, 0, pBuffer, dwFileSize, szFile, len);
|
||||
szEnd = szFile + len;
|
||||
break;
|
||||
|
||||
case ENCODING_UTF16LE:
|
||||
szFile = pBuffer;
|
||||
szEnd = (WCHAR *)((char *)pBuffer + dwFileSize);
|
||||
break;
|
||||
|
||||
case ENCODING_UTF16BE:
|
||||
szFile = pBuffer;
|
||||
szEnd = (WCHAR *)((char *)pBuffer + dwFileSize);
|
||||
ParserByteSwapShortBuffer(szFile, dwFileSize / sizeof(WCHAR));
|
||||
break;
|
||||
|
||||
default:
|
||||
HeapFree(GetProcessHeap(), 0, buffer_base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
first_section = HeapAlloc(GetProcessHeap(), 0, sizeof(*section));
|
||||
if (first_section == NULL)
|
||||
{
|
||||
if (szFile != pBuffer)
|
||||
HeapFree(GetProcessHeap(), 0, szFile);
|
||||
HeapFree(GetProcessHeap(), 0, buffer_base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
first_section->name[0] = 0;
|
||||
first_section->key = NULL;
|
||||
first_section->next = NULL;
|
||||
next_section = &first_section->next;
|
||||
next_key = &first_section->key;
|
||||
prev_key = NULL;
|
||||
next_line = szFile;
|
||||
|
||||
while (next_line < szEnd)
|
||||
{
|
||||
szLineStart = next_line;
|
||||
next_line = memchrW(szLineStart, '\n', szEnd - szLineStart);
|
||||
if (!next_line) next_line = memchrW(szLineStart, '\r', szEnd - szLineStart);
|
||||
if (!next_line) next_line = szEnd;
|
||||
else next_line++;
|
||||
szLineEnd = next_line;
|
||||
|
||||
line++;
|
||||
|
||||
while (szLineStart < szLineEnd && ParserIsSpace(*szLineStart)) szLineStart++;
|
||||
while ((szLineEnd > szLineStart) && ParserIsSpace(szLineEnd[-1])) szLineEnd--;
|
||||
|
||||
if (szLineStart >= szLineEnd)
|
||||
continue;
|
||||
|
||||
if (*szLineStart == '[')
|
||||
{
|
||||
const WCHAR * szSectionEnd;
|
||||
if ((szSectionEnd = memrchrW(szLineStart, ']', szLineEnd - szLineStart)))
|
||||
{
|
||||
szLineStart++;
|
||||
len = (int)(szSectionEnd - szLineStart);
|
||||
if (!(section = HeapAlloc(GetProcessHeap(), 0, sizeof(*section) + len * sizeof(WCHAR))))
|
||||
break;
|
||||
memcpy(section->name, szLineStart, len * sizeof(WCHAR));
|
||||
section->name[len] = '\0';
|
||||
section->key = NULL;
|
||||
section->next = NULL;
|
||||
*next_section = section;
|
||||
next_section = §ion->next;
|
||||
next_key = §ion->key;
|
||||
prev_key = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
len = szLineEnd - szLineStart;
|
||||
if ((szValueStart = memchrW(szLineStart, '=', szLineEnd - szLineStart)) != NULL)
|
||||
{
|
||||
const WCHAR *szNameEnd = szValueStart;
|
||||
while ((szNameEnd > szLineStart) && ParserIsSpace(szNameEnd[-1])) szNameEnd--;
|
||||
len = szNameEnd - szLineStart;
|
||||
szValueStart++;
|
||||
while (szValueStart < szLineEnd && ParserIsSpace(*szValueStart)) szValueStart++;
|
||||
}
|
||||
|
||||
if (len || !prev_key || *prev_key->name)
|
||||
{
|
||||
if (!(key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key) + len * sizeof(WCHAR)))) break;
|
||||
memcpy(key->name, szLineStart, len * sizeof(WCHAR));
|
||||
key->name[len] = '\0';
|
||||
if (szValueStart)
|
||||
{
|
||||
len = (int)(szLineEnd - szValueStart);
|
||||
key->value = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
|
||||
memcpy(key->value, szValueStart, len * sizeof(WCHAR));
|
||||
key->value[len] = '\0';
|
||||
}
|
||||
else key->value = NULL;
|
||||
|
||||
key->next = NULL;
|
||||
*next_key = key;
|
||||
next_key = &key->next;
|
||||
prev_key = key;
|
||||
}
|
||||
}
|
||||
|
||||
if (szFile != pBuffer)
|
||||
HeapFree(GetProcessHeap(), 0, szFile);
|
||||
HeapFree(GetProcessHeap(), 0, buffer_base);
|
||||
|
||||
return first_section;
|
||||
}
|
||||
|
||||
static
|
||||
SECTIONKEY
|
||||
*ParserFind(SECTION **section, LPCWSTR section_name, LPCWSTR key_name, BOOL create, BOOL create_always)
|
||||
{
|
||||
LPCWSTR p;
|
||||
int seclen, keylen;
|
||||
|
||||
while (ParserIsSpace(*section_name)) section_name++;
|
||||
if (*section_name)
|
||||
p = section_name + wcslen(section_name) - 1;
|
||||
else
|
||||
p = section_name;
|
||||
|
||||
while ((p > section_name) && ParserIsSpace(*p)) p--;
|
||||
seclen = p - section_name + 1;
|
||||
|
||||
while (ParserIsSpace(*key_name)) key_name++;
|
||||
if (*key_name)
|
||||
p = key_name + wcslen(key_name) - 1;
|
||||
else
|
||||
p = key_name;
|
||||
|
||||
while ((p > key_name) && ParserIsSpace(*p)) p--;
|
||||
keylen = p - key_name + 1;
|
||||
|
||||
while (*section)
|
||||
{
|
||||
if (((*section)->name[0])
|
||||
&& (!(_wcsnicmp((*section)->name, section_name, seclen)))
|
||||
&& (((*section)->name)[seclen] == '\0'))
|
||||
{
|
||||
SECTIONKEY **key = &(*section)->key;
|
||||
|
||||
while (*key)
|
||||
{
|
||||
if(!create_always)
|
||||
{
|
||||
if ((!(_wcsnicmp((*key)->name, key_name, keylen)))
|
||||
&& (((*key)->name)[keylen] == '\0'))
|
||||
return *key;
|
||||
}
|
||||
key = &(*key)->next;
|
||||
}
|
||||
if (!create)
|
||||
return NULL;
|
||||
if (!(*key = HeapAlloc(GetProcessHeap(), 0, sizeof(SECTIONKEY) + wcslen(key_name) * sizeof(WCHAR))))
|
||||
return NULL;
|
||||
wcscpy((*key)->name, key_name);
|
||||
(*key)->value = NULL;
|
||||
(*key)->next = NULL;
|
||||
return *key;
|
||||
}
|
||||
section = &(*section)->next;
|
||||
}
|
||||
if (!create) return NULL;
|
||||
*section = HeapAlloc(GetProcessHeap(), 0, sizeof(SECTION) + wcslen(section_name) * sizeof(WCHAR));
|
||||
if(*section == NULL) return NULL;
|
||||
wcscpy((*section)->name, section_name);
|
||||
(*section)->next = NULL;
|
||||
if (!((*section)->key = HeapAlloc(GetProcessHeap(), 0,
|
||||
sizeof(SECTIONKEY) + wcslen(key_name) * sizeof(WCHAR))))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, *section);
|
||||
return NULL;
|
||||
}
|
||||
wcscpy((*section)->key->name, key_name);
|
||||
(*section)->key->value = NULL;
|
||||
(*section)->key->next = NULL;
|
||||
return (*section)->key;
|
||||
}
|
||||
|
||||
static
|
||||
BOOL
|
||||
ParserFlushFile(void)
|
||||
{
|
||||
HANDLE hFile = NULL;
|
||||
|
||||
if (!CurProfile) return FALSE;
|
||||
|
||||
if (!CurProfile->changed) return TRUE;
|
||||
|
||||
hFile = CreateFileW(CurProfile->filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
|
||||
|
||||
ParserSave(hFile, CurProfile->section, CurProfile->encoding);
|
||||
|
||||
CloseHandle(hFile);
|
||||
CurProfile->changed = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
ParserReleaseFile(void)
|
||||
{
|
||||
ParserFlushFile();
|
||||
ParserFree(CurProfile->section);
|
||||
HeapFree(GetProcessHeap(), 0, CurProfile->filename);
|
||||
CurProfile->changed = FALSE;
|
||||
CurProfile->section = NULL;
|
||||
CurProfile->filename = NULL;
|
||||
CurProfile->encoding = ENCODING_UTF8;
|
||||
}
|
||||
|
||||
static
|
||||
BOOL
|
||||
ParserOpen(LPCWSTR filename, BOOL write_access)
|
||||
{
|
||||
WCHAR szDir[MAX_PATH];
|
||||
WCHAR buffer[MAX_PATH];
|
||||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||
int i, j;
|
||||
ITEMS *tempProfile;
|
||||
static const WCHAR wszSeparator[] = L"\\rapps\\";
|
||||
|
||||
if (!CurProfile)
|
||||
for (i = 0; i < N_CACHED_ITEMS; i++)
|
||||
{
|
||||
ItemsArray[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(ITEMS));
|
||||
if (ItemsArray[i] == NULL) break;
|
||||
ItemsArray[i]->changed = FALSE;
|
||||
ItemsArray[i]->section = NULL;
|
||||
ItemsArray[i]->filename = NULL;
|
||||
ItemsArray[i]->encoding = ENCODING_UTF8;
|
||||
}
|
||||
|
||||
GetCurrentDirectoryW(MAX_PATH, szDir);
|
||||
|
||||
wcscpy(buffer, szDir);
|
||||
wcscat(buffer, wszSeparator);
|
||||
wcscat(buffer, filename);
|
||||
|
||||
hFile = CreateFileW(buffer, GENERIC_READ | (write_access ? GENERIC_WRITE : 0),
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if ((hFile == INVALID_HANDLE_VALUE) && (GetLastError() != ERROR_FILE_NOT_FOUND))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < N_CACHED_ITEMS; i++)
|
||||
{
|
||||
if ((ItemsArray[i]->filename && !wcscmp(buffer, ItemsArray[i]->filename)))
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
ParserFlushFile();
|
||||
tempProfile = ItemsArray[i];
|
||||
for (j = i; j > 0; j--)
|
||||
ItemsArray[j] = ItemsArray[j - 1];
|
||||
CurProfile = tempProfile;
|
||||
}
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
ParserFlushFile();
|
||||
|
||||
if (i == N_CACHED_ITEMS)
|
||||
{
|
||||
tempProfile = ItemsArray[N_CACHED_ITEMS - 1];
|
||||
for (i = N_CACHED_ITEMS - 1; i > 0; i--)
|
||||
ItemsArray[i] = ItemsArray[i - 1];
|
||||
CurProfile = tempProfile;
|
||||
}
|
||||
|
||||
if (CurProfile->filename) ParserReleaseFile();
|
||||
|
||||
CurProfile->filename = HeapAlloc(GetProcessHeap(), 0, (wcslen(buffer) + 1) * sizeof(WCHAR));
|
||||
if (CurProfile->filename == NULL)
|
||||
return FALSE;
|
||||
|
||||
wcscpy(CurProfile->filename, buffer);
|
||||
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CurProfile->section = ParserLoad(hFile, &CurProfile->encoding);
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
INT
|
||||
ParserGetSection(SECTION *section, LPCWSTR section_name, LPWSTR buffer, UINT len, BOOL return_values)
|
||||
{
|
||||
SECTIONKEY *key;
|
||||
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
while (section)
|
||||
{
|
||||
if (section->name[0] && !_wcsicmp(section->name, section_name))
|
||||
{
|
||||
UINT oldlen = len;
|
||||
for (key = section->key; key; key = key->next)
|
||||
{
|
||||
if (len <= 2) break;
|
||||
if (!*key->name) continue; /* Skip empty lines */
|
||||
if (IS_ENTRY_COMMENT(key->name)) continue; /* Skip comments */
|
||||
if (!return_values && !key->value) continue; /* Skip lines w.o. '=' */
|
||||
|
||||
ParserCopyEntry(buffer, key->name, len - 1, 0);
|
||||
len -= wcslen(buffer) + 1;
|
||||
buffer += wcslen(buffer) + 1;
|
||||
|
||||
if (len < 2) break;
|
||||
if (return_values && key->value)
|
||||
{
|
||||
buffer[-1] = '=';
|
||||
ParserCopyEntry(buffer, key->value, len - 1, 0);
|
||||
len -= wcslen(buffer) + 1;
|
||||
buffer += wcslen(buffer) + 1;
|
||||
}
|
||||
}
|
||||
*buffer = '\0';
|
||||
if (len <= 1)
|
||||
{
|
||||
buffer[-1] = '\0';
|
||||
return oldlen - 2;
|
||||
}
|
||||
return oldlen - len;
|
||||
}
|
||||
section = section->next;
|
||||
}
|
||||
buffer[0] = buffer[1] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
INT
|
||||
ParserInternalGetString(LPCWSTR section, LPCWSTR key_name, LPWSTR buffer, UINT len)
|
||||
{
|
||||
SECTIONKEY *key = NULL;
|
||||
static const WCHAR empty_strW[] = { 0 };
|
||||
|
||||
if (!buffer || !len) return 0;
|
||||
|
||||
if (key_name)
|
||||
{
|
||||
if (!key_name[0])
|
||||
{
|
||||
ParserCopyEntry(buffer, empty_strW, len, TRUE);
|
||||
return wcslen(buffer);
|
||||
}
|
||||
key = ParserFind(&CurProfile->section, section, key_name, FALSE, FALSE);
|
||||
ParserCopyEntry(buffer, (key && key->value) ? key->value : empty_strW,
|
||||
len, TRUE);
|
||||
return wcslen(buffer);
|
||||
}
|
||||
|
||||
if (section && section[0])
|
||||
{
|
||||
INT ret = ParserGetSection(CurProfile->section, section, buffer, len, FALSE);
|
||||
if (!buffer[0])
|
||||
{
|
||||
ParserCopyEntry(buffer, empty_strW, len, TRUE);
|
||||
ret = wcslen(buffer);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
buffer[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
ParserGetString(LPCWSTR Section, LPCWSTR ValueName, LPWSTR Buffer, UINT Len, LPCWSTR FileName)
|
||||
{
|
||||
if (Section == NULL) return 0;
|
||||
|
||||
if (ParserOpen(FileName, FALSE))
|
||||
return ParserInternalGetString(Section, ValueName, Buffer, Len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT
|
||||
ParserGetInt(LPCWSTR Section, LPCWSTR ValueName, LPCWSTR FileName)
|
||||
{
|
||||
WCHAR Buffer[30];
|
||||
UNICODE_STRING BufferW;
|
||||
ULONG Result;
|
||||
|
||||
if (!ParserGetString(Section,
|
||||
ValueName,
|
||||
Buffer,
|
||||
sizeof(Buffer) / sizeof(WCHAR),
|
||||
FileName))
|
||||
return -1;
|
||||
|
||||
if (!Buffer[0]) return -1;
|
||||
|
||||
RtlInitUnicodeString(&BufferW, Buffer);
|
||||
RtlUnicodeStringToInteger(&BufferW, 0, &Result);
|
||||
return Result;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue