|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
renregfn.c
Abstract:
Implements code-based registry rename.
Author:
Jim Schmidt (jimschm) 15-Sep-2000
Revision History:
<alias> <date> <comments>
--*/
//
// Includes
//
#include "pch.h"
#include "v1p.h"
#define DBG_RENREGFN "RenRegFn"
//
// Strings
//
// None
//
// Constants
//
// None
//
// Macros
//
// None
//
// Types
//
typedef VOID(RENREGFNINIT)(MIG_PLATFORMTYPEID); typedef RENREGFNINIT *PRENREGFNINIT;
typedef BOOL (STDMETHODCALLTYPE RENAMERULE)( IN PCTSTR OldNode, IN PCTSTR NewNode, IN PCTSTR Leaf, IN BOOL NoRestoreObject, OUT PMIG_FILTEROUTPUT OutputData ); typedef RENAMERULE FAR *LPRENAMERULE;
//
// Globals
//
PTSTR g_DestIdentityGUID = NULL; BOOL g_OERulesMigrated = FALSE;
//
// Macro expansion list
//
//
// DEFMAC(<script tag>, <enum callback>, <operation name>, <op init>, <operation callback>)
//
// It is assumed that <operation callback> is a tree filter (it can modify part of a path).
// The code does not currently support the contrary.
//
#define DEFAULT_ENUM pDefaultRenRegFnQueueCallback
#define DEFAULT_INIT pNulInit
#define RENAME_FUNCTIONS \
DEFMAC(ConvertOE4, DEFAULT_ENUM, MOVE.ConvertOE4, pConvertOE4Init, pConvertOE4Move ) \ DEFMAC(ConvertOE4IAM, DEFAULT_ENUM, MOVE.ConvertOE4IAM, pConvertOE4Init, pConvertOEIAMMove ) \ DEFMAC(ConvertOE5IAM, DEFAULT_ENUM, MOVE.ConvertOE5IAM, pConvertOE5IAMInit, pConvertOEIAMMove ) \ DEFMAC(ConvertOE5IdIAM, DEFAULT_ENUM, MOVE.ConvertOE5IdIAM, DEFAULT_INIT, pConvertOEIdIAMMove) \ DEFMAC(ConvertOE5MailRules, DEFAULT_ENUM, MOVE.ConvertOE5MailRules, DEFAULT_INIT, pConvertOE5MailRulesMove) \ DEFMAC(ConvertOE5NewsRules, DEFAULT_ENUM, MOVE.ConvertOE5NewsRules, DEFAULT_INIT, pConvertOE5NewsRulesMove) \ DEFMAC(ConvertOE5Block, DEFAULT_ENUM, MOVE.ConvertOE5Block, DEFAULT_INIT, pConvertOE5BlockMove) \
//
// Private function prototypes
//
// None
//
// Macro expansion definition
//
//
// Declare special rename operation apply callback functions
//
#define DEFMAC(ifn,ec,opn,opi,opc) SGMENUMERATIONCALLBACK ec; RENREGFNINIT opi; OPMFILTERCALLBACK opc;
RENAME_FUNCTIONS #undef DEFMAC
//
// This is the structure used for handling action functions
//
typedef struct { PCTSTR InfFunctionName; PSGMENUMERATIONCALLBACK EnumerationCallback; PCTSTR OperationName; MIG_OPERATIONID OperationId; PRENREGFNINIT OperationInit; POPMFILTERCALLBACK OperationCallback; } RENAME_STRUCT, *PRENAME_STRUCT;
//
// Declare a global array of rename functions
//
#define DEFMAC(ifn,ec,opn,opi,opc) {TEXT("\\")TEXT(#ifn),ec,TEXT(#opn),0,opi,opc},
static RENAME_STRUCT g_RenameFunctions[] = { RENAME_FUNCTIONS {NULL, NULL, NULL, 0, NULL, NULL} }; #undef DEFMAC
//
// Code
//
VOID pNulInit ( IN MIG_PLATFORMTYPEID Platform ) { }
UINT pDefaultRenRegFnQueueCallback ( IN PCMIG_OBJECTENUMDATA Data, IN ULONG_PTR CallerArg ) { PRENAME_STRUCT p = (PRENAME_STRUCT)CallerArg;
IsmSetOperationOnObject (Data->ObjectTypeId, Data->ObjectName, p->OperationId, NULL, NULL);
return CALLBACK_ENUM_CONTINUE; }
PRENAME_STRUCT pGetRenameStruct ( IN PCTSTR FunctionName ) { PRENAME_STRUCT p = g_RenameFunctions; INT i = 0; while (p->InfFunctionName != NULL) { if (StringIMatch (p->InfFunctionName, FunctionName)) { return p; } p++; i++; } return NULL; }
VOID InitSpecialRename ( IN MIG_PLATFORMTYPEID Platform ) { PRENAME_STRUCT p = g_RenameFunctions;
while (p->InfFunctionName) { p->OperationId = IsmRegisterOperation (p->OperationName, FALSE); if (Platform == PLATFORM_DESTINATION) { IsmRegisterOperationFilterCallback (p->OperationId, p->OperationCallback, TRUE, TRUE, FALSE); }
p->OperationInit(Platform); p++; } }
VOID TerminateSpecialRename ( VOID ) { if (g_DestIdentityGUID) { FreeText (g_DestIdentityGUID); } }
BOOL AddSpecialRenameRule ( IN PCTSTR Pattern, IN PCTSTR Function ) { PRENAME_STRUCT functionStruct = NULL; BOOL result = FALSE;
functionStruct = pGetRenameStruct (Function);
if (functionStruct) { result = IsmHookEnumeration ( g_RegType, Pattern, functionStruct->EnumerationCallback? functionStruct->EnumerationCallback: pDefaultRenRegFnQueueCallback, (ULONG_PTR)functionStruct, functionStruct->InfFunctionName ); } else { LOG (( LOG_ERROR, (PCSTR) MSG_DATA_RENAME_BAD_FN, Function, Pattern )); }
return result; }
BOOL pProcessDataRenameSection ( IN PINFSTRUCT InfStruct, IN HINF InfHandle, IN PCTSTR Section ) { PCTSTR pattern; ENCODEDSTRHANDLE encodedPattern = NULL; PCTSTR functionName; BOOL result = FALSE;
__try { if (InfFindFirstLine (InfHandle, Section, NULL, InfStruct)) { do {
if (IsmCheckCancel()) { __leave; }
pattern = InfGetStringField (InfStruct, 0);
if (!pattern) { continue; } encodedPattern = TurnRegStringIntoHandle (pattern, TRUE, NULL);
functionName = InfGetStringField (InfStruct, 1);
if (functionName) { AddSpecialRenameRule(encodedPattern, functionName); } else { LOG ((LOG_ERROR, (PCSTR) MSG_DATA_RENAME_NO_FN, pattern)); }
IsmDestroyObjectHandle (encodedPattern); encodedPattern = NULL; } while (InfFindNextLine (InfStruct)); }
result = TRUE; } __finally { InfCleanUpInfStruct (InfStruct); }
return result; }
BOOL DoRegistrySpecialRename ( IN HINF InfHandle, IN PCTSTR Section ) { PCTSTR osSpecificSection; BOOL b; INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
b = pProcessDataRenameSection (&is, InfHandle, Section);
if (b) { osSpecificSection = GetMostSpecificSection (&is, InfHandle, Section);
if (osSpecificSection) { b = pProcessDataRenameSection (&is, InfHandle, osSpecificSection); FreeText (osSpecificSection); } }
InfCleanUpInfStruct (&is); return b; }
//
// Helpers below
//
VOID pConvertOE4Init ( IN MIG_PLATFORMTYPEID Platform ) { if (Platform == PLATFORM_DESTINATION && IsmGetRealPlatform() == PLATFORM_DESTINATION && IsmIsComponentSelected (S_OE_COMPONENT, 0) && IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE4_APPDETECT)) {
if (g_DestIdentityGUID != NULL) { // Already got it.. punt
return; }
// pull out the GUID from dest
g_DestIdentityGUID = OEGetDefaultId (PLATFORM_DESTINATION);
if (g_DestIdentityGUID == NULL) { // This is when we created a new user
g_DestIdentityGUID = OECreateFirstIdentity(); } else { // This is when applying to a user who never ran OE
OEInitializeIdentity(); } } }
BOOL WINAPI pConvertOE4Move ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PCTSTR srcNode = NULL; PCTSTR srcLeaf = NULL; PTSTR newNode = NULL; PTSTR ptr = NULL; MIG_OBJECTSTRINGHANDLE newName;
if (g_DestIdentityGUID == NULL) { return FALSE; }
IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf);
// srcNode should be "HKCU\Software\Microsoft\Outlook Express\..."
if (!srcNode) { return FALSE; }
ptr = (PTSTR)_tcsistr (srcNode, TEXT("\\Outlook Express")); if (!ptr) { return FALSE; } ptr += 16;
newNode = AllocText (CharCount (srcNode) + CharCount (g_DestIdentityGUID) + 17); StringCopy (newNode, TEXT("HKCU\\Identities\\")); // +12
StringCat (newNode, g_DestIdentityGUID); StringCat (newNode, TEXT("\\Software\\Microsoft\\Outlook Express\\5.0")); // +4
StringCat (newNode, ptr);
// newNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Outlook Express\5.0\..."
newName = IsmCreateObjectHandle (newNode, srcLeaf); FreeText (newNode); IsmDestroyObjectString (srcLeaf); IsmDestroyObjectString (srcNode);
OutputData->NewObject.ObjectName = newName;
return TRUE; }
VOID pConvertOE5IAMInit ( IN MIG_PLATFORMTYPEID Platform ) { BOOL remap = TRUE; PTSTR srcAssocId; PTSTR newIdentity; PTSTR srcDefaultId; PTSTR destDefaultId;
if (Platform == PLATFORM_DESTINATION && IsmGetRealPlatform() == PLATFORM_DESTINATION && IsmIsComponentSelected (S_OE_COMPONENT, 0) && IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE5_APPDETECT)) { // g_DestIdentityGUID should remain NULL if we do not want to remap the IAM tree
// This is true when the destination user profile has not been created yet. We also
// want to leave it alone when the IAM has not yet been initialized (assume that [AssociatedID]
// has not yet been written.. if this is not a valid assumption, compare to source's AssociatedID)
if (g_DestIdentityGUID != NULL) { // Already got it.. punt
return; }
srcAssocId = OEGetAssociatedId (PLATFORM_SOURCE); if (srcAssocId) { newIdentity = OEGetRemappedId (srcAssocId); if (newIdentity) { if (OEIsIdentityAssociated(newIdentity)) { FreeText(newIdentity); } else { g_DestIdentityGUID = newIdentity; } } FreeText(srcAssocId); }
OEInitializeIdentity(); } }
BOOL WINAPI pConvertOE5IAMMove ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PCTSTR srcNode = NULL; PCTSTR srcLeaf = NULL; PTSTR newNode = NULL; PTSTR ptr = NULL; BOOL retval = FALSE;
if (g_DestIdentityGUID == NULL || OEIsIdentityAssociated (g_DestIdentityGUID)) { // Do Nothing
return TRUE; }
IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf); if (srcNode) { // srcNode should be "HKCU\Software\Microsoft\Internet Account Manager\..."
ptr = _tcschr (srcNode, TEXT('\\')); if (ptr) {
newNode = AllocText (CharCount (srcNode) + CharCount (g_DestIdentityGUID) + 13); StringCopy (newNode, TEXT("HKCU\\Identities\\")); // +12
StringCat (newNode, g_DestIdentityGUID); StringCat (newNode, ptr);
// newNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Internet Account Manager\..."
OutputData->NewObject.ObjectName = IsmCreateObjectHandle (newNode, srcLeaf); FreeText (newNode); retval = TRUE; } }
IsmDestroyObjectString (srcNode); IsmDestroyObjectString (srcLeaf);
return retval; }
BOOL pConcatRuleIndex ( IN PCTSTR Node, IN PCTSTR SearchStr ) { MIG_OBJECTSTRINGHANDLE objectName; MIG_CONTENT objectContent; PTSTR tmpNode; PTSTR ptr; TCHAR number[5]; PTSTR newStr;
tmpNode = DuplicateText(Node); if (tmpNode) { ptr = (PTSTR)_tcsistr (tmpNode, SearchStr); if (ptr) { ptr += CharCount(SearchStr); StringCopyCharCount(number, ptr, 4); number[4] = 0; *ptr = 0; objectName = IsmCreateObjectHandle (tmpNode, TEXT("Order")); if (IsmAcquireObject(g_RegType | PLATFORM_DESTINATION, objectName, &objectContent)) { if (IsValidRegSz(&objectContent)) { if (!_tcsistr ((PCTSTR)objectContent.MemoryContent.ContentBytes, number)) { newStr = IsmGetMemory(objectContent.MemoryContent.ContentSize + SizeOfString(number) + 1); StringCopy(newStr, (PCTSTR)objectContent.MemoryContent.ContentBytes); StringCat(newStr, TEXT(" ")); StringCat(newStr, number);
IsmReleaseMemory(objectContent.MemoryContent.ContentBytes); objectContent.MemoryContent.ContentSize = SizeOfString(newStr); objectContent.MemoryContent.ContentBytes = (PCBYTE)newStr;
IsmReplacePhysicalObject (g_RegType, objectName, &objectContent); } } IsmReleaseObject(&objectContent); } IsmDestroyObjectHandle(objectName); } FreeText(tmpNode); } return TRUE; }
BOOL pRenameEx ( IN PCTSTR OldNode, IN PCTSTR NewNode, IN PCTSTR Leaf, IN BOOL NoRestoreObject, IN PCTSTR PrevKey, IN PCTSTR FormatStr, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL ZeroBase ) { BOOL result = FALSE; PTSTR patternNode; PTSTR tmpNode; PTSTR ptr; PTSTR searchStr; DWORD prevCount; DWORD keySize = 1; MIG_FILTERINPUT filterInput; MIG_FILTEROUTPUT filterOutput; MIG_BLOB migBlob; MIG_BLOB zeroBaseBlob; PTSTR filteredNode = NULL;
tmpNode = DuplicateText(NewNode); if (tmpNode) { prevCount = CharCount(PrevKey); searchStr = AllocText(prevCount + 3); if (searchStr) { _stprintf(searchStr, TEXT("\\%s\\"), PrevKey);
ptr = (PTSTR)_tcsistr (tmpNode, searchStr); if (ptr) { ptr += (prevCount + 2); // Advance to next portion
*ptr = 0; ptr = _tcsinc(ptr); while (*ptr && *ptr != TEXT('\\')) { ptr = _tcsinc(ptr); keySize++; }
patternNode = AllocText(CharCount(NewNode) + (CharCount(FormatStr) - keySize)); if (patternNode) { StringCopy(patternNode, tmpNode); StringCat(patternNode, FormatStr); StringCat(patternNode, ptr);
filterInput.OriginalObject.ObjectTypeId = g_RegType; filterInput.OriginalObject.ObjectName = IsmCreateObjectHandle (OldNode, NULL); filterInput.CurrentObject.ObjectTypeId = g_RegType; filterInput.CurrentObject.ObjectName = IsmCreateObjectHandle (OldNode, NULL); migBlob.Type = BLOBTYPE_STRING; migBlob.String = IsmCreateObjectHandle (patternNode, NULL);
if (ZeroBase) { zeroBaseBlob.Type = BLOBTYPE_BINARY; zeroBaseBlob.BinarySize = sizeof(PCBYTE); zeroBaseBlob.BinaryData = (PCBYTE)TRUE;
FilterRenameExFilter (&filterInput, &filterOutput, NoRestoreObject, &zeroBaseBlob, &migBlob); } else { FilterRenameExFilter (&filterInput, &filterOutput, NoRestoreObject, NULL, &migBlob); }
IsmDestroyObjectHandle (migBlob.String); IsmDestroyObjectHandle (filterInput.CurrentObject.ObjectName); IsmDestroyObjectHandle (filterInput.OriginalObject.ObjectName);
IsmCreateObjectStringsFromHandle (filterOutput.NewObject.ObjectName, &filteredNode, NULL); IsmDestroyObjectHandle (filterOutput.NewObject.ObjectName);
OutputData->NewObject.ObjectName = IsmCreateObjectHandle (filteredNode, Leaf); if (0 == *ptr) { pConcatRuleIndex(filteredNode, searchStr); } FreeText (filteredNode);
FreeText(patternNode); } } else { OutputData->NewObject.ObjectName = IsmCreateObjectHandle (tmpNode, Leaf); } FreeText(searchStr); } else { OutputData->NewObject.ObjectName = IsmCreateObjectHandle (tmpNode, Leaf); } FreeText(tmpNode); } return TRUE; }
BOOL pRenameNewsRule ( IN PCTSTR OldNode, IN PCTSTR NewNode, IN PCTSTR Leaf, IN BOOL NoRestoreObject, OUT PMIG_FILTEROUTPUT OutputData ) { return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("News"), TEXT("<%03d>"), OutputData, TRUE); }
BOOL pRenameMailRule ( IN PCTSTR OldNode, IN PCTSTR NewNode, IN PCTSTR Leaf, IN BOOL NoRestoreObject, OUT PMIG_FILTEROUTPUT OutputData ) { return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("Mail"), TEXT("<%03d>"), OutputData, TRUE); }
BOOL pRenameBlockRule ( IN PCTSTR OldNode, IN PCTSTR NewNode, IN PCTSTR Leaf, IN BOOL NoRestoreObject, OUT PMIG_FILTEROUTPUT OutputData ) { return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("Criteria"), TEXT("<%03d>"), OutputData, TRUE); }
BOOL pRenameAccount ( IN PCTSTR OldNode, IN PCTSTR NewNode, IN PCTSTR Leaf, IN BOOL NoRestoreObject, OUT PMIG_FILTEROUTPUT OutputData ) { return pRenameEx(OldNode, NewNode, Leaf, NoRestoreObject, TEXT("Accounts"), TEXT("<%08d>"), OutputData, FALSE); }
BOOL WINAPI pConvertOE5RulesMove ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN LPRENAMERULE fnRename ) { PCTSTR srcNode = NULL; PCTSTR srcLeaf = NULL; PTSTR newNode = NULL; PTSTR tmpText; TCHAR *endId; TCHAR *srcIdentity; PTSTR newIdentity;
// Move tree and Merge account name
IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf); if (srcNode) { // srcNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Outlook Express\Rules\Mail\..."
tmpText = DuplicateText(srcNode); if (tmpText) { srcIdentity = _tcschr(tmpText, TEXT('{')); if (srcIdentity) { endId = _tcschr(srcIdentity, TEXT('\\')); if (endId) { *endId = 0; endId = _tcsinc(endId);
// endId should be "Software\Microsoft\Outlook Express\Rules\Mail\..."
// srcIdentity should be "{GUID}"
newIdentity = OEGetRemappedId (srcIdentity); if (newIdentity) { newNode = AllocText (CharCount(srcNode) + 1); StringCopy (newNode, TEXT("HKCU\\Identities\\")); StringCat (newNode, newIdentity); StringCat (newNode, TEXT("\\")); StringCat (newNode, endId);
if (newNode) { if (srcLeaf && !g_OERulesMigrated && !StringIMatch(srcLeaf, TEXT("Version"))) { g_OERulesMigrated = TRUE; } fnRename(srcNode, newNode, srcLeaf, NoRestoreObject, OutputData); FreeText(newNode); } FreeText(newIdentity); } } } FreeText(tmpText); } IsmDestroyObjectString (srcNode); } IsmDestroyObjectString (srcLeaf);
return TRUE; }
BOOL WINAPI pConvertOE5NewsRulesMove ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { return pConvertOE5RulesMove(InputData, OutputData, NoRestoreObject, pRenameNewsRule); }
BOOL WINAPI pConvertOE5MailRulesMove ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { return pConvertOE5RulesMove(InputData, OutputData, NoRestoreObject, pRenameMailRule); }
BOOL WINAPI pConvertOE5BlockMove ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { return pConvertOE5RulesMove(InputData, OutputData, NoRestoreObject, pRenameBlockRule); }
BOOL WINAPI pConvertOEIdIAMMove ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PCTSTR srcNode = NULL; PCTSTR srcLeaf = NULL; PTSTR newNode = NULL; PTSTR tmpText; TCHAR *endId; TCHAR *srcIdentity; PTSTR newIdentity;
// Move tree and Merge account name
IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf); if (srcNode) { // srcNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Internet Account Manager\..."
tmpText = DuplicateText(srcNode); if (tmpText) { srcIdentity = _tcschr(tmpText, TEXT('{')); if (srcIdentity) { endId = _tcschr(srcIdentity, TEXT('\\')); if (endId) { *endId = 0; endId = _tcsinc(endId);
// endId should be "Software\Microsoft\Internet Account Manager\..."
// srcIdentity should be "{GUID}"
newIdentity = OEGetRemappedId (srcIdentity); if (newIdentity) { if (OEIsIdentityAssociated (newIdentity)) { // allocText below does include 1 extra for Null
newNode = AllocText (CharCount(endId) + 6); StringCopy (newNode, TEXT("HKCU\\")); // +5
StringCat (newNode, endId); // newNode should be "HKCU\Software\Microsoft\Internet Account Manager\..."
} else { newNode = AllocText (CharCount(srcNode) + 1); StringCopy (newNode, TEXT("HKCU\\Identities\\")); StringCat (newNode, newIdentity); StringCat (newNode, TEXT("\\")); StringCat (newNode, endId); }
if (newNode) { pRenameAccount(srcNode, newNode, srcLeaf, NoRestoreObject, OutputData); FreeText(newNode); } FreeText(newIdentity); } } } FreeText(tmpText); } IsmDestroyObjectString (srcNode); } IsmDestroyObjectString (srcLeaf);
return TRUE; }
BOOL WINAPI pConvertOEIAMMove ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PCTSTR srcNode = NULL; PCTSTR srcLeaf = NULL; PTSTR newNode = NULL; PTSTR filteredNode = NULL; PTSTR ptr = NULL;
// Move tree and Merge account name
IsmCreateObjectStringsFromHandle (InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf); if (srcNode) { // srcNode should be "HKCU\Software\Microsoft\Internet Account Manager\..."
if (g_DestIdentityGUID != NULL && !OEIsIdentityAssociated (g_DestIdentityGUID)) {
ptr = _tcschr (srcNode, TEXT('\\')); if (ptr) { newNode = AllocText (TcharCount (srcNode) + TcharCount (g_DestIdentityGUID) + 13); StringCopy (newNode, TEXT("HKCU\\Identities\\")); // +12
StringCat (newNode, g_DestIdentityGUID); StringCat (newNode, ptr);
// newNode should be "HKCU\Identities\{GUID}\Software\Microsoft\Internet Account Manager\..."
} } else { newNode = DuplicateText (srcNode); }
if (newNode) { pRenameAccount(srcNode, newNode, srcLeaf, NoRestoreObject, OutputData); FreeText (newNode); } IsmDestroyObjectString (srcNode); } IsmDestroyObjectString (srcLeaf);
return TRUE; }
|