00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#include "cmp.h"
00025
00026 PUCHAR
00027
CmpGetValueDataFromCache(
00028 IN
PHHIVE Hive,
00029 IN
PPCM_CACHED_VALUE ContainingList,
00030 IN
PCELL_DATA ValueKey,
00031 IN BOOLEAN ValueCached
00032 );
00033
00034
#ifdef ALLOC_PRAGMA
00035
#pragma alloc_text(PAGE,CmpGetValueDataFromCache)
00036
#pragma alloc_text(PAGE,CmpFreeValue)
00037
#pragma alloc_text(PAGE,CmpQueryKeyData)
00038
#pragma alloc_text(PAGE,CmpQueryKeyValueData)
00039
#endif
00040
00041
00042
00043
00044
00045 #define ALIGN_OFFSET(Offset) (ULONG) \
00046
((((ULONG)(Offset) + sizeof(ULONG)-1)) & (~(sizeof(ULONG) - 1)))
00047
00048 #define ALIGN_OFFSET64(Offset) (ULONG) \
00049
((((ULONG)(Offset) + sizeof(ULONGLONG)-1)) & (~(sizeof(ULONGLONG) - 1)))
00050
00051
00052
VOID
00053 CmpFreeValue(
00054
PHHIVE Hive,
00055 HCELL_INDEX Cell
00056 )
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 {
00078
PCELL_DATA value;
00079 ULONG realsize;
00080 BOOLEAN small;
00081
00082
00083
00084
00085 value =
HvGetCell(
Hive,
Cell);
00086
00087
00088
00089
00090 small =
CmpIsHKeyValueSmall(realsize, value->
u.
KeyValue.
DataLength);
00091
if ((! small) && (realsize > 0))
00092 {
00093
HvFreeCell(
Hive, value->
u.
KeyValue.
Data);
00094 }
00095
00096
00097
00098
00099
HvFreeCell(
Hive,
Cell);
00100
00101
return;
00102 }
00103
00104
00105
00106
00107
00108
00109
NTSTATUS
00110 CmpQueryKeyData(
00111
PHHIVE Hive,
00112
PCM_KEY_NODE Node,
00113 KEY_INFORMATION_CLASS KeyInformationClass,
00114 PVOID KeyInformation,
00115 ULONG Length,
00116 PULONG ResultLength
00117 )
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 {
00157
NTSTATUS status;
00158
PCELL_DATA pclass;
00159 ULONG requiredlength;
00160 LONG leftlength;
00161 ULONG offset;
00162 ULONG minimumlength;
00163
PKEY_INFORMATION pbuffer;
00164
USHORT NameLength;
00165
00166 pbuffer = (
PKEY_INFORMATION)KeyInformation;
00167 NameLength =
CmpHKeyNameLen(Node);
00168
00169
switch (KeyInformationClass) {
00170
00171
case KeyBasicInformation:
00172
00173
00174
00175
00176 requiredlength = FIELD_OFFSET(KEY_BASIC_INFORMATION,
Name) +
00177 NameLength;
00178
00179 minimumlength = FIELD_OFFSET(KEY_BASIC_INFORMATION,
Name);
00180
00181 *ResultLength = requiredlength;
00182
00183 status = STATUS_SUCCESS;
00184
00185
if (Length < minimumlength) {
00186
00187 status = STATUS_BUFFER_TOO_SMALL;
00188
00189 }
else {
00190
00191 pbuffer->
KeyBasicInformation.LastWriteTime =
00192 Node->
LastWriteTime;
00193
00194 pbuffer->
KeyBasicInformation.TitleIndex = 0;
00195
00196 pbuffer->
KeyBasicInformation.NameLength =
00197 NameLength;
00198
00199 leftlength = Length - minimumlength;
00200
00201 requiredlength = NameLength;
00202
00203
if (leftlength < (LONG)requiredlength) {
00204 requiredlength = leftlength;
00205 status = STATUS_BUFFER_OVERFLOW;
00206 }
00207
00208
if (Node->
Flags &
KEY_COMP_NAME) {
00209
CmpCopyCompressedName(pbuffer->
KeyBasicInformation.Name,
00210 leftlength,
00211 Node->
Name,
00212 Node->
NameLength);
00213 }
else {
00214 RtlCopyMemory(
00215 &(pbuffer->
KeyBasicInformation.Name[0]),
00216 &(Node->
Name[0]),
00217 requiredlength
00218 );
00219 }
00220 }
00221
00222
break;
00223
00224
00225
case KeyNodeInformation:
00226
00227
00228
00229
00230
00231 requiredlength = FIELD_OFFSET(KEY_NODE_INFORMATION,
Name) +
00232 NameLength +
00233 Node->
ClassLength;
00234
00235 minimumlength = FIELD_OFFSET(KEY_NODE_INFORMATION,
Name);
00236
00237 *ResultLength = requiredlength;
00238
00239 status = STATUS_SUCCESS;
00240
00241
if (Length < minimumlength) {
00242
00243 status = STATUS_BUFFER_TOO_SMALL;
00244
00245 }
else {
00246
00247 pbuffer->
KeyNodeInformation.LastWriteTime =
00248 Node->
LastWriteTime;
00249
00250 pbuffer->
KeyNodeInformation.TitleIndex = 0;
00251
00252 pbuffer->
KeyNodeInformation.ClassLength =
00253 Node->
ClassLength;
00254
00255 pbuffer->
KeyNodeInformation.NameLength =
00256 NameLength;
00257
00258 leftlength = Length - minimumlength;
00259 requiredlength = NameLength;
00260
00261
if (leftlength < (LONG)requiredlength) {
00262 requiredlength = leftlength;
00263 status = STATUS_BUFFER_OVERFLOW;
00264 }
00265
00266
if (Node->
Flags &
KEY_COMP_NAME) {
00267
CmpCopyCompressedName(pbuffer->
KeyNodeInformation.Name,
00268 leftlength,
00269 Node->
Name,
00270 Node->
NameLength);
00271 }
else {
00272 RtlCopyMemory(
00273 &(pbuffer->
KeyNodeInformation.Name[0]),
00274 &(Node->
Name[0]),
00275 requiredlength
00276 );
00277 }
00278
00279
if (Node->
ClassLength > 0) {
00280
00281 offset = FIELD_OFFSET(KEY_NODE_INFORMATION,
Name) +
00282 NameLength;
00283 offset =
ALIGN_OFFSET(offset);
00284
00285 pbuffer->
KeyNodeInformation.ClassOffset = offset;
00286
00287 pclass =
HvGetCell(
Hive, Node->
Class);
00288
00289 pbuffer = (
PKEY_INFORMATION)((PUCHAR)pbuffer + offset);
00290
00291 leftlength = (((LONG)Length - (LONG)offset) < 0) ?
00292 0 :
00293 Length - offset;
00294
00295 requiredlength = Node->
ClassLength;
00296
00297
if (leftlength < (LONG)requiredlength) {
00298 requiredlength = leftlength;
00299 status = STATUS_BUFFER_OVERFLOW;
00300 }
00301
00302 RtlMoveMemory(
00303 pbuffer,
00304 pclass,
00305 requiredlength
00306 );
00307
00308 }
else {
00309 pbuffer->
KeyNodeInformation.ClassOffset = (ULONG)-1;
00310 }
00311 }
00312
00313
break;
00314
00315
00316
case KeyFullInformation:
00317
00318
00319
00320
00321
00322
00323 requiredlength = FIELD_OFFSET(KEY_FULL_INFORMATION, Class) +
00324 Node->
ClassLength;
00325
00326 minimumlength = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
00327
00328 *ResultLength = requiredlength;
00329
00330 status = STATUS_SUCCESS;
00331
00332
if (Length < minimumlength) {
00333
00334 status = STATUS_BUFFER_TOO_SMALL;
00335
00336 }
else {
00337
00338 pbuffer->
KeyFullInformation.LastWriteTime =
00339 Node->
LastWriteTime;
00340
00341 pbuffer->
KeyFullInformation.TitleIndex = 0;
00342
00343 pbuffer->
KeyFullInformation.ClassLength =
00344 Node->
ClassLength;
00345
00346
if (Node->
ClassLength > 0) {
00347
00348 pbuffer->
KeyFullInformation.ClassOffset =
00349 FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
00350
00351 pclass =
HvGetCell(
Hive, Node->
Class);
00352
00353 leftlength = Length - minimumlength;
00354 requiredlength = Node->
ClassLength;
00355
00356
if (leftlength < (LONG)requiredlength) {
00357 requiredlength = leftlength;
00358 status = STATUS_BUFFER_OVERFLOW;
00359 }
00360
00361 RtlMoveMemory(
00362 &(pbuffer->
KeyFullInformation.Class[0]),
00363 pclass,
00364 requiredlength
00365 );
00366
00367 }
else {
00368 pbuffer->
KeyFullInformation.ClassOffset = (ULONG)-1;
00369 }
00370
00371 pbuffer->
KeyFullInformation.SubKeys =
00372 Node->
SubKeyCounts[
Stable] +
00373 Node->
SubKeyCounts[
Volatile];
00374
00375 pbuffer->
KeyFullInformation.Values =
00376 Node->
ValueList.
Count;
00377
00378 pbuffer->
KeyFullInformation.MaxNameLen =
00379 Node->
MaxNameLen;
00380
00381 pbuffer->
KeyFullInformation.MaxClassLen =
00382 Node->
MaxClassLen;
00383
00384 pbuffer->
KeyFullInformation.MaxValueNameLen =
00385 Node->
MaxValueNameLen;
00386
00387 pbuffer->
KeyFullInformation.MaxValueDataLen =
00388 Node->
MaxValueDataLen;
00389
00390 }
00391
00392
break;
00393
00394
00395
default:
00396 status = STATUS_INVALID_PARAMETER;
00397
break;
00398 }
00399
return status;
00400 }
00401
00402 PUCHAR
00403 CmpGetValueDataFromCache(
00404 IN
PHHIVE Hive,
00405 IN
PPCM_CACHED_VALUE ContainingList,
00406 IN
PCELL_DATA ValueKey,
00407 IN BOOLEAN ValueCached
00408 )
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 {
00432
00433
00434
00435
PCM_CACHED_VALUE OldEntry;
00436
PCM_CACHED_VALUE NewEntry;
00437 PUCHAR datapointer;
00438 PUCHAR Cacheddatapointer;
00439 ULONG AllocSize;
00440 ULONG CopySize;
00441 ULONG DataSize;
00442
00443
if (ValueCached) {
00444 OldEntry = (
PCM_CACHED_VALUE)
CMP_GET_CACHED_ADDRESS(*ContainingList);
00445
if (OldEntry->
DataCacheType ==
CM_CACHE_DATA_CACHED) {
00446
00447
00448
00449 datapointer = (PUCHAR) ((ULONG_PTR) ValueKey + OldEntry->
ValueKeySize);
00450 }
else if (OldEntry->
DataCacheType ==
CM_CACHE_DATA_TOO_BIG) {
00451
00452
00453
00454 datapointer = (PUCHAR)
HvGetCell(
Hive, ValueKey->u.KeyValue.Data);
00455 }
else {
00456
00457
00458
00459
ASSERT(OldEntry->
DataCacheType ==
CM_CACHE_DATA_NOT_CACHED);
00460
00461
00462
00463
00464
00465 datapointer = (PUCHAR)
HvGetCell(
Hive, ValueKey->u.KeyValue.Data);
00466 DataSize = (ULONG)
HvGetCellSize(
Hive, datapointer);
00467
if (DataSize <=
MAXIMUM_CACHED_DATA) {
00468
00469
00470
00471
00472 CopySize = DataSize + OldEntry->
ValueKeySize;
00473 AllocSize = CopySize + FIELD_OFFSET(
CM_CACHED_VALUE, KeyValue);
00474
00475
00476
00477
00478 NewEntry = (
PCM_CACHED_VALUE)
ExAllocatePoolWithTag(
PagedPool, AllocSize, CM_CACHE_VALUE_DATA_TAG);
00479
00480
if (NewEntry) {
00481
00482
00483
00484 NewEntry->
DataCacheType =
CM_CACHE_DATA_CACHED;
00485 NewEntry->
ValueKeySize = OldEntry->
ValueKeySize;
00486
00487 RtlCopyMemory((PVOID)&(NewEntry->
KeyValue),
00488 (PVOID)&(OldEntry->
KeyValue),
00489 NewEntry->
ValueKeySize);
00490
00491 Cacheddatapointer = (PUCHAR) ((ULONG_PTR) &(NewEntry->
KeyValue) + OldEntry->
ValueKeySize);
00492 RtlCopyMemory(Cacheddatapointer, datapointer, DataSize);
00493
00494
00495
CmpMakeSpecialPoolReadWrite( OldEntry );
00496
00497 *ContainingList = (
PCM_CACHED_VALUE)
CMP_MARK_CELL_CACHED(NewEntry);
00498
00499
00500
CmpMakeSpecialPoolReadOnly( NewEntry );
00501
00502
00503
00504
00505
00506
ExFreePool(OldEntry);
00507 }
00508 }
else {
00509
00510
CmpMakeSpecialPoolReadWrite( OldEntry );
00511
00512
00513
00514
00515 OldEntry->
DataCacheType =
CM_CACHE_DATA_TOO_BIG;
00516
00517
00518
CmpMakeSpecialPoolReadOnly( OldEntry );
00519 }
00520 }
00521 }
else {
00522 datapointer = (PUCHAR)
HvGetCell(
Hive, ValueKey->u.KeyValue.Data);
00523 }
00524
00525
return (datapointer);
00526 }
00527
00528
00529
00530
NTSTATUS
00531 CmpQueryKeyValueData(
00532
PHHIVE Hive,
00533
PPCM_CACHED_VALUE ContainingList,
00534
PCM_KEY_VALUE ValueKey,
00535 BOOLEAN ValueCached,
00536 KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
00537 PVOID KeyValueInformation,
00538 ULONG Length,
00539 PULONG ResultLength
00540 )
00541
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
00568
00569
00570
00571
00572
00573 {
00574
NTSTATUS status;
00575
PKEY_VALUE_INFORMATION pbuffer;
00576
PCELL_DATA pcell;
00577 LONG leftlength;
00578 ULONG requiredlength;
00579 ULONG minimumlength;
00580 ULONG offset;
00581 ULONG base;
00582 ULONG realsize;
00583 PUCHAR datapointer;
00584 BOOLEAN small;
00585
USHORT NameLength;
00586
00587 pbuffer = (
PKEY_VALUE_INFORMATION)KeyValueInformation;
00588
00589 pcell = (
PCELL_DATA) ValueKey;
00590 NameLength =
CmpValueNameLen(&pcell->
u.
KeyValue);
00591
00592
switch (KeyValueInformationClass) {
00593
00594
case KeyValueBasicInformation:
00595
00596
00597
00598
00599 requiredlength = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION,
Name) +
00600 NameLength;
00601
00602 minimumlength = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION,
Name);
00603
00604 *ResultLength = requiredlength;
00605
00606 status = STATUS_SUCCESS;
00607
00608
if (Length < minimumlength) {
00609
00610 status = STATUS_BUFFER_TOO_SMALL;
00611
00612 }
else {
00613
00614 pbuffer->
KeyValueBasicInformation.TitleIndex = 0;
00615
00616 pbuffer->
KeyValueBasicInformation.Type =
00617 pcell->
u.
KeyValue.
Type;
00618
00619 pbuffer->
KeyValueBasicInformation.NameLength =
00620 NameLength;
00621
00622 leftlength = Length - minimumlength;
00623 requiredlength = NameLength;
00624
00625
if (leftlength < (LONG)requiredlength) {
00626 requiredlength = leftlength;
00627 status = STATUS_BUFFER_OVERFLOW;
00628 }
00629
00630
if (pcell->
u.
KeyValue.
Flags &
VALUE_COMP_NAME) {
00631
CmpCopyCompressedName(pbuffer->
KeyValueBasicInformation.Name,
00632 requiredlength,
00633 pcell->
u.
KeyValue.
Name,
00634 pcell->
u.
KeyValue.
NameLength);
00635 }
else {
00636 RtlCopyMemory(&(pbuffer->
KeyValueBasicInformation.Name[0]),
00637 &(pcell->
u.
KeyValue.
Name[0]),
00638 requiredlength);
00639 }
00640 }
00641
00642
break;
00643
00644
00645
00646
case KeyValueFullInformation:
00647
case KeyValueFullInformationAlign64:
00648
00649
00650
00651
00652
00653 small =
CmpIsHKeyValueSmall(realsize, pcell->
u.
KeyValue.
DataLength);
00654
00655 requiredlength = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION,
Name) +
00656 NameLength +
00657 realsize;
00658
00659 minimumlength = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION,
Name);
00660
if (realsize > 0) {
00661 base = requiredlength - realsize;
00662
00663
#if defined(_WIN64)
00664
00665 offset =
ALIGN_OFFSET64(base);
00666
00667
#else
00668
00669
if (KeyValueInformationClass == KeyValueFullInformationAlign64) {
00670 offset =
ALIGN_OFFSET64(base);
00671
00672 }
else {
00673 offset =
ALIGN_OFFSET(base);
00674 }
00675
00676
#endif
00677
00678
if (offset > base) {
00679 requiredlength += (offset - base);
00680 }
00681
00682
#if DBG && defined(_WIN64)
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
if((KeyValueInformationClass == KeyValueFullInformation) &&
00695 (Length != minimumlength) &&
00696 (requiredlength > Length) &&
00697 ((requiredlength - Length) <=
00698 (
ALIGN_OFFSET64(base) -
ALIGN_OFFSET(base)))) {
00699
00700 KdPrint((
"ntos/config-64 KeyValueFullInformation: "
00701
"Possible client buffer size problem.\n"));
00702
00703 KdPrint((
" Required size = %d\n", requiredlength));
00704 KdPrint((
" Supplied size = %d\n", Length));
00705 }
00706
00707
#endif
00708
00709 }
00710
00711 *ResultLength = requiredlength;
00712
00713 status = STATUS_SUCCESS;
00714
00715
if (Length < minimumlength) {
00716
00717 status = STATUS_BUFFER_TOO_SMALL;
00718
00719 }
else {
00720
00721 pbuffer->
KeyValueFullInformation.TitleIndex = 0;
00722
00723 pbuffer->
KeyValueFullInformation.Type =
00724 pcell->
u.
KeyValue.
Type;
00725
00726 pbuffer->
KeyValueFullInformation.DataLength =
00727 realsize;
00728
00729 pbuffer->
KeyValueFullInformation.NameLength =
00730 NameLength;
00731
00732 leftlength = Length - minimumlength;
00733 requiredlength = NameLength;
00734
00735
if (leftlength < (LONG)requiredlength) {
00736 requiredlength = leftlength;
00737 status = STATUS_BUFFER_OVERFLOW;
00738 }
00739
00740
if (pcell->
u.
KeyValue.
Flags &
VALUE_COMP_NAME) {
00741
CmpCopyCompressedName(pbuffer->
KeyValueFullInformation.Name,
00742 requiredlength,
00743 pcell->
u.
KeyValue.
Name,
00744 pcell->
u.
KeyValue.
NameLength);
00745 }
else {
00746 RtlMoveMemory(
00747 &(pbuffer->
KeyValueFullInformation.Name[0]),
00748 &(pcell->
u.
KeyValue.
Name[0]),
00749 requiredlength
00750 );
00751 }
00752
00753
if (realsize > 0) {
00754
00755
if (small ==
TRUE) {
00756 datapointer = (PUCHAR)(&(pcell->
u.
KeyValue.
Data));
00757 }
else {
00758 datapointer =
CmpGetValueDataFromCache(
Hive, ContainingList, pcell, ValueCached);
00759 }
00760
00761 pbuffer->
KeyValueFullInformation.DataOffset = offset;
00762
00763 leftlength = (((LONG)Length - (LONG)offset) < 0) ?
00764 0 :
00765 Length - offset;
00766
00767 requiredlength = realsize;
00768
00769
if (leftlength < (LONG)requiredlength) {
00770 requiredlength = leftlength;
00771 status = STATUS_BUFFER_OVERFLOW;
00772 }
00773
00774
ASSERT((small ? (requiredlength <=
CM_KEY_VALUE_SMALL) :
TRUE));
00775
00776 RtlMoveMemory(
00777 ((PUCHAR)pbuffer + offset),
00778 datapointer,
00779 requiredlength
00780 );
00781
00782 }
else {
00783 pbuffer->
KeyValueFullInformation.DataOffset = (ULONG)-1;
00784 }
00785 }
00786
00787
break;
00788
00789
00790
case KeyValuePartialInformation:
00791
00792
00793
00794
00795 small =
CmpIsHKeyValueSmall(realsize, pcell->
u.
KeyValue.
DataLength);
00796 requiredlength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
00797 realsize;
00798
00799 minimumlength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
00800
00801 *ResultLength = requiredlength;
00802
00803 status = STATUS_SUCCESS;
00804
00805
if (Length < minimumlength) {
00806
00807 status = STATUS_BUFFER_TOO_SMALL;
00808
00809 }
else {
00810
00811 pbuffer->
KeyValuePartialInformation.TitleIndex = 0;
00812
00813 pbuffer->
KeyValuePartialInformation.Type =
00814 pcell->
u.
KeyValue.
Type;
00815
00816 pbuffer->
KeyValuePartialInformation.DataLength =
00817 realsize;
00818
00819 leftlength = Length - minimumlength;
00820 requiredlength = realsize;
00821
00822
if (leftlength < (LONG)requiredlength) {
00823 requiredlength = leftlength;
00824 status = STATUS_BUFFER_OVERFLOW;
00825 }
00826
00827
if (realsize > 0) {
00828
00829
if (small ==
TRUE) {
00830 datapointer = (PUCHAR)(&(pcell->
u.
KeyValue.
Data));
00831 }
else {
00832 datapointer =
CmpGetValueDataFromCache(
Hive, ContainingList, pcell, ValueCached);
00833 }
00834
00835
ASSERT((small ? (requiredlength <=
CM_KEY_VALUE_SMALL) :
TRUE));
00836
00837 RtlMoveMemory((PUCHAR)&(pbuffer->
KeyValuePartialInformation.Data[0]),
00838 datapointer,
00839 requiredlength);
00840 }
00841 }
00842
00843
break;
00844
case KeyValuePartialInformationAlign64:
00845
00846
00847
00848
00849 small =
CmpIsHKeyValueSmall(realsize, pcell->
u.
KeyValue.
DataLength);
00850 requiredlength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data) +
00851 realsize;
00852
00853 minimumlength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, Data);
00854
00855 *ResultLength = requiredlength;
00856
00857 status = STATUS_SUCCESS;
00858
00859
if (Length < minimumlength) {
00860
00861 status = STATUS_BUFFER_TOO_SMALL;
00862
00863 }
else {
00864
00865 pbuffer->
KeyValuePartialInformationAlign64.Type =
00866 pcell->
u.
KeyValue.
Type;
00867
00868 pbuffer->
KeyValuePartialInformationAlign64.DataLength =
00869 realsize;
00870
00871 leftlength = Length - minimumlength;
00872 requiredlength = realsize;
00873
00874
if (leftlength < (LONG)requiredlength) {
00875 requiredlength = leftlength;
00876 status = STATUS_BUFFER_OVERFLOW;
00877 }
00878
00879
if (realsize > 0) {
00880
00881
if (small ==
TRUE) {
00882 datapointer = (PUCHAR)(&(pcell->
u.
KeyValue.
Data));
00883 }
else {
00884 datapointer =
CmpGetValueDataFromCache(
Hive, ContainingList, pcell, ValueCached);
00885 }
00886
00887
ASSERT((small ? (requiredlength <=
CM_KEY_VALUE_SMALL) :
TRUE));
00888 RtlMoveMemory((PUCHAR)&(pbuffer->
KeyValuePartialInformationAlign64.Data[0]),
00889 datapointer,
00890 requiredlength);
00891 }
00892 }
00893
00894
break;
00895
00896
default:
00897 status = STATUS_INVALID_PARAMETER;
00898
break;
00899 }
00900
return status;
00901 }
00902