windows-nt/Source/XPSP1/NT/windows/winstate/cobra/modules/script/renregfn.c

910 lines
26 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
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;
}