910 lines
26 KiB
C
910 lines
26 KiB
C
|
/*++
|
||
|
|
||
|
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;
|
||
|
}
|