00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
#include "cmp.h"
00029
#include "string.h"
00030
#include "ctype.h"
00031
#include "stdlib.h"
00032
#include "parseini.h"
00033
00034 typedef struct _value VALUE, *
PVALUE;
00035 typedef struct _line LINE, *
PLINE;
00036 typedef struct _section SECTION, *
PSECTION;
00037 typedef struct _inf INF, *
PINF;
00038 typedef struct _token TOKEN, *
PTOKEN;
00039 typedef enum _tokentype TOKENTYPE, *
PTOKENTTYPE;
00040 typedef enum _stringsSectionType STRINGSSECTIONTYPE;;
00041
00042 struct _value
00043 {
00044 PVALUE pNext;
00045 PCHAR
pName;
00046 BOOLEAN
Allocated;
00047 };
00048
00049 struct _line
00050 {
00051 PLINE pNext;
00052 PCHAR
pName;
00053 PVALUE pValue;
00054 BOOLEAN
Allocated;
00055 };
00056
00057 struct _section
00058 {
00059 PSECTION pNext;
00060 PCHAR
pName;
00061 PLINE pLine;
00062 BOOLEAN
Allocated;
00063 };
00064
00065 struct _inf
00066 {
00067 PSECTION pSection;
00068 PSECTION pSectionRecord;
00069 PLINE pLineRecord;
00070 PVALUE pValueRecord;
00071 STRINGSSECTIONTYPE StringsSectionType;
00072 PSECTION StringsSection;
00073 };
00074
00075
00076
00077
00078 enum _stringsSectionType
00079 {
00080
StringsSectionNone,
00081
StringsSectionPlain,
00082
StringsSectionLoosePrimaryMatch,
00083
StringsSectionExactPrimaryMatch,
00084
StringsSectionExactMatch
00085 };
00086
00087 enum _tokentype
00088 {
00089
TOK_EOF,
00090
TOK_EOL,
00091
TOK_LBRACE,
00092
TOK_RBRACE,
00093
TOK_STRING,
00094
TOK_EQUAL,
00095
TOK_COMMA,
00096
TOK_ERRPARSE,
00097
TOK_ERRNOMEM
00098 };
00099
00100 struct _token
00101 {
00102 TOKENTYPE
Type;
00103 PCHAR
pValue;
00104 BOOLEAN
Allocated;
00105 };
00106
00107
VOID
00108
CmpFreeValueList(
00109 IN PVALUE pValue
00110 );
00111
00112
VOID
00113
CmpFreeLineList(
00114 IN PLINE pLine
00115 );
00116
00117
VOID
00118
CmpFreeSectionList(
00119 IN PSECTION pSection
00120 );
00121
00122 PCHAR
00123
CmpProcessForSimpleStringSub(
00124 IN PINF pInf,
00125 IN PCHAR String
00126 );
00127
00128 BOOLEAN
00129
CmpAppendSection(
00130 IN PINF pInf,
00131 IN PCHAR pSectionName,
00132 IN BOOLEAN Allocated
00133 );
00134
00135 BOOLEAN
00136
CmpAppendLine(
00137 IN PINF pInf,
00138 IN PCHAR pLineKey,
00139 IN BOOLEAN Allocated
00140 );
00141
00142 BOOLEAN
00143
CmpAppendValue(
00144 IN PINF pInf,
00145 IN PCHAR pValueString,
00146 IN BOOLEAN Allocated
00147 );
00148
00149
VOID
00150
CmpGetToken(
00151 IN OUT PCHAR *Stream,
00152 IN PCHAR MaxStream,
00153 IN OUT PULONG LineNumber,
00154 IN OUT PTOKEN Token
00155 );
00156
00157
PINF
00158
CmpParseInfBuffer(
00159 IN PCHAR Buffer,
00160 IN ULONG Size,
00161 IN OUT PULONG ErrorLine
00162 );
00163
00164
PVALUE
00165
CmpSearchValueInLine(
00166 IN PLINE pLine,
00167 IN ULONG ValueIndex
00168 );
00169
00170
PLINE
00171
CmpSearchLineInSectionByIndex(
00172 IN PSECTION pSection,
00173 IN ULONG LineIndex
00174 );
00175
00176
PSECTION
00177
CmpSearchSectionByName(
00178 IN PINF pInf,
00179 IN PCHAR SectionName
00180 );
00181
00182
#ifdef ALLOC_PRAGMA
00183
#pragma alloc_text(INIT,CmpFreeValueList)
00184
#pragma alloc_text(INIT,CmpFreeLineList)
00185
#pragma alloc_text(INIT,CmpFreeSectionList)
00186
#pragma alloc_text(INIT,CmpProcessForSimpleStringSub)
00187
#pragma alloc_text(INIT,CmpAppendSection)
00188
#pragma alloc_text(INIT,CmpAppendLine)
00189
#pragma alloc_text(INIT,CmpAppendValue)
00190
#pragma alloc_text(INIT,CmpGetToken)
00191
#pragma alloc_text(INIT,CmpParseInfBuffer)
00192
#pragma alloc_text(INIT,CmpSearchValueInLine)
00193
#pragma alloc_text(INIT,CmpSearchLineInSectionByIndex)
00194
#pragma alloc_text(INIT,CmpSearchSectionByName)
00195
#pragma alloc_text(INIT,CmpSearchInfLine)
00196
#pragma alloc_text(INIT,CmpOpenInfFile)
00197
#pragma alloc_text(INIT,CmpCloseInfFile)
00198
#pragma alloc_text(INIT,CmpGetKeyName)
00199
#pragma alloc_text(INIT,CmpSearchInfSection)
00200
#pragma alloc_text(INIT,CmpGetSectionLineIndex)
00201
#pragma alloc_text(INIT,CmpGetSectionLineIndexValueCount)
00202
#pragma alloc_text(INIT,CmpGetIntField)
00203
#pragma alloc_text(INIT,CmpGetBinaryField)
00204
#endif
00205
00206
00207
00208
00209
00210
00211
00212
00213 CHAR StringTerminators[] =
"[]=,\t \"\n\f\v\r";
00214 PCHAR
QStringTerminators =
StringTerminators + 6;
00215 PCHAR
EmptyValue;
00216 CHAR DblSpaceSection[] =
"DBLSPACE_SECTION";
00217
00218 BOOLEAN
00219 CmpAppendSection(
00220 IN PINF pInf,
00221 IN PCHAR pSectionName,
00222 IN BOOLEAN Allocated
00223 )
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 {
00246
PSECTION pNewSection;
00247
PLINE pLineRecord;
00248
STRINGSSECTIONTYPE type;
00249
USHORT id;
00250
USHORT threadLang;
00251 PCHAR p;
00252
00253
00254
00255
00256
00257
if ( pInf == (
PINF)
NULL ||
00258 pSectionName == (PCHAR)
NULL)
00259 {
00260
return (
FALSE);
00261 }
00262
00263
00264
00265
00266
00267
00268
for( pNewSection = pInf->pSection;
00269 pNewSection;
00270 pNewSection = pNewSection->pNext)
00271 {
00272
if(pNewSection->pName && _stricmp(pNewSection->pName,pSectionName) == 0)
00273 {
00274
break;
00275 }
00276 }
00277
00278
if(pNewSection)
00279 {
00280
00281
00282
00283
00284
for( pLineRecord = pNewSection->pLine;
00285 pLineRecord && pLineRecord->pNext;
00286 pLineRecord = pLineRecord->pNext);
00287
00288 pInf->pLineRecord = pLineRecord;
00289 }
00290
else
00291 {
00292
00293
00294
00295
00296 pNewSection = (
PSECTION)
ExAllocatePoolWithTag(
PagedPool,
sizeof(
SECTION), CM_PARSEINI_TAG);
00297
00298
if (pNewSection == (
PSECTION)
NULL)
00299 {
00300
ASSERT(pNewSection);
00301
return (
FALSE);
00302 }
00303
00304
00305
00306
00307
00308 pNewSection->pNext =
NULL;
00309 pNewSection->pLine =
NULL;
00310 pNewSection->pName = pSectionName;
00311 pNewSection->Allocated = Allocated;
00312
00313
00314
00315
00316
00317 pNewSection->pNext = pInf->pSection;
00318 pInf->pSection = pNewSection;
00319
00320
if(_strnicmp(pSectionName,
"Strings", 7) == 0)
00321 {
00322
type =
StringsSectionNone;
00323
00324
if(pSectionName[7] ==
'.')
00325 {
00326
00327
00328
00329
00330
id = (
USHORT)strtoul(pSectionName + 8, &p, 16);
00331
if(p == (pSectionName + 8 + 5) && *p ==
'\0')
00332 {
00333 threadLang = LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale);
00334
00335
if(threadLang ==
id)
00336 {
00337
type =
StringsSectionExactMatch;
00338 }
00339
else
00340 {
00341
if(
id == PRIMARYLANGID(threadLang))
00342 {
00343
type =
StringsSectionExactPrimaryMatch;
00344 }
00345
else
00346 {
00347
if(PRIMARYLANGID(
id) == PRIMARYLANGID(threadLang))
00348 {
00349
type =
StringsSectionLoosePrimaryMatch;
00350 }
00351 }
00352 }
00353 }
00354 }
00355
else
00356 {
00357
if(!pSectionName[7])
00358 {
00359
type =
StringsSectionPlain;
00360 }
00361 }
00362
00363
if(
type > pInf->StringsSectionType)
00364 {
00365 pInf->StringsSection = pNewSection;
00366 }
00367 }
00368
00369
00370
00371
00372
00373 pInf->pLineRecord =
NULL;
00374 }
00375
00376 pInf->pSectionRecord = pNewSection;
00377 pInf->pValueRecord =
NULL;
00378
00379
return (
TRUE);
00380 }
00381
00382 BOOLEAN
00383 CmpAppendLine(
00384 IN PINF pInf,
00385 IN PCHAR pLineKey,
00386 IN BOOLEAN Allocated
00387 )
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 {
00410
PLINE pNewLine;
00411
00412
00413
00414
00415
00416
if (pInf->pSectionRecord == (
PSECTION)
NULL)
00417 {
00418
return (
FALSE);
00419 }
00420
00421
00422
00423
00424
00425 pNewLine = (
PLINE)
ExAllocatePoolWithTag(
PagedPool,
sizeof(LINE), CM_PARSEINI_TAG);
00426
if (pNewLine == (
PLINE)
NULL)
00427 {
00428
ASSERT(pNewLine);
00429
return (
FALSE);
00430 }
00431
00432
00433
00434
00435
00436 pNewLine->pNext = (
PLINE)
NULL;
00437 pNewLine->pValue = (
PVALUE)
NULL;
00438 pNewLine->pName = pLineKey;
00439 pNewLine->Allocated = Allocated;
00440
00441
if (pInf->pLineRecord == (
PLINE)
NULL)
00442 {
00443 pInf->pSectionRecord->pLine = pNewLine;
00444 }
00445
else
00446 {
00447 pInf->pLineRecord->pNext = pNewLine;
00448 }
00449
00450 pInf->pLineRecord = pNewLine;
00451
00452
00453
00454
00455
00456 pInf->pValueRecord = (
PVALUE)
NULL;
00457
00458
return (
TRUE);
00459 }
00460
00461 BOOLEAN
00462 CmpAppendValue(
00463 IN PINF pInf,
00464 IN PCHAR pValueString,
00465 IN BOOLEAN Allocated
00466 )
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 {
00489
PVALUE pNewValue;
00490
00491
00492
00493
00494
00495
00496
if ( pInf->pLineRecord == (
PLINE)
NULL ||
00497 pValueString == (PCHAR)
NULL)
00498 {
00499
return (
FALSE);
00500 }
00501
00502
00503
00504
00505
00506 pNewValue = (
PVALUE)
ExAllocatePoolWithTag(
PagedPool,
sizeof(VALUE), CM_PARSEINI_TAG);
00507
00508
if (pNewValue == (
PVALUE)
NULL)
00509 {
00510
ASSERT(pNewValue);
00511
return (
FALSE);
00512 }
00513
00514
00515
00516
00517
00518 pNewValue->pNext = (
PVALUE)
NULL;
00519 pNewValue->pName = pValueString;
00520 pNewValue->Allocated = Allocated;
00521
00522
if (pInf->pValueRecord == (
PVALUE)
NULL)
00523 {
00524 pInf->pLineRecord->pValue = pNewValue;
00525 }
00526
else
00527 {
00528 pInf->pValueRecord->pNext = pNewValue;
00529 }
00530
00531 pInf->pValueRecord = pNewValue;
00532
00533
return (
TRUE);
00534 }
00535
00536
VOID
00537 CmpGetToken(
00538 IN OUT PCHAR *Stream,
00539 IN PCHAR MaxStream,
00540 IN OUT PULONG LineNumber,
00541 IN OUT PTOKEN Token
00542 )
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 {
00566
00567 PCHAR pch;
00568 PCHAR pchStart;
00569 PCHAR pchNew;
00570 ULONG length;
00571 BOOLEAN done;
00572
00573
Token->Allocated =
FALSE;
00574
Token->pValue =
NULL;
00575
00576
do
00577 {
00578 done =
TRUE;
00579
00580
00581
00582
00583
00584
for ( pch = *Stream;
00585 pch < MaxStream && *pch !=
'\n' && isspace(*pch);
00586 pch++);
00587
00588
00589
00590
00591
00592
if ( pch < MaxStream &&
00593 (*pch ==
'#' || *pch ==
';'))
00594 {
00595
while (pch < MaxStream && *pch !=
'\n')
00596 {
00597 pch++;
00598 }
00599 }
00600
00601
00602
00603
00604
00605
00606
if (pch >= MaxStream || *pch == 26)
00607 {
00608 *Stream = pch;
00609
Token->Type =
TOK_EOF;
00610
Token->pValue =
NULL;
00611
00612
return;
00613 }
00614
00615
switch (*pch)
00616 {
00617
case '[':
00618
00619 pch++;
00620
Token->Type =
TOK_LBRACE;
00621
break;
00622
00623
case ']':
00624
00625 pch++;
00626
Token->Type =
TOK_RBRACE;
00627
break;
00628
00629
case '=':
00630
00631 pch++;
00632
Token->Type =
TOK_EQUAL;
00633
break;
00634
00635
case ',':
00636
00637 pch++;
00638
Token->Type =
TOK_COMMA;
00639
break;
00640
00641
case '\n':
00642
00643 pch++;
00644
Token->Type =
TOK_EOL;
00645
break;
00646
00647
case '\"':
00648
00649 pch++;
00650
00651
00652
00653
00654
00655
for ( pchStart = pch;
00656 pch < MaxStream && (strchr(
QStringTerminators, *pch) ==
NULL);
00657 pch++);
00658
00659
if (pch >= MaxStream || *pch !=
'\"')
00660 {
00661
Token->Type =
TOK_ERRPARSE;
00662 }
00663
else
00664 {
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 *pch++ =
'\0';
00681
Token->Type =
TOK_STRING;
00682
Token->pValue = pchStart;
00683 }
00684
break;
00685
00686
case '\\':
00687
00688
for ( pchNew = ++pch;
00689 pchNew < MaxStream &&
00690 *pchNew !=
'\n' && isspace(*pchNew);
00691 pchNew++);
00692
00693
if (*pchNew ==
'\n')
00694 {
00695 pch = pchNew + 1;
00696 done =
FALSE;
00697
break;
00698 }
00699
00700
default:
00701
00702
00703
00704
00705
00706
for ( pchStart = pch;
00707 pch < MaxStream && (strchr(
StringTerminators, *pch) ==
NULL);
00708 pch++);
00709
00710
if (pch == pchStart)
00711 {
00712 pch++;
00713
Token->Type =
TOK_ERRPARSE;
00714 }
00715
else
00716 {
00717 length = (ULONG)(pch - pchStart);
00718 pchNew =
ExAllocatePoolWithTag(
PagedPool, length + 1, CM_PARSEINI_TAG);
00719
if (pchNew ==
NULL)
00720 {
00721
ASSERT(pchNew);
00722
Token->Type =
TOK_ERRNOMEM;
00723 }
00724
else
00725 {
00726 strncpy(pchNew, pchStart, length);
00727 pchNew[length] = 0;
00728
Token->Type =
TOK_STRING;
00729
Token->pValue = pchNew;
00730
Token->Allocated =
TRUE;
00731 }
00732 }
00733
break;
00734 }
00735
00736 *Stream = pch;
00737 }
00738
while (!done);
00739
00740
return;
00741 }
00742
00743
PINF
00744 CmpParseInfBuffer(
00745 IN PCHAR Buffer,
00746 IN ULONG Size,
00747 IN OUT PULONG ErrorLine
00748 )
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 {
00775
PINF pInf;
00776 ULONG state;
00777 PCHAR stream;
00778 PCHAR maxStream;
00779 PCHAR pchSectionName;
00780 PCHAR pchValue;
00781
TOKEN token;
00782 BOOLEAN done;
00783 BOOLEAN error;
00784 ULONG infLine;
00785 BOOLEAN allocated;
00786
00787
00788
00789
00790
00791
EmptyValue =
StringTerminators +
strlen(
StringTerminators);
00792
00793
00794
00795
00796
00797 pInf = (
PINF)
ExAllocatePoolWithTag(
PagedPool,
sizeof(INF), CM_PARSEINI_TAG);
00798
00799
if (pInf ==
NULL)
00800 {
00801
ASSERT(pInf);
00802
return (pInf);
00803 }
00804
00805 pInf->pSection =
NULL;
00806 pInf->pSectionRecord =
NULL;
00807 pInf->pLineRecord =
NULL;
00808 pInf->pValueRecord =
NULL;
00809 pInf->StringsSectionType =
StringsSectionNone;
00810 pInf->StringsSection =
NULL;
00811
00812
00813
00814
00815
00816 state = 1;
00817 stream =
Buffer;
00818 maxStream =
Buffer +
Size;
00819 pchSectionName =
NULL;
00820 pchValue =
NULL;
00821 done =
FALSE;
00822 error =
FALSE;
00823 infLine = 1;
00824
00825
00826
00827
00828
00829
while (!done)
00830 {
00831
00832
CmpGetToken(&stream, maxStream, &infLine, &token);
00833
00834
switch (state)
00835 {
00836
00837
00838
00839
00840
00841
00842
00843
case 1:
00844
00845
switch (token.Type)
00846 {
00847
case TOK_EOL:
00848
00849
break;
00850
00851
case TOK_EOF:
00852
00853 done =
TRUE;
00854
00855
break;
00856
00857
case TOK_LBRACE:
00858
00859 state = 2;
00860
00861
break;
00862
00863
case TOK_STRING:
00864
00865 pchSectionName =
ExAllocatePoolWithTag(
PagedPool,
sizeof(
DblSpaceSection), CM_PARSEINI_TAG);
00866
if (pchSectionName)
00867 {
00868 strcpy(pchSectionName,
DblSpaceSection);
00869 pchValue = token.pValue;
00870 allocated =
TRUE;
00871 token.Allocated =
TRUE;
00872
if (
CmpAppendSection(pInf, pchSectionName,
TRUE))
00873 {
00874 pchSectionName =
NULL;
00875 state = 6;
00876 }
00877
else
00878 {
00879 error = done =
TRUE;
00880 }
00881 }
00882
else
00883 {
00884
ASSERT(pchSectionName);
00885 error = done =
TRUE;
00886 }
00887
00888
break;
00889
00890
default:
00891
00892 error = done =
TRUE;
00893
00894
break;
00895 }
00896
00897
break;
00898
00899
00900
00901
00902
00903
00904
00905
case 2:
00906
00907
switch (token.Type)
00908 {
00909
case TOK_STRING:
00910
00911 state = 3;
00912 pchSectionName = token.pValue;
00913 allocated = token.Allocated;
00914
00915
break;
00916
00917
case TOK_RBRACE:
00918
00919 token.pValue =
EmptyValue;
00920 token.Allocated =
FALSE;
00921 allocated =
FALSE;
00922 state = 4;
00923
00924
break;
00925
00926
default:
00927
00928 error = done =
TRUE;
00929
00930
break;
00931
00932 }
00933
00934
break;
00935
00936
00937
00938
00939
00940
00941
00942
case 3:
00943
00944
switch (token.Type)
00945 {
00946
case TOK_RBRACE:
00947
00948 state = 4;
00949
00950
break;
00951
00952
default:
00953
00954 error = done =
TRUE;
00955
00956
break;
00957 }
00958
00959
break;
00960
00961
00962
00963
00964
00965
00966
00967
case 4:
00968
00969
switch (token.Type)
00970 {
00971
00972
case TOK_EOL:
00973
00974
if (!
CmpAppendSection(pInf, pchSectionName, allocated))
00975 {
00976
00977 error = done =
TRUE;
00978 }
00979
else
00980 {
00981 pchSectionName =
NULL;
00982 state = 5;
00983 }
00984
00985
break;
00986
00987
case TOK_EOF:
00988
00989
if (!
CmpAppendSection(pInf, pchSectionName, allocated))
00990 {
00991 error = done =
TRUE;
00992 }
00993
else
00994 {
00995 pchSectionName =
NULL;
00996 done =
TRUE;
00997 }
00998
00999
break;
01000
01001
default:
01002
01003 error = done =
TRUE;
01004
01005
break;
01006 }
01007
01008
break;
01009
01010
01011
01012
01013
01014
01015
01016
case 5:
01017
01018
switch (token.Type)
01019 {
01020
case TOK_EOL:
01021
01022
break;
01023
01024
case TOK_EOF:
01025
01026 done =
TRUE;
01027
01028
break;
01029
01030
case TOK_STRING:
01031
01032 pchValue = token.pValue;
01033 allocated = token.Allocated;
01034 state = 6;
01035
01036
break;
01037
01038
case TOK_LBRACE:
01039
01040 state = 2;
01041
01042
break;
01043
01044
default:
01045
01046 error = done =
TRUE;
01047
01048
break;
01049 }
01050
01051
break;
01052
01053
01054
01055
01056
01057
01058
01059
case 6:
01060
01061
switch (token.Type)
01062 {
01063
01064
case TOK_EOL:
01065
01066
if ( !
CmpAppendLine(pInf,
NULL,
FALSE) ||
01067 !
CmpAppendValue(pInf, pchValue, allocated))
01068 {
01069 error = done =
TRUE;
01070 }
01071
else
01072 {
01073 pchValue =
NULL;
01074 state = 5;
01075 }
01076
01077
break;
01078
01079
case TOK_EOF:
01080
01081
if ( !
CmpAppendLine(pInf,
NULL,
FALSE) ||
01082 !
CmpAppendValue(pInf, pchValue, allocated))
01083 {
01084 error = done =
TRUE;
01085 }
01086
else
01087 {
01088 pchValue =
NULL;
01089 done =
TRUE;
01090 }
01091
01092
break;
01093
01094
case TOK_COMMA:
01095
01096
if ( !
CmpAppendLine(pInf,
NULL,
FALSE) ||
01097 !
CmpAppendValue(pInf, pchValue, allocated))
01098 {
01099 error = done =
TRUE;
01100 }
01101
else
01102 {
01103 pchValue =
NULL;
01104 state = 7;
01105 }
01106
01107
break;
01108
01109
case TOK_EQUAL:
01110
01111
if (!
CmpAppendLine(pInf, pchValue, allocated))
01112 {
01113 error = done =
TRUE;
01114 }
01115
else
01116 {
01117 pchValue =
NULL;
01118 state = 8;
01119 }
01120
01121
break;
01122
01123
default:
01124
01125 error = done =
TRUE;
01126
01127
break;
01128 }
01129
01130
break;
01131
01132
01133
01134
01135
01136
01137
01138
01139
case 7:
01140
01141
switch (token.Type)
01142 {
01143
01144
case TOK_COMMA:
01145
01146 token.pValue =
EmptyValue;
01147 token.Allocated =
FALSE;
01148 allocated =
FALSE;
01149
if (!
CmpAppendValue(pInf, token.pValue,
FALSE))
01150 {
01151 error = done =
TRUE;
01152 }
01153
01154
01155
01156
01157
01158
break;
01159
01160
case TOK_STRING:
01161
01162
if (!
CmpAppendValue(pInf, token.pValue, token.Allocated))
01163 {
01164 error = done =
TRUE;
01165 }
01166
else
01167 {
01168 state = 9;
01169 }
01170
01171
break;
01172
01173
default:
01174
01175 error = done =
TRUE;
01176
01177
break;
01178 }
01179
01180
break;
01181
01182
01183
01184
01185
01186
01187
01188
01189
case 8:
01190
01191
switch (token.Type)
01192 {
01193
case TOK_EOF:
01194
01195 token.pValue =
EmptyValue;
01196 token.Allocated =
FALSE;
01197 allocated =
FALSE;
01198
if(!
CmpAppendValue(pInf, token.pValue,
FALSE))
01199 {
01200 error =
TRUE;
01201 }
01202
01203 done =
TRUE;
01204
01205
break;
01206
01207
case TOK_EOL:
01208
01209 token.pValue =
EmptyValue;
01210 token.Allocated =
FALSE;
01211 allocated =
FALSE;
01212
if(!
CmpAppendValue(pInf, token.pValue,
FALSE))
01213 {
01214 error =
TRUE;
01215 done =
TRUE;
01216 }
01217
else
01218 {
01219 state = 5;
01220 }
01221
01222
break;
01223
01224
case TOK_STRING:
01225
01226
if (!
CmpAppendValue(pInf, token.pValue,
FALSE))
01227 {
01228 error = done =
TRUE;
01229 }
01230
else
01231 {
01232 state = 9;
01233 }
01234
01235
break;
01236
01237
default:
01238
01239 error = done =
TRUE;
01240
01241
break;
01242 }
01243
01244
break;
01245
01246
01247
01248
01249
01250
01251
01252
case 9:
01253
01254
switch (token.Type)
01255 {
01256
case TOK_EOL:
01257
01258 state = 5;
01259
01260
break;
01261
01262
case TOK_EOF:
01263
01264 done =
TRUE;
01265
01266
break;
01267
01268
case TOK_COMMA:
01269
01270 state = 7;
01271
01272
break;
01273
01274
default:
01275
01276 error = done =
TRUE;
01277
01278
break;
01279 }
01280
01281
break;
01282
01283
01284
01285
01286
01287
01288
01289
case 10:
01290
01291
switch (token.Type)
01292 {
01293
case TOK_EOL:
01294
01295 state =5;
01296
01297
break;
01298
01299
case TOK_EOF:
01300
01301 done =
TRUE;
01302
01303
break;
01304
01305
case TOK_COMMA:
01306
01307 state = 7;
01308
01309
break;
01310
01311
default:
01312
01313 error = done =
TRUE;
01314
01315
break;
01316 }
01317
01318
break;
01319
01320
default:
01321
01322 error = done =
TRUE;
01323
01324
break;
01325
01326 }
01327
01328
01329
if (error)
01330 {
01331 *ErrorLine = infLine;
01332
if (pchSectionName != (PCHAR)
NULL && allocated)
01333 {
01334
ExFreePool(pchSectionName);
01335 }
01336
01337
if (pchValue != (PCHAR)
NULL && allocated)
01338 {
01339
ExFreePool(pchValue);
01340 }
01341
01342
ExFreePool(pInf);
01343
01344 pInf = (
PINF)
NULL;
01345 }
01346
else
01347 {
01348
01349
01350
01351
01352
if (token.Type ==
TOK_EOL)
01353 {
01354 infLine++;
01355 }
01356 }
01357
01358 }
01359
01360
if (pInf)
01361 {
01362 pInf->pSectionRecord =
NULL;
01363 }
01364
01365
return(pInf);
01366 }
01367
01368 PCHAR
01369 CmpProcessForSimpleStringSub(
01370 IN PINF pInf,
01371 IN PCHAR String
01372 )
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392 {
01393 ULONG len;
01394 PCHAR returnString;
01395
PSECTION pSection;
01396
PLINE pLine;
01397
01398
01399
01400
01401
01402 returnString =
String;
01403 len =
strlen(
String);
01404 pSection = pInf->StringsSection;
01405
01406
01407
01408
01409
01410
01411
01412
01413
if(
String[0] ==
'%' &&
01414 len > 2 &&
01415
String[len - 1] ==
'%' &&
01416 pSection)
01417 {
01418
01419
for(pLine = pSection->pLine; pLine; pLine = pLine->pNext)
01420 {
01421
if( pLine->pName &&
01422 _strnicmp(pLine->pName,
String + 1, len - 2) == 0 &&
01423 pLine->pName[len - 2] ==
'\0')
01424 {
01425
break;
01426 }
01427 }
01428
01429
if(pLine && pLine->pValue && pLine->pValue->pName)
01430 {
01431 returnString = pLine->pValue->pName;
01432 }
01433 }
01434
01435
return(returnString);
01436 }
01437
01438
VOID
01439 CmpFreeValueList(
01440 IN PVALUE pValue
01441 )
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459 {
01460
PVALUE pNext;
01461
01462
while (pValue)
01463 {
01464
01465
01466
01467
01468
01469 pNext = pValue->
pNext;
01470
01471
01472
01473
01474
01475
if (pValue->Allocated && pValue->pName)
01476 {
01477
ExFreePool((PVOID)pValue->pName);
01478 }
01479
01480
01481
01482
01483
01484
ExFreePool(pValue);
01485
01486
01487
01488
01489
01490 pValue = pNext;
01491 }
01492 }
01493
01494
VOID
01495 CmpFreeLineList(
01496 IN PLINE pLine
01497 )
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516 {
01517
PLINE pNext;
01518
01519
while (pLine)
01520 {
01521
01522
01523
01524
01525
01526 pNext = pLine->
pNext;
01527
01528
01529
01530
01531
01532
if (pLine->Allocated && pLine->pName)
01533 {
01534
ExFreePool((PVOID)pLine->pName);
01535 }
01536
01537
01538
01539
01540
01541
CmpFreeValueList(pLine->pValue);
01542
01543
01544
01545
01546
01547
ExFreePool((PVOID)pLine);
01548
01549
01550
01551
01552
01553 pLine = pNext;
01554 }
01555 }
01556
01557
VOID
01558 CmpFreeSectionList(
01559 IN PSECTION pSection
01560 )
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579 {
01580
PSECTION pNext;
01581
01582
while (pSection)
01583 {
01584
01585
01586
01587
01588
01589 pNext = pSection->
pNext;
01590
01591
01592
01593
01594
01595
if (pSection->Allocated && pSection->pName)
01596 {
01597
ExFreePool((PVOID)pSection->pName);
01598 }
01599
01600
01601
01602
01603
01604
CmpFreeLineList(pSection->pLine);
01605
01606
01607
01608
01609
01610
ExFreePool((PVOID)pSection);
01611
01612
01613
01614
01615
01616 pSection = pNext;
01617 }
01618
01619 }
01620
01621
PVALUE
01622 CmpSearchValueInLine(
01623 IN PLINE pLine,
01624 IN ULONG ValueIndex
01625 )
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645 {
01646 ULONG i;
01647
PVALUE pValue =
NULL;
01648
01649
if (pLine)
01650 {
01651
for ( i = 0, pValue = pLine->pValue;
01652 i < ValueIndex && pValue;
01653 i++, pValue = pValue->pNext);
01654 }
01655
01656
return (pValue);
01657 }
01658
01659
01660
PSECTION
01661 CmpSearchSectionByName(
01662 IN PINF pInf,
01663 IN PCHAR SectionName
01664 )
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684 {
01685
PSECTION pSection =
NULL;
01686
PSECTION pFirstSearchedSection;
01687
01688
01689
01690
01691
01692
if (pInf && SectionName)
01693 {
01694
01695
01696
01697
01698
01699
for ( pSection = pFirstSearchedSection = pInf->pSectionRecord;
01700 pSection && _stricmp(pSection->pName, SectionName);
01701 pSection = pSection->pNext);
01702
01703
01704
01705
01706
01707
if (pSection ==
NULL)
01708 {
01709
for ( pSection = pInf->pSection;
01710 pSection && pSection != pFirstSearchedSection;
01711 pSection = pSection->pNext)
01712 {
01713
if (pSection->pName && _stricmp(pSection->pName, SectionName) == 0)
01714 {
01715
break;
01716 }
01717 }
01718
01719
if (pSection == pFirstSearchedSection)
01720 {
01721 pSection =
NULL;
01722 }
01723 }
01724
01725
if (pSection)
01726 {
01727 pInf->pSectionRecord = pSection;
01728 }
01729 }
01730
01731
01732
01733
01734
01735
return (pSection);
01736 }
01737
01738
PLINE
01739 CmpSearchLineInSectionByIndex(
01740 IN PSECTION pSection,
01741 IN ULONG LineIndex
01742 )
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762 {
01763
PLINE pLine =
NULL;
01764 ULONG i;
01765
01766
01767
01768
01769
01770
if (pSection)
01771 {
01772
01773
01774
01775
01776
01777
for( i = 0, pLine = pSection->pLine;
01778 i < LineIndex && pLine;
01779 i++, pLine = pLine->pNext);
01780 }
01781
01782
01783
01784
01785
01786
return (pLine);
01787 }
01788
01789 PVOID
01790 CmpOpenInfFile(
01791 IN PVOID InfImage,
01792 IN ULONG ImageSize
01793 )
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813 {
01814
PINF infHandle;
01815 ULONG errorLine = 0;
01816
01817
01818
01819
01820
01821 infHandle =
CmpParseInfBuffer(InfImage, ImageSize, &errorLine);
01822
01823
if (infHandle ==
NULL)
01824 {
01825
DbgPrint(
"Error on line %d in CmpOpenInfFile!\n", errorLine);
01826 }
01827
01828
return (infHandle);
01829 }
01830
01831
VOID
01832 CmpCloseInfFile(
01833 PVOID InfHandle
01834 )
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853 {
01854
if (InfHandle)
01855 {
01856
CmpFreeSectionList(((
PINF)InfHandle)->pSection);
01857
ExFreePool(InfHandle);
01858 }
01859 }
01860
01861 BOOLEAN
01862 CmpSearchInfSection(
01863 IN PINF pInf,
01864 IN PCHAR Section
01865 )
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885 {
01886
return (
CmpSearchSectionByName(pInf, Section) !=
NULL);
01887 }
01888
01889 PCHAR
01890 CmpGetKeyName(
01891 IN PVOID InfHandle,
01892 IN PCHAR Section,
01893 IN ULONG LineIndex
01894 )
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916 {
01917
PSECTION pSection;
01918
PLINE pLine;
01919
01920
01921
01922
01923
01924 pSection =
CmpSearchSectionByName((
PINF)InfHandle, Section);
01925
if(pSection)
01926 {
01927
01928
01929
01930
01931 pLine =
CmpSearchLineInSectionByIndex(pSection, LineIndex);
01932
if(pLine)
01933 {
01934
return(pLine->pName);
01935 }
01936 }
01937
01938
return (
NULL);
01939 }
01940
01941 BOOLEAN
01942 CmpSearchInfLine(
01943 IN PVOID InfHandle,
01944 IN PCHAR Section,
01945 IN ULONG LineIndex
01946 )
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968 {
01969
PSECTION pSection;
01970
PLINE pLine =
NULL;
01971
01972
01973
01974
01975
01976 pSection =
CmpSearchSectionByName((
PINF)InfHandle, Section);
01977
if(pSection)
01978 {
01979
01980
01981
01982
01983 pLine =
CmpSearchLineInSectionByIndex(pSection, LineIndex);
01984 }
01985
01986
return (pLine !=
NULL);
01987 }
01988
01989
01990 PCHAR
01991 CmpGetSectionLineIndex (
01992 IN PVOID InfHandle,
01993 IN PCHAR Section,
01994 IN ULONG LineIndex,
01995 IN ULONG ValueIndex
01996 )
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020 {
02021
PSECTION pSection;
02022
PLINE pLine;
02023
PVALUE pValue;
02024
02025
02026
02027
02028
02029 pSection =
CmpSearchSectionByName((
PINF)InfHandle, Section);
02030
if(pSection)
02031 {
02032
02033
02034
02035
02036 pLine =
CmpSearchLineInSectionByIndex(pSection, LineIndex);
02037
if(pLine)
02038 {
02039
02040
02041
02042
02043 pValue =
CmpSearchValueInLine(pLine, ValueIndex);
02044
if(pValue)
02045 {
02046
02047
02048
02049
02050
02051
return(
CmpProcessForSimpleStringSub(InfHandle, pValue->pName));
02052 }
02053 }
02054 }
02055
02056
return(
NULL);
02057 }
02058
02059 ULONG
02060 CmpGetSectionLineIndexValueCount(
02061 IN PVOID InfHandle,
02062 IN PCHAR Section,
02063 IN ULONG LineIndex
02064 )
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086 {
02087
PSECTION pSection;
02088
PLINE pLine;
02089
PVALUE pValue;
02090 ULONG count = 0;
02091
02092
02093
02094
02095
02096 pSection =
CmpSearchSectionByName((
PINF)InfHandle, Section);
02097
if(pSection)
02098 {
02099
02100
02101
02102
02103 pLine =
CmpSearchLineInSectionByIndex(pSection, LineIndex);
02104
if (pLine)
02105 {
02106
02107
02108
02109
02110
for( pValue = pLine->pValue;
02111 pValue;
02112 pValue = pValue->pNext, count++);
02113 }
02114 }
02115
02116
return (count);
02117 }
02118
02119 BOOLEAN
02120 CmpGetIntField(
02121 IN PVOID InfHandle,
02122 IN PCHAR Section,
02123 IN ULONG LineIndex,
02124 IN ULONG ValueIndex,
02125 IN OUT PULONG Data
02126 )
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152 {
02153 PCHAR valueStr;
02154
02155
02156
02157
02158
02159 valueStr =
CmpGetSectionLineIndex( InfHandle,
02160 Section,
02161 LineIndex,
02162 ValueIndex);
02163
02164
02165
02166
02167
if (valueStr && *valueStr)
02168 {
02169 *Data = strtoul(valueStr,
NULL, 16);
02170
return (
TRUE);
02171 }
02172
02173
return (
FALSE);
02174 }
02175
02176 BOOLEAN
02177 CmpGetBinaryField(
02178 IN PVOID InfHandle,
02179 IN PCHAR Section,
02180 IN ULONG LineIndex,
02181 IN ULONG ValueIndex,
02182 IN OUT PVOID Buffer,
02183 IN ULONG BufferSize,
02184 IN OUT PULONG ActualSize
02185 )
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215 {
02216 BOOLEAN result =
FALSE;
02217 ULONG requiredSize;
02218
PSECTION pSection;
02219
PLINE pLine;
02220
PVALUE pValue;
02221 ULONG count;
02222 PCHAR valueStr;
02223
02224
02225
02226
02227
02228 requiredSize = (
CmpGetSectionLineIndexValueCount( InfHandle,
02229 Section,
02230 LineIndex) - ValueIndex) *
sizeof(UCHAR);
02231
02232
02233
02234
02235
if (
Buffer &&
BufferSize >= requiredSize)
02236 {
02237
02238
02239
02240
02241 pSection =
CmpSearchSectionByName((
PINF)InfHandle, Section);
02242
if(pSection)
02243 {
02244
02245
02246
02247
02248 pLine =
CmpSearchLineInSectionByIndex(pSection, LineIndex);
02249
if (pLine)
02250 {
02251
02252
02253
02254
02255
for( pValue = pLine->pValue, count = 0;
02256 pValue && count < ValueIndex;
02257 pValue = pValue->pNext, count++);
02258
02259
02260
02261
02262
02263
for ( ;
02264 pValue;
02265 pValue = pValue->pNext)
02266 {
02267 valueStr =
CmpGetSectionLineIndex( InfHandle,
02268 Section,
02269 LineIndex,
02270 ValueIndex++);
02271
if (valueStr ==
NULL)
02272 {
02273
break;
02274 }
02275 *((PUCHAR)
Buffer)++ = (UCHAR)strtoul(valueStr,
NULL, 16);
02276 }
02277
if (valueStr)
02278 {
02279 result =
TRUE;
02280 }
02281 }
02282 }
02283 }
02284
02285
02286
02287
02288
02289
if (ActualSize)
02290 {
02291 *ActualSize = requiredSize;
02292 result =
TRUE;
02293 }
02294
02295
return (result);
02296 }