ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

parser.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Applications Manager
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            base/applications/rapps/parser.c
00005  * PURPOSE:         Parser functions
00006  * PROGRAMMERS:     Dmitry Chapyshev (dmitry@reactos.org)
00007  */
00008 
00009 #include "rapps.h"
00010 
00011 typedef LONG NTSTATUS;
00012 
00013 typedef struct _UNICODE_STRING {
00014   USHORT Length;
00015   USHORT MaximumLength;
00016   PWSTR  Buffer;
00017 } UNICODE_STRING, *PUNICODE_STRING;
00018 
00019 void WINAPI RtlInitUnicodeString(PUNICODE_STRING,PCWSTR);
00020 NTSTATUS WINAPI RtlUnicodeStringToInteger(const UNICODE_STRING*,ULONG,ULONG*);
00021 BOOLEAN WINAPI RtlIsTextUnicode(LPCVOID,INT,INT*);
00022 
00023 static const char bom_utf8[] = {0xEF,0xBB,0xBF};
00024 
00025 typedef enum
00026 {
00027     ENCODING_UTF8 = 1,
00028     ENCODING_UTF16LE,
00029     ENCODING_UTF16BE
00030 } ENCODING;
00031 
00032 typedef struct tagSECTIONKEY
00033 {
00034     WCHAR *value;
00035     struct tagSECTIONKEY *next;
00036     WCHAR name[1];
00037 } SECTIONKEY;
00038 
00039 typedef struct tagSECTION
00040 {
00041     struct tagSECTIONKEY *key;
00042     struct tagSECTION *next;
00043     WCHAR name[1];
00044 } SECTION;
00045 
00046 typedef struct
00047 {
00048     BOOL changed;
00049     SECTION *section;
00050     WCHAR *filename;
00051     ENCODING encoding;
00052 } ITEMS;
00053 
00054 
00055 #define N_CACHED_ITEMS 10
00056 static ITEMS *ItemsArray[N_CACHED_ITEMS] = {NULL};
00057 #define CurProfile (ItemsArray[0])
00058 #define IS_ENTRY_COMMENT(str)  ((str)[0] == ';')
00059 #define ParserIsSpace(c) (iswspace(c) || c == 0x1a)
00060 
00061 
00062 static
00063 WCHAR*
00064 memchrW(const WCHAR *ptr, WCHAR ch, size_t n)
00065 {
00066     const WCHAR *end;
00067     for (end = ptr + n; ptr < end; ptr++)
00068         if (*ptr == ch)
00069             return (WCHAR *)(ULONG_PTR)ptr;
00070     return NULL;
00071 }
00072 
00073 static
00074 WCHAR
00075 *memrchrW(const WCHAR *ptr, WCHAR ch, size_t n)
00076 {
00077     const WCHAR *end;
00078     WCHAR *ret = NULL;
00079     for (end = ptr + n; ptr < end; ptr++)
00080         if (*ptr == ch)
00081             ret = (WCHAR *)(ULONG_PTR)ptr;
00082     return ret;
00083 }
00084 
00085 static
00086 void
00087 ParserCopyEntry(LPWSTR buffer, LPCWSTR value, int len, BOOL strip_quote)
00088 {
00089     WCHAR quote = '\0';
00090 
00091     if (!buffer) return;
00092 
00093     if (strip_quote && ((*value == '\'') || (*value == '\"')))
00094     {
00095         if (value[1] && (value[wcslen(value)-1] == *value))
00096             quote = *value++;
00097     }
00098 
00099     lstrcpynW(buffer, value, len);
00100     if (quote && (len >= (int)wcslen(value))) buffer[wcslen(buffer)-1] = '\0';
00101 }
00102 
00103 static
00104 void
00105 ParserByteSwapShortBuffer(WCHAR * buffer, int len)
00106 {
00107     int i;
00108     USHORT * shortbuffer = buffer;
00109     for (i = 0; i < len; i++)
00110         shortbuffer[i] = (shortbuffer[i] >> 8) | (shortbuffer[i] << 8);
00111 }
00112 
00113 static
00114 void
00115 ParserWriteMarker(HANDLE hFile, ENCODING encoding)
00116 {
00117     DWORD dwBytesWritten;
00118     WCHAR bom;
00119 
00120     switch (encoding)
00121     {
00122         case ENCODING_UTF8:
00123             WriteFile(hFile, bom_utf8, sizeof(bom_utf8), &dwBytesWritten, NULL);
00124             break;
00125 
00126         case ENCODING_UTF16LE:
00127             bom = 0xFEFF;
00128             WriteFile(hFile, &bom, sizeof(bom), &dwBytesWritten, NULL);
00129             break;
00130 
00131         case ENCODING_UTF16BE:
00132             bom = 0xFFFE;
00133             WriteFile(hFile, &bom, sizeof(bom), &dwBytesWritten, NULL);
00134             break;
00135     }
00136 }
00137 
00138 static
00139 void
00140 ParserWriteLine(HANDLE hFile, WCHAR * szLine, int len, ENCODING encoding)
00141 {
00142     char * write_buffer;
00143     int write_buffer_len;
00144     DWORD dwBytesWritten;
00145 
00146     switch (encoding)
00147     {
00148         case ENCODING_UTF8:
00149             write_buffer_len = WideCharToMultiByte(CP_UTF8, 0, szLine, len, NULL, 0, NULL, NULL);
00150             write_buffer = HeapAlloc(GetProcessHeap(), 0, write_buffer_len);
00151             if (!write_buffer) return;
00152             len = WideCharToMultiByte(CP_UTF8, 0, szLine, len, write_buffer, write_buffer_len, NULL, NULL);
00153             WriteFile(hFile, write_buffer, len, &dwBytesWritten, NULL);
00154             HeapFree(GetProcessHeap(), 0, write_buffer);
00155             break;
00156 
00157         case ENCODING_UTF16LE:
00158             WriteFile(hFile, szLine, len * sizeof(WCHAR), &dwBytesWritten, NULL);
00159             break;
00160 
00161         case ENCODING_UTF16BE:
00162             ParserByteSwapShortBuffer(szLine, len);
00163             WriteFile(hFile, szLine, len * sizeof(WCHAR), &dwBytesWritten, NULL);
00164             break;
00165     }
00166 }
00167 
00168 static
00169 void
00170 ParserSave(HANDLE hFile, const SECTION *section, ENCODING encoding)
00171 {
00172     SECTIONKEY *key;
00173     WCHAR *buffer, *p;
00174 
00175     ParserWriteMarker(hFile, encoding);
00176 
00177     for ( ; section; section = section->next)
00178     {
00179         int len = 0;
00180 
00181         if (section->name[0]) len += wcslen(section->name) + 4;
00182 
00183         for (key = section->key; key; key = key->next)
00184         {
00185             len += wcslen(key->name) + 2;
00186             if (key->value) len += wcslen(key->value) + 1;
00187         }
00188 
00189         buffer = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
00190         if (!buffer) return;
00191 
00192         p = buffer;
00193         if (section->name[0])
00194         {
00195             *p++ = '[';
00196             wcscpy(p, section->name);
00197             p += wcslen(p);
00198             *p++ = ']';
00199             *p++ = '\r';
00200             *p++ = '\n';
00201         }
00202 
00203         for (key = section->key; key; key = key->next)
00204         {
00205             wcscpy(p, key->name);
00206             p += wcslen(p);
00207             if (key->value)
00208             {
00209                 *p++ = '=';
00210                 wcscpy(p, key->value);
00211                 p += wcslen(p);
00212             }
00213             *p++ = '\r';
00214             *p++ = '\n';
00215         }
00216         ParserWriteLine(hFile, buffer, len, encoding);
00217         HeapFree(GetProcessHeap(), 0, buffer);
00218     }
00219 }
00220 
00221 static
00222 void
00223 ParserFree(SECTION *section)
00224 {
00225     SECTION *next_section;
00226     SECTIONKEY *key, *next_key;
00227 
00228     for ( ; section; section = next_section)
00229     {
00230         for (key = section->key; key; key = next_key)
00231         {
00232             next_key = key->next;
00233             HeapFree(GetProcessHeap(), 0, key->value);
00234             HeapFree(GetProcessHeap(), 0, key);
00235         }
00236         next_section = section->next;
00237         HeapFree(GetProcessHeap(), 0, section);
00238     }
00239 }
00240 
00241 static
00242 ENCODING
00243 ParserDetectTextEncoding(const void * buffer, int * len)
00244 {
00245     INT flags = IS_TEXT_UNICODE_SIGNATURE |
00246                 IS_TEXT_UNICODE_REVERSE_SIGNATURE |
00247                 IS_TEXT_UNICODE_ODD_LENGTH;
00248 
00249     if (*len >= sizeof(bom_utf8) && !memcmp(buffer, bom_utf8, sizeof(bom_utf8)))
00250     {
00251         *len = sizeof(bom_utf8);
00252         return ENCODING_UTF8;
00253     }
00254 
00255     RtlIsTextUnicode((void *)buffer, *len, &flags);
00256 
00257     if (flags & IS_TEXT_UNICODE_SIGNATURE)
00258     {
00259         *len = sizeof(WCHAR);
00260         return ENCODING_UTF16LE;
00261     }
00262 
00263     if (flags & IS_TEXT_UNICODE_REVERSE_SIGNATURE)
00264     {
00265         *len = sizeof(WCHAR);
00266         return ENCODING_UTF16BE;
00267     }
00268 
00269     *len = 0;
00270 
00271     return ENCODING_UTF8;
00272 }
00273 
00274 static
00275 SECTION
00276 *ParserLoad(HANDLE hFile, ENCODING * pEncoding)
00277 {
00278     void *buffer_base, *pBuffer;
00279     WCHAR * szFile;
00280     const WCHAR *szLineStart, *szLineEnd;
00281     const WCHAR *szValueStart, *szEnd, *next_line;
00282     int line = 0, len;
00283     SECTION *section, *first_section;
00284     SECTION **next_section;
00285     SECTIONKEY *key, *prev_key, **next_key;
00286     DWORD dwFileSize;
00287 
00288     dwFileSize = GetFileSize(hFile, NULL);
00289     if (dwFileSize == INVALID_FILE_SIZE || dwFileSize == 0)
00290         return NULL;
00291 
00292     buffer_base = HeapAlloc(GetProcessHeap(), 0 , dwFileSize);
00293     if (!buffer_base)
00294         return NULL;
00295 
00296     if (!ReadFile(hFile, buffer_base, dwFileSize, &dwFileSize, NULL))
00297     {
00298         HeapFree(GetProcessHeap(), 0, buffer_base);
00299         return NULL;
00300     }
00301 
00302     len = dwFileSize;
00303     *pEncoding = ParserDetectTextEncoding(buffer_base, &len);
00304 
00305     pBuffer = (char *)buffer_base + len;
00306     dwFileSize -= len;
00307 
00308     switch (*pEncoding)
00309     {
00310         case ENCODING_UTF8:
00311             len = MultiByteToWideChar(CP_UTF8, 0, pBuffer, dwFileSize, NULL, 0);
00312             szFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
00313             if (!szFile)
00314             {
00315                 HeapFree(GetProcessHeap(), 0, buffer_base);
00316                 return NULL;
00317             }
00318             MultiByteToWideChar(CP_UTF8, 0, pBuffer, dwFileSize, szFile, len);
00319             szEnd = szFile + len;
00320             break;
00321 
00322         case ENCODING_UTF16LE:
00323             szFile = pBuffer;
00324             szEnd = (WCHAR *)((char *)pBuffer + dwFileSize);
00325             break;
00326 
00327         case ENCODING_UTF16BE:
00328             szFile = pBuffer;
00329             szEnd = (WCHAR *)((char *)pBuffer + dwFileSize);
00330             ParserByteSwapShortBuffer(szFile, dwFileSize / sizeof(WCHAR));
00331             break;
00332 
00333         default:
00334             HeapFree(GetProcessHeap(), 0, buffer_base);
00335             return NULL;
00336     }
00337 
00338     first_section = HeapAlloc(GetProcessHeap(), 0, sizeof(*section));
00339     if (first_section == NULL)
00340     {
00341         if (szFile != pBuffer)
00342             HeapFree(GetProcessHeap(), 0, szFile);
00343         HeapFree(GetProcessHeap(), 0, buffer_base);
00344         return NULL;
00345     }
00346 
00347     first_section->name[0] = 0;
00348     first_section->key  = NULL;
00349     first_section->next = NULL;
00350     next_section = &first_section->next;
00351     next_key = &first_section->key;
00352     prev_key = NULL;
00353     next_line = szFile;
00354 
00355     while (next_line < szEnd)
00356     {
00357         szLineStart = next_line;
00358         next_line = memchrW(szLineStart, '\n', szEnd - szLineStart);
00359         if (!next_line) next_line = memchrW(szLineStart, '\r', szEnd - szLineStart);
00360         if (!next_line) next_line = szEnd;
00361         else next_line++;
00362         szLineEnd = next_line;
00363 
00364         line++;
00365 
00366         while (szLineStart < szLineEnd && ParserIsSpace(*szLineStart)) szLineStart++;
00367         while ((szLineEnd > szLineStart) && ParserIsSpace(szLineEnd[-1])) szLineEnd--;
00368 
00369         if (szLineStart >= szLineEnd)
00370             continue;
00371 
00372         if (*szLineStart == '[')
00373         {
00374             const WCHAR * szSectionEnd;
00375             if ((szSectionEnd = memrchrW(szLineStart, ']', szLineEnd - szLineStart)))
00376             {
00377                 szLineStart++;
00378                 len = (int)(szSectionEnd - szLineStart);
00379                 if (!(section = HeapAlloc(GetProcessHeap(), 0, sizeof(*section) + len * sizeof(WCHAR))))
00380                     break;
00381                 memcpy(section->name, szLineStart, len * sizeof(WCHAR));
00382                 section->name[len] = '\0';
00383                 section->key  = NULL;
00384                 section->next = NULL;
00385                 *next_section = section;
00386                 next_section = &section->next;
00387                 next_key = &section->key;
00388                 prev_key = NULL;
00389 
00390                 continue;
00391             }
00392         }
00393 
00394         len = szLineEnd - szLineStart;
00395         if ((szValueStart = memchrW(szLineStart, '=', szLineEnd - szLineStart)) != NULL)
00396         {
00397             const WCHAR *szNameEnd = szValueStart;
00398             while ((szNameEnd > szLineStart) && ParserIsSpace(szNameEnd[-1])) szNameEnd--;
00399             len = szNameEnd - szLineStart;
00400             szValueStart++;
00401             while (szValueStart < szLineEnd && ParserIsSpace(*szValueStart)) szValueStart++;
00402         }
00403 
00404         if (len || !prev_key || *prev_key->name)
00405         {
00406             if (!(key = HeapAlloc(GetProcessHeap(), 0, sizeof(*key) + len * sizeof(WCHAR)))) break;
00407             memcpy(key->name, szLineStart, len * sizeof(WCHAR));
00408             key->name[len] = '\0';
00409             if (szValueStart)
00410             {
00411                 len = (int)(szLineEnd - szValueStart);
00412                 key->value = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
00413                 memcpy(key->value, szValueStart, len * sizeof(WCHAR));
00414                 key->value[len] = '\0';
00415             }
00416             else key->value = NULL;
00417 
00418            key->next  = NULL;
00419            *next_key  = key;
00420            next_key   = &key->next;
00421            prev_key   = key;
00422         }
00423     }
00424 
00425     if (szFile != pBuffer)
00426         HeapFree(GetProcessHeap(), 0, szFile);
00427     HeapFree(GetProcessHeap(), 0, buffer_base);
00428 
00429     return first_section;
00430 }
00431 
00432 static
00433 SECTIONKEY
00434 *ParserFind(SECTION **section, LPCWSTR section_name, LPCWSTR key_name, BOOL create, BOOL create_always)
00435 {
00436     LPCWSTR p;
00437     int seclen, keylen;
00438 
00439     while (ParserIsSpace(*section_name)) section_name++;
00440     if (*section_name)
00441         p = section_name + wcslen(section_name) - 1;
00442     else
00443         p = section_name;
00444 
00445     while ((p > section_name) && ParserIsSpace(*p)) p--;
00446     seclen = p - section_name + 1;
00447 
00448     while (ParserIsSpace(*key_name)) key_name++;
00449     if (*key_name)
00450         p = key_name + wcslen(key_name) - 1;
00451     else
00452         p = key_name;
00453 
00454     while ((p > key_name) && ParserIsSpace(*p)) p--;
00455     keylen = p - key_name + 1;
00456 
00457     while (*section)
00458     {
00459         if (((*section)->name[0])
00460              && (!(_wcsnicmp((*section)->name, section_name, seclen)))
00461              && (((*section)->name)[seclen] == '\0'))
00462         {
00463             SECTIONKEY **key = &(*section)->key;
00464 
00465             while (*key)
00466             {
00467                 if(!create_always)
00468                 {
00469                     if ((!(_wcsnicmp((*key)->name, key_name, keylen)))
00470                          && (((*key)->name)[keylen] == '\0'))
00471                         return *key;
00472                 }
00473                 key = &(*key)->next;
00474             }
00475             if (!create)
00476                 return NULL;
00477             if (!(*key = HeapAlloc(GetProcessHeap(), 0, sizeof(SECTIONKEY) + wcslen(key_name) * sizeof(WCHAR))))
00478                 return NULL;
00479             wcscpy((*key)->name, key_name);
00480             (*key)->value = NULL;
00481             (*key)->next  = NULL;
00482             return *key;
00483         }
00484         section = &(*section)->next;
00485     }
00486     if (!create) return NULL;
00487     *section = HeapAlloc(GetProcessHeap(), 0, sizeof(SECTION) + wcslen(section_name) * sizeof(WCHAR));
00488     if(*section == NULL) return NULL;
00489     wcscpy((*section)->name, section_name);
00490     (*section)->next = NULL;
00491     if (!((*section)->key  = HeapAlloc(GetProcessHeap(), 0,
00492                                         sizeof(SECTIONKEY) + wcslen(key_name) * sizeof(WCHAR))))
00493     {
00494         HeapFree(GetProcessHeap(), 0, *section);
00495         return NULL;
00496     }
00497     wcscpy((*section)->key->name, key_name);
00498     (*section)->key->value = NULL;
00499     (*section)->key->next  = NULL;
00500     return (*section)->key;
00501 }
00502 
00503 static
00504 BOOL
00505 ParserFlushFile(void)
00506 {
00507     HANDLE hFile = NULL;
00508 
00509     if (!CurProfile) return FALSE;
00510 
00511     if (!CurProfile->changed) return TRUE;
00512 
00513     hFile = CreateFileW(CurProfile->filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
00514                         NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
00515 
00516     if (hFile == INVALID_HANDLE_VALUE) return FALSE;
00517 
00518     ParserSave(hFile, CurProfile->section, CurProfile->encoding);
00519 
00520     CloseHandle(hFile);
00521     CurProfile->changed = FALSE;
00522     return TRUE;
00523 }
00524 
00525 static
00526 void
00527 ParserReleaseFile(void)
00528 {
00529     ParserFlushFile();
00530     ParserFree(CurProfile->section);
00531     HeapFree(GetProcessHeap(), 0, CurProfile->filename);
00532     CurProfile->changed = FALSE;
00533     CurProfile->section = NULL;
00534     CurProfile->filename = NULL;
00535     CurProfile->encoding = ENCODING_UTF8;
00536 }
00537 
00538 static
00539 BOOL
00540 ParserOpen(LPCWSTR filename, BOOL write_access)
00541 {
00542     WCHAR szDir[MAX_PATH];
00543     WCHAR buffer[MAX_PATH];
00544     HANDLE hFile = INVALID_HANDLE_VALUE;
00545     int i, j;
00546     ITEMS *tempProfile;
00547     static const WCHAR wszSeparator[] = L"\\rapps\\";
00548 
00549     if (!CurProfile)
00550         for (i = 0; i < N_CACHED_ITEMS; i++)
00551         {
00552             ItemsArray[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(ITEMS));
00553             if (ItemsArray[i] == NULL) break;
00554             ItemsArray[i]->changed = FALSE;
00555             ItemsArray[i]->section = NULL;
00556             ItemsArray[i]->filename = NULL;
00557             ItemsArray[i]->encoding = ENCODING_UTF8;
00558         }
00559 
00560     GetCurrentDirectoryW(MAX_PATH, szDir);
00561 
00562     wcscpy(buffer, szDir);
00563     wcscat(buffer, wszSeparator);
00564     wcscat(buffer, filename);
00565 
00566     hFile = CreateFileW(buffer, GENERIC_READ | (write_access ? GENERIC_WRITE : 0),
00567                         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
00568                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00569 
00570     if ((hFile == INVALID_HANDLE_VALUE) && (GetLastError() != ERROR_FILE_NOT_FOUND))
00571     {
00572         return FALSE;
00573     }
00574 
00575     for (i = 0; i < N_CACHED_ITEMS; i++)
00576     {
00577         if ((ItemsArray[i]->filename && !wcscmp(buffer, ItemsArray[i]->filename)))
00578         {
00579             if (i)
00580             {
00581                 ParserFlushFile();
00582                 tempProfile = ItemsArray[i];
00583                 for (j = i; j > 0; j--)
00584                     ItemsArray[j] = ItemsArray[j - 1];
00585                 CurProfile = tempProfile;
00586             }
00587             if (hFile != INVALID_HANDLE_VALUE)
00588             {
00589                 CloseHandle(hFile);
00590             }
00591 
00592             return TRUE;
00593         }
00594     }
00595 
00596     ParserFlushFile();
00597 
00598     if (i == N_CACHED_ITEMS)
00599     {
00600         tempProfile = ItemsArray[N_CACHED_ITEMS - 1];
00601         for (i = N_CACHED_ITEMS - 1; i > 0; i--)
00602             ItemsArray[i] = ItemsArray[i - 1];
00603         CurProfile = tempProfile;
00604     }
00605 
00606     if (CurProfile->filename) ParserReleaseFile();
00607 
00608     CurProfile->filename = HeapAlloc(GetProcessHeap(), 0, (wcslen(buffer) + 1) * sizeof(WCHAR));
00609     if (CurProfile->filename == NULL)
00610         return FALSE;
00611 
00612     wcscpy(CurProfile->filename, buffer);
00613 
00614     if (hFile != INVALID_HANDLE_VALUE)
00615     {
00616         CurProfile->section = ParserLoad(hFile, &CurProfile->encoding);
00617         CloseHandle(hFile);
00618     }
00619     return TRUE;
00620 }
00621 
00622 static
00623 INT
00624 ParserGetSection(SECTION *section, LPCWSTR section_name, LPWSTR buffer, UINT len, BOOL return_values)
00625 {
00626     SECTIONKEY *key;
00627 
00628     if (!buffer)
00629         return 0;
00630 
00631     while (section)
00632     {
00633         if (section->name[0] && !_wcsicmp(section->name, section_name))
00634         {
00635             UINT oldlen = len;
00636             for (key = section->key; key; key = key->next)
00637             {
00638                 if (len <= 2) break;
00639                 if (!*key->name) continue;  /* Skip empty lines */
00640                 if (IS_ENTRY_COMMENT(key->name)) continue;  /* Skip comments */
00641                 if (!return_values && !key->value) continue;  /* Skip lines w.o. '=' */
00642 
00643                 ParserCopyEntry(buffer, key->name, len - 1, 0);
00644                 len -= wcslen(buffer) + 1;
00645                 buffer += wcslen(buffer) + 1;
00646 
00647                 if (len < 2) break;
00648                 if (return_values && key->value)
00649                 {
00650                     buffer[-1] = '=';
00651                     ParserCopyEntry(buffer, key->value, len - 1, 0);
00652                     len -= wcslen(buffer) + 1;
00653                     buffer += wcslen(buffer) + 1;
00654                 }
00655             }
00656             *buffer = '\0';
00657             if (len <= 1)
00658             {
00659                 buffer[-1] = '\0';
00660                 return oldlen - 2;
00661             }
00662             return oldlen - len;
00663         }
00664         section = section->next;
00665     }
00666     buffer[0] = buffer[1] = '\0';
00667     return 0;
00668 }
00669 
00670 static
00671 INT
00672 ParserInternalGetString(LPCWSTR section, LPCWSTR key_name, LPWSTR buffer, UINT len)
00673 {
00674     SECTIONKEY *key = NULL;
00675     static const WCHAR empty_strW[] = { 0 };
00676 
00677     if (!buffer || !len) return 0;
00678 
00679     if (key_name)
00680     {
00681         if (!key_name[0])
00682         {
00683             ParserCopyEntry(buffer, empty_strW, len, TRUE);
00684             return wcslen(buffer);
00685         }
00686         key = ParserFind(&CurProfile->section, section, key_name, FALSE, FALSE);
00687         ParserCopyEntry(buffer, (key && key->value) ? key->value : empty_strW,
00688                            len, TRUE);
00689         return wcslen(buffer);
00690     }
00691 
00692     if (section && section[0])
00693     {
00694         INT ret = ParserGetSection(CurProfile->section, section, buffer, len, FALSE);
00695         if (!buffer[0])
00696         {
00697             ParserCopyEntry(buffer, empty_strW, len, TRUE);
00698             ret = wcslen(buffer);
00699         }
00700         return ret;
00701     }
00702 
00703     buffer[0] = '\0';
00704     return 0;
00705 }
00706 
00707 INT
00708 ParserGetString(LPCWSTR Section, LPCWSTR ValueName, LPWSTR Buffer, UINT Len, LPCWSTR FileName)
00709 {
00710     if (Section == NULL) return 0;
00711 
00712     if (ParserOpen(FileName, FALSE))
00713         return ParserInternalGetString(Section, ValueName, Buffer, Len);
00714 
00715     return 0;
00716 }
00717 
00718 UINT
00719 ParserGetInt(LPCWSTR Section, LPCWSTR ValueName, LPCWSTR FileName)
00720 {
00721     WCHAR Buffer[30];
00722     UNICODE_STRING BufferW;
00723     ULONG Result;
00724 
00725     if (!ParserGetString(Section,
00726                          ValueName,
00727                          Buffer,
00728                          sizeof(Buffer) / sizeof(WCHAR),
00729                          FileName))
00730         return -1;
00731 
00732     if (!Buffer[0]) return -1;
00733 
00734     RtlInitUnicodeString(&BufferW, Buffer);
00735     RtlUnicodeStringToInteger(&BufferW, 0, &Result);
00736     return Result;
00737 }

Generated on Sun May 27 2012 04:17:19 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.