|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
oe.c
Abstract:
Implements Outlook Express utilities
Author:
Jay Thaler (jthaler) 05-Apr-2001
Revision History:
<alias> <date> <comments>
--*/
//
// Includes
//
#include "pch.h"
#include "v1p.h"
#include <wab.h>
#include <sddl.h>
#include <rpcdce.h>
#define COBJMACROS
#include <msoeimp.h>
#define DBG_V1 "v1"
//
// Strings
//
// None
//
// Constants
//
#define OETEMPDIR TEXT("%CSIDL_LOCAL_APPDATA%\\Identities\\USMTTMP")
#define DEFAULTWAB TEXT("default.wab")
//
// Macros
//
#define IF_NULLEND(x) if (NULL==x) { goto end; }
//
// Types
//
typedef IMailImport * (STDMETHODCALLTYPE OECREATE)( LPCSTR pszSrcDir ); typedef OECREATE FAR *LPOECREATE;
typedef HRESULT (STDMETHODCALLTYPE IMPORTSTORE)( IMailImport *pMailImport, GUID *pDestUUID, LPCSTR pszDestDir ); typedef IMPORTSTORE FAR *LPIMPORTSTORE;
typedef HRESULT (STDMETHODCALLTYPE IMPORTNEWS)( LPCSTR pszSrcDir, GUID *pDestUUID, LPCSTR pszDestDir ); typedef IMPORTNEWS FAR *LPIMPORTNEWS;
//
// Globals
//
PTSTR g_DestAssociatedId = NULL; HMODULE g_msoedll = NULL; HMODULE g_oemiglib = NULL; BOOL g_CoInit = FALSE;
//
// Macro expansion list
//
// None
//
// Private function prototypes
//
// None
//
// Macro expansion definition
//
// None
//
// Code
//
BOOL pUuidFromBracketedString ( PCTSTR InStr, UUID *Uuid ) { PTSTR strippedStr = NULL; TCHAR *p; BOOL retval = FALSE;
if (!InStr || !Uuid) { return FALSE; }
if (*InStr == TEXT('{')) { strippedStr = DuplicateText(_tcsinc(InStr)); p = _tcsrchr (strippedStr, TEXT('}')); if (p) { *p = 0; } } else { strippedStr = DuplicateText(InStr); }
if (strippedStr) { if (RPC_S_OK == UuidFromString(strippedStr, Uuid)) { retval = TRUE; } FreeText(strippedStr); }
return retval; }
MIG_OBJECTSTRINGHANDLE pBuildStoreRootKeyForId ( PCTSTR Identity ) { MIG_OBJECTSTRINGHANDLE objectName = NULL; PTSTR tmpStr;
tmpStr = JoinPathsInPoolEx (( NULL, TEXT("HKCU\\Identities"), Identity, TEXT("Software\\Microsoft\\Outlook Express\\5.0"), NULL ));
if (tmpStr) { objectName = IsmCreateObjectHandle (tmpStr, TEXT("Store Root")); FreePathString (tmpStr); tmpStr = NULL; }
return objectName; }
PTSTR pGetDestStoreRootForId ( PCTSTR Identity ) { MIG_OBJECTSTRINGHANDLE objectName; MIG_CONTENT objectContent; PTSTR retval = NULL; PTSTR tmpStr; PCTSTR destStore;
objectName = pBuildStoreRootKeyForId (Identity); if (IsmAcquireObject (g_RegType | PLATFORM_DESTINATION, objectName, &objectContent)) { if (IsValidRegSz(&objectContent)) { destStore = IsmExpandEnvironmentString (PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, (PCTSTR)objectContent.MemoryContent.ContentBytes, NULL); if (destStore) { retval = DuplicateText(destStore); IsmReleaseMemory(destStore); } } IsmReleaseObject (&objectContent); } IsmDestroyObjectHandle(objectName);
return retval; }
VOID WABMerge ( VOID ) { MIG_OBJECTSTRINGHANDLE filteredName = NULL; MIG_OBJECTSTRINGHANDLE objectName = NULL; MIG_OBJECTSTRINGHANDLE destObjectName; MIG_OBJECTSTRINGHANDLE lpWABObjectName = NULL; MIG_CONTENT objectContent; PCTSTR srcFile = NULL; PCTSTR srcNode = NULL; PCTSTR srcLeaf = NULL; PTSTR destFile = NULL; PCTSTR wabKey = NULL; PCTSTR wabPath = NULL; PCTSTR destPath; HANDLE lib; LPWABOPEN lpfnWABOpen = NULL; LPWABOBJECT lpWABObject; LPADRBOOK lpAdrBookWAB; WAB_PARAM wabParams; WABIMPORTPARAM wabImportParam; HRESULT hr; PCTSTR srcIdentity; PCTSTR destIdentity; PCTSTR destNode; PCTSTR defaultWABPath = NULL; BOOL fNewOE = FALSE;
if (IsmIsComponentSelected (S_OE_COMPONENT, 0) && (IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE4_APPDETECT) || IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE5_APPDETECT))) { //
// Get the source WAB filename
//
lpWABObjectName = IsmCreateObjectHandle (TEXT("HKCU\\Software\\Microsoft\\WAB\\WAB4\\Wab File Name"), TEXT("")); if (IsmAcquireObject (g_RegType | PLATFORM_SOURCE, lpWABObjectName, &objectContent)) { if (IsValidRegSz (&objectContent)) { objectName = TurnFileStringIntoHandle ((PCTSTR)objectContent.MemoryContent.ContentBytes, PFF_NO_PATTERNS_ALLOWED); filteredName = IsmFilterObject (g_FileType | PLATFORM_SOURCE, objectName, NULL, NULL, NULL); if (filteredName) { IsmCreateObjectStringsFromHandle (filteredName, &srcNode, &srcLeaf); IsmDestroyObjectHandle (filteredName); } else { IsmCreateObjectStringsFromHandle (objectName, &srcNode, &srcLeaf); } srcFile = JoinPaths (srcNode, srcLeaf);
IsmDestroyObjectString (srcNode); IsmDestroyObjectString (srcLeaf); IsmDestroyObjectHandle (objectName); } IsmReleaseObject (&objectContent); }
//
// Get the dest WAB filename
//
if (srcFile) { if (IsmAcquireObject (g_RegType | PLATFORM_DESTINATION, lpWABObjectName, &objectContent)) { if (IsValidRegSz (&objectContent)) { destFile = DuplicateText ((PCTSTR)objectContent.MemoryContent.ContentBytes); } IsmReleaseObject (&objectContent); } }
if (destFile) { // If we are upgrading from an old WAB version, and the destination does not have
// a new WAB already, then we need to supply a new filename to WABOpen
// if srcFile = destFile, then we wrote destFile during migration, which means it
// didn't exist before. They would not otherwise be equal, because we'd filename
// collide the wab
if (StringIMatch (srcFile, destFile)) { fNewOE = TRUE;
defaultWABPath = GetStringResource (OE_DEFAULT_WAB_PATH); if (defaultWABPath) { destPath = IsmExpandEnvironmentString ( PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, defaultWABPath, NULL);
FreeStringResource (defaultWABPath); }
FreeText (destFile); destFile = AllocText (TcharCount(destPath) + TcharCount(DEFAULTWAB) + 1); StringCopy (destFile, destPath); StringCat (destFile, DEFAULTWAB);
if StringIMatch (srcFile, destFile) { // Crud! Now what?
// We should name collide the default wab filename in this case, which
// would mean allocating a bigger destFile
} if (!DoesFileExist (destPath)) { BfCreateDirectory (destPath); }
IsmReleaseMemory (destPath);
// Set HKCU\Software\Microsoft\WAB\WAB4\Wab File Name [] = destFile
ZeroMemory (&objectContent, sizeof(MIG_CONTENT)); objectContent.ObjectTypeId = g_RegType; objectContent.Details.DetailsSize = sizeof(DWORD); objectContent.Details.DetailsData = IsmGetMemory (sizeof(DWORD)); *((PDWORD)objectContent.Details.DetailsData) = REG_SZ; objectContent.MemoryContent.ContentSize = SizeOfString (destFile); objectContent.MemoryContent.ContentBytes = IsmGetMemory (objectContent.MemoryContent.ContentSize); CopyMemory ((PVOID)objectContent.MemoryContent.ContentBytes, destFile, objectContent.MemoryContent.ContentSize);
objectName = IsmCreateObjectHandle(TEXT("HKCU\\Software\\Microsoft\\WAB\\WAB4\\Wab File Name"), TEXT("")); if (objectName) { IsmReplacePhysicalObject (g_RegType, objectName, &objectContent); IsmDestroyObjectHandle (objectName); } IsmReleaseMemory (objectContent.MemoryContent.ContentBytes); IsmReleaseMemory (objectContent.Details.DetailsData); } }
if (destFile) { // Get the WAB32.DLL location
wabKey = JoinPaths (TEXT("HKLM"), WAB_DLL_PATH_KEY); objectName = IsmCreateObjectHandle (wabKey, TEXT("")); FreePathString (wabKey); if (IsmAcquireObject (g_RegType | PLATFORM_DESTINATION, objectName, &objectContent)) { if (IsValidRegSz (&objectContent)) { wabPath = DuplicateText ((PCTSTR)objectContent.MemoryContent.ContentBytes); } IsmReleaseObject (&objectContent); } IsmDestroyObjectHandle (objectName); }
if (wabPath) { // Loadlibrary the DLL
lib = LoadLibrary (wabPath); if (lib) {
// Open the destination WAB
lpfnWABOpen = (LPWABOPEN) GetProcAddress (lib, "WABOpen"); if (lpfnWABOpen) { ZeroMemory (&wabParams, sizeof (WAB_PARAM)); wabParams.cbSize = sizeof (WAB_PARAM); if (!fNewOE) { wabParams.ulFlags = WAB_ENABLE_PROFILES | MAPI_UNICODE; } #ifdef UNICODE
wabParams.szFileName = (PSTR) ConvertWtoA (destFile); #else
wabParams.szFileName = (PSTR) destFile; #endif
hr = lpfnWABOpen (&lpAdrBookWAB, &lpWABObject, &wabParams, 0); #ifdef UNICODE
FreeConvertedStr (wabParams.szFileName); #endif
if (hr == S_OK) {
// Import the source WAB
ZeroMemory (&wabImportParam, sizeof (WABIMPORTPARAM)); wabImportParam.cbSize = sizeof (WABIMPORTPARAM); wabImportParam.lpAdrBook = lpAdrBookWAB; #ifdef UNICODE
wabImportParam.lpszFileName = (PSTR) ConvertWtoA (srcFile); #else
wabImportParam.lpszFileName = (PSTR) srcFile; #endif
hr = lpWABObject->lpVtbl->Import (lpWABObject, (LPSTR)&wabImportParam); #ifdef UNICODE
FreeConvertedStr (wabImportParam.lpszFileName); #endif
if (hr == S_OK) { if (!StringIMatch (srcFile, destFile)) { // Delete the source WAB
DeleteFile (srcFile); } } else { // Log a message that the user must manually import the WAB
LOG ((LOG_WARNING, (PCSTR) MSG_WAB_MERGE_FAILED, srcFile)); }
lpWABObject->lpVtbl->Release (lpWABObject); lpAdrBookWAB->lpVtbl->Release (lpAdrBookWAB); } } FreeLibrary (lib); } }
if (srcFile) { FreePathString (srcFile); } if (destFile) { FreeText (destFile); } if (wabPath) { FreeText (wabPath); } if (lpWABObjectName) { IsmDestroyObjectHandle (lpWABObjectName); } } }
PCTSTR pBuildDefaultStoreRoot ( IN PCTSTR Guid, IN BOOL GuidHasBrackets ) { PTSTR storeRoot = NULL; PCTSTR storeBegin = NULL; UINT charCount;
// output should be "%UserProfile%\Local Settings\Application Data\Identities\{guid}\Microsoft\Outlook Express"
#define STOREEND TEXT("\\Microsoft\\Outlook Express")
storeBegin = GetStringResource (OE_DEFAULT_ID_PATH); if (storeBegin) { storeRoot = AllocText(TcharCount(storeBegin) + TcharCount(Guid) + TcharCount(STOREEND) + (GuidHasBrackets ? 1 : 3)); if (!storeRoot) { // Out of memory?
return NULL; } StringCopy (storeRoot, storeBegin); FreeStringResource (storeBegin); } if (FALSE == GuidHasBrackets) { StringCat (storeRoot, TEXT("{")); } StringCat (storeRoot, Guid); if (FALSE == GuidHasBrackets) { StringCat (storeRoot, TEXT("}")); } StringCat (storeRoot, STOREEND);
return storeRoot; }
BOOL pOE5Import ( IN PCTSTR SourceDir, IN PCTSTR DestDir, IN PCTSTR DestIdentity ) { UUID uid; BOOL result = FALSE; PSTR szSrcPath; PSTR szDestPath;
MIG_CONTENT dllObjectContent; MIG_OBJECTSTRINGHANDLE dllObjectName = NULL; PCTSTR dllExpPath = NULL; PTSTR dllTmpPath = NULL; IMailImport *mailImport = NULL; static LPOECREATE lpfnOE5SimpleCreate = NULL; static LPIMPORTSTORE lpfnImportMailStoreToGUID = NULL; static LPIMPORTNEWS lpfnImportNewsListToGUID = NULL;
if (g_msoedll == NULL) { CoInitialize(NULL); g_CoInit = TRUE;
dllObjectName = IsmCreateObjectHandle (TEXT("HKLM\\Software\\Microsoft\\Outlook Express"), TEXT("InstallRoot")); if (IsmAcquireObject (g_RegType | PLATFORM_DESTINATION, dllObjectName, &dllObjectContent)) { // dllObjectContent should be "%ProgramFiles%\\Outlook Express"
if (IsValidRegSz (&dllObjectContent)) { dllExpPath = IsmExpandEnvironmentString(PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, (PCTSTR)dllObjectContent.MemoryContent.ContentBytes, NULL); } if (dllExpPath) {
dllTmpPath = JoinPaths (dllExpPath, TEXT("oemiglib.dll")); if (dllTmpPath) { g_oemiglib = LoadLibrary(dllTmpPath); FreePathString (dllTmpPath); }
dllTmpPath = JoinPaths (dllExpPath, TEXT("msoe.dll")); if (dllTmpPath) { g_msoedll = LoadLibrary(dllTmpPath); FreePathString (dllTmpPath); }
IsmReleaseMemory (dllExpPath); } IsmReleaseObject (&dllObjectContent); } IsmDestroyObjectHandle (dllObjectName);
if (g_msoedll && g_oemiglib) { lpfnOE5SimpleCreate = (LPOECREATE) GetProcAddress (g_oemiglib, "OE5SimpleCreate"); lpfnImportMailStoreToGUID = (LPIMPORTSTORE) GetProcAddress (g_msoedll, "ImportMailStoreToGUID"); lpfnImportNewsListToGUID = (LPIMPORTNEWS) GetProcAddress (g_msoedll, "ImportNewsListToGUID"); } }
if (DestDir) { if (lpfnOE5SimpleCreate && lpfnImportMailStoreToGUID && lpfnImportNewsListToGUID) {
// Convert to GUID *
if (pUuidFromBracketedString(DestIdentity, &uid)) { #ifdef UNICODE
szSrcPath = (PSTR) ConvertWtoA (SourceDir); szDestPath = (PSTR) ConvertWtoA (DestDir); #else
szSrcPath = (PSTR) SourceDir; szDestPath = (PSTR) DestDir; #endif
mailImport = lpfnOE5SimpleCreate(szSrcPath);
if (mailImport) { lpfnImportMailStoreToGUID(mailImport, &uid, szDestPath); IMailImport_Release(mailImport); mailImport = NULL; result = TRUE; }
lpfnImportNewsListToGUID (szSrcPath, &uid, szDestPath); #ifdef UNICODE
FreeConvertedStr (szSrcPath); FreeConvertedStr (szDestPath); #endif
} } if (SourceDir && DestDir) { // Copy source folder to dest folder, but never overwrite
if (!DoesFileExist (DestDir)) { BfCreateDirectory (DestDir); } FiCopyAllFilesInTreeEx(SourceDir, DestDir, TRUE); } }
return result; }
//////////////////////////////////////////////////////////////////////////////////////
// OE5MergeStorefolders
// This cycles through every store folder and decides whether to just copy it to the
// destination or merge into an existing store folder in the destination
VOID OE5MergeStoreFolders ( VOID ) { TCHAR szGuid[37]; MIG_OBJECTSTRINGHANDLE objectName = NULL; MIG_OBJECTSTRINGHANDLE filteredName = NULL; MIG_CONTENT objectContent; MIG_CONTENT destObjectContent; MIG_OBJECT_ENUM objectEnum; MIG_OBJECTSTRINGHANDLE enumPattern; PTSTR srcStoreRoot = NULL; PCTSTR destStoreRoot = NULL; PCTSTR destFolderFile = NULL; PTSTR node; PTSTR leaf; PTSTR junk; PCTSTR expandedName = NULL; BOOL fImport;
if (IsmIsComponentSelected (S_OE_COMPONENT, 0) && IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE5_APPDETECT)) {
// Enumerate each source Store Folder
enumPattern = IsmCreateSimpleObjectPattern ( TEXT("HKCU\\Identities"), TRUE, TEXT("Store Root"), FALSE); if (IsmEnumFirstSourceObject (&objectEnum, g_RegType, enumPattern)) { do { fImport = FALSE;
IsmCreateObjectStringsFromHandle (objectEnum.ObjectName, &node, &leaf); if (leaf && *leaf) { if (IsmAcquireObject (g_RegType | PLATFORM_SOURCE, objectEnum.ObjectName, &objectContent)) { if (IsValidRegSz (&objectContent)) { expandedName = IsmExpandEnvironmentString ( PLATFORM_SOURCE, S_SYSENVVAR_GROUP, (PCTSTR)objectContent.MemoryContent.ContentBytes, NULL); } if (expandedName) { objectName = IsmCreateObjectHandle(expandedName, NULL); IsmReleaseMemory (expandedName); expandedName = NULL; }
if (objectName) { filteredName = IsmFilterObject (g_FileType | PLATFORM_SOURCE, objectName, NULL, NULL, NULL);
if (filteredName) { IsmCreateObjectStringsFromHandle (filteredName, &srcStoreRoot, &junk); // srcStoreRoot is now the source directory
IsmDestroyObjectHandle (filteredName); filteredName = NULL; } else { IsmCreateObjectStringsFromHandle(objectName, &srcStoreRoot, &junk); }
if (junk) { IsmDestroyObjectString (junk); junk = NULL; }
IsmDestroyObjectHandle (objectName); objectName = NULL; }
// Now check to see if the dest Store Root previously existed
if (srcStoreRoot) { filteredName = IsmFilterObject (g_RegType | PLATFORM_SOURCE, objectEnum.ObjectName, NULL, NULL, NULL);
// Extract GUID out of destination object name
_stscanf(filteredName ? filteredName : objectEnum.ObjectName, TEXT("%*[^{]{%[^}]"), szGuid); // szGuid is now the destination identity guid, minus the {}
if (IsmAcquireObject (g_RegType | PLATFORM_DESTINATION, filteredName ? filteredName : objectEnum.ObjectName, &destObjectContent)) { if (IsValidRegSz (&destObjectContent)) { destStoreRoot = IsmExpandEnvironmentString ( PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, (PCTSTR)destObjectContent.MemoryContent.ContentBytes, NULL); } if (destStoreRoot) { destFolderFile = JoinPaths(destStoreRoot, TEXT("folders.dbx")); } if (destFolderFile) { if ((!StringIMatch(srcStoreRoot, destStoreRoot)) && (DoesFileExist(destFolderFile))) { fImport = TRUE; } FreePathString(destFolderFile); } IsmReleaseObject (&destObjectContent); } }
if (szGuid[0]) { if (!fImport) { // This is a FIRST migration, so set the dest store root to default
IsmReleaseMemory(destStoreRoot); destStoreRoot = pBuildDefaultStoreRoot(szGuid, FALSE);
// Set [StoreRoot] = destStoreRoot
ZeroMemory (&destObjectContent, sizeof(MIG_CONTENT)); destObjectContent.ObjectTypeId = g_RegType; destObjectContent.Details.DetailsSize = sizeof(DWORD); destObjectContent.Details.DetailsData = IsmGetMemory (sizeof(DWORD)); *((PDWORD)destObjectContent.Details.DetailsData) = REG_EXPAND_SZ; destObjectContent.MemoryContent.ContentSize = SizeOfString (destStoreRoot); destObjectContent.MemoryContent.ContentBytes = (PBYTE)destStoreRoot;
IsmReplacePhysicalObject (g_RegType, filteredName ? filteredName : objectEnum.ObjectName, &destObjectContent); IsmDestroyObjectHandle (objectName);
// expand environment on destStoreRoot
FreeText(destStoreRoot);
destStoreRoot = IsmExpandEnvironmentString ( PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, (PCTSTR)destObjectContent.MemoryContent.ContentBytes, NULL);
// Cleanup the objectContent we allocated
IsmReleaseMemory (destObjectContent.Details.DetailsData); }
if (srcStoreRoot && destStoreRoot) { if (!DoesFileExist (destStoreRoot)) { BfCreateDirectory (destStoreRoot); } pOE5Import(srcStoreRoot, destStoreRoot, szGuid); } }
if (filteredName) { IsmDestroyObjectHandle(filteredName); filteredName = NULL; }
if (destStoreRoot) { IsmReleaseMemory(destStoreRoot); destStoreRoot = NULL; }
if (srcStoreRoot) { IsmDestroyObjectString (srcStoreRoot); srcStoreRoot = NULL; }
IsmReleaseObject (&objectContent); } } IsmDestroyObjectString (node); IsmDestroyObjectString (leaf); } while (IsmEnumNextObject (&objectEnum));
// Remove temp folder
expandedName = IsmExpandEnvironmentString (PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, OETEMPDIR, NULL); if (expandedName) { FiRemoveAllFilesInTree (expandedName); IsmReleaseMemory (expandedName); } else { FiRemoveAllFilesInTree (OETEMPDIR); } } IsmDestroyObjectHandle (enumPattern); } }
VOID OE4MergeStoreFolder ( VOID ) { MIG_OBJECTSTRINGHANDLE regKey; MIG_OBJECTSTRINGHANDLE objectName = NULL; MIG_OBJECTSTRINGHANDLE filteredName; MIG_CONTENT objectContent; HANDLE h; PCTSTR srcStorePath = NULL; PCTSTR expPath = NULL; PTSTR destIdentity = NULL; PTSTR tmpStr = NULL; PTSTR tmpNode = NULL; PTSTR cmdLine = NULL; PCTSTR sid = NULL; DWORD exitCode; DWORD cmdLen; TCHAR tmpDir[MAX_PATH]; PCTSTR destDir = NULL;
if (IsmIsComponentSelected (S_OE_COMPONENT, 0) && IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE4_APPDETECT)) {
objectName = IsmCreateObjectHandle (TEXT("HKLM\\Software\\Microsoft\\Outlook Express"), TEXT("InstallRoot")); if (IsmAcquireObject (g_RegType | PLATFORM_DESTINATION, objectName, &objectContent)) {
// objectContent should be "%ProgramFiles%\\Outlook Express"
if (IsValidRegSz (&objectContent)) { tmpStr = JoinPaths (objectContent.MemoryContent.ContentBytes, TEXT("oemig50.exe"));
// tmpStr should be "%ProgramFiles%\\OutlookExpress\\oemig50.exe"
expPath = IsmExpandEnvironmentString (PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, tmpStr, NULL);
FreePathString (tmpStr); } IsmReleaseObject (&objectContent); } IsmDestroyObjectHandle (objectName);
// Get the dest identity
if (expPath) { destIdentity = OEGetDefaultId (PLATFORM_DESTINATION); }
// Now get the source's Store Root
if (destIdentity) { objectName = IsmCreateObjectHandle (TEXT("HKCU\\Software\\Microsoft\\Outlook Express"), TEXT("Store Root")); if (IsmAcquireObject (g_RegType | PLATFORM_SOURCE, objectName, &objectContent)) { if (IsValidRegSz (&objectContent)) { IsmDestroyObjectHandle (objectName); objectName = IsmCreateObjectHandle ((PCTSTR) objectContent.MemoryContent.ContentBytes, NULL); filteredName = IsmFilterObject (g_FileType | PLATFORM_SOURCE, objectName, NULL, NULL, NULL); if (filteredName) { IsmCreateObjectStringsFromHandle (filteredName, &srcStorePath, NULL); IsmDestroyObjectHandle (filteredName); } else { IsmCreateObjectStringsFromHandle (objectName, &srcStorePath, NULL); } } IsmReleaseObject (&objectContent); } IsmDestroyObjectHandle (objectName); }
// Now grab a temporary place to stuff the upgraded files
IsmGetTempDirectory(tmpDir, ARRAYSIZE(tmpDir));
// Call the external upgrade exe
if (srcStorePath != NULL && expPath != NULL) {
sid = IsmGetCurrentSidString();
cmdLen = TcharCount(expPath) + TcharCount(srcStorePath) + TcharCount(tmpDir) + 35; if (sid) { cmdLen += TcharCount(sid) + 6; } cmdLine = AllocText (cmdLen); StringCopy (cmdLine, expPath); StringCat (cmdLine, TEXT(" /type:V1+V4-V5 /src:")); // 21
StringCat (cmdLine, srcStorePath); StringCat (cmdLine, TEXT(" /dst:")); // 6
StringCat (cmdLine, tmpDir); StringCat (cmdLine, TEXT(" /quiet")); // 7
if (sid) { StringCat (cmdLine, TEXT(" /key:")); // (6)
StringCat (cmdLine, sid); }
LOG ((LOG_INFORMATION, (PCSTR) MSG_SPAWNING_PROCESS_INFO, cmdLine));
h = StartProcess (cmdLine); if (h != NULL) { WaitForSingleObject (h, INFINITE); if (GetExitCodeProcess (h, &exitCode)) { if ((exitCode != STILL_ACTIVE) && ((exitCode & 0xFFFF) != 800 )) { LOG ((LOG_ERROR, (PCSTR)MSG_OE4_UPGRADE_FAILED)); } } CloseHandle (h);
FreeText (cmdLine);
// Cleanup the source store
FiRemoveAllFilesInTree (srcStorePath); }
destDir = pGetDestStoreRootForId(destIdentity); if (destDir) { if (!DoesFileExist (destDir)) { // Just copy into to the dest dir
BfCreateDirectory (destDir); FiCopyAllFilesInTreeEx(tmpDir, destDir, TRUE); } else { // Now do an OE5 Import from tmpDir to destIdentity
pOE5Import(tmpDir, destDir, destIdentity); } FreeText(destDir); } FiRemoveAllFilesInTree (tmpDir);
// Set [StoreMigratedV5] = 1
// Set [ConvertedToDBX] = 1
tmpStr = JoinText(TEXT("HKCU\\Identities\\"), destIdentity); if (tmpStr) { tmpNode = JoinText(tmpStr, TEXT("\\Software\\Microsoft\\Outlook Express\\5.0")); if (tmpNode) { CreateDwordRegObject (tmpNode, TEXT("StoreMigratedV5"), 1); CreateDwordRegObject (tmpNode, TEXT("ConvertedToDBX"), 1); FreeText(tmpNode); }
FreeText(tmpStr); } }
if (destIdentity) { FreeText(destIdentity); } if (sid) { IsmReleaseMemory (sid); } if (expPath) { IsmReleaseMemory (expPath); } if (srcStorePath) { IsmDestroyObjectString (srcStorePath); } } }
BOOL OEIAMAssociateId ( IN PTSTR SrcId ) { MIG_OBJECTSTRINGHANDLE objectName; MIG_OBJECTTYPEID objectTypeId; MIG_CONTENT objectContent; PTSTR srcStr; TCHAR *p; UUID srcUUID; RPC_STATUS status; BOOL retval = FALSE; DWORD regType = REG_BINARY;
if (pUuidFromBracketedString (SrcId, &srcUUID)) { // Create [AssociatedID] = Uuid
objectTypeId = g_RegType | PLATFORM_DESTINATION;
ZeroMemory(&objectContent, sizeof(MIG_CONTENT));
objectContent.ContentInFile = FALSE; objectContent.MemoryContent.ContentSize = sizeof(UUID); objectContent.MemoryContent.ContentBytes = IsmGetMemory(sizeof(UUID)); CopyMemory ((PVOID)objectContent.MemoryContent.ContentBytes, &srcUUID, sizeof(UUID)); objectContent.Details.DetailsData = ®Type;
objectName = IsmCreateObjectHandle (TEXT("HKCU\\Software\\Microsoft\\Internet Account Manager\\Accounts"), TEXT("AssociatedID")); if (objectName) { retval = IsmReplacePhysicalObject (objectTypeId, objectName, &objectContent); IsmDestroyObjectHandle (objectName); g_DestAssociatedId = DuplicateText(SrcId); }
IsmReleaseMemory (objectContent.MemoryContent.ContentBytes); } return retval; }
BOOL OEIsIdentityAssociated ( IN PTSTR IdStr ) { BOOL associated = FALSE;
if (!g_DestAssociatedId) { g_DestAssociatedId = OEGetAssociatedId(PLATFORM_DESTINATION); }
if (g_DestAssociatedId) { associated = StringIMatch(IdStr, g_DestAssociatedId); } else { // Apparently there is no associated ID. Let's claim it.
OEIAMAssociateId(IdStr); associated = TRUE; } return associated; }
PTSTR OEGetRemappedId( IN PCTSTR IdStr ) { MIG_OBJECTSTRINGHANDLE objectName; MIG_OBJECTSTRINGHANDLE filteredName; PTSTR tmpName; PTSTR node; PTSTR leaf; PTSTR result = NULL; TCHAR *p;
tmpName = JoinText(TEXT("HKCU\\Identities\\"), IdStr); if (tmpName) { objectName = IsmCreateObjectHandle(tmpName, NULL); if (objectName) { filteredName = IsmFilterObject(g_RegType | PLATFORM_SOURCE, objectName, NULL, NULL, NULL); if (filteredName) { IsmCreateObjectStringsFromHandle (filteredName, &node, &leaf); if (node) { p = (PTSTR)FindLastWack(node); if (p) { result = DuplicateText(_tcsinc(p)); } IsmDestroyObjectString(node); } if (leaf) { IsmDestroyObjectString (leaf); } IsmDestroyObjectHandle(filteredName); } else { result = DuplicateText(IdStr); } IsmDestroyObjectHandle (objectName); } FreeText(tmpName); } return result; }
PTSTR OEGetDefaultId ( IN MIG_PLATFORMTYPEID Platform ) { MIG_OBJECTSTRINGHANDLE objectName; MIG_CONTENT objectContent; PTSTR retval = NULL;
objectName = IsmCreateObjectHandle (TEXT("HKCU\\Identities"), TEXT("Default User ID")); if (objectName) { if (IsmAcquireObject ( g_RegType | Platform, objectName, &objectContent)) { if (IsValidRegSz(&objectContent)) { retval = DuplicateText((PTSTR)objectContent.MemoryContent.ContentBytes); } IsmReleaseObject (&objectContent); } IsmDestroyObjectHandle (objectName); } return retval; }
PTSTR OEGetAssociatedId ( IN MIG_PLATFORMTYPEID Platform ) { MIG_OBJECTSTRINGHANDLE objectName; MIG_CONTENT objectContent; PTSTR uuidStr; PTSTR retval = NULL;
objectName = IsmCreateObjectHandle (TEXT("HKCU\\Software\\Microsoft\\Internet Account Manager\\Accounts"), TEXT("AssociatedID")); if (objectName) { if (IsmAcquireObject ( g_RegType | Platform, objectName, &objectContent)) { if (IsValidRegType(&objectContent, REG_BINARY)) { if (RPC_S_OK == UuidToString ((UUID *)objectContent.MemoryContent.ContentBytes, &uuidStr)) { retval = AllocText(CharCount(uuidStr) + 3); if (retval) { StringCopy(retval, TEXT("{")); StringCat(retval, uuidStr); StringCat(retval, TEXT("}")); } RpcStringFree(&uuidStr); } } IsmReleaseObject (&objectContent); } IsmDestroyObjectHandle (objectName); }
return retval; }
VOID OETerminate ( VOID ) { if (g_DestAssociatedId) { FreeText(g_DestAssociatedId); } if (g_msoedll) { FreeLibrary(g_msoedll); g_msoedll = NULL; } if (g_oemiglib) { FreeLibrary(g_oemiglib); g_oemiglib = NULL; } if (g_CoInit) { CoUninitialize(); g_CoInit = FALSE; }
}
pRenameRegTreePattern ( IN MIG_OBJECTSTRINGHANDLE Pattern, IN PCMIG_BLOB SrcBlob, IN PCMIG_BLOB DestBlob, IN BOOL ReplaceOld ) { MIG_OBJECT_ENUM objectEnum;
if (IsmEnumFirstSourceObject (&objectEnum, g_RegType, Pattern)) { if (!g_RenameOp) { g_RenameOp = IsmRegisterOperation (S_OPERATION_MOVE, FALSE); }
do { // Set operation on all source objects in this ID
if (ReplaceOld) { IsmClearOperationOnObject(g_RegType | PLATFORM_SOURCE, objectEnum.ObjectName, g_RenameOp); } IsmSetOperationOnObject(g_RegType | PLATFORM_SOURCE, objectEnum.ObjectName, g_RenameOp, SrcBlob, DestBlob); } while (IsmEnumNextObject(&objectEnum)); } }
pRenameRegTree ( IN PCTSTR SrcIdName, IN PCTSTR DestIdName, IN BOOL ReplaceOld ) { MIG_BLOB srcBlob; MIG_BLOB destBlob; MIG_OBJECTSTRINGHANDLE pattern;
srcBlob.Type = BLOBTYPE_STRING; srcBlob.String = IsmCreateObjectHandle(SrcIdName, NULL); if (srcBlob.String) { destBlob.Type = BLOBTYPE_STRING; destBlob.String = IsmCreateObjectHandle(DestIdName, NULL); if (destBlob.String) {
// Recursive
pattern = IsmCreateSimpleObjectPattern(SrcIdName, TRUE, NULL, TRUE); if (pattern) { pRenameRegTreePattern(pattern, &srcBlob, &destBlob, ReplaceOld); IsmDestroyObjectHandle(pattern); }
// Now for the node's values
pattern = IsmCreateSimpleObjectPattern(SrcIdName, FALSE, NULL, TRUE); if (pattern) { pRenameRegTreePattern(pattern, &srcBlob, &destBlob, ReplaceOld); IsmDestroyObjectHandle(pattern); }
// Now for only the node itself
pattern = IsmCreateSimpleObjectPattern(SrcIdName, FALSE, NULL, FALSE); if (pattern) { pRenameRegTreePattern(pattern, &srcBlob, &destBlob, ReplaceOld); IsmDestroyObjectHandle(pattern); } IsmDestroyObjectHandle(destBlob.String); } IsmDestroyObjectHandle(srcBlob.String); } }
BOOL pClearApply ( IN PCTSTR Node, IN PCTSTR Leaf ) { MIG_OBJECTSTRINGHANDLE objectName; BOOL result = FALSE;
objectName = IsmCreateObjectHandle(Node, Leaf); if (objectName) { IsmClearApplyOnObject((g_RegType & (~PLATFORM_MASK)) | PLATFORM_SOURCE, objectName); IsmDestroyObjectHandle (objectName); result = TRUE; }
return result; }
BOOL OE5RemapDefaultId ( VOID ) { MIG_OBJECTSTRINGHANDLE destObjectName; MIG_OBJECTSTRINGHANDLE pattern; MIG_CONTENT destIdObjectContent; PTSTR idName; PTSTR destIdName; PTSTR srcDefaultId; PTSTR destDefaultId; MIG_OBJECT_ENUM objectEnum;
if (IsmIsComponentSelected (S_OE_COMPONENT, 0) && IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE5_APPDETECT)) {
srcDefaultId = OEGetDefaultId(PLATFORM_SOURCE); if (srcDefaultId) { destDefaultId = OEGetDefaultId(PLATFORM_DESTINATION); if (destDefaultId) { if (!StringIMatch (srcDefaultId, destDefaultId)) { // different default IDs
idName = JoinText(TEXT("HKCU\\Identities\\"), srcDefaultId); if (idName) { destObjectName = IsmCreateObjectHandle(idName, NULL); if (IsmAcquireObject( g_RegType | PLATFORM_DESTINATION, destObjectName, &destIdObjectContent)) {
// The source ID already exists on the dest.. do nothing extra
IsmReleaseObject(&destIdObjectContent); } else { // Remap this identity into destination default
destIdName = JoinText(TEXT("HKCU\\Identities\\"), destDefaultId); if (destIdName) { pRenameRegTree(idName, destIdName, TRUE); FreeText(destIdName); } pClearApply(TEXT("HKCU\\Identities"), TEXT("Default User ID")); pClearApply(TEXT("HKCU\\Identities"), TEXT("Last User ID")); pClearApply(TEXT("HKCU\\Identities"), TEXT("Last Username"));
// ForceDestReg the top level Identities values
pattern = IsmCreateSimpleObjectPattern(idName, FALSE, NULL, TRUE); if (pattern) { if (IsmEnumFirstSourceObject (&objectEnum, g_RegType, pattern)) { do { IsmClearApplyOnObject( (g_RegType & (~PLATFORM_MASK)) | PLATFORM_SOURCE, objectEnum.ObjectName); } while (IsmEnumNextObject(&objectEnum)); } IsmDestroyObjectHandle(pattern); } } IsmDestroyObjectHandle(destObjectName); FreeText(idName); } } FreeText(destDefaultId); } FreeText(srcDefaultId); } }
return TRUE; }
//////////////////////////////////////////////////////////////////////////////////////
// pOE5RemapRules
// This adds a renregfn rule for \ConvertOE5MailRules to
// HKCU\Identities\{*}\Software\Microsoft\Outlook Express\5.0\Rules\Mail\*
// ditto for News rules
// Also for Block Senders\Mail\Criteria\* and News
BOOL pOE5RemapRules ( VOID ) { MIG_OBJECT_ENUM objectEnum; MIG_OBJECTSTRINGHANDLE enumPattern; MIG_OBJECTSTRINGHANDLE subPattern; PTSTR tmpNode; PTSTR node; PTSTR leaf;
if (IsmIsComponentSelected (S_OE_COMPONENT, 0) && IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE5_APPDETECT)) {
// Find HKCU\Identities\{*}\Software\Microsoft\Outlook Express\5.0\Rules\Mail\*
// First enum each identity
enumPattern = IsmCreateSimpleObjectPattern (TEXT("HKCU\\Identities"), TRUE, TEXT("User ID"), FALSE); if (IsmEnumFirstSourceObject (&objectEnum, g_RegType, enumPattern)) { do { IsmCreateObjectStringsFromHandle (objectEnum.ObjectName, &node, &leaf); if (node && leaf) { // Enum the Rules keys under this identity
tmpNode = JoinText(node, TEXT("\\Software\\Microsoft\\Outlook Express\\5.0\\Rules\\Mail")); if (tmpNode) { subPattern = IsmCreateSimpleObjectPattern (tmpNode, TRUE, NULL, TRUE); if (subPattern) { AddSpecialRenameRule (subPattern, TEXT("\\ConvertOE5MailRules")); IsmDestroyObjectHandle(subPattern); } FreeText(tmpNode); } tmpNode = JoinText(node, TEXT("\\Software\\Microsoft\\Outlook Express\\5.0\\Rules\\News")); if (tmpNode) { subPattern = IsmCreateSimpleObjectPattern (tmpNode, TRUE, NULL, TRUE); if (subPattern) { AddSpecialRenameRule (subPattern, TEXT("\\ConvertOE5NewsRules")); IsmDestroyObjectHandle(subPattern); } FreeText(tmpNode); } tmpNode = JoinText( node, TEXT("\\Software\\Microsoft\\Outlook Express\\5.0\\Block Senders\\Mail\\Criteria") ); if (tmpNode) { subPattern = IsmCreateSimpleObjectPattern (tmpNode, TRUE, NULL, TRUE); if (subPattern) { AddSpecialRenameRule (subPattern, TEXT("\\ConvertOE5Block")); IsmDestroyObjectHandle(subPattern); } FreeText(tmpNode); } tmpNode = JoinText( node, TEXT("\\Software\\Microsoft\\Outlook Express\\5.0\\Block Senders\\News\\Criteria") ); if (tmpNode) { subPattern = IsmCreateSimpleObjectPattern (tmpNode, TRUE, NULL, TRUE); if (subPattern) { AddSpecialRenameRule (subPattern, TEXT("\\ConvertOE5Block")); IsmDestroyObjectHandle(subPattern); } FreeText(tmpNode); } } IsmDestroyObjectString(node); if (leaf) { IsmDestroyObjectString(leaf); } } while (IsmEnumNextObject (&objectEnum)); } IsmDestroyObjectHandle (enumPattern); } return TRUE; }
//////////////////////////////////////////////////////////////////////////////////////
// pOE5RemapAccounts
// This adds a renregfn rule for \ConvertOE5IdIAM to
// HKCU\Identities\{*}\Software\Microsoft\Internet Account Manager\*
BOOL pOE5RemapAccounts ( VOID ) { MIG_OBJECT_ENUM objectEnum; MIG_OBJECTSTRINGHANDLE enumPattern; MIG_OBJECTSTRINGHANDLE subPattern; PTSTR tmpNode; PTSTR node; PTSTR leaf;
if (IsmIsComponentSelected (S_OE_COMPONENT, 0) && IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE5_APPDETECT)) {
// Find HKCU\Identities\{*}\Software\Microsoft\Internet Account Manger\*
// First enum each identity
enumPattern = IsmCreateSimpleObjectPattern (TEXT("HKCU\\Identities"), TRUE, TEXT("User ID"), FALSE); if (IsmEnumFirstSourceObject (&objectEnum, g_RegType, enumPattern)) { do { IsmCreateObjectStringsFromHandle (objectEnum.ObjectName, &node, &leaf); if (node && leaf) { // Enum the IAM keys under this identity
tmpNode = JoinText(node, TEXT("\\Software\\Microsoft\\Internet Account Manager")); if (tmpNode) { subPattern = IsmCreateSimpleObjectPattern (tmpNode, TRUE, NULL, TRUE); if (subPattern) { AddSpecialRenameRule (subPattern, TEXT("\\ConvertOE5IdIAM")); IsmDestroyObjectHandle(subPattern); } FreeText(tmpNode); } } IsmDestroyObjectString(node); if (leaf) { IsmDestroyObjectString(leaf); } } while (IsmEnumNextObject (&objectEnum)); } IsmDestroyObjectHandle (enumPattern); } return TRUE; }
//////////////////////////////////////////////////////////////////////////////////////
// OECreateFirstIdentity
// This is used to create the very first identity for a user that we just created
PTSTR OECreateFirstIdentity ( VOID ) { PTSTR destID = NULL; PTSTR uuidStr; UUID uuid; RPC_STATUS result; MIG_OBJECTSTRINGHANDLE objectName = NULL; MIG_CONTENT objectContent; PTSTR node; PCTSTR defaultStore;
result = UuidCreate (&uuid); if (result == RPC_S_OK || result == RPC_S_UUID_LOCAL_ONLY) { result = UuidToString (&uuid, &uuidStr); if (result == RPC_S_OK) { destID = AllocText (CharCount (uuidStr) + 3); wsprintf (destID, TEXT("{%s}"), uuidStr); RpcStringFree (&uuidStr); } } if (destID) { // Create [Default User ID] = &destID
ZeroMemory (&objectContent, sizeof(MIG_CONTENT)); objectContent.ObjectTypeId = g_RegType; objectContent.Details.DetailsSize = sizeof(DWORD); objectContent.Details.DetailsData = IsmGetMemory (sizeof(DWORD)); *((PDWORD)objectContent.Details.DetailsData) = REG_SZ; objectContent.MemoryContent.ContentSize = SizeOfString (destID); objectContent.MemoryContent.ContentBytes = IsmGetMemory (objectContent.MemoryContent.ContentSize); CopyMemory ((PVOID)objectContent.MemoryContent.ContentBytes, destID, objectContent.MemoryContent.ContentSize);
objectName = IsmCreateObjectHandle(TEXT("HKCU\\Identities"), TEXT("Default User ID")); if (objectName) { IsmReplacePhysicalObject (g_RegType, objectName, &objectContent); IsmDestroyObjectHandle (objectName); objectName = NULL; }
// Set [Last User ID] = &destID
objectName = IsmCreateObjectHandle(TEXT("HKCU\\Identities"), TEXT("Last User ID")); if (objectName) { IsmReplacePhysicalObject (g_RegType, objectName, &objectContent); IsmDestroyObjectHandle (objectName); objectName = NULL; } // Create [User ID] = &destID
node = JoinPaths (TEXT("HKCU\\Identities"), destID); if (node) { objectName = IsmCreateObjectHandle(node, TEXT("User ID")); FreePathString (node); } if (objectName) { IsmReplacePhysicalObject (g_RegType, objectName, &objectContent); IsmDestroyObjectHandle (objectName); objectName = NULL; }
IsmReleaseMemory (objectContent.MemoryContent.ContentBytes);
// Set [Store Root] = %UserProfile%\Local Settings\Application Data\Identities\&destID\Microsoft\Outlook Express
defaultStore = pBuildDefaultStoreRoot(destID, TRUE); if (defaultStore) { objectContent.MemoryContent.ContentBytes = (PCBYTE)defaultStore; objectContent.MemoryContent.ContentSize = SizeOfString(defaultStore); *((PDWORD)objectContent.Details.DetailsData) = REG_EXPAND_SZ;
node = JoinPathsInPoolEx (( NULL, TEXT("HKCU\\Identities"), destID, TEXT("Software\\Microsoft\\Outlook Express\\5.0"), NULL )); if (node) { objectName = IsmCreateObjectHandle(node, TEXT("Store Root")); FreePathString (node); } if (objectName) { IsmReplacePhysicalObject (g_RegType, objectName, &objectContent); IsmDestroyObjectHandle (objectName); } FreeText(defaultStore); } IsmReleaseMemory (objectContent.Details.DetailsData);
OEIAMAssociateId (destID); }
return destID; }
//////////////////////////////////////////////////////////////////////////////////////
// OEInitializeIdentity
// This is used to initialize a destination identity that has been created but never used.
BOOL OEInitializeIdentity ( VOID ) { MIG_OBJECTSTRINGHANDLE storeRootKey = NULL; MIG_CONTENT objectContent; PCTSTR defaultId; PCTSTR defaultStoreRoot; BOOL reinit = TRUE;
defaultId = OEGetDefaultId (PLATFORM_DESTINATION); if (defaultId) { storeRootKey = pBuildStoreRootKeyForId (defaultId); if (storeRootKey) { if (IsmAcquireObject (g_RegType | PLATFORM_DESTINATION, storeRootKey, &objectContent)) { if (IsValidRegSz(&objectContent)) { reinit = FALSE; } IsmReleaseObject (&objectContent); }
if (reinit) { defaultStoreRoot = pBuildDefaultStoreRoot (defaultId, TRUE); if (defaultStoreRoot) { ZeroMemory (&objectContent, sizeof(MIG_CONTENT)); objectContent.ObjectTypeId = g_RegType; objectContent.Details.DetailsSize = sizeof(DWORD); objectContent.Details.DetailsData = IsmGetMemory (sizeof(DWORD)); *((PDWORD)objectContent.Details.DetailsData) = REG_EXPAND_SZ; objectContent.MemoryContent.ContentSize = SizeOfString (defaultStoreRoot); objectContent.MemoryContent.ContentBytes = (PBYTE)defaultStoreRoot;
IsmReplacePhysicalObject (g_RegType, storeRootKey, &objectContent);
IsmReleaseMemory (objectContent.Details.DetailsData); FreeText(defaultStoreRoot); } } IsmDestroyObjectHandle(storeRootKey); } FreeText(defaultId); } return TRUE; }
//////////////////////////////////////////////////////////////////////////////////////
// pOE5RemapStores
// This is used to set a special RegFolder rule for the OE5 [Store Root] values
// The rule will redirect all store folders into a temporary directory. Later,
// OE5MergeStorefolders will decide whether to copy or merge them into the proper
// location on the destination
BOOL pOE5RemapStores ( VOID ) { MIG_OBJECTSTRINGHANDLE enumPattern; MIG_OBJECT_ENUM objectEnum; PTSTR node; PTSTR leaf; TCHAR tmpDir[MAX_PATH]; BOOL result = FALSE; ACTION_STRUCT actionStruct; DWORD index = 0;
if (IsmIsComponentSelected (S_OE_COMPONENT, 0) && IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE5_APPDETECT)) {
// Find HKCU\Identities\* [Store Root]
// First enum each identity
enumPattern = IsmCreateSimpleObjectPattern (TEXT("HKCU\\Identities"), TRUE, TEXT("Store Root"), FALSE); if (IsmEnumFirstSourceObject (&objectEnum, g_RegType, enumPattern)) { do { IsmCreateObjectStringsFromHandle (objectEnum.ObjectName, &node, &leaf); if (node && leaf) { // Regfolder the rule with a destination to a unique TEMP directory
// Grab a temporary place to copy the mail store
wsprintf(tmpDir, TEXT("%s\\%03x"), OETEMPDIR, index++);
ZeroMemory(&actionStruct, sizeof(ACTION_STRUCT)); actionStruct.ObjectBase = objectEnum.ObjectName; actionStruct.AddnlDest = TurnFileStringIntoHandle ( tmpDir, PFF_COMPUTE_BASE| PFF_NO_SUBDIR_PATTERN| PFF_NO_PATTERNS_ALLOWED| PFF_NO_LEAF_AT_ALL ); result = AddRule (g_RegType, objectEnum.ObjectName, objectEnum.ObjectName, ACTIONGROUP_INCFOLDER, ACTION_PERSIST_PATH_IN_DATA, &actionStruct); } IsmDestroyObjectString(node); if (leaf) { IsmDestroyObjectString(leaf); } } while (IsmEnumNextObject (&objectEnum)); } IsmDestroyObjectHandle (enumPattern); } return result; }
BOOL OEAddComplexRules ( VOID ) { pOE5RemapRules(); pOE5RemapAccounts(); pOE5RemapStores(); return TRUE; }
//////////////////////////////////////////////////////////////////////////////////////
// OEFixLastUser
// If for some reason the [Last User ID] value is set to zeroes or does not exist,
// we'll copy in the [Default User ID] value. If we dont do this, we'll get a popup
// during migration asking the user to select an identity, which would be really bad.
BOOL OEFixLastUser ( VOID ) { MIG_OBJECTSTRINGHANDLE objectName; MIG_CONTENT objectContent; MIG_OBJECTSTRINGHANDLE defName; MIG_CONTENT defContent; BOOL fFix = FALSE;
if (IsmIsComponentSelected (S_OE_COMPONENT, 0) && (IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE4_APPDETECT) || IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OE5_APPDETECT))) {
objectName = IsmCreateObjectHandle (TEXT("HKCU\\Identities"), TEXT("Last User ID")); if (objectName) { if (IsmAcquireObject (g_RegType | PLATFORM_DESTINATION, objectName, &objectContent)) { if (IsValidRegSz(&objectContent) && StringMatch((PCTSTR)objectContent.MemoryContent.ContentBytes, TEXT("{00000000-0000-0000-0000-000000000000}"))) { fFix = TRUE; } IsmReleaseObject (&objectContent); } else { fFix = TRUE; }
if (fFix) { defName = IsmCreateObjectHandle (TEXT("HKCU\\Identities"), TEXT("Default User ID")); if (defName) { if (IsmAcquireObject (g_RegType | PLATFORM_DESTINATION, defName, &defContent)) { if (IsValidRegSz (&defContent)) { IsmReplacePhysicalObject (g_RegType, objectName, &defContent); } IsmReleaseObject (&defContent); } IsmDestroyObjectHandle (defName); } } IsmDestroyObjectHandle (objectName); } } return TRUE; }
|