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

cmtrecpy.c File Reference

#include "cmp.h"

Go to the source code of this file.

Classes

struct  CMP_COPY_STACK_ENTRY

Defines

#define DEBUG_TREE_SYNC   FALSE
#define CMP_INITIAL_STACK_SIZE   1024

Typedefs

typedef * PCMP_COPY_STACK_ENTRY

Functions

BOOLEAN CmpCopySyncTree2 (PCMP_COPY_STACK_ENTRY CmpCopyStack, ULONG CmpCopyStackSize, ULONG CmpCopyStackTop, PHHIVE CmpSourceHive, PHHIVE CmpTargetHive, BOOLEAN CopyVolatile, CMP_COPY_TYPE CopyType)
BOOLEAN CmpFreeKeyValues (PHHIVE Hive, HCELL_INDEX Cell, PCM_KEY_NODE Node)
BOOLEAN CmpSyncKeyValues (PHHIVE SourceHive, HCELL_INDEX SourceKeyCell, PCM_KEY_NODE SourceKeyNode, PHHIVE TargetHive, HCELL_INDEX TargetKeyCell, PCM_KEY_NODE TargetKeyNode)
BOOLEAN CmpMergeKeyValues (PHHIVE SourceHive, HCELL_INDEX SourceKeyCell, PCM_KEY_NODE SourceKeyNode, PHHIVE TargetHive, HCELL_INDEX TargetKeyCell, PCM_KEY_NODE TargetKeyNode)
BOOLEAN CmpSyncSubKeysAfterDelete (PHHIVE SourceHive, PCM_KEY_NODE SourceCell, PHHIVE TargetHive, PCM_KEY_NODE TargetCell, WCHAR *NameBuffer)
BOOLEAN CmpMarkKeyValuesDirty (PHHIVE Hive, HCELL_INDEX Cell, PCM_KEY_NODE Node)
BOOLEAN CmpMarkKeyParentDirty (PHHIVE Hive, HCELL_INDEX Cell)
BOOLEAN CmpCopySyncTree (PHHIVE SourceHive, HCELL_INDEX SourceCell, PHHIVE TargetHive, HCELL_INDEX TargetCell, BOOLEAN CopyVolatile, CMP_COPY_TYPE CopyType)
HCELL_INDEX CmpCopyKeyPartial (PHHIVE SourceHive, HCELL_INDEX SourceKeyCell, PHHIVE TargetHive, HCELL_INDEX Parent, BOOLEAN CopyValues)
HCELL_INDEX CmpCopyValue (PHHIVE SourceHive, HCELL_INDEX SourceValueCell, PHHIVE TargetHive, HSTORAGE_TYPE Type)
HCELL_INDEX CmpCopyCell (PHHIVE SourceHive, HCELL_INDEX SourceCell, PHHIVE TargetHive, HSTORAGE_TYPE Type)
VOID CmpInitializeKeyNameString (PCM_KEY_NODE Cell, PUNICODE_STRING KeyName, WCHAR *NameBuffer)
VOID CmpInitializeValueNameString (PCM_KEY_VALUE Cell, PUNICODE_STRING ValueName, WCHAR *NameBuffer)


Define Documentation

#define CMP_INITIAL_STACK_SIZE   1024
 

Definition at line 38 of file cmtrecpy.c.

Referenced by CmpCopySyncTree().

#define DEBUG_TREE_SYNC   FALSE
 

Definition at line 31 of file cmtrecpy.c.


Typedef Documentation

typedef * PCMP_COPY_STACK_ENTRY
 

Referenced by CmpCopySyncTree(), and CmpCopySyncTree2().


Function Documentation

HCELL_INDEX CmpCopyCell PHHIVE  SourceHive,
HCELL_INDEX  SourceCell,
PHHIVE  TargetHive,
HSTORAGE_TYPE  Type
 

Definition at line 1009 of file cmtrecpy.c.

References CML_MINOR, CMLOG, CMS_SAVRES, HCELL_INDEX, HCELL_NIL, HvAllocateCell(), HvGetCell, and HvGetCellSize().

Referenced by CmpCopyKeyPartial(), CmpCopyValue(), and CmpSyncKeyValues().

01017 : 01018 01019 Copy SourceHive.SourceCell to TargetHive.TargetCell. 01020 01021 Arguments: 01022 01023 SourceHive - pointer to hive control structure for source 01024 01025 SourceCell - index of cell to copy from 01026 01027 TargetHive - pointer to hive control structure for target 01028 01029 Type - storage type (stable or volatile) of new cell 01030 01031 Return Value: 01032 01033 HCELL_INDEX of new cell, or HCELL_NIL if failure. 01034 01035 --*/ 01036 { 01037 PVOID psource; 01038 PVOID ptarget; 01039 ULONG size; 01040 HCELL_INDEX newcell; 01041 01042 CMLOG(CML_MINOR, CMS_SAVRES) { 01043 KdPrint(("CmpCopyCell:\n")); 01044 KdPrint(("\tSourceHive=%08lx SourceCell=%08lx\n",SourceHive,SourceCell)); 01045 KdPrint(("\tTargetHive=%08lx\n",TargetHive)); 01046 } 01047 01048 psource = HvGetCell(SourceHive, SourceCell); 01049 size = HvGetCellSize(SourceHive, psource); 01050 01051 newcell = HvAllocateCell(TargetHive, size, Type); 01052 if (newcell == HCELL_NIL) { 01053 return HCELL_NIL; 01054 } 01055 01056 ptarget = HvGetCell(TargetHive, newcell); 01057 01058 RtlCopyMemory(ptarget, psource, size); 01059 01060 return newcell; 01061 }

HCELL_INDEX CmpCopyKeyPartial PHHIVE  SourceHive,
HCELL_INDEX  SourceKeyCell,
PHHIVE  TargetHive,
HCELL_INDEX  Parent,
BOOLEAN  CopyValues
 

Definition at line 686 of file cmtrecpy.c.

References _CM_KEY_NODE::Class, _CM_KEY_NODE::ClassLength, CML_MINOR, CMLOG, CmpAssignSecurityDescriptor(), CmpCopyCell(), CmpCopyValue(), CMS_SAVRES, _CHILD_LIST::Count, _CM_KEY_SECURITY::Descriptor, FALSE, _CM_KEY_NODE::Flags, HCELL_INDEX, HCELL_NIL, HvAllocateCell(), HvFreeCell(), HvGetCell, HvGetCellType, KEY_COMP_NAME, KEY_HIVE_ENTRY, KEY_NO_DELETE, _CELL_DATA::_u::KeyList, _CELL_DATA::_u::KeyNode, _CELL_DATA::_u::KeySecurity, _CHILD_LIST::List, NT_SUCCESS, NTSTATUS(), _CM_KEY_NODE::Parent, _CM_KEY_NODE::Security, Stable, _CM_KEY_NODE::SubKeyCounts, _CM_KEY_NODE::SubKeyLists, TRUE, _CELL_DATA::u, _CM_KEY_NODE::ValueList, and Volatile.

Referenced by CmpCopySyncTree2(), CmpLoadHiveVolatile(), CmRestoreKey(), CmSaveKey(), and CmSaveMergedKeys().

00695 : 00696 00697 Copy a key body and all of its values, but NOT its subkeylist or 00698 subkey entries. SubKeyList.Count will be set to 0. 00699 00700 Arguments: 00701 00702 SourceHive - pointer to hive control structure for source 00703 00704 SourceKeyCell - value entry being copied 00705 00706 TargetHive - pointer to hive control structure for target 00707 00708 Parent - parent value to set into newly created key body 00709 00710 CopyValues - if FALSE value entries will not be copied, if TRUE, they will 00711 00712 Return Value: 00713 00714 HCELL_INDEX - Cell of body of new key entry, or HCELL_NIL 00715 if some error. 00716 00717 --*/ 00718 { 00719 NTSTATUS status; 00720 HCELL_INDEX newkey = HCELL_NIL; 00721 HCELL_INDEX newclass = HCELL_NIL; 00722 HCELL_INDEX newsecurity = HCELL_NIL; 00723 HCELL_INDEX newlist = HCELL_NIL; 00724 HCELL_INDEX newvalue; 00725 BOOLEAN success = FALSE; 00726 ULONG i; 00727 PCELL_DATA psrckey; 00728 PCM_KEY_NODE ptarkey; 00729 PCELL_DATA psrclist; 00730 PCELL_DATA ptarlist; 00731 PCELL_DATA psrcsecurity; 00732 HCELL_INDEX security; 00733 HCELL_INDEX class; 00734 ULONG classlength; 00735 ULONG count; 00736 ULONG Type; 00737 00738 CMLOG(CML_MINOR, CMS_SAVRES) { 00739 KdPrint(("CmpCopyKeyPartial:\n")); 00740 KdPrint(("\tSHive=%08lx SCell=%08lx\n",SourceHive,SourceKeyCell)); 00741 KdPrint(("\tTHive=%08lx\n",TargetHive)); 00742 } 00743 00744 00745 // 00746 // get description of source 00747 // 00748 if (Parent == HCELL_NIL) { 00749 // 00750 // This is a root node we are creating, so don't make it volatile. 00751 // 00752 Type = Stable; 00753 } else { 00754 Type = HvGetCellType(Parent); 00755 } 00756 psrckey = HvGetCell(SourceHive, SourceKeyCell); 00757 security = psrckey->u.KeyNode.Security; 00758 class = psrckey->u.KeyNode.Class; 00759 classlength = psrckey->u.KeyNode.ClassLength; 00760 00761 // 00762 // Allocate and copy the body 00763 // 00764 newkey = CmpCopyCell(SourceHive, SourceKeyCell, TargetHive, Type); 00765 if (newkey == HCELL_NIL) { 00766 goto DoFinally; 00767 } 00768 00769 // 00770 // Allocate and copy class 00771 // 00772 if (classlength > 0) { 00773 newclass = CmpCopyCell(SourceHive, class, TargetHive, Type); 00774 if (newclass == HCELL_NIL) { 00775 goto DoFinally; 00776 } 00777 } 00778 00779 // 00780 // Fill in the target body 00781 // 00782 ptarkey = (PCM_KEY_NODE)HvGetCell(TargetHive, newkey); 00783 00784 ptarkey->Class = newclass; 00785 ptarkey->Security = HCELL_NIL; 00786 ptarkey->SubKeyLists[Stable] = HCELL_NIL; 00787 ptarkey->SubKeyLists[Volatile] = HCELL_NIL; 00788 ptarkey->SubKeyCounts[Stable] = 0; 00789 ptarkey->SubKeyCounts[Volatile] = 0; 00790 ptarkey->Parent = Parent; 00791 00792 ptarkey->Flags = (psrckey->u.KeyNode.Flags & KEY_COMP_NAME); 00793 if (Parent == HCELL_NIL) { 00794 ptarkey->Flags |= KEY_HIVE_ENTRY + KEY_NO_DELETE; 00795 } 00796 00797 // 00798 // Allocate and copy security 00799 // 00800 psrcsecurity = HvGetCell(SourceHive, security); 00801 00802 status = CmpAssignSecurityDescriptor(TargetHive, 00803 newkey, 00804 ptarkey, 00805 &(psrcsecurity->u.KeySecurity.Descriptor)); 00806 if (!NT_SUCCESS(status)) { 00807 goto DoFinally; 00808 } 00809 00810 00811 // 00812 // Set up the value list 00813 // 00814 count = psrckey->u.KeyNode.ValueList.Count; 00815 00816 if ((count == 0) || (CopyValues == FALSE)) { 00817 ptarkey->ValueList.List = HCELL_NIL; 00818 ptarkey->ValueList.Count = 0; 00819 success = TRUE; 00820 } else { 00821 00822 psrclist = HvGetCell(SourceHive, psrckey->u.KeyNode.ValueList.List); 00823 00824 newlist = HvAllocateCell( 00825 TargetHive, 00826 count * sizeof(HCELL_INDEX), 00827 Type 00828 ); 00829 if (newlist == HCELL_NIL) { 00830 goto DoFinally; 00831 } 00832 ptarkey->ValueList.List = newlist; 00833 ptarlist = HvGetCell(TargetHive, newlist); 00834 00835 00836 // 00837 // Copy the values 00838 // 00839 for (i = 0; i < count; i++) { 00840 00841 newvalue = CmpCopyValue( 00842 SourceHive, 00843 psrclist->u.KeyList[i], 00844 TargetHive, 00845 Type 00846 ); 00847 00848 if (newvalue != HCELL_NIL) { 00849 00850 ptarlist->u.KeyList[i] = newvalue; 00851 00852 } else { 00853 00854 for (; i > 0; i--) { 00855 HvFreeCell( 00856 TargetHive, 00857 ptarlist->u.KeyList[i - 1] 00858 ); 00859 } 00860 goto DoFinally; 00861 } 00862 } 00863 success = TRUE; 00864 } 00865 00866 DoFinally: 00867 if (success == FALSE) { 00868 00869 if (newlist != HCELL_NIL) { 00870 HvFreeCell(TargetHive, newlist); 00871 } 00872 00873 if (newsecurity != HCELL_NIL) { 00874 HvFreeCell(TargetHive, newsecurity); 00875 } 00876 00877 if (newclass != HCELL_NIL) { 00878 HvFreeCell(TargetHive, newclass); 00879 } 00880 00881 if (newkey != HCELL_NIL) { 00882 HvFreeCell(TargetHive, newkey); 00883 } 00884 00885 return HCELL_NIL; 00886 00887 } else { 00888 00889 return newkey; 00890 } 00891 }

BOOLEAN CmpCopySyncTree PHHIVE  SourceHive,
HCELL_INDEX  SourceCell,
PHHIVE  TargetHive,
HCELL_INDEX  TargetCell,
BOOLEAN  CopyVolatile,
CMP_COPY_TYPE  CopyType
 

Definition at line 127 of file cmtrecpy.c.

References CML_MAJOR, CMLOG, CMP_INITIAL_STACK_SIZE, CmpCopySyncTree2(), CMS_SAVRES, ExAllocatePool, ExFreePool(), FALSE, NULL, PagedPool, and PCMP_COPY_STACK_ENTRY.

00137 : 00138 00139 This routine can perform two distinct (yet similar) tasks: 00140 a tree copy or a tree synchronization (sync). Which task 00141 is performed is determined by the TreeSync parameter. 00142 00143 For both operations: 00144 -------------------- 00145 00146 The source root key and target root key must exist in advance. 00147 These root nodes and their value entries will NOT be copied/synced. 00148 00149 NOTE: Volatile keys are only copied/synced if the CopyVolatile 00150 parameter is set to true. 00151 00152 00153 For a tree copy: 00154 ---------------- 00155 00156 A tree is copied from source to destination. The subkeys 00157 of the source root key and the full trees under those 00158 subkeys will be copied to a new tree at target root key. 00159 00160 NOTE: If this call fails part way through, it will NOT undo 00161 any successfully completed key copies, thus a partial 00162 tree copy CAN occur. 00163 00164 For a tree sync: 00165 ---------------- 00166 00167 The target tree is synchronized with the source tree. It is 00168 assumed that for a certain period of the time the target tree 00169 has remained unmodified while modifications may have been made 00170 to the source tree. During a sync, any such modifications 00171 to the source tree are made to the target tree. Thus, at the 00172 end of a successful sync, the target tree is identical to the 00173 source tree. 00174 00175 Since only things that have changed in the source tree 00176 are modified in the target tree, a sync operation is far 00177 more efficient than the delete/copy operations necessary 00178 to accomplish the same results. 00179 00180 NOTE: It is assumed that no open handles are held 00181 on any target tree keys. Registry in-memory data 00182 structures may be corrupted if this is not true. 00183 00184 Arguments: 00185 00186 SourceHive - pointer to hive control structure for source 00187 00188 SourceCell - index of cell at root of tree to copy/sync 00189 00190 TargetHive - pointer to hive control structure for target 00191 00192 TargetCell - pointer to cell at root of target tree 00193 00194 CopyVolatile - indicates whether volatile keys should be 00195 copied/synced. 00196 00197 CopyType - indicates the type of the copy operation: 00198 Copy - A copy is requested 00199 Sync - A sync is requested 00200 Merge - A merge is requested i.e.: 00201 1. the target nodes that are not present on the source tree are not 00202 deleted. 00203 2. the target nodes that are present in the source tree gets overrided 00204 no matter what the LastWriteTime value is. 00205 Return Value: 00206 00207 BOOLEAN - Result code from call, among the following: 00208 TRUE - it worked 00209 FALSE - the tree copy/sync was not completed (though more than 0 00210 keys may have been copied/synced) 00211 00212 --*/ 00213 { 00214 BOOLEAN result; 00215 PCMP_COPY_STACK_ENTRY CmpCopyStack; 00216 00217 CMLOG(CML_MAJOR, CMS_SAVRES) { 00218 KdPrint(("CmpCopyTree:\n")); 00219 } 00220 00221 CmpCopyStack = ExAllocatePool( 00222 PagedPool, 00223 sizeof(CMP_COPY_STACK_ENTRY)*CMP_INITIAL_STACK_SIZE 00224 ); 00225 if (CmpCopyStack == NULL) { 00226 return FALSE; 00227 } 00228 CmpCopyStack[0].SourceCell = SourceCell; 00229 CmpCopyStack[0].TargetCell = TargetCell; 00230 00231 result = CmpCopySyncTree2( 00232 CmpCopyStack, 00233 CMP_INITIAL_STACK_SIZE, 00234 0, 00235 SourceHive, 00236 TargetHive, 00237 CopyVolatile, 00238 CopyType 00239 ); 00240 00241 ExFreePool(CmpCopyStack); 00242 return result; 00243 }

BOOLEAN CmpCopySyncTree2 PCMP_COPY_STACK_ENTRY  CmpCopyStack,
ULONG  CmpCopyStackSize,
ULONG  CmpCopyStackTop,
PHHIVE  CmpSourceHive,
PHHIVE  CmpTargetHive,
BOOLEAN  CopyVolatile,
CMP_COPY_TYPE  CopyType
 

Definition at line 251 of file cmtrecpy.c.

References CML_MINOR, CMLOG, CmpAddSubKey(), CmpCopyKeyPartial(), CmpFindSubKeyByName(), CmpFindSubKeyByNumber(), CmpInitializeKeyNameString(), CmpMarkKeyParentDirty(), CmpMergeKeyValues(), CmpSyncKeyValues(), CmpSyncSubKeysAfterDelete(), CMS_SAVRES, ExAllocatePool, ExFreePool(), FALSE, HCELL_INDEX, HCELL_NIL, HvGetCell, HvGetCellType, KeyName, _CM_KEY_NODE::LastWriteTime, MAX_KEY_NAME_LENGTH, Merge, NULL, PagedPool, PCMP_COPY_STACK_ENTRY, Stable, _CM_KEY_NODE::SubKeyCounts, Sync, TRUE, and Volatile.

Referenced by CmpCopySyncTree().

00262 : 00263 00264 This is a helper routine for CmpCopySyncTree. It accomplishes 00265 the functionality described by that routine in a "virtually" 00266 recursive manner which frees this routine from the limitations 00267 of the Kernel stack. 00268 00269 This routine should not be called directly. Use CmpCopySyncTree!. 00270 00271 Arguments: 00272 00273 (All of these are "virtual globals") 00274 00275 CmpCopyStack - "global" pointer to stack for frames 00276 00277 CmpCopyStackSize - alloced size of stack 00278 00279 CmpCopyStackTop - current top 00280 00281 CmpSourceHive, CmpTargetHive - source and target hives 00282 00283 CopyVolatile, CopyType - same as CmpCopySyncTree. 00284 00285 00286 Return Value: 00287 00288 BOOLEAN - Result code from call, among the following: 00289 TRUE - it worked 00290 FALSE - the tree copy/sync was not completed (though more than 0 00291 keys may have been copied/synced) 00292 00293 --*/ 00294 { 00295 PCMP_COPY_STACK_ENTRY Frame; 00296 HCELL_INDEX SourceChild; 00297 HCELL_INDEX NewSubKey; 00298 00299 BOOLEAN Ret = FALSE, SyncNeedsTreeCopy = FALSE; 00300 UNICODE_STRING KeyName; 00301 PCM_KEY_NODE SourceChildCell, TargetChildCell; 00302 PCM_KEY_NODE SourceCell, TargetCell; 00303 ULONG SyncTreeCopyStackStart; 00304 WCHAR *NameBuffer = NULL; 00305 00306 // A merge is a particular case of a sync !!! 00307 BOOLEAN TreeSync = (CopyType == Sync || CopyType == Merge)?TRUE:FALSE; 00308 00309 CMLOG(CML_MINOR, CMS_SAVRES) { 00310 KdPrint(("CmpCopyTree2:\n")); 00311 } 00312 00313 if (TreeSync) { 00314 00315 // 00316 // The sync operation involves some work with key names, 00317 // so we must allocate a buffer used for key name decompression. 00318 // 00319 00320 NameBuffer = ExAllocatePool(PagedPool, MAX_KEY_NAME_LENGTH); 00321 if(!NameBuffer) return FALSE; 00322 00323 } 00324 00325 // 00326 // outer loop, apply to entire tree, emulate recursion here 00327 // jump to here is a virtual call 00328 // 00329 Outer: while (TRUE) { 00330 00331 Frame = &(CmpCopyStack[CmpCopyStackTop]); 00332 00333 Frame->i = 0; 00334 00335 // 00336 // inner loop, applies to one key 00337 // jump to here is a virtual return 00338 // 00339 Inner: while (TRUE) { 00340 00341 SourceCell = (PCM_KEY_NODE)HvGetCell(CmpSourceHive, Frame->SourceCell); 00342 00343 SourceChild = CmpFindSubKeyByNumber(CmpSourceHive, 00344 SourceCell, 00345 Frame->i); 00346 (Frame->i)++; 00347 00348 if ((SourceChild == HCELL_NIL) || (!CopyVolatile && 00349 (HvGetCellType(SourceChild) == Volatile))) { 00350 00351 // 00352 // we've stepped through all the children (or we are only 00353 // interested in stable children and have just stepped through 00354 // the stable children and into the volatile ones) 00355 // 00356 00357 if(TreeSync && (CopyType != Merge)) 00358 { 00359 // 00360 // If we are here during a sync, that means most of sync operations 00361 // applied to the current SourceCell have been completed. 00362 // That is, we have: 00363 // 1) Synchronized SourceCell's values with its counterpart in the 00364 // target tree. 00365 // 2) Synchronized any new SourceCell subkeys (subkeys present 00366 // in SourceCell but not its counterpart) by creating 00367 // and copying them to the proper place in the target tree. 00368 // 00369 // What this means is that SourceCell's counterpart in the target tree 00370 // (TargetCell) now has at least as many subkeys as SourceCell. 00371 // 00372 // This implies that if TargetCell now has more subkeys that SourceCell 00373 // than some subkeys of TargetCell are not present in the source tree 00374 // (probably because those keys were deleted from the source tree 00375 // during the period between the previous sync and now). 00376 // 00377 // If such keys exist, then they must be delete them from TargetCell 00378 // in order to complete the sync. We do this below. 00379 // 00380 00381 TargetCell = (PCM_KEY_NODE)HvGetCell(CmpTargetHive, Frame->TargetCell); 00382 00383 // 00384 // Does TargetCell have more subkeys than SourceCell? 00385 // 00386 00387 if((TargetCell->SubKeyCounts[Stable] + 00388 TargetCell->SubKeyCounts[Volatile]) > 00389 (SourceCell->SubKeyCounts[Stable] + 00390 00391 // We only count the volatile keys if we are actually 00392 // syncing them. Note, however, that we always use 00393 // the volatile counts in TargetCell since we may 00394 // be syncing to a volatile tree where all keys are volatile. 00395 00396 (CopyVolatile ? SourceCell->SubKeyCounts[Volatile] : 0))) 00397 00398 { 00399 #if DEBUG_TREE_SYNC 00400 KdPrint(("CONFIG: SubKey Deletion from Source Cell #%lu.\n", 00401 Frame->SourceCell)); 00402 #endif 00403 00404 // 00405 // Delete what should be deleted from TargetCell 00406 // 00407 00408 CmpSyncSubKeysAfterDelete(CmpSourceHive, 00409 SourceCell, 00410 CmpTargetHive, 00411 TargetCell, 00412 NameBuffer); 00413 } 00414 } 00415 00416 break; 00417 } 00418 00419 if (TreeSync) { 00420 00421 // 00422 // For a sync, we want to check if the current child (subkey) 00423 // of SourceCell is also a child of TargetCell - i.e. if 00424 // the subkey in question has a counterpart in the target tree. 00425 // 00426 // There is no guarantee that the counterpart's index number 00427 // will be the same so we must perform this check using 00428 // the subkey name. 00429 // 00430 00431 // 00432 // Get the name of the current child 00433 // 00434 00435 SourceChildCell = (PCM_KEY_NODE)HvGetCell(CmpSourceHive, 00436 SourceChild); 00437 00438 CmpInitializeKeyNameString(SourceChildCell, 00439 &KeyName, 00440 NameBuffer); 00441 00442 // 00443 // Try to find the current child's counterpart in 00444 // in the target tree using the child's name. 00445 // 00446 00447 NewSubKey = CmpFindSubKeyByName(CmpTargetHive, 00448 (PCM_KEY_NODE)HvGetCell(CmpTargetHive, 00449 Frame->TargetCell), 00450 &KeyName); 00451 00452 00453 if (NewSubKey != HCELL_NIL) { 00454 00455 // 00456 // Found it, the current child (subkey) has a counterpart 00457 // in the target tree. Thus, we just need to check if 00458 // the counterpart's values are out of date and should 00459 // be updated. 00460 // 00461 00462 TargetChildCell = (PCM_KEY_NODE)HvGetCell(CmpTargetHive, 00463 NewSubKey); 00464 00465 // 00466 // Check if the current subkey has been modified 00467 // more recently than its target tree counterpart. 00468 // When we are doing a tree merge, always override the target. 00469 // 00470 00471 if ( (CopyType == Merge) || 00472 ((TargetChildCell->LastWriteTime.QuadPart) < 00473 (SourceChildCell->LastWriteTime.QuadPart))) { 00474 00475 // 00476 // The counterpart is out of date. Its values 00477 // must be synchornized with the current subkey. 00478 // 00479 #if DEBUG_TREE_SYNC 00480 KdPrint(("CONFIG: Target Refresh.\n")); 00481 KdPrint(("CONFIG: Source Cell %lu = %.*S\n", 00482 SourceChild, 00483 KeyName.Length / sizeof(WCHAR), 00484 KeyName.Buffer)); 00485 #endif 00486 00487 // 00488 // Sync up the key's values, sd, & class 00489 // 00490 00491 if(CopyType == Merge) { 00492 if(!CmpMergeKeyValues(CmpSourceHive, SourceChild, SourceChildCell, 00493 CmpTargetHive, NewSubKey, TargetChildCell)) { 00494 goto CopyEnd; 00495 } 00496 } else { 00497 if(!CmpSyncKeyValues(CmpSourceHive, SourceChild, SourceChildCell, 00498 CmpTargetHive, NewSubKey, TargetChildCell)) { 00499 goto CopyEnd; 00500 } 00501 } 00502 00503 // 00504 // Sync the timestamps so that we don't do this again. 00505 // 00506 00507 TargetChildCell->LastWriteTime.QuadPart = 00508 SourceChildCell->LastWriteTime.QuadPart; 00509 00510 } 00511 00512 // 00513 // If we are here, then the current subkey's target 00514 // tree counterpart has been synchronized (or did not need 00515 // to be). Transfer control to the code that will apply 00516 // this function "recursively" to the current subkey in order 00517 // to continue the sync. 00518 // 00519 00520 goto NewKeyCreated; 00521 00522 } 00523 00524 // 00525 // If we are here, it means that the current child (subkey) 00526 // does not have a counterpart in the target tree. This means 00527 // we have encountered a new subkey in the source tree and must 00528 // create it in the target tree. 00529 // 00530 // The standard copy code below will create this subkey. However, 00531 // we must also make sure that the tree under this subkey is properly 00532 // copied from source to target. The most efficient way of doing 00533 // this is to temporarily forget that we are in a sync operation 00534 // and merely perform a copy until the desired result is achieved. 00535 // 00536 00537 #if DEBUG_TREE_SYNC 00538 KdPrint(("CONFIG: New SubKey.\n")); 00539 KdPrint(("CONFIG: Source Cell %lu = %.*S\n", 00540 SourceChild, 00541 KeyName.Length / sizeof(WCHAR), 00542 KeyName.Buffer)); 00543 #endif 00544 00545 // 00546 // Indicate that we will just copy and not sync for a while 00547 // 00548 00549 SyncNeedsTreeCopy = TRUE; 00550 00551 } 00552 00553 NewSubKey = CmpCopyKeyPartial( 00554 CmpSourceHive, 00555 SourceChild, 00556 CmpTargetHive, 00557 Frame->TargetCell, 00558 TRUE 00559 ); 00560 00561 00562 if (NewSubKey == HCELL_NIL) { 00563 00564 goto CopyEnd; 00565 } 00566 00567 if ( ! CmpAddSubKey( 00568 CmpTargetHive, 00569 Frame->TargetCell, 00570 NewSubKey 00571 ) 00572 ) { 00573 00574 goto CopyEnd; 00575 } 00576 00577 // 00578 // Check if the sync operation determined that this 00579 // subtree should be copied 00580 // 00581 00582 if(TreeSync && SyncNeedsTreeCopy) { 00583 00584 // 00585 // We have just created a new key in the target tree 00586 // with the above code. However, since this is a sync, 00587 // the parent of that new key has not been created by our 00588 // code and thus may not have been modified at all before 00589 // the creation of the new key. But this parent now 00590 // has a new child, and must therefore be marked as dirty. 00591 // 00592 00593 if (! CmpMarkKeyParentDirty(CmpTargetHive, NewSubKey)) { 00594 00595 goto CopyEnd; 00596 } 00597 00598 // 00599 // Record the stack level where we start the copy 00600 // (and temporarily abandon the sync) 00601 // so that we can return to the sync operation when this 00602 // stack level is reached again (i.e. when the tree 00603 // under the current subkey is fully copied) 00604 // 00605 00606 SyncTreeCopyStackStart = CmpCopyStackTop; 00607 00608 // 00609 // Pretend that this is not a sync in order 00610 // to simply start copying 00611 // 00612 00613 TreeSync = FALSE; 00614 } 00615 00616 NewKeyCreated: 00617 00618 // 00619 // We succeeded in copying/syncing the subkey, apply 00620 // ourselves to it 00621 // 00622 CmpCopyStackTop++; 00623 00624 if (CmpCopyStackTop >= CmpCopyStackSize) { 00625 00626 // 00627 // if we're here, it means that the tree 00628 // we're trying to copy is more than 1024 00629 // COMPONENTS deep (from 2048 to 256k bytes) 00630 // we could grow the stack, but this is pretty 00631 // severe, so return FALSE and fail the copy 00632 // 00633 00634 goto CopyEnd; 00635 } 00636 00637 CmpCopyStack[CmpCopyStackTop].SourceCell = 00638 SourceChild; 00639 00640 CmpCopyStack[CmpCopyStackTop].TargetCell = 00641 NewSubKey; 00642 00643 goto Outer; 00644 00645 00646 } // Inner: while 00647 00648 if (CmpCopyStackTop == 0) { 00649 Ret = TRUE; 00650 goto CopyEnd; 00651 } 00652 00653 CmpCopyStackTop--; 00654 Frame = &(CmpCopyStack[CmpCopyStackTop]); 00655 00656 // 00657 // We have just completed working at a certain stack level. 00658 // This is a good time to check if we need to resume a temporarily 00659 // suspended sync operation. 00660 // 00661 00662 if(SyncNeedsTreeCopy && (CmpCopyStackTop == SyncTreeCopyStackStart)) 00663 { 00664 // 00665 // We've been copying a tree for a sync. But now, that tree is fully 00666 // copied. So, let's resume the sync once again. 00667 // 00668 00669 TreeSync = TRUE; 00670 SyncNeedsTreeCopy = FALSE; 00671 } 00672 00673 00674 goto Inner; 00675 00676 } // Outer: while 00677 00678 CopyEnd: 00679 00680 if (NameBuffer) ExFreePool(NameBuffer); 00681 return Ret; 00682 }

HCELL_INDEX CmpCopyValue PHHIVE  SourceHive,
HCELL_INDEX  SourceValueCell,
PHHIVE  TargetHive,
HSTORAGE_TYPE  Type
 

Definition at line 895 of file cmtrecpy.c.

References CM_KEY_VALUE_SMALL, CM_KEY_VALUE_SPECIAL_SIZE, CML_MINOR, CMLOG, CmpCopyCell(), CmpIsHKeyValueSmall, CMS_SAVRES, _CM_KEY_VALUE::Data, _CM_KEY_VALUE::DataLength, HCELL_INDEX, HCELL_NIL, HvFreeCell(), HvGetCell, _CELL_DATA::_u::KeyValue, and _CELL_DATA::u.

Referenced by CmpCopyKeyPartial(), CmpMergeKeyValues(), and CmpSyncKeyValues().

00903 : 00904 00905 Copy a value entry. Copies the body of a value entry and the 00906 data. Returns cell of new value entry. 00907 00908 Arguments: 00909 00910 SourceHive - pointer to hive control structure for source 00911 00912 SourceValueCell - value entry being copied 00913 00914 TargetHive - pointer to hive control structure for target 00915 00916 Type - storage type to allocate for target (stable or volatile) 00917 00918 Return Value: 00919 00920 HCELL_INDEX - Cell of body of new value entry, or HCELL_NIL 00921 if some error. 00922 00923 --*/ 00924 { 00925 HCELL_INDEX newvalue; 00926 HCELL_INDEX newdata; 00927 PCELL_DATA pvalue; 00928 ULONG datalength; 00929 HCELL_INDEX olddata; 00930 ULONG tempdata; 00931 BOOLEAN small; 00932 00933 CMLOG(CML_MINOR, CMS_SAVRES) { 00934 KdPrint(("CmpCopyValue:\n")); 00935 KdPrint(("\tSHive=%08lx SCell=%08lx\n",SourceHive,SourceValueCell)); 00936 KdPrint(("\tTargetHive=%08lx\n",TargetHive)); 00937 } 00938 00939 // 00940 // get source data 00941 // 00942 pvalue = HvGetCell(SourceHive, SourceValueCell); 00943 small = CmpIsHKeyValueSmall(datalength, pvalue->u.KeyValue.DataLength); 00944 olddata = pvalue->u.KeyValue.Data; 00945 00946 // 00947 // Copy body 00948 // 00949 newvalue = CmpCopyCell(SourceHive, SourceValueCell, TargetHive, Type); 00950 if (newvalue == HCELL_NIL) { 00951 return HCELL_NIL; 00952 } 00953 00954 // 00955 // Copy data (if any) 00956 // 00957 if (datalength > 0) { 00958 00959 if (datalength > CM_KEY_VALUE_SMALL) { 00960 00961 // 00962 // there's data, and it's "big", so do standard copy 00963 // 00964 newdata = CmpCopyCell(SourceHive, olddata, TargetHive, Type); 00965 00966 if (newdata == HCELL_NIL) { 00967 HvFreeCell(TargetHive, newvalue); 00968 return HCELL_NIL; 00969 } 00970 00971 pvalue = HvGetCell(TargetHive, newvalue); 00972 pvalue->u.KeyValue.Data = newdata; 00973 pvalue->u.KeyValue.DataLength = datalength; 00974 00975 } else { 00976 00977 // 00978 // the data is small, but may be stored in either large or 00979 // small format for historical reasons 00980 // 00981 if (small) { 00982 00983 // 00984 // data is already small, so just do a body to body copy 00985 // 00986 tempdata = pvalue->u.KeyValue.Data; 00987 00988 } else { 00989 00990 // 00991 // data is stored externally in old cell, will be internal in new 00992 // 00993 pvalue = HvGetCell(SourceHive, pvalue->u.KeyValue.Data); 00994 tempdata = *((PULONG)pvalue); 00995 } 00996 pvalue = HvGetCell(TargetHive, newvalue); 00997 pvalue->u.KeyValue.Data = tempdata; 00998 pvalue->u.KeyValue.DataLength = 00999 datalength + CM_KEY_VALUE_SPECIAL_SIZE; 01000 01001 } 01002 } 01003 01004 return newvalue; 01005 }

BOOLEAN CmpFreeKeyValues PHHIVE  Hive,
HCELL_INDEX  Cell,
PCM_KEY_NODE  Node
 

Definition at line 1064 of file cmtrecpy.c.

References Cell, _CM_KEY_NODE::Class, _CM_KEY_NODE::ClassLength, CmpFreeSecurityDescriptor(), CmpFreeValue(), CmpMarkKeyValuesDirty(), _CHILD_LIST::Count, FALSE, _CM_KEY_NODE::Flags, HCELL_NIL, Hive, HvFreeCell(), HvGetCell, KEY_HIVE_EXIT, _CELL_DATA::_u::KeyList, _CHILD_LIST::List, TRUE, _CELL_DATA::u, and _CM_KEY_NODE::ValueList.

Referenced by CmpSyncKeyValues().

01071 : 01072 01073 Free the cells associated with the value entries, the security descriptor, 01074 and the class of a particular key. 01075 01076 Arguments: 01077 01078 Hive - The hive of the key in question 01079 Cell - The cell of the key in question 01080 Node - The key body of the key in question 01081 01082 Return Value: 01083 01084 TRUE if successful, FALSE otherwise. 01085 01086 --*/ 01087 { 01088 PCELL_DATA plist; 01089 ULONG i; 01090 01091 // 01092 // Mark all the value-related cells dirty 01093 // 01094 01095 if (! CmpMarkKeyValuesDirty(Hive, Cell, Node)) { 01096 return FALSE; 01097 } 01098 01099 // 01100 // Link nodes don't have things that we need to free 01101 // 01102 01103 if (!(Node->Flags & KEY_HIVE_EXIT)) { 01104 01105 // 01106 // First, free the value entries 01107 // 01108 if (Node->ValueList.Count > 0) { 01109 01110 // Get value list 01111 plist = HvGetCell(Hive, Node->ValueList.List); 01112 01113 // Free each value 01114 for (i = 0; i < Node->ValueList.Count; i++) { 01115 CmpFreeValue(Hive, plist->u.KeyList[i]); 01116 } 01117 01118 // Free the value list 01119 HvFreeCell(Hive, Node->ValueList.List); 01120 } 01121 01122 // 01123 // Make this key value-less 01124 // 01125 01126 Node->ValueList.List = HCELL_NIL; 01127 Node->ValueList.Count = 0; 01128 01129 // 01130 // Free the security descriptor 01131 // 01132 CmpFreeSecurityDescriptor(Hive, Cell); 01133 01134 // 01135 // Free the Class information 01136 // 01137 01138 if (Node->ClassLength > 0) { 01139 HvFreeCell(Hive, Node->Class); 01140 Node->Class = HCELL_NIL; 01141 Node->ClassLength = 0; 01142 } 01143 01144 } 01145 01146 return TRUE; 01147 }

VOID CmpInitializeKeyNameString PCM_KEY_NODE  Cell,
PUNICODE_STRING  KeyName,
WCHAR *  NameBuffer
 

Definition at line 1515 of file cmtrecpy.c.

References Cell, CmpCompressedNameSize(), CmpCopyCompressedName(), KEY_COMP_NAME, KeyName, MAX_KEY_NAME_LENGTH, and USHORT.

Referenced by CmpCopySyncTree2(), CmpFlushNotify(), CmpFreePostBlock(), CmpNotifyChangeKey(), CmpPostNotify(), and CmpSyncSubKeysAfterDelete().

01521 : 01522 01523 Initializes a UNICODE_STRING with the name of a given key. 01524 01525 N.B. The initialized string's buffer is not meant 01526 to be modified. 01527 01528 Arguments: 01529 01530 Cell - The body of the key in question 01531 KeyName - The UNICODE_STRING to initialize 01532 NameBuffer - A buffer MAX_KEY_NAME_LENGTH bytes in size 01533 that will possibly be used as the UNICODE_STRING's 01534 buffer. 01535 01536 Return Value: 01537 01538 NONE. 01539 01540 --*/ 01541 { 01542 // is the name stored in compressed form? 01543 01544 if(Cell->Flags & KEY_COMP_NAME) { 01545 01546 // Name is compressed. 01547 01548 // Get the uncompressed length. 01549 01550 KeyName->Length = CmpCompressedNameSize(Cell->Name, 01551 Cell->NameLength); 01552 01553 // Decompress the name into a buffer. 01554 01555 CmpCopyCompressedName(NameBuffer, 01556 MAX_KEY_NAME_LENGTH, 01557 Cell->Name, 01558 Cell->NameLength); 01559 01560 // 01561 // Use the decompression buffer as the string buffer 01562 // 01563 01564 KeyName->Buffer = NameBuffer; 01565 KeyName->MaximumLength = MAX_KEY_NAME_LENGTH; 01566 01567 } else { 01568 01569 // 01570 // Name is not compressed. Just use the name string 01571 // from the key buffer as the string buffer. 01572 // 01573 01574 KeyName->Length = Cell->NameLength; 01575 KeyName->Buffer = Cell->Name; 01576 KeyName->MaximumLength = (USHORT)Cell->MaxNameLen; 01577 01578 } 01579 }

VOID CmpInitializeValueNameString PCM_KEY_VALUE  Cell,
PUNICODE_STRING  ValueName,
WCHAR *  NameBuffer
 

Definition at line 1582 of file cmtrecpy.c.

References Cell, CmpCompressedNameSize(), CmpCopyCompressedName(), MAX_KEY_VALUE_NAME_LENGTH, VALUE_COMP_NAME, and ValueName.

Referenced by CmpMergeKeyValues().

01587 : 01588 01589 Initializes a UNICODE_STRING with the name of a given value key. 01590 01591 N.B. The initialized string's buffer is not meant 01592 to be modified. 01593 01594 Arguments: 01595 01596 Cell - The value key in question 01597 ValueName - The UNICODE_STRING to initialize 01598 NameBuffer - A buffer MAX_KEY_NAME_LENGTH bytes in size 01599 that will possibly be used as the UNICODE_STRING's 01600 buffer. 01601 01602 Return Value: 01603 01604 NONE. 01605 */ 01606 01607 { 01608 // is the name stored in compressed form? 01609 01610 if(Cell->Flags & VALUE_COMP_NAME) { 01611 01612 // Name is compressed. 01613 01614 // Get the uncompressed length. 01615 01616 ValueName->Length = CmpCompressedNameSize(Cell->Name, 01617 Cell->NameLength); 01618 01619 // Decompress the name into a buffer. 01620 01621 CmpCopyCompressedName(NameBuffer, 01622 MAX_KEY_VALUE_NAME_LENGTH, 01623 Cell->Name, 01624 Cell->NameLength); 01625 01626 // 01627 // Use the decompression buffer as the string buffer 01628 // 01629 01630 ValueName->Buffer = NameBuffer; 01631 ValueName->MaximumLength = MAX_KEY_VALUE_NAME_LENGTH; 01632 01633 } else { 01634 01635 // 01636 // Name is not compressed. Just use the name string 01637 // from the ValueName buffer as the string buffer. 01638 // 01639 01640 ValueName->Length = Cell->NameLength; 01641 ValueName->Buffer = Cell->Name; 01642 ValueName->MaximumLength = ValueName->Length; 01643 01644 } 01645 }

BOOLEAN CmpMarkKeyParentDirty PHHIVE  Hive,
HCELL_INDEX  Cell
 

Definition at line 1870 of file cmtrecpy.c.

References Cell, CmpMarkIndexDirty(), FALSE, _CM_KEY_NODE::Flags, Hive, HvGetCell, HvMarkCellDirty(), KEY_HIVE_ENTRY, _CELL_DATA::_u::KeyNode, _CM_KEY_NODE::Parent, TRUE, and _CELL_DATA::u.

Referenced by CmpCopySyncTree2().

01876 : 01877 01878 Marks the parent of a given key and the parent's subkey list as dirty. 01879 01880 Arguments: 01881 01882 Hive - The hive of the key in question. 01883 Cell - The cell of the key in question. 01884 01885 01886 Return Value: 01887 01888 TRUE if successful, FALSE otherwise. 01889 01890 A failure probably indicates that no log space was available. 01891 01892 --*/ 01893 { 01894 01895 PCELL_DATA ptarget; 01896 01897 // 01898 // Map in the target 01899 // 01900 ptarget = HvGetCell(Hive, Cell); 01901 01902 01903 if (ptarget->u.KeyNode.Flags & KEY_HIVE_ENTRY) { 01904 01905 // 01906 // if this is an entry node, we are done. our parent will 01907 // be in the master hive (and thus volatile) 01908 // 01909 return TRUE; 01910 } 01911 01912 // 01913 // Mark the parent's Subkey list 01914 // 01915 if (! CmpMarkIndexDirty(Hive, ptarget->u.KeyNode.Parent, Cell)) { 01916 return FALSE; 01917 } 01918 01919 // 01920 // Mark the parent 01921 // 01922 if (! HvMarkCellDirty(Hive, ptarget->u.KeyNode.Parent)) { 01923 return FALSE; 01924 } 01925 01926 return TRUE; 01927 } }

BOOLEAN CmpMarkKeyValuesDirty PHHIVE  Hive,
HCELL_INDEX  Cell,
PCM_KEY_NODE  Node
 

Definition at line 1767 of file cmtrecpy.c.

References _CM_KEY_SECURITY::Blink, Cell, _CM_KEY_NODE::Class, CmpIsHKeyValueSmall, _CHILD_LIST::Count, _CM_KEY_VALUE::Data, _CM_KEY_VALUE::DataLength, FALSE, _CM_KEY_NODE::Flags, _CM_KEY_SECURITY::Flink, HCELL_NIL, Hive, HvGetCell, HvMarkCellDirty(), KEY_HIVE_EXIT, _CELL_DATA::_u::KeyList, _CELL_DATA::_u::KeySecurity, _CELL_DATA::_u::KeyValue, _CHILD_LIST::List, _CM_KEY_NODE::Security, TRUE, _CELL_DATA::u, and _CM_KEY_NODE::ValueList.

Referenced by CmpFreeKeyValues().

01774 : 01775 01776 01777 Marks the cells associated with a key's value entries, security descriptor, 01778 and class information as dirty. 01779 01780 Arguments: 01781 01782 Hive - The hive of the key in question 01783 Cell - The cell of the key in question 01784 Node - The body of the key in question 01785 01786 01787 Return Value: 01788 01789 TRUE if successful, FALSE otherwise. 01790 01791 A failure probably indicates that no log space was available. 01792 01793 --*/ 01794 { 01795 PCELL_DATA plist, security, pvalue; 01796 ULONG i, realsize; 01797 01798 if (Node->Flags & KEY_HIVE_EXIT) { 01799 01800 // 01801 // If this is a link node, we are done. Link nodes never have 01802 // classes, values, subkeys, or security descriptors. Since 01803 // they always reside in the master hive, they're always volatile. 01804 // 01805 return(TRUE); 01806 } 01807 01808 // 01809 // mark cell itself 01810 // 01811 if (! HvMarkCellDirty(Hive, Cell)) { 01812 return FALSE; 01813 } 01814 01815 // 01816 // Mark the class 01817 // 01818 if (Node->Class != HCELL_NIL) { 01819 if (! HvMarkCellDirty(Hive, Node->Class)) { 01820 return FALSE; 01821 } 01822 } 01823 01824 // 01825 // Mark security 01826 // 01827 if (Node->Security != HCELL_NIL) { 01828 if (! HvMarkCellDirty(Hive, Node->Security)) { 01829 return FALSE; 01830 } 01831 01832 security = HvGetCell(Hive, Node->Security); 01833 if (! (HvMarkCellDirty(Hive, security->u.KeySecurity.Flink) && 01834 HvMarkCellDirty(Hive, security->u.KeySecurity.Blink))) 01835 { 01836 return FALSE; 01837 } 01838 } 01839 01840 // 01841 // Mark the value entries and their data 01842 // 01843 if (Node->ValueList.Count > 0) { 01844 01845 // Value list 01846 if (! HvMarkCellDirty(Hive, Node->ValueList.List)) { 01847 return FALSE; 01848 } 01849 plist = HvGetCell(Hive, Node->ValueList.List); 01850 01851 for (i = 0; i < Node->ValueList.Count; i++) { 01852 if (! HvMarkCellDirty(Hive, plist->u.KeyList[i])) { 01853 return FALSE; 01854 } 01855 01856 pvalue = HvGetCell(Hive, plist->u.KeyList[i]); 01857 01858 if (!CmpIsHKeyValueSmall(realsize, pvalue->u.KeyValue.DataLength)) { 01859 if (! HvMarkCellDirty(Hive, pvalue->u.KeyValue.Data)) { 01860 return(FALSE); 01861 } 01862 } 01863 } 01864 } 01865 01866 return TRUE; 01867 }

BOOLEAN CmpMergeKeyValues PHHIVE  SourceHive,
HCELL_INDEX  SourceKeyCell,
PCM_KEY_NODE  SourceKeyNode,
PHHIVE  TargetHive,
HCELL_INDEX  TargetKeyCell,
PCM_KEY_NODE  TargetKeyNode
 

Referenced by CmpCopySyncTree2(), and CmSaveMergedKeys().

BOOLEAN CmpSyncKeyValues PHHIVE  SourceHive,
HCELL_INDEX  SourceKeyCell,
PCM_KEY_NODE  SourceKeyNode,
PHHIVE  TargetHive,
HCELL_INDEX  TargetKeyCell,
PCM_KEY_NODE  TargetKeyNode
 

Definition at line 1338 of file cmtrecpy.c.

References _CM_KEY_NODE::Class, _CM_KEY_NODE::ClassLength, CmpAssignSecurityDescriptor(), CmpCopyCell(), CmpCopyValue(), CmpFreeKeyValues(), _CHILD_LIST::Count, _CM_KEY_SECURITY::Descriptor, FALSE, HCELL_INDEX, HCELL_NIL, HvAllocateCell(), HvFreeCell(), HvGetCell, HvGetCellType, _CELL_DATA::_u::KeyList, _CELL_DATA::_u::KeySecurity, _CHILD_LIST::List, NT_SUCCESS, NTSTATUS(), _CM_KEY_NODE::Security, TRUE, _CELL_DATA::u, and _CM_KEY_NODE::ValueList.

Referenced by CmpCopySyncTree2(), and CmpMergeKeyValues().

01348 : 01349 01350 Synchronizes the value entries, security descriptor, and class of a 01351 target key with that of a source key - ensuring that the keys are 01352 identical with respect to the synchronized information. 01353 01354 Arguments: 01355 01356 SourceHive - Hive of the source key 01357 SourceKeyCell - The source key's cell 01358 SourceKeyNode - The source key's body 01359 01360 TargetHive - Hive of the target key 01361 TargetKeyCell - The target key's cell 01362 TargetKeyNode - The target key's body 01363 01364 Return Value: 01365 01366 TRUE of successful, FALSE otherwise. 01367 01368 --*/ 01369 { 01370 NTSTATUS status; 01371 BOOLEAN success = FALSE; 01372 PCELL_DATA psrclist, ptarlist, psrcsecurity; 01373 HCELL_INDEX newvalue, newlist = HCELL_NIL, newclass = HCELL_NIL, newsecurity = HCELL_NIL; 01374 ULONG i, count, Type; 01375 01376 // 01377 // First, free the target key's values, sd, and class info. 01378 // 01379 01380 if(!CmpFreeKeyValues(TargetHive, TargetKeyCell, TargetKeyNode)) 01381 return FALSE; 01382 01383 // 01384 // Now, copy the values, class, & sd from the source cell 01385 // 01386 01387 // 01388 // The type of the new cells will be the same as that 01389 // of the target cell. 01390 // 01391 01392 Type = HvGetCellType(TargetKeyCell); 01393 01394 // 01395 // Allocate and copy class 01396 // 01397 if ((SourceKeyNode->ClassLength > 0) && (SourceKeyNode->Class != HCELL_NIL)) { 01398 newclass = CmpCopyCell(SourceHive, SourceKeyNode->Class, TargetHive, Type); 01399 if (newclass == HCELL_NIL) { 01400 goto EndValueSync; 01401 } 01402 01403 // only if class is valid. Otherwise remains 0 (set by CmpFreeKeyValues) 01404 TargetKeyNode->ClassLength = SourceKeyNode->ClassLength; 01405 } 01406 01407 // 01408 // Associate the new class with the target key 01409 // and prepare and security descriptor assignment. 01410 // 01411 01412 TargetKeyNode->Class = newclass; 01413 TargetKeyNode->Security = HCELL_NIL; 01414 01415 // 01416 // Allocate and assign security 01417 // 01418 psrcsecurity = HvGetCell(SourceHive, SourceKeyNode->Security); 01419 01420 status = CmpAssignSecurityDescriptor(TargetHive, 01421 TargetKeyCell, 01422 TargetKeyNode, 01423 &(psrcsecurity->u.KeySecurity.Descriptor)); 01424 if (!NT_SUCCESS(status)) { 01425 goto EndValueSync; 01426 } 01427 01428 // 01429 // Set up the value list 01430 // 01431 count = SourceKeyNode->ValueList.Count; 01432 01433 if (count == 0) { 01434 01435 // No values in source, no list needed. 01436 01437 TargetKeyNode->ValueList.List = HCELL_NIL; 01438 TargetKeyNode->ValueList.Count = 0; 01439 success = TRUE; 01440 } else { 01441 01442 // Allocate the value list for target 01443 01444 psrclist = HvGetCell(SourceHive, SourceKeyNode->ValueList.List); 01445 01446 newlist = HvAllocateCell( 01447 TargetHive, 01448 count * sizeof(HCELL_INDEX), 01449 Type 01450 ); 01451 if (newlist == HCELL_NIL) { 01452 goto EndValueSync; 01453 } 01454 TargetKeyNode->ValueList.List = newlist; 01455 ptarlist = HvGetCell(TargetHive, newlist); 01456 01457 01458 // 01459 // Copy the values 01460 // 01461 for (i = 0; i < count; i++) { 01462 01463 newvalue = CmpCopyValue( 01464 SourceHive, 01465 psrclist->u.KeyList[i], 01466 TargetHive, 01467 Type 01468 ); 01469 01470 if (newvalue != HCELL_NIL) { 01471 01472 ptarlist->u.KeyList[i] = newvalue; 01473 01474 } else { 01475 01476 // Delete all the copied values on an error. 01477 01478 for (; i > 0; i--) { 01479 HvFreeCell( 01480 TargetHive, 01481 ptarlist->u.KeyList[i - 1] 01482 ); 01483 } 01484 goto EndValueSync; 01485 } 01486 } 01487 01488 TargetKeyNode->ValueList.Count = count; 01489 success = TRUE; 01490 } 01491 01492 EndValueSync: 01493 if (success == FALSE) { 01494 01495 // Clean-up on failure 01496 01497 if (newlist != HCELL_NIL) { 01498 HvFreeCell(TargetHive, newlist); 01499 } 01500 01501 if (newsecurity != HCELL_NIL) { 01502 HvFreeCell(TargetHive, newsecurity); 01503 } 01504 01505 if (newclass != HCELL_NIL) { 01506 HvFreeCell(TargetHive, newclass); 01507 } 01508 01509 } 01510 01511 return success; 01512 }

BOOLEAN CmpSyncSubKeysAfterDelete PHHIVE  SourceHive,
PCM_KEY_NODE  SourceCell,
PHHIVE  TargetHive,
PCM_KEY_NODE  TargetCell,
WCHAR *  NameBuffer
 

Definition at line 1648 of file cmtrecpy.c.

References CmpDeleteTree(), CmpFindSubKeyByName(), CmpFindSubKeyByNumber(), CmpFreeKeyByCell(), CmpInitializeKeyNameString(), FALSE, HCELL_INDEX, HCELL_NIL, HvGetCell, NT_SUCCESS, Stable, _CM_KEY_NODE::SubKeyCounts, TRUE, and Volatile.

Referenced by CmpCopySyncTree2().

01655 : 01656 01657 This routine makes sure that any subkeys present in the target key 01658 but not present in the source key are deleted from the target key 01659 along with any trees under those subkeys. 01660 01661 This routine is useful for synchronizing key deletion changes 01662 in a source cell with a target cell. It is used in this way 01663 from CmpCopySyncTree. 01664 01665 NOTE: It is assumed that no open handles are held for the keys 01666 being deleted. If this is not so, registry in-memory 01667 data structures may become corrupted. 01668 01669 Arguments: 01670 01671 SourceHive - The hive of the source key 01672 SourceCell - The body of the source key 01673 TargetHive - The hive of the target key 01674 TargetCell - The body of the target key 01675 NameBuffer - A buffer MAX_KEY_NAME_LENGTH bytes in size 01676 01677 Return Value: 01678 01679 TRUE if successful, FALSE otherwise. 01680 01681 --*/ 01682 { 01683 HCELL_INDEX TargetSubKey, SourceSubKey; 01684 ULONG i = 0; 01685 PCM_KEY_NODE SubKeyCell; 01686 UNICODE_STRING SubKeyName; 01687 01688 // 01689 // Run through all of the target cell's subkeys 01690 // 01691 01692 while((TargetSubKey = CmpFindSubKeyByNumber( 01693 TargetHive, 01694 TargetCell, 01695 i)) != HCELL_NIL) 01696 { 01697 01698 // 01699 // Check if the current subkey has a counterpart 01700 // subkey of the source cell. 01701 // (Note that we use similar techniques as in the code 01702 // of CmpCopySyncTree2) 01703 // 01704 01705 SubKeyCell = (PCM_KEY_NODE)HvGetCell(TargetHive, TargetSubKey); 01706 01707 CmpInitializeKeyNameString(SubKeyCell, 01708 &SubKeyName, 01709 NameBuffer); 01710 01711 SourceSubKey = CmpFindSubKeyByName(SourceHive, 01712 SourceCell, 01713 &SubKeyName); 01714 01715 if(SourceSubKey == HCELL_NIL) 01716 { 01717 // 01718 // The current subkey has no counterpart, 01719 // it must therefore be deleted from the target cell. 01720 // 01721 01722 #if DEBUG_TREE_SYNC 01723 KdPrint(("CONFIG: SubKey Deletion of %.*S\n", 01724 SubKeyName.Length / sizeof(WCHAR), 01725 SubKeyName.Buffer)); 01726 #endif 01727 01728 if(SubKeyCell->SubKeyCounts[Stable] + SubKeyCell->SubKeyCounts[Volatile]) 01729 { 01730 // The subkey we are deleting has subkeys - use delete tree to get rid of them 01731 01732 CmpDeleteTree(TargetHive, TargetSubKey); 01733 01734 #if DEBUG_TREE_SYNC 01735 KdPrint(("CONFIG: Delete TREE performed.\n")); 01736 #endif 01737 } 01738 01739 // The subkey we are deleting is now a leaf (or has always been one), 01740 // just delete it. 01741 01742 if(!NT_SUCCESS(CmpFreeKeyByCell(TargetHive, TargetSubKey, TRUE))) 01743 { 01744 return FALSE; 01745 } 01746 01747 // 01748 // We have deleted a subkey, so *i* does not need to get incremented 01749 // here because it now refers to the next subkey. 01750 // 01751 } 01752 else 01753 { 01754 // 01755 // Counterpart found. No deletion necessary. Move on to the next subkey 01756 // 01757 01758 i++; 01759 } 01760 } 01761 01762 return TRUE; 01763 }


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