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
00029
00030
#include "cmp.h"
00031
#include "stdlib.h"
00032
#include "parseini.h"
00033
#include "geninst.h"
00034
00035
typedef
00036 BOOLEAN
00037 (* PFN_INFRULE)(
00038 IN PVOID InfHandle,
00039 IN PCHAR Section,
00040 IN PVOID
RefData
00041 );
00042
00043
typedef
00044 BOOLEAN
00045 (* PFN_REGLINE)(
00046 IN PVOID InfHandle,
00047 IN PCHAR Section,
00048 IN ULONG LineIndex
00049 );
00050
00051 BOOLEAN
00052
CmpProcessReg(
00053 IN PVOID InfHandle,
00054 IN PCHAR Section,
00055 IN PVOID RefData
00056 );
00057
00058
NTSTATUS
00059
CmpProcessAddRegLine(
00060 IN PVOID InfHandle,
00061 IN PCHAR Section,
00062 IN ULONG LineIndex
00063 );
00064
00065
NTSTATUS
00066
CmpProcessDelRegLine(
00067 IN PVOID InfHandle,
00068 IN PCHAR Section,
00069 IN ULONG LineIndex
00070 );
00071
00072
NTSTATUS
00073
CmpProcessBitRegLine(
00074 IN PVOID InfHandle,
00075 IN PCHAR Section,
00076 IN ULONG LineIndex
00077 );
00078
00079
NTSTATUS
00080
CmpGetAddRegInfData(
00081 IN PVOID InfHandle,
00082 IN PCHAR Section,
00083 IN ULONG LineIndex,
00084 IN ULONG ValueIndex,
00085 IN ULONG ValueType,
00086 OUT PVOID *Data,
00087 OUT PULONG DataSize
00088 );
00089
00090
NTSTATUS
00091
CmpOpenRegKey(
00092 IN OUT PHANDLE Key,
00093 IN OUT PULONG Disposition,
00094 IN PCHAR Root,
00095 IN PCHAR SubKey,
00096 IN ULONG DesiredAccess,
00097 IN BOOLEAN Create
00098 );
00099
00100
NTSTATUS
00101
CmpAppendStringToMultiSz(
00102 IN HANDLE Key,
00103 IN PCHAR ValueName,
00104 IN OUT PVOID *Data,
00105 IN OUT PULONG DataSize
00106 );
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 #define FLG_ADDREG_BINVALUETYPE ( 0x00000001 )
00123 #define FLG_ADDREG_NOCLOBBER ( 0x00000002 )
00124 #define FLG_ADDREG_DELVAL ( 0x00000004 )
00125 #define FLG_ADDREG_APPEND ( 0x00000008 ) // Currently supported only
00126
00127 #define FLG_ADDREG_KEYONLY ( 0x00000010 ) // Just create the key, ignore value
00128 #define FLG_ADDREG_OVERWRITEONLY ( 0x00000020 ) // Set only if value already exists
00129
00130 #define FLG_ADDREG_TYPE_MASK ( 0xFFFF0000 | FLG_ADDREG_BINVALUETYPE )
00131 #define FLG_ADDREG_TYPE_SZ ( 0x00000000 )
00132 #define FLG_ADDREG_TYPE_MULTI_SZ ( 0x00010000 )
00133 #define FLG_ADDREG_TYPE_EXPAND_SZ ( 0x00020000 )
00134 #define FLG_ADDREG_TYPE_BINARY ( 0x00000000 | FLG_ADDREG_BINVALUETYPE )
00135 #define FLG_ADDREG_TYPE_DWORD ( 0x00010000 | FLG_ADDREG_BINVALUETYPE )
00136 #define FLG_ADDREG_TYPE_NONE ( 0x00020000 | FLG_ADDREG_BINVALUETYPE )
00137
00138 #define FLG_BITREG_CLEAR ( 0x00000000 )
00139 #define FLG_BITREG_SET ( 0x00000001 )
00140 #define FLG_BITREG_TYPE_BINARY ( 0x00000000 )
00141 #define FLG_BITREG_TYPE_DWORD ( 0x00000002 )
00142
00143
00144
00145
00146
00147 #define NUM_OF_INF_RULES 3
00148
00149
00150
00151
00152
00153
struct {
00154 PCHAR
Name;
00155 PFN_INFRULE Action;
00156 PVOID
RefData;
00157 }
gInfRuleTable[
NUM_OF_INF_RULES] =
00158 {
00159 {
"AddReg",
CmpProcessReg,
CmpProcessAddRegLine},
00160 {
"DelReg",
CmpProcessReg,
CmpProcessDelRegLine},
00161 {
"BitReg",
CmpProcessReg,
CmpProcessBitRegLine}
00162 };
00163
00164
#ifdef ALLOC_PRAGMA
00165
#pragma alloc_text(INIT,CmpAppendStringToMultiSz)
00166
#pragma alloc_text(INIT,CmpOpenRegKey)
00167
#pragma alloc_text(INIT,CmpGetAddRegInfData)
00168
#pragma alloc_text(INIT,CmpProcessReg)
00169
#pragma alloc_text(INIT,CmpProcessAddRegLine)
00170
#pragma alloc_text(INIT,CmpProcessDelRegLine)
00171
#pragma alloc_text(INIT,CmpProcessBitRegLine)
00172
#pragma alloc_text(INIT,CmpGenInstall)
00173
#endif
00174
00175 BOOLEAN
00176 CmpGenInstall(
00177 IN PVOID InfHandle,
00178 IN PCHAR Section
00179 )
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 {
00200 ULONG ruleNumber;
00201 ULONG i;
00202 PCHAR ruleName;
00203 PCHAR regSection;
00204 BOOLEAN result =
FALSE;
00205
00206
if (
CmpSearchInfSection(InfHandle, Section))
00207 {
00208
00209
00210
00211
00212
00213
for ( ruleNumber = 0;
00214 ruleName =
CmpGetKeyName(InfHandle, Section, ruleNumber);
00215 ruleNumber++)
00216 {
00217
00218
00219
00220
00221
00222
for ( i = 0;
00223 i <
NUM_OF_INF_RULES &&
00224 _stricmp(ruleName,
gInfRuleTable[i].
Name);
00225 i++);
00226
00227
if ( i >=
NUM_OF_INF_RULES ||
00228 (regSection =
CmpGetSectionLineIndex( InfHandle,
00229 Section,
00230 ruleNumber,
00231 0)) ==
NULL ||
00232 !
CmpSearchInfSection(InfHandle, Section))
00233 {
00234 result =
FALSE;
00235
break;
00236 }
00237
00238
if (!(*
gInfRuleTable[i].Action)(InfHandle, regSection,
gInfRuleTable[i].RefData))
00239 {
00240 result =
FALSE;
00241 }
00242 }
00243
00244
00245
00246
00247
00248
if (ruleNumber)
00249 {
00250 result =
TRUE;
00251 }
00252 }
00253
00254
return (result);
00255 }
00256
00257 BOOLEAN
00258 CmpProcessReg(
00259 IN PVOID InfHandle,
00260 IN PCHAR Section,
00261 IN PVOID RefData
00262 )
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 {
00283 ULONG lineIndex;
00284
NTSTATUS status = STATUS_SUCCESS;
00285
NTSTATUS temp;
00286
00287
00288
00289
00290
00291
for ( lineIndex = 0;
00292
CmpSearchInfLine(InfHandle, Section, lineIndex);
00293 lineIndex++)
00294 {
00295 temp = (*(
PFN_REGLINE)
RefData)(InfHandle, Section, lineIndex);
00296
if (!
NT_SUCCESS(temp))
00297 {
00298 status = temp;
00299 }
00300 }
00301
00302
if (
NT_SUCCESS(status))
00303 {
00304
return (
TRUE);
00305 }
00306
00307
return (
FALSE);
00308 }
00309
00310
NTSTATUS
00311 CmpProcessAddRegLine(
00312 IN PVOID InfHandle,
00313 IN PCHAR Section,
00314 IN ULONG LineIndex
00315 )
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 {
00338
NTSTATUS status = STATUS_UNSUCCESSFUL;
00339 PCHAR rootKeyName;
00340 PCHAR subKeyName;
00341 PCHAR valueName;
00342 ULONG flags;
00343 ULONG valueType;
00344 PCHAR buffer;
00345 HANDLE key;
00346 ULONG disposition;
00347 BOOLEAN dontSet;
00348 PVOID data = 0;
00349 ULONG dataSize = 0;
00350 ANSI_STRING ansiString;
00351 UNICODE_STRING unicodeString;
00352 OBJECT_ATTRIBUTES objectAttributes;
00353
00354
00355
00356
00357
00358 rootKeyName =
CmpGetSectionLineIndex( InfHandle,
00359 Section,
00360 LineIndex,
00361 0);
00362
if (rootKeyName)
00363 {
00364
00365
00366
00367
00368 subKeyName =
CmpGetSectionLineIndex( InfHandle,
00369 Section,
00370 LineIndex,
00371 1);
00372
00373
00374
00375
00376
00377 valueName =
CmpGetSectionLineIndex( InfHandle,
00378 Section,
00379 LineIndex,
00380 2);
00381
00382
00383
00384
00385
00386 valueType = REG_SZ;
00387
00388
00389
00390
00391
00392
if (!
CmpGetIntField( InfHandle,
00393 Section,
00394 LineIndex,
00395 3,
00396 &flags))
00397 {
00398 flags = 0;
00399 }
00400
00401
00402
00403
00404
00405
switch(flags &
FLG_ADDREG_TYPE_MASK)
00406 {
00407
00408
case FLG_ADDREG_TYPE_SZ:
00409
00410 valueType = REG_SZ;
00411
break;
00412
00413
case FLG_ADDREG_TYPE_MULTI_SZ:
00414
00415 valueType = REG_MULTI_SZ;
00416
break;
00417
00418
case FLG_ADDREG_TYPE_EXPAND_SZ:
00419
00420 valueType = REG_EXPAND_SZ;
00421
break;
00422
00423
case FLG_ADDREG_TYPE_BINARY:
00424
00425 valueType = REG_BINARY;
00426
break;
00427
00428
case FLG_ADDREG_TYPE_DWORD:
00429
00430 valueType = REG_DWORD;
00431
break;
00432
00433
case FLG_ADDREG_TYPE_NONE:
00434
00435 valueType = REG_NONE;
00436
break;
00437
00438
default :
00439
00440
00441
00442
00443
00444
00445
if(flags &
FLG_ADDREG_BINVALUETYPE)
00446 {
00447
00448
00449
00450
00451
00452
00453 valueType = HIGHWORD(flags);
00454
00455
if(valueType < REG_BINARY || valueType == REG_MULTI_SZ)
00456 {
00457
return (STATUS_INVALID_PARAMETER);
00458 }
00459
00460 }
00461
else
00462 {
00463
return (STATUS_INVALID_PARAMETER);
00464 }
00465
break;
00466 }
00467
00468
00469
00470
00471
00472
00473
if((flags &
FLG_ADDREG_APPEND) && valueType != REG_MULTI_SZ)
00474 {
00475
return (STATUS_INVALID_PARAMETER);
00476 }
00477
00478
00479
00480
00481
00482
if( (!valueName || *valueName ==
'\0') && valueType == REG_EXPAND_SZ)
00483 {
00484 valueType = REG_SZ;
00485 }
00486
00487 status =
CmpGetAddRegInfData( InfHandle,
00488 Section,
00489 LineIndex,
00490 4,
00491 valueType,
00492 &data,
00493 &dataSize);
00494
00495
if (
NT_SUCCESS(status))
00496 {
00497
00498
00499
00500
00501 status =
CmpOpenRegKey( &key,
00502 &disposition,
00503 rootKeyName,
00504 subKeyName,
00505 KEY_QUERY_VALUE | KEY_SET_VALUE,
00506 (BOOLEAN)!(flags &
FLG_ADDREG_OVERWRITEONLY));
00507
00508
00509
00510
00511
00512 dontSet =
FALSE;
00513
if (
NT_SUCCESS(status))
00514 {
00515
if (flags &
FLG_ADDREG_APPEND)
00516 {
00517 status =
CmpAppendStringToMultiSz( key,
00518 valueName,
00519 &data,
00520 &dataSize);
00521 }
00522
if (
NT_SUCCESS(status))
00523 {
00524
00525
00526
00527
00528
if (disposition == REG_OPENED_EXISTING_KEY)
00529 {
00530
if ( (flags &
FLG_ADDREG_NOCLOBBER) &&
00531 (valueName ==
NULL || *valueName ==
'\0'))
00532 {
00533
RtlInitAnsiString(&ansiString,
"");
00534 status =
RtlAnsiStringToUnicodeString(&unicodeString, &ansiString,
TRUE);
00535
if (
NT_SUCCESS(status))
00536 {
00537
00538 status =
NtQueryValueKey( key,
00539 &unicodeString,
00540 KeyValueBasicInformation,
00541
NULL,
00542 0,
00543 &disposition);
00544
if (
NT_SUCCESS(status) || status == STATUS_BUFFER_TOO_SMALL)
00545 {
00546 flags &= ~
FLG_ADDREG_NOCLOBBER;
00547 }
00548 status = STATUS_SUCCESS;
00549
00550
RtlFreeUnicodeString(&unicodeString);
00551 }
00552 }
00553
00554
if (flags &
FLG_ADDREG_DELVAL)
00555 {
00556
00557
00558
00559
00560 dontSet =
TRUE;
00561
if (valueName)
00562 {
00563
00564
00565
00566
00567
RtlInitAnsiString(&ansiString, valueName);
00568 status =
RtlAnsiStringToUnicodeString(&unicodeString, &ansiString,
TRUE);
00569
if (
NT_SUCCESS(status))
00570 {
00571 status =
NtDeleteValueKey(key, &unicodeString);
00572
RtlFreeUnicodeString(&unicodeString);
00573 }
00574 }
00575 }
00576 }
00577
else
00578 {
00579 flags &= ~
FLG_ADDREG_NOCLOBBER;
00580 }
00581
00582
if (!dontSet)
00583 {
00584
00585
00586
00587
00588
if (!(flags &
FLG_ADDREG_KEYONLY))
00589 {
00590
00591
00592
00593
00594
00595
RtlInitAnsiString(&ansiString, valueName);
00596 status =
RtlAnsiStringToUnicodeString(&unicodeString, &ansiString,
TRUE);
00597
if (
NT_SUCCESS(status))
00598 {
00599
NTSTATUS existStatus;
00600
00601
if (flags &
FLG_ADDREG_NOCLOBBER)
00602 {
00603 existStatus =
NtQueryValueKey( key,
00604 &unicodeString,
00605 KeyValueBasicInformation,
00606
NULL,
00607 0,
00608 &disposition);
00609
if (
NT_SUCCESS(existStatus) || existStatus == STATUS_BUFFER_TOO_SMALL) {
00610 dontSet =
TRUE;
00611 }
00612 }
00613
else
00614 {
00615
if (flags &
FLG_ADDREG_OVERWRITEONLY)
00616 {
00617 existStatus =
NtQueryValueKey( key,
00618 &unicodeString,
00619 KeyValueBasicInformation,
00620
NULL,
00621 0,
00622 &disposition);
00623
if (!
NT_SUCCESS(existStatus) && existStatus != STATUS_BUFFER_TOO_SMALL) {
00624 dontSet =
TRUE;
00625 }
00626 }
00627 }
00628
00629
if (!dontSet)
00630 {
00631 status =
NtSetValueKey( key,
00632 &unicodeString,
00633 0,
00634 valueType,
00635 data,
00636 dataSize);
00637 }
00638
00639
RtlFreeUnicodeString(&unicodeString);
00640 }
00641 }
00642 }
00643 }
00644
00645
NtClose(key);
00646 }
00647
else if (flags &
FLG_ADDREG_OVERWRITEONLY)
00648 {
00649 status = STATUS_SUCCESS;
00650 }
00651 }
00652 }
00653
00654
return (status);
00655 }
00656
00657
NTSTATUS
00658 CmpProcessDelRegLine(
00659 IN PVOID InfHandle,
00660 IN PCHAR Section,
00661 IN ULONG LineIndex
00662 )
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 {
00685
NTSTATUS status = STATUS_UNSUCCESSFUL;
00686 PCHAR rootKeyName;
00687 PCHAR subKeyName;
00688 PCHAR valueName;
00689 HANDLE key;
00690 ULONG disposition;
00691 ANSI_STRING ansiString;
00692 UNICODE_STRING unicodeString;
00693
00694
00695
00696
00697
00698 rootKeyName =
CmpGetSectionLineIndex( InfHandle,
00699 Section,
00700 LineIndex,
00701 0);
00702
00703 subKeyName =
CmpGetSectionLineIndex( InfHandle,
00704 Section,
00705 LineIndex,
00706 1);
00707
00708
if (rootKeyName && subKeyName)
00709 {
00710
00711
00712
00713
00714 valueName =
CmpGetSectionLineIndex( InfHandle,
00715 Section,
00716 LineIndex,
00717 2);
00718
00719
00720
00721
00722
00723 status =
CmpOpenRegKey( &key,
00724 &disposition,
00725 rootKeyName,
00726 subKeyName,
00727 KEY_ALL_ACCESS,
00728
FALSE);
00729
00730
00731
00732
00733
00734
if (
NT_SUCCESS(status))
00735 {
00736
00737
00738
00739
00740
00741
if (valueName)
00742 {
00743
00744
00745
00746
00747
RtlInitAnsiString(&ansiString, valueName);
00748 status =
RtlAnsiStringToUnicodeString(&unicodeString, &ansiString,
TRUE);
00749
if (
NT_SUCCESS(status))
00750 {
00751 status =
NtDeleteValueKey(key, &unicodeString);
00752
RtlFreeUnicodeString(&unicodeString);
00753 }
00754 }
00755
else
00756 {
00757
00758
00759
00760
00761 status =
NtDeleteKey(key);
00762 }
00763
00764
00765
00766
00767
00768
NtClose(key);
00769 }
00770 }
00771
00772
return (status);
00773 }
00774
00775
NTSTATUS
00776 CmpProcessBitRegLine(
00777 IN PVOID InfHandle,
00778 IN PCHAR Section,
00779 IN ULONG LineIndex
00780 )
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802 {
00803
NTSTATUS status = STATUS_UNSUCCESSFUL;
00804 PCHAR rootKeyName;
00805 PCHAR subKeyName;
00806 PCHAR valueName;
00807 ULONG flags;
00808 ULONG mask;
00809 ULONG field;
00810 HANDLE key;
00811 ULONG disposition;
00812 ANSI_STRING ansiString;
00813 UNICODE_STRING unicodeString;
00814 PCHAR buffer;
00815 ULONG size;
00816 PKEY_VALUE_FULL_INFORMATION valueInfo;
00817
00818
00819
00820
00821
00822 rootKeyName =
CmpGetSectionLineIndex( InfHandle,
00823 Section,
00824 LineIndex,
00825 0);
00826
if (rootKeyName)
00827 {
00828
00829
00830
00831
00832 subKeyName =
CmpGetSectionLineIndex( InfHandle,
00833 Section,
00834 LineIndex,
00835 1);
00836
00837
00838
00839
00840
00841 valueName =
CmpGetSectionLineIndex( InfHandle,
00842 Section,
00843 LineIndex,
00844 2);
00845
if (valueName && *valueName)
00846 {
00847
00848
00849
00850
00851
if (!
CmpGetIntField( InfHandle,
00852 Section,
00853 LineIndex,
00854 3,
00855 &flags))
00856 {
00857 flags = 0;
00858 }
00859
00860
if (!
CmpGetIntField( InfHandle,
00861 Section,
00862 LineIndex,
00863 4,
00864 &mask))
00865 {
00866 mask = 0;
00867 }
00868
00869
if (!(flags &
FLG_BITREG_TYPE_DWORD))
00870 {
00871
if (!
CmpGetIntField( InfHandle,
00872 Section,
00873 LineIndex,
00874 5,
00875 &field))
00876 {
00877
return (status);
00878 }
00879 }
00880
00881
00882
00883
00884
00885 status =
CmpOpenRegKey( &key,
00886 &disposition,
00887 rootKeyName,
00888 subKeyName,
00889 KEY_ALL_ACCESS,
00890
FALSE);
00891
if (
NT_SUCCESS(status))
00892 {
00893
00894
00895
00896
00897
RtlInitAnsiString(&ansiString, valueName);
00898 status =
RtlAnsiStringToUnicodeString(&unicodeString, &ansiString,
TRUE);
00899
if (
NT_SUCCESS(status))
00900 {
00901 size = 0;
00902 status =
NtQueryValueKey( key,
00903 &unicodeString,
00904 KeyValueFullInformation,
00905
NULL,
00906 0,
00907 &size);
00908
if (size)
00909 {
00910 status = STATUS_NO_MEMORY;
00911 buffer =
ExAllocatePoolWithTag(
PagedPool, size, CM_GENINST_TAG);
00912
if (buffer)
00913 {
00914 status =
NtQueryValueKey( key,
00915 &unicodeString,
00916 KeyValueFullInformation,
00917 buffer,
00918 size,
00919 &size);
00920
if (
NT_SUCCESS(status))
00921 {
00922 valueInfo = (PKEY_VALUE_FULL_INFORMATION)buffer;
00923
if (flags &
FLG_BITREG_TYPE_DWORD)
00924 {
00925
if (valueInfo->Type == REG_DWORD && valueInfo->DataLength ==
sizeof(ULONG))
00926 {
00927
if (flags &
FLG_BITREG_SET)
00928 {
00929 *(PULONG)(buffer + valueInfo->DataOffset) |= mask;
00930 }
00931
else
00932 {
00933 *(PULONG)(buffer + valueInfo->DataOffset) &= ~mask;
00934 }
00935 }
00936 }
00937
else
00938 {
00939
if (valueInfo->Type == REG_BINARY && field < valueInfo->DataLength)
00940 {
00941
if (flags &
FLG_BITREG_SET)
00942 {
00943 *(PUCHAR)(buffer + valueInfo->DataOffset + field) |= mask;
00944 }
00945
else
00946 {
00947 *(PUCHAR)(buffer + valueInfo->DataOffset + field) &= ~mask;
00948 }
00949 }
00950 }
00951 status =
NtSetValueKey( key,
00952 &unicodeString,
00953 0,
00954 valueInfo->Type,
00955 buffer + valueInfo->DataOffset,
00956 valueInfo->DataLength);
00957 }
00958
else
00959 {
00960
DbgPrint(
"Value cannot be read for BitReg in %s line %d\n", Section, LineIndex);
00961
ASSERT(
NT_SUCCESS(status));
00962 }
00963
ExFreePool(buffer);
00964 }
00965
else
00966 {
00967
ASSERT(buffer);
00968 status = STATUS_NO_MEMORY;
00969 }
00970 }
00971
00972
RtlFreeUnicodeString(&unicodeString);
00973 }
00974
00975
00976
00977
00978
NtClose(key);
00979 }
00980 }
00981 }
00982
00983
return (status);
00984 }
00985
00986
NTSTATUS
00987 CmpGetAddRegInfData(
00988 IN PVOID InfHandle,
00989 IN PCHAR Section,
00990 IN ULONG LineIndex,
00991 IN ULONG ValueIndex,
00992 IN ULONG ValueType,
00993 OUT PVOID *Data,
00994 OUT PULONG DataSize
00995 )
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025 {
01026
NTSTATUS status = STATUS_UNSUCCESSFUL;
01027 PCHAR str;
01028 ULONG count;
01029 ULONG i;
01030 ANSI_STRING ansiString;
01031 UNICODE_STRING unicodeString;
01032
01033
01034
01035
01036
01037
ASSERT(Data);
01038
ASSERT(DataSize);
01039
01040
switch (ValueType)
01041 {
01042
case REG_DWORD:
01043
01044 *DataSize =
sizeof(ULONG);
01045 *Data =
ExAllocatePoolWithTag(
PagedPool, *DataSize, CM_GENINST_TAG);
01046
if (*Data)
01047 {
01048
01049
01050
01051
01052
if (
CmpGetSectionLineIndexValueCount( InfHandle,
01053 Section,
01054 LineIndex) == 8)
01055 {
01056
if (!
CmpGetBinaryField( InfHandle,
01057 Section,
01058 LineIndex,
01059 ValueIndex,
01060 *Data,
01061 *DataSize,
01062
NULL))
01063 {
01064 *((PULONG)*Data) = 0;
01065 }
01066
01067 status = STATUS_SUCCESS;
01068 }
01069
else
01070 {
01071
01072
01073
01074
01075
if (!
CmpGetIntField( InfHandle,
01076 Section,
01077 LineIndex,
01078 4,
01079 *Data))
01080 {
01081 *((PULONG)*Data) = 0;
01082 }
01083
01084 status = STATUS_SUCCESS;
01085 }
01086 }
01087
else
01088 {
01089
ASSERT(*Data);
01090 status = STATUS_NO_MEMORY;
01091 }
01092
01093
break;
01094
01095
case REG_SZ:
01096
case REG_EXPAND_SZ:
01097
01098
01099
01100
01101
01102
01103 str =
CmpGetSectionLineIndex( InfHandle,
01104 Section,
01105 LineIndex,
01106 ValueIndex);
01107
if (str)
01108 {
01109
RtlInitAnsiString(&ansiString, str);
01110 *DataSize = (ansiString.Length << 1) +
sizeof(UNICODE_NULL);
01111 unicodeString.MaximumLength = (
USHORT)*DataSize;
01112 unicodeString.Buffer =
ExAllocatePoolWithTag(
PagedPool, *DataSize, CM_GENINST_TAG);
01113 *Data =
NULL;
01114
if (unicodeString.Buffer)
01115 {
01116 status =
RtlAnsiStringToUnicodeString(&unicodeString, &ansiString,
FALSE);
01117
if (
NT_SUCCESS(status))
01118 {
01119 *Data = unicodeString.Buffer;
01120 status = STATUS_SUCCESS;
01121 }
01122 }
01123
else
01124 {
01125
ASSERT(unicodeString.Buffer);
01126 status = STATUS_NO_MEMORY;
01127 }
01128 }
01129
else
01130 {
01131
ASSERT(str);
01132 status = STATUS_NO_MEMORY;
01133 }
01134
01135
break;
01136
01137
case REG_MULTI_SZ:
01138
01139 *DataSize = 0;
01140 *Data =
NULL;
01141
01142
01143
01144
01145
01146 count =
CmpGetSectionLineIndexValueCount( InfHandle,
01147 Section,
01148 LineIndex);
01149
if (count > ValueIndex)
01150 {
01151 count -= ValueIndex;
01152
for (i = 0; i < count; i++)
01153 {
01154 str =
CmpGetSectionLineIndex( InfHandle,
01155 Section,
01156 LineIndex,
01157 ValueIndex + i);
01158
if (str ==
NULL)
01159 {
01160
break;
01161 }
01162
01163 *DataSize += ((
strlen(str) *
sizeof(WCHAR)) +
sizeof(UNICODE_NULL));
01164 }
01165
01166
if (i == count)
01167 {
01168
01169
01170
01171
01172 *DataSize +=
sizeof(UNICODE_NULL);
01173 *Data =
ExAllocatePoolWithTag(
PagedPool, *DataSize, CM_GENINST_TAG);
01174
if (*Data)
01175 {
01176
for ( i = 0, unicodeString.Buffer = *Data;
01177 i < count;
01178 i++, (PCHAR)unicodeString.Buffer += unicodeString.MaximumLength)
01179 {
01180 str =
CmpGetSectionLineIndex( InfHandle,
01181 Section,
01182 LineIndex,
01183 ValueIndex + i);
01184
if (str ==
NULL)
01185 {
01186
break;
01187 }
01188
RtlInitAnsiString(&ansiString, str);
01189 unicodeString.MaximumLength = (ansiString.Length *
sizeof(WCHAR)) +
sizeof(UNICODE_NULL);
01190 status =
RtlAnsiStringToUnicodeString(&unicodeString, &ansiString,
FALSE);
01191
if (!
NT_SUCCESS(status))
01192 {
01193
break;
01194 }
01195 }
01196
01197
01198
01199
01200
01201
if (i == count)
01202 {
01203 unicodeString.Buffer[0] = UNICODE_NULL;
01204 status = STATUS_SUCCESS;
01205 }
01206 }
01207
else
01208 {
01209
ASSERT(*Data);
01210 status = STATUS_NO_MEMORY;
01211 }
01212 }
01213 }
01214
01215
break;
01216
01217
case REG_BINARY:
01218
default:
01219
01220
01221
01222
01223
01224
if (
CmpGetBinaryField( InfHandle,
01225 Section,
01226 LineIndex,
01227 ValueIndex,
01228
NULL,
01229 0,
01230 DataSize) && *DataSize)
01231 {
01232 *Data =
ExAllocatePoolWithTag(
PagedPool, *DataSize, CM_GENINST_TAG);
01233
if (*Data)
01234 {
01235
if (
CmpGetBinaryField( InfHandle,
01236 Section,
01237 LineIndex,
01238 4,
01239 *Data,
01240 *DataSize,
01241
NULL))
01242 {
01243 status = STATUS_SUCCESS;
01244 }
01245 }
01246
else
01247 {
01248
ASSERT(*Data);
01249 status = STATUS_NO_MEMORY;
01250 }
01251 }
01252
else
01253 {
01254 status = STATUS_UNSUCCESSFUL;
01255 }
01256
01257
break;
01258 }
01259
01260
return (status);
01261 }
01262
01263
NTSTATUS
01264 CmpOpenRegKey(
01265 IN OUT PHANDLE Key,
01266 IN OUT PULONG Disposition,
01267 IN PCHAR Root,
01268 IN PCHAR SubKey,
01269 IN ULONG DesiredAccess,
01270 IN BOOLEAN Create
01271 )
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299 {
01300
NTSTATUS status = STATUS_OBJECT_NAME_INVALID;
01301 ULONG size;
01302 PCHAR str;
01303 ANSI_STRING ansiString;
01304 UNICODE_STRING unicodeString;
01305 OBJECT_ATTRIBUTES objectAttributes;
01306
01307 str =
NULL;
01308 size =
strlen(SubKey) + 1;
01309
01310
01311
01312
01313
01314
if (_stricmp(Root,
"HKLM") == 0)
01315 {
01316 size +=
strlen(
"\\Registry\\Machine\\");
01317 str =
ExAllocatePoolWithTag(
PagedPool, size, CM_GENINST_TAG);
01318
if (str)
01319 {
01320 strcpy(str,
"\\Registry\\Machine\\");
01321 strcat(str, SubKey);
01322 }
01323
else
01324 {
01325
ASSERT(str);
01326 status = STATUS_NO_MEMORY;
01327 }
01328 }
01329
else
01330 {
01331
ASSERT(_stricmp(Root,
"HKLM") == 0);
01332 }
01333
01334
01335
01336
01337
01338
if (str)
01339 {
01340
RtlInitAnsiString(&ansiString, str);
01341 status =
RtlAnsiStringToUnicodeString(&unicodeString, &ansiString,
TRUE);
01342
if (
NT_SUCCESS(status))
01343 {
01344 InitializeObjectAttributes( &objectAttributes,
01345 &unicodeString,
01346 OBJ_CASE_INSENSITIVE,
01347
NULL,
01348
NULL);
01349
if (
Create)
01350 {
01351
01352
01353
01354
01355 status =
NtCreateKey(
Key,
01356 DesiredAccess,
01357 &objectAttributes,
01358 0,
01359
NULL,
01360 REG_OPTION_NON_VOLATILE,
01361 Disposition ? Disposition : &size);
01362 }
01363
else
01364 {
01365
01366
01367
01368
01369
if (Disposition)
01370 {
01371 *Disposition = REG_OPENED_EXISTING_KEY;
01372 }
01373 status =
NtOpenKey(
Key,
01374 DesiredAccess,
01375 &objectAttributes);
01376 }
01377
01378
RtlFreeUnicodeString(&unicodeString);
01379 }
01380
else
01381 {
01382
ASSERT(
NT_SUCCESS(status));
01383 }
01384
01385
ExFreePool(str);
01386 }
01387
01388
return (status);
01389 }
01390
01391
NTSTATUS
01392 CmpAppendStringToMultiSz(
01393 IN HANDLE Key,
01394 IN PCHAR ValueName,
01395 IN OUT PVOID *Data,
01396 IN OUT PULONG DataSize
01397 )
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421 {
01422
NTSTATUS status;
01423 ULONG size;
01424 ANSI_STRING ansiString;
01425 UNICODE_STRING unicodeString;
01426 PKEY_VALUE_FULL_INFORMATION valueInfo;
01427 PVOID buffer;
01428 PVOID str;
01429
01430
ASSERT(DataSize && *DataSize);
01431
ASSERT(*Data);
01432
01433
RtlInitAnsiString(&ansiString,
ValueName);
01434 status =
RtlAnsiStringToUnicodeString(&unicodeString, &ansiString,
TRUE);
01435
if (
NT_SUCCESS(status))
01436 {
01437 size = 0;
01438 status =
NtQueryValueKey(
Key,
01439 &unicodeString,
01440 KeyValueFullInformation,
01441
NULL,
01442 0,
01443 &size);
01444
if (size)
01445 {
01446 buffer =
ExAllocatePoolWithTag(
PagedPool, size, CM_GENINST_TAG);
01447
if (buffer)
01448 {
01449 status =
NtQueryValueKey(
Key,
01450 &unicodeString,
01451 KeyValueFullInformation,
01452 buffer,
01453 size,
01454 &size);
01455
if (
NT_SUCCESS(status))
01456 {
01457 valueInfo = (PKEY_VALUE_FULL_INFORMATION)buffer;
01458 str =
ExAllocatePoolWithTag(
PagedPool,
01459 valueInfo->DataLength +
01460 *DataSize -
sizeof(UNICODE_NULL),
01461 CM_GENINST_TAG);
01462
if (str)
01463 {
01464 memcpy( str,
01465 (PCHAR)buffer + valueInfo->DataOffset,
01466 valueInfo->DataLength);
01467 memcpy( (PCHAR)str + valueInfo->DataLength -
sizeof(UNICODE_NULL),
01468 *Data,
01469 *DataSize);
01470
ExFreePool(*Data);
01471 *Data = str;
01472 *DataSize += valueInfo->DataLength -
sizeof(UNICODE_NULL);
01473 }
01474
else
01475 {
01476
DbgPrint(
"CmpAppendStringToMultiSz: Failed to allocate memory!\n");
01477
ASSERT(str);
01478 status = STATUS_NO_MEMORY;
01479 }
01480 }
01481
ExFreePool(buffer);
01482 }
01483
else
01484 {
01485
DbgPrint(
"CmpAppendStringToMultiSz: Failed to allocate memory!\n");
01486
ASSERT(buffer);
01487 status = STATUS_NO_MEMORY;
01488 }
01489 }
01490
RtlFreeUnicodeString(&unicodeString);
01491 }
01492
01493
return (status);
01494 }