Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

cmsubs2.c File Reference

#include "cmp.h"

Go to the source code of this file.

Defines

#define ALIGN_OFFSET(Offset)
#define ALIGN_OFFSET64(Offset)

Functions

PUCHAR CmpGetValueDataFromCache (IN PHHIVE Hive, IN PPCM_CACHED_VALUE ContainingList, IN PCELL_DATA ValueKey, IN BOOLEAN ValueCached)
VOID CmpFreeValue (PHHIVE Hive, HCELL_INDEX Cell)
NTSTATUS CmpQueryKeyData (PHHIVE Hive, PCM_KEY_NODE Node, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG Length, PULONG ResultLength)
NTSTATUS CmpQueryKeyValueData (PHHIVE Hive, PPCM_CACHED_VALUE ContainingList, PCM_KEY_VALUE ValueKey, BOOLEAN ValueCached, KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, PVOID KeyValueInformation, ULONG Length, PULONG ResultLength)


Define Documentation

#define ALIGN_OFFSET Offset   ) 
 

Value:

(ULONG) \ ((((ULONG)(Offset) + sizeof(ULONG)-1)) & (~(sizeof(ULONG) - 1)))

Definition at line 45 of file cmsubs2.c.

Referenced by CmpQueryKeyData(), and CmpQueryKeyValueData().

#define ALIGN_OFFSET64 Offset   ) 
 

Value:

(ULONG) \ ((((ULONG)(Offset) + sizeof(ULONGLONG)-1)) & (~(sizeof(ULONGLONG) - 1)))

Definition at line 48 of file cmsubs2.c.

Referenced by CmpQueryKeyValueData().


Function Documentation

VOID CmpFreeValue PHHIVE  Hive,
HCELL_INDEX  Cell
 

Definition at line 53 of file cmsubs2.c.

References Cell, CmpIsHKeyValueSmall, _CM_KEY_VALUE::Data, _CM_KEY_VALUE::DataLength, Hive, HvFreeCell(), HvGetCell, _CELL_DATA::_u::KeyValue, and _CELL_DATA::u.

Referenced by CmDeleteValueKey(), CmpFreeKeyByCell(), and CmpFreeKeyValues().

00059 : 00060 00061 Free the value entry Hive.Cell refers to, including 00062 its name and data cells. 00063 00064 Arguments: 00065 00066 Hive - supplies a pointer to the hive control structure for the hive 00067 00068 Cell - supplies index of value to delete 00069 00070 Return Value: 00071 00072 NTSTATUS - Result code from call, among the following: 00073 00074 <TBS> 00075 00076 --*/ 00077 { 00078 PCELL_DATA value; 00079 ULONG realsize; 00080 BOOLEAN small; 00081 00082 // 00083 // map in the cell 00084 // 00085 value = HvGetCell(Hive, Cell); 00086 00087 // 00088 // free data if present 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 // free the cell itself 00098 // 00099 HvFreeCell(Hive, Cell); 00100 00101 return; 00102 }

PUCHAR CmpGetValueDataFromCache IN PHHIVE  Hive,
IN PPCM_CACHED_VALUE  ContainingList,
IN PCELL_DATA  ValueKey,
IN BOOLEAN  ValueCached
 

Definition at line 403 of file cmsubs2.c.

References ASSERT, CM_CACHE_DATA_CACHED, CM_CACHE_DATA_NOT_CACHED, CM_CACHE_DATA_TOO_BIG, CMP_GET_CACHED_ADDRESS, CMP_MARK_CELL_CACHED, CmpMakeSpecialPoolReadOnly, CmpMakeSpecialPoolReadWrite, _CM_CACHED_VALUE::DataCacheType, ExAllocatePoolWithTag, ExFreePool(), Hive, HvGetCell, HvGetCellSize(), _CM_CACHED_VALUE::KeyValue, MAXIMUM_CACHED_DATA, PagedPool, and _CM_CACHED_VALUE::ValueKeySize.

Referenced by CmpQueryKeyValueData().

00411 : 00412 00413 Get the cached Value Data given a value node. 00414 00415 Arguments: 00416 00417 Hive - pointer to hive control structure for hive of interest 00418 00419 ContainingList - Address that stores the allocation address of the value node. 00420 We need to update this when we do a re-allocate to cache 00421 both value key and value data. 00422 00423 ValueKey - pointer to the Value Key 00424 00425 ValueCached - Indicating whether Value key is cached or not. 00426 00427 Return Value: 00428 00429 Pointer to the Valve Index. 00430 --*/ 00431 { 00432 // 00433 // Cache the data if needed. 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 // Data is already cached, use it. 00448 // 00449 datapointer = (PUCHAR) ((ULONG_PTR) ValueKey + OldEntry->ValueKeySize); 00450 } else if (OldEntry->DataCacheType == CM_CACHE_DATA_TOO_BIG) { 00451 // 00452 // Data is too big to warrent caching, get it from the registry. 00453 // 00454 datapointer = (PUCHAR)HvGetCell(Hive, ValueKey->u.KeyValue.Data); 00455 } else { 00456 // 00457 // consistency check 00458 // 00459 ASSERT(OldEntry->DataCacheType == CM_CACHE_DATA_NOT_CACHED); 00460 00461 // 00462 // Value data is not cached. 00463 // Check the size of value data, if it is smaller than MAXIMUM_CACHED_DATA, cache it. 00464 // 00465 datapointer = (PUCHAR)HvGetCell(Hive, ValueKey->u.KeyValue.Data); 00466 DataSize = (ULONG) HvGetCellSize(Hive, datapointer); 00467 if (DataSize <= MAXIMUM_CACHED_DATA) { 00468 // 00469 // Data is not cached and now we are going to do it. 00470 // Reallocate a new cached entry for both value key and value data. 00471 // 00472 CopySize = DataSize + OldEntry->ValueKeySize; 00473 AllocSize = CopySize + FIELD_OFFSET(CM_CACHED_VALUE, KeyValue); 00474 00475 // Dragos: Changed to catch the memory violator 00476 // it didn't work 00477 //NewEntry = (PCM_CACHED_VALUE) ExAllocatePoolWithTagPriority(PagedPool, AllocSize, CM_CACHE_VALUE_DATA_TAG,NormalPoolPrioritySpecialPoolUnderrun); 00478 NewEntry = (PCM_CACHED_VALUE) ExAllocatePoolWithTag(PagedPool, AllocSize, CM_CACHE_VALUE_DATA_TAG); 00479 00480 if (NewEntry) { 00481 // 00482 // Now fill the data to the new cached entry 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 // Trying to catch the BAD guy who writes over our pool. 00495 CmpMakeSpecialPoolReadWrite( OldEntry ); 00496 00497 *ContainingList = (PCM_CACHED_VALUE) CMP_MARK_CELL_CACHED(NewEntry); 00498 00499 // Trying to catch the BAD guy who writes over our pool. 00500 CmpMakeSpecialPoolReadOnly( NewEntry ); 00501 00502 // 00503 // Free the old entry 00504 // 00505 00506 ExFreePool(OldEntry); 00507 } 00508 } else { 00509 // Trying to catch the BAD guy who writes over our pool. 00510 CmpMakeSpecialPoolReadWrite( OldEntry ); 00511 00512 // 00513 // Mark the type and do not cache it. 00514 // 00515 OldEntry->DataCacheType = CM_CACHE_DATA_TOO_BIG; 00516 00517 // Trying to catch the BAD guy who writes over our pool. 00518 CmpMakeSpecialPoolReadOnly( OldEntry ); 00519 } 00520 } 00521 } else { 00522 datapointer = (PUCHAR)HvGetCell(Hive, ValueKey->u.KeyValue.Data); 00523 } 00524 00525 return (datapointer); 00526 }

NTSTATUS CmpQueryKeyData PHHIVE  Hive,
PCM_KEY_NODE  Node,
KEY_INFORMATION_CLASS  KeyInformationClass,
PVOID  KeyInformation,
ULONG  Length,
PULONG  ResultLength
 

Definition at line 110 of file cmsubs2.c.

References ALIGN_OFFSET, _CM_KEY_NODE::Class, _CM_KEY_NODE::ClassLength, CmpCopyCompressedName(), CmpHKeyNameLen, _CHILD_LIST::Count, _CM_KEY_NODE::Flags, Hive, HvGetCell, KEY_COMP_NAME, _KEY_INFORMATION::KeyBasicInformation, _KEY_INFORMATION::KeyFullInformation, _KEY_INFORMATION::KeyNodeInformation, _CM_KEY_NODE::LastWriteTime, _CM_KEY_NODE::MaxClassLen, _CM_KEY_NODE::MaxNameLen, _CM_KEY_NODE::MaxValueDataLen, _CM_KEY_NODE::MaxValueNameLen, _CM_KEY_NODE::Name, Name, _CM_KEY_NODE::NameLength, NTSTATUS(), Stable, _CM_KEY_NODE::SubKeyCounts, USHORT, _CM_KEY_NODE::ValueList, and Volatile.

Referenced by CmEnumerateKey(), and CmQueryKey().

00120 : 00121 00122 Do the actual copy of data for a key into caller's buffer. 00123 00124 If KeyInformation is not long enough to hold all requested data, 00125 STATUS_BUFFER_OVERFLOW will be returned, and ResultLength will be 00126 set to the number of bytes actually required. 00127 00128 Arguments: 00129 00130 Hive - supplies a pointer to the hive control structure for the hive 00131 00132 Node - Supplies pointer to node whose subkeys are to be found 00133 00134 KeyInformationClass - Specifies the type of information returned in 00135 Buffer. One of the following types: 00136 00137 KeyBasicInformation - return last write time, title index, and name. 00138 (see KEY_BASIC_INFORMATION structure) 00139 00140 KeyNodeInformation - return last write time, title index, name, class. 00141 (see KEY_NODE_INFORMATION structure) 00142 00143 KeyInformation -Supplies pointer to buffer to receive the data. 00144 00145 Length - Length of KeyInformation in bytes. 00146 00147 ResultLength - Number of bytes actually written into KeyInformation. 00148 00149 Return Value: 00150 00151 NTSTATUS - Result code from call, among the following: 00152 00153 <TBS> 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 // LastWriteTime, TitleIndex, NameLength, Name 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 // LastWriteTime, TitleIndex, ClassOffset, ClassLength 00229 // NameLength, Name, Class 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 // LastWriteTime, TitleIndex, ClassOffset, ClassLength, 00320 // SubKeys, MaxNameLen, MaxClassLen, Values, MaxValueNameLen, 00321 // MaxValueDataLen, Class 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 }

NTSTATUS CmpQueryKeyValueData PHHIVE  Hive,
PPCM_CACHED_VALUE  ContainingList,
PCM_KEY_VALUE  ValueKey,
BOOLEAN  ValueCached,
KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass,
PVOID  KeyValueInformation,
ULONG  Length,
PULONG  ResultLength
 

Definition at line 531 of file cmsubs2.c.

References ALIGN_OFFSET, ALIGN_OFFSET64, ASSERT, CM_KEY_VALUE_SMALL, CmpCopyCompressedName(), CmpGetValueDataFromCache(), CmpIsHKeyValueSmall, CmpValueNameLen, _CM_KEY_VALUE::Data, _CM_KEY_VALUE::DataLength, _CM_KEY_VALUE::Flags, Hive, _CELL_DATA::_u::KeyValue, _KEY_VALUE_INFORMATION::KeyValueBasicInformation, _KEY_VALUE_INFORMATION::KeyValueFullInformation, _KEY_VALUE_INFORMATION::KeyValuePartialInformation, _KEY_VALUE_INFORMATION::KeyValuePartialInformationAlign64, _CM_KEY_VALUE::Name, Name, _CM_KEY_VALUE::NameLength, NTSTATUS(), TRUE, _CM_KEY_VALUE::Type, _CELL_DATA::u, USHORT, and VALUE_COMP_NAME.

Referenced by CmEnumerateValueKey(), and CmQueryValueKey().

00543 : 00544 00545 Do the actual copy of data for a key value into caller's buffer. 00546 00547 If KeyValueInformation is not long enough to hold all requested data, 00548 STATUS_BUFFER_OVERFLOW will be returned, and ResultLength will be 00549 set to the number of bytes actually required. 00550 00551 Arguments: 00552 00553 Hive - supplies a pointer to the hive control structure for the hive 00554 00555 Cell - supplies index of node to whose sub keys are to be found 00556 00557 KeyValueInformationClass - Specifies the type of information returned in 00558 KeyValueInformation. One of the following types: 00559 00560 KeyValueInformation -Supplies pointer to buffer to receive the data. 00561 00562 Length - Length of KeyInformation in bytes. 00563 00564 ResultLength - Number of bytes actually written into KeyInformation. 00565 00566 Return Value: 00567 00568 NTSTATUS - Result code from call, among the following: 00569 00570 <TBS> 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 // TitleIndex, Type, NameLength, Name 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 // TitleIndex, Type, DataOffset, DataLength, NameLength, 00651 // Name, Data 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 // Some clients will have passed in a structure that they "know" 00686 // will be exactly the right size. The fact that alignment 00687 // has changed on NT64 may cause these clients to have problems. 00688 // 00689 // The solution is to fix the client, but print out some debug 00690 // spew here if it looks like this is the case. This problem 00691 // isn't particularly easy to spot from the client end. 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 // TitleIndex, Type, DataLength, Data 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 // TitleIndex, Type, DataLength, Data 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 } }


Generated on Sat May 15 19:43:11 2004 for test by doxygen 1.3.7