|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
opm.c
Abstract:
Implements the data apply portion of scanstate v1 compatiblity.
Author:
Jim Schmidt (jimschm) 12-Mar-2000
Revision History:
<alias> <date> <comments>
--*/
//
// Includes
//
#include "pch.h"
#include "v1p.h"
#include <sddl.h>
#define DBG_V1 "v1"
#define MAXINISIZE 65536
//
// Strings
//
#define S_RENAMEEX_START_CHAR TEXT('<')
#define S_RENAMEEX_END_CHAR TEXT('>')
//
// Constants
//
// None
//
// Macros
//
// None
//
// Types
//
// None
//
// Globals
//
MIG_OPERATIONID g_V1MoveExOp; MIG_OPERATIONID g_V1MoveOp; MIG_OPERATIONID g_DeleteOp; MIG_OPERATIONID g_PartMoveOp; PMAPSTRUCT g_RegNodeFilterMap; PMAPSTRUCT g_RegLeafFilterMap; PMAPSTRUCT g_FileNodeFilterMap; PMAPSTRUCT g_FileLeafFilterMap; PMAPSTRUCT g_IniSectFilterMap; PMAPSTRUCT g_IniKeyFilterMap; PMAPSTRUCT g_DestEnvMap; HASHTABLE g_RegCollisionDestTable; HASHTABLE g_RegCollisionSrcTable;
//
// Macro expansion list
//
// None
//
// Private function prototypes
//
OPMINITIALIZE ScriptOpmInitialize; OPMFILTERCALLBACK FilterV1MoveEx; OPMFILTERCALLBACK FilterV1Move; OPMFILTERCALLBACK FilterMove; OPMFILTERCALLBACK FilterIniMove; OPMAPPLYCALLBACK DoRegAutoFilter; OPMAPPLYCALLBACK DoIniAutoFilter; OPMFILTERCALLBACK FilterRegAutoFilter; OPMFILTERCALLBACK FilterIniAutoFilter; OPMFILTERCALLBACK FilterFileAutoFilter; OPMFILTERCALLBACK FilterDelete; OPMAPPLYCALLBACK DoFixDefaultIcon; OPMFILTERCALLBACK FilterRenameExFilter; OPMFILTERCALLBACK FilterRenameIniExFilter; OPMFILTERCALLBACK FilterPartitionMove; OPMAPPLYCALLBACK DoDestAddObject;
//
// Macro expansion definition
//
// None
//
// Code
//
BOOL pParseInfForRemapEnvVar ( IN HINF InfHandle ) { INFSTRUCT is = INITINFSTRUCT_PMHANDLE; PCTSTR envVar; PTSTR envValue; UINT sizeNeeded; PTSTR encodedVariableName; BOOL result = FALSE;
__try {
// on all systems, process "Delete Destination Settings"
if (InfFindFirstLine (InfHandle, TEXT("RemapEnvVar"), NULL, &is)) { do {
if (IsmCheckCancel()) { __leave; }
envVar = InfGetStringField (&is, 1);
if (!envVar) { LOG ((LOG_WARNING, (PCSTR) MSG_EMPTY_REG_SPEC)); continue; }
if (IsmGetEnvironmentString ( PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, envVar, NULL, 0, &sizeNeeded )) {
envValue = AllocPathString (sizeNeeded); if (envValue) {
if (IsmGetEnvironmentString ( PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, envVar, envValue, sizeNeeded, NULL )) { AddRemappingEnvVar (g_DestEnvMap, g_FileNodeFilterMap, NULL, envVar, envValue); } FreePathString (envValue); envValue = NULL; } }
// now let's see if this env. variable was present on the source machine.
// If it was, we are going to add it into g_RevEnvMap to allow file move
// to create subdirectories only from this variable up.
if (IsmGetEnvironmentString ( PLATFORM_SOURCE, S_SYSENVVAR_GROUP, envVar, NULL, 0, &sizeNeeded )) {
envValue = AllocPathString (sizeNeeded); if (envValue) { if (IsmGetEnvironmentString ( PLATFORM_SOURCE, S_SYSENVVAR_GROUP, envVar, envValue, sizeNeeded, NULL )) { encodedVariableName = AllocPathString (TcharCount (envVar) + 3); if (encodedVariableName) { wsprintf (encodedVariableName, TEXT("%%%s%%"), envVar); AddStringMappingPair (g_RevEnvMap, envValue, encodedVariableName); FreePathString (encodedVariableName); encodedVariableName = NULL; }
} FreePathString (envValue); envValue = NULL; } }
} while (InfFindNextLine (&is)); }
result = TRUE; } __finally { InfCleanUpInfStruct (&is); }
return result; }
BOOL pParseRemapEnvVar ( VOID ) { PTSTR multiSz = NULL; MULTISZ_ENUM e; UINT sizeNeeded; HINF infHandle = INVALID_HANDLE_VALUE; ENVENTRY_TYPE dataType; BOOL result = TRUE;
if (IsmGetEnvironmentValue ( IsmGetRealPlatform (), NULL, S_GLOBAL_INF_HANDLE, (PBYTE)(&infHandle), sizeof (HINF), &sizeNeeded, &dataType ) && (sizeNeeded == sizeof (HINF)) && (dataType == ENVENTRY_BINARY) ) { if (!pParseInfForRemapEnvVar (infHandle)) { result = FALSE; } } else {
if (!IsmGetEnvironmentValue (IsmGetRealPlatform (), NULL, S_INF_FILE_MULTISZ, NULL, 0, &sizeNeeded, NULL)) { return TRUE; // no INF files specified
}
__try { multiSz = AllocText (sizeNeeded); if (!multiSz) { result = FALSE; __leave; }
if (!IsmGetEnvironmentValue (IsmGetRealPlatform (), NULL, S_INF_FILE_MULTISZ, (PBYTE) multiSz, sizeNeeded, NULL, NULL)) { result = FALSE; __leave; }
if (EnumFirstMultiSz (&e, multiSz)) {
do { infHandle = InfOpenInfFile (e.CurrentString); if (infHandle != INVALID_HANDLE_VALUE) { if (!pParseInfForRemapEnvVar (infHandle)) { InfCloseInfFile (infHandle); infHandle = INVALID_HANDLE_VALUE; result = FALSE; __leave; }
InfCloseInfFile (infHandle); infHandle = INVALID_HANDLE_VALUE; } else { LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_INF, e.CurrentString)); } } while (EnumNextMultiSz (&e));
} } __finally { if (multiSz) { FreeText (multiSz); multiSz = NULL; } } }
return result; }
VOID pOutlookClearConvKeys ( VOID ) { MIG_CONTENT objectContent; MIG_OBJECT_ENUM objectEnum; MIG_OBJECTSTRINGHANDLE enumPattern = NULL;
// This registry tree was needed only for conversion data. We don't want to
// write them to the destination, so clear the apply attribute on each item.
if ((IsmIsComponentSelected (S_OUTLOOK9798_COMPONENT, 0) && IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OUTLOOK9798_APPDETECT)) || (IsmIsComponentSelected (S_OFFICE_COMPONENT, 0) && IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, S_OFFICE9798_APPDETECT))) {
enumPattern = IsmCreateSimpleObjectPattern ( TEXT("HKLM\\Software\\Microsoft\\MS Setup (ACME)\\Table Files"), TRUE, NULL, TRUE);
if (IsmEnumFirstSourceObject (&objectEnum, g_RegType, enumPattern)) { do { IsmClearApplyOnObject (g_RegType | PLATFORM_SOURCE, objectEnum.ObjectName); } while (IsmEnumNextObject (&objectEnum)); } IsmDestroyObjectHandle (enumPattern); } }
BOOL WINAPI ScriptOpmInitialize ( IN PMIG_LOGCALLBACK LogCallback, IN PVOID Reserved ) { //
// Get file and registry types
//
g_FileType = MIG_FILE_TYPE; g_RegType = MIG_REGISTRY_TYPE; g_IniType = MIG_INI_TYPE;
//
// Get attribute and operation types
//
g_V1MoveExOp = IsmRegisterOperation (S_OPERATION_V1_FILEMOVEEX, TRUE); g_V1MoveOp = IsmRegisterOperation (S_OPERATION_V1_FILEMOVE, TRUE); g_RenameOp = IsmRegisterOperation (S_OPERATION_MOVE, FALSE); g_RenameIniOp = IsmRegisterOperation (S_OPERATION_INIMOVE, FALSE); g_DeleteOp = IsmRegisterOperation (S_OPERATION_DELETE, FALSE); g_DefaultIconOp = IsmRegisterOperation (S_OPERATION_DEFICON_FIXCONTENT, FALSE); g_DefaultIconData = IsmRegisterProperty (S_V1PROP_ICONDATA, FALSE); g_FileCollPatternData = IsmRegisterProperty (S_V1PROP_FILECOLLPATTERN, FALSE); g_RenameExOp = IsmRegisterOperation (S_OPERATION_ENHANCED_MOVE, FALSE); g_RenameIniExOp = IsmRegisterOperation (S_OPERATION_ENHANCED_INIMOVE, FALSE); g_PartMoveOp = IsmRegisterOperation (S_OPERATION_PARTITION_MOVE, TRUE); g_DestAddObject = IsmRegisterOperation (S_OPERATION_DESTADDOBJ, FALSE); g_RegAutoFilterOp = IsmRegisterOperation (S_OPERATION_REG_AUTO_FILTER, FALSE); g_IniAutoFilterOp = IsmRegisterOperation (S_OPERATION_INI_AUTO_FILTER, FALSE);
//
// Register operation callbacks
//
// FYI: Filter callbacks adjust the name of the object
// Apply callbacks adjust the content of the object
// global operation callbacks
IsmRegisterGlobalApplyCallback (g_RegType | PLATFORM_SOURCE, TEXT("ContentAutoFilter"), DoRegAutoFilter); IsmRegisterGlobalApplyCallback (g_IniType | PLATFORM_SOURCE, TEXT("ContentAutoFilter"), DoIniAutoFilter); IsmRegisterGlobalFilterCallback (g_RegType | PLATFORM_SOURCE, TEXT("AutoFilter"), FilterRegAutoFilter, TRUE, FALSE); IsmRegisterGlobalFilterCallback (g_IniType | PLATFORM_SOURCE, TEXT("AutoFilter"), FilterIniAutoFilter, TRUE, FALSE); IsmRegisterGlobalFilterCallback (g_FileType | PLATFORM_SOURCE, TEXT("AutoFilter"), FilterFileAutoFilter, TRUE, TRUE);
// operation-specific callbacks
IsmRegisterOperationFilterCallback (g_V1MoveExOp, FilterV1MoveEx, TRUE, TRUE, FALSE); IsmRegisterOperationFilterCallback (g_V1MoveOp, FilterV1Move, TRUE, TRUE, FALSE); IsmRegisterOperationFilterCallback (g_RenameOp, FilterMove, TRUE, TRUE, FALSE); IsmRegisterOperationFilterCallback (g_RenameIniOp, FilterIniMove, TRUE, TRUE, FALSE); IsmRegisterOperationFilterCallback (g_DeleteOp, FilterDelete, FALSE, TRUE, FALSE); IsmRegisterOperationApplyCallback (g_DefaultIconOp, DoFixDefaultIcon, TRUE); IsmRegisterOperationFilterCallback (g_RenameExOp, FilterRenameExFilter, TRUE, TRUE, FALSE); IsmRegisterOperationFilterCallback (g_RenameIniExOp, FilterRenameIniExFilter, TRUE, TRUE, FALSE); IsmRegisterOperationFilterCallback (g_PartMoveOp, FilterPartitionMove, TRUE, TRUE, FALSE); IsmRegisterOperationApplyCallback (g_DestAddObject, DoDestAddObject, TRUE); IsmRegisterOperationApplyCallback (g_RegAutoFilterOp, DoRegAutoFilter, TRUE); IsmRegisterOperationApplyCallback (g_IniAutoFilterOp, DoIniAutoFilter, TRUE);
//
// Call special conversion entry point
//
InitSpecialConversion (PLATFORM_DESTINATION); InitSpecialRename (PLATFORM_DESTINATION);
g_RegNodeFilterMap = CreateStringMapping();
g_FileNodeFilterMap = CreateStringMapping();
g_DestEnvMap = CreateStringMapping();
SetIsmEnvironmentFromPhysicalMachine (g_DestEnvMap, FALSE, NULL); SetIsmEnvironmentFromPhysicalMachine (g_FileNodeFilterMap, TRUE, NULL);
pParseRemapEnvVar ();
g_RegLeafFilterMap = CreateStringMapping();
g_FileLeafFilterMap = CreateStringMapping();
if ((!g_EnvMap) || (!g_RevEnvMap) || (!g_UndefMap)) { g_EnvMap = CreateStringMapping(); g_UndefMap = CreateStringMapping(); g_RevEnvMap = CreateStringMapping(); SetIsmEnvironmentFromVirtualMachine (g_EnvMap, g_RevEnvMap, g_UndefMap); }
g_IniSectFilterMap = CreateStringMapping (); g_IniKeyFilterMap = CreateStringMapping ();
g_RegCollisionDestTable = HtAllocWithData (sizeof (MIG_OBJECTSTRINGHANDLE)); g_RegCollisionSrcTable = HtAllocWithData (sizeof (HASHITEM));
InitRestoreCallback (PLATFORM_DESTINATION);
pOutlookClearConvKeys();
return TRUE; }
BOOL pDoesDifferentRegExist ( IN MIG_OBJECTSTRINGHANDLE DestName ) { BOOL result = FALSE; MIG_CONTENT content;
if (IsmAcquireObject (g_RegType|PLATFORM_DESTINATION, DestName, &content)) { IsmReleaseObject (&content); result = TRUE; } else if (HtFindString (g_RegCollisionDestTable, DestName)) { result = TRUE; }
return result; }
BOOL WINAPI FilterV1MoveEx ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PCTSTR orgSrcNode = NULL; PCTSTR orgSrcLeaf = NULL; PCTSTR srcNode = NULL; PCTSTR srcLeaf = NULL; PCTSTR destNode = NULL; PCTSTR destLeaf = NULL; PCTSTR newDestNode = NULL; PCTSTR destNodePtr = NULL; // NTRAID#NTBUG9-153274-2000/08/01-jimschm Static buffer size
TCHAR expDestNode[MAX_PATH * 4]; PCTSTR ismExpDestNode = NULL; TCHAR expDestLeaf[MAX_PATH * 4]; PCTSTR ismExpDestLeaf = NULL; CHARTYPE ch; MIG_OBJECTSTRINGHANDLE destHandle;
__try {
//
// For v1 compatibility, we support only a transformation from
// original source to inf-specified destination. Chaining of
// operations is not allowed (these are restrictions caused by the
// existing INF syntax).
//
if (!DestinationOperationData) { DEBUGMSG ((DBG_ERROR, "Missing dest data in FilterV1MoveEx")); __leave; }
if ((InputData->CurrentObject.ObjectTypeId & (~PLATFORM_MASK)) != g_FileType) { DEBUGMSG ((DBG_ERROR, "Unexpected object type in FilterV1MoveEx")); __leave; }
if (!IsmCreateObjectStringsFromHandle ( DestinationOperationData->String, &destNode, &destLeaf )) { DEBUGMSG ((DBG_ERROR, "Can't split dest object in FilterV1MoveEx")); __leave; }
MYASSERT (destNode);
if (!destNode) { DEBUGMSG ((DBG_ERROR, "Destination spec must be a node")); __leave; }
//
// Split the source object into node and leaf
//
if (!IsmCreateObjectStringsFromHandle ( InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf )) { DEBUGMSG ((DBG_ERROR, "Can't split v1 src object in FilterV1MoveEx")); __leave; }
if (!srcNode) { MYASSERT (FALSE); __leave; }
//
// If not a local path, do not process
//
if (!_istalpha ((CHARTYPE) _tcsnextc (srcNode)) || _tcsnextc (srcNode + 1) != TEXT(':') ) { DEBUGMSG ((DBG_WARNING, "Ignoring %s\\%s because it does not have a drive spec", srcNode, srcLeaf)); __leave; }
ch = (CHARTYPE) _tcsnextc (srcNode + 2);
if (ch && ch != TEXT('\\')) { DEBUGMSG ((DBG_WARNING, "Ignoring %s\\%s because it does not have a drive spec (2)", srcNode, srcLeaf)); __leave; }
// let's see if the current name has something in common
// with SourceOperationData->String. If so, get the extra part
// and add it to the destNode
//
// Split the original rule source object into node and leaf
//
if (SourceOperationData) {
if (IsmCreateObjectStringsFromHandle ( SourceOperationData->String, &orgSrcNode, &orgSrcLeaf )) { if (orgSrcNode) { if (StringIPrefix (srcNode, orgSrcNode)) { destNodePtr = srcNode + TcharCount (orgSrcNode); if (destNodePtr && *destNodePtr) { if (_tcsnextc (destNodePtr) == TEXT('\\')) { destNodePtr = _tcsinc (destNodePtr); } if (destNodePtr) { newDestNode = JoinPaths (destNode, destNodePtr); } } } } } }
if (!newDestNode) { newDestNode = destNode; }
//
// Expand the destination
//
MappingSearchAndReplaceEx ( g_DestEnvMap, newDestNode, expDestNode, 0, NULL, MAX_PATH, STRMAP_FIRST_CHAR_MUST_MATCH, NULL, NULL );
ismExpDestNode = IsmExpandEnvironmentString ( PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, expDestNode, NULL );
if (destLeaf) { MappingSearchAndReplaceEx ( g_DestEnvMap, destLeaf, expDestLeaf, 0, NULL, MAX_PATH, STRMAP_FIRST_CHAR_MUST_MATCH, NULL, NULL ); ismExpDestLeaf = IsmExpandEnvironmentString ( PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, expDestLeaf, NULL );
}
if (destLeaf) { destHandle = IsmCreateObjectHandle ( ismExpDestNode?ismExpDestNode:expDestNode, ismExpDestLeaf?ismExpDestLeaf:expDestLeaf ); } else { destHandle = IsmCreateObjectHandle ( ismExpDestNode?ismExpDestNode:expDestNode, srcLeaf ); }
if (ismExpDestNode) { IsmReleaseMemory (ismExpDestNode); ismExpDestNode = NULL; } if (ismExpDestLeaf) { IsmReleaseMemory (ismExpDestLeaf); ismExpDestLeaf = NULL; }
if (destHandle) { OutputData->NewObject.ObjectName = destHandle; } } __finally { if (newDestNode && (newDestNode != destNode)) { FreePathString (newDestNode); newDestNode = NULL; } IsmDestroyObjectString (orgSrcNode); IsmDestroyObjectString (orgSrcLeaf); IsmDestroyObjectString (destNode); IsmDestroyObjectString (destLeaf); IsmDestroyObjectString (srcNode); IsmDestroyObjectString (srcLeaf); }
return TRUE; }
BOOL WINAPI FilterV1Move ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PCTSTR destNode = NULL; // NTRAID#NTBUG9-153274-2000/08/01-jimschm Static buffer size
TCHAR expDest[MAX_PATH * 4]; PCTSTR destLeaf = NULL; PCTSTR srcNode = NULL; PCTSTR srcLeaf = NULL; PCTSTR pathStart; // NTRAID#NTBUG9-153274-2000/08/01-jimschm Static buffer size
TCHAR pathCopy[MAX_PATH * 4]; PCTSTR newDestNode = NULL; PCTSTR newerDestNode = NULL; PCTSTR subPath; BOOL b; CHARTYPE ch; MIG_OBJECTSTRINGHANDLE destHandle;
__try {
//
// For v1 compatibility, we support only a transformation from
// original source to inf-specified destination. Chaining of
// operations is not allowed (these are restrictions caused by the
// existing INF syntax).
//
if (!DestinationOperationData) { DEBUGMSG ((DBG_ERROR, "Missing dest data in FilterV1Move")); __leave; }
if ((InputData->CurrentObject.ObjectTypeId & (~PLATFORM_MASK)) != g_FileType) { DEBUGMSG ((DBG_ERROR, "Unexpected object type in FilterV1Move")); __leave; }
if (!IsmCreateObjectStringsFromHandle ( DestinationOperationData->String, &destNode, &destLeaf )) { DEBUGMSG ((DBG_ERROR, "Can't split dest object in FilterV1Move")); __leave; }
MYASSERT (destNode);
if (!destNode) { DEBUGMSG ((DBG_ERROR, "Destination spec must be a node")); __leave; }
if (destLeaf) { DEBUGMSG ((DBG_WARNING, "Dest leaf specification %s (in %s) ignored", destLeaf, destNode)); }
//
// Find the longest CSIDL inside InputData. Take that as the base directory,
// and take the rest as the subdirectory.
//
if (!IsmCreateObjectStringsFromHandle ( InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf )) { DEBUGMSG ((DBG_ERROR, "Can't split v1 src object in FilterV1Move")); __leave; }
if (!srcNode) { MYASSERT (FALSE); __leave; }
//
// If not a local path, do not process
//
if (!_istalpha ((CHARTYPE) _tcsnextc (srcNode)) || _tcsnextc (srcNode + 1) != TEXT(':') ) { DEBUGMSG ((DBG_WARNING, "Ignoring %s\\%s because it does not have a drive spec", srcNode, srcLeaf)); __leave; }
ch = (CHARTYPE) _tcsnextc (srcNode + 2);
if (ch && ch != TEXT('\\')) { DEBUGMSG ((DBG_WARNING, "Ignoring %s\\%s because it does not have a drive spec (2)", srcNode, srcLeaf)); __leave; }
//
// Expand the destination
//
b = MappingSearchAndReplaceEx ( g_DestEnvMap, destNode, expDest, 0, NULL, MAX_PATH, STRMAP_FIRST_CHAR_MUST_MATCH, NULL, NULL );
//
// Skip over the drive spec
//
pathStart = srcNode;
//
// Find the longest CSIDL by using the reverse mapping table. This takes
// our full path spec in pathStart and encodes it with an environment
// variable.
//
b = MappingSearchAndReplaceEx ( g_RevEnvMap, pathStart, pathCopy, 0, NULL, ARRAYSIZE(pathCopy), STRMAP_FIRST_CHAR_MUST_MATCH| STRMAP_RETURN_AFTER_FIRST_REPLACE| STRMAP_REQUIRE_WACK_OR_NUL, NULL, &subPath );
#ifdef DEBUG
if (!b) { TCHAR debugBuf[MAX_PATH];
if (MappingSearchAndReplaceEx ( g_RevEnvMap, pathStart, debugBuf, 0, NULL, ARRAYSIZE(debugBuf), STRMAP_FIRST_CHAR_MUST_MATCH|STRMAP_RETURN_AFTER_FIRST_REPLACE, NULL, NULL )) { DEBUGMSG ((DBG_WARNING, "Ignoring conversion: %s -> %s", pathStart, debugBuf)); } } #endif
if (!b) { subPath = pathStart + (UINT) (ch ? 3 : 2); *pathCopy = 0; } else { if (*subPath) { MYASSERT (_tcsnextc (subPath) == TEXT('\\'));
*(PTSTR) subPath = 0; subPath++; } }
//
// pathCopy gives us the base, with CSIDL_ environment variables (might be an empty string)
// subPath gives us the subdir (might also be an empty string)
//
// append subPath to the destination node
//
if (*subPath) { newDestNode = JoinPaths (expDest, subPath); } else { newDestNode = expDest; }
destHandle = IsmCreateObjectHandle (newDestNode, srcLeaf);
if (destHandle) { OutputData->NewObject.ObjectName = destHandle; } } __finally { IsmDestroyObjectString (destNode); IsmDestroyObjectString (destLeaf); IsmDestroyObjectString (srcNode); IsmDestroyObjectString (srcLeaf);
if (newDestNode != expDest) { FreePathString (newDestNode); } }
return TRUE; }
BOOL WINAPI FilterMove ( 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; PCTSTR baseNode = NULL; PCTSTR baseLeaf = NULL; PCTSTR destNode = NULL; PCTSTR destLeaf = NULL; PCTSTR node; PCTSTR leaf; UINT baseNodeLen;
__try { //
// Take InputData, break it into node & leaf, take DestinationOperationData,
// do the same, then replace InputData's node & leaf as appropriate.
//
if (!SourceOperationData) { DEBUGMSG ((DBG_ERROR, "Missing source data in general move operation")); __leave; }
if (!DestinationOperationData) { DEBUGMSG ((DBG_ERROR, "Missing destination data in general move operation")); __leave; }
if (!IsmCreateObjectStringsFromHandle ( InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf )) { DEBUGMSG ((DBG_ERROR, "Can't split src object in general move operation")); __leave; }
if (!IsmCreateObjectStringsFromHandle ( SourceOperationData->String, &baseNode, &baseLeaf )) { DEBUGMSG ((DBG_ERROR, "Can't split src object in general move operation")); __leave; }
if (!IsmCreateObjectStringsFromHandle ( DestinationOperationData->String, &destNode, &destLeaf )) { DEBUGMSG ((DBG_ERROR, "Can't split dest object in general move operation")); __leave; }
baseNodeLen = TcharCount (baseNode); node = NULL; leaf = NULL; if (StringIMatchTcharCount (srcNode, baseNode, baseNodeLen)) { if (srcNode [baseNodeLen]) { node = JoinPaths (destNode, &(srcNode [baseNodeLen])); } else { node = DuplicatePathString (destNode, 0); } if (!baseLeaf && !destLeaf) { leaf = srcLeaf; } else if (baseLeaf && srcLeaf && StringIMatch (srcLeaf, baseLeaf)) { leaf = destLeaf?destLeaf:baseLeaf; } else if (!baseLeaf && destLeaf) { if (srcLeaf) { leaf = destLeaf; } } else { FreePathString (node); node = NULL; } }
if (node) { OutputData->NewObject.ObjectName = IsmCreateObjectHandle (node, leaf); FreePathString (node); node = NULL; } } __finally { IsmDestroyObjectString (srcNode); IsmDestroyObjectString (srcLeaf); IsmDestroyObjectString (baseNode); IsmDestroyObjectString (baseLeaf); IsmDestroyObjectString (destNode); IsmDestroyObjectString (destLeaf); }
return TRUE; }
BOOL WINAPI FilterIniMove ( 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 srcFile = NULL; PTSTR srcSect = NULL; PTSTR srcKey = NULL; PCTSTR baseNode = NULL; PCTSTR baseFile = NULL; PTSTR baseSect = NULL; PTSTR baseKey = NULL; PCTSTR destNode = NULL; PCTSTR destFile = NULL; PTSTR destSect = NULL; PTSTR destKey = NULL; UINT baseNodeLen; BOOL nodeAlloc = FALSE; BOOL fileAlloc = FALSE; PCTSTR node = NULL; PCTSTR file = NULL; PCTSTR destSectKey = NULL; PCTSTR destLeaf = NULL; MIG_OBJECTSTRINGHANDLE baseNodeHandle = NULL; MIG_OBJECTSTRINGHANDLE newBaseNode = NULL; PCTSTR tempStr = NULL;
__try { //
// Take InputData, break it into node & leaf, take DestinationOperationData,
// do the same, then replace InputData's node & leaf as appropriate.
//
if (!SourceOperationData) { DEBUGMSG ((DBG_ERROR, "Missing source data in general move operation")); __leave; }
if (!DestinationOperationData) { DEBUGMSG ((DBG_ERROR, "Missing destination data in general move operation")); __leave; }
if (!IsmCreateObjectStringsFromHandle ( InputData->CurrentObject.ObjectName, &srcNode, &srcFile )) { DEBUGMSG ((DBG_ERROR, "Can't split src object in general move operation")); __leave; } if (srcFile [0] == 0) { IsmDestroyObjectString (srcFile); srcFile = NULL; } if (srcFile) { srcSect = _tcschr (srcFile, TEXT('\\')); if (srcSect) { *srcSect = 0; srcSect ++; srcKey = _tcsrchr (srcSect, TEXT('=')); if (srcKey) { *srcKey = 0; srcKey ++; } } }
if (!srcNode || !srcFile || !srcSect || !srcKey) { DEBUGMSG ((DBG_ERROR, "INI src object expected to have node, file, section and key")); __leave; }
if (!IsmCreateObjectStringsFromHandle ( SourceOperationData->String, &baseNode, &baseFile )) { DEBUGMSG ((DBG_ERROR, "Can't split base object in general move operation")); __leave; } if (baseFile [0] == 0) { IsmDestroyObjectString (baseFile); baseFile = NULL; } if (baseFile) { baseSect = _tcschr (baseFile, TEXT('\\')); if (baseSect) { *baseSect = 0; baseSect ++; baseKey = _tcsrchr (baseSect, TEXT('=')); if (baseKey) { *baseKey = 0; baseKey ++; } } }
if (!baseNode) { DEBUGMSG ((DBG_ERROR, "INI base object expected to have at least a node")); __leave; }
if (!IsmCreateObjectStringsFromHandle ( DestinationOperationData->String, &destNode, &destFile )) { DEBUGMSG ((DBG_ERROR, "Can't split dest object in general move operation")); __leave; } if (destFile [0] == 0) { IsmDestroyObjectString (destFile); destFile = NULL; } if (destFile) { destSect = _tcschr (destFile, TEXT('\\')); if (destSect) { *destSect = 0; destSect ++; destKey = _tcsrchr (destSect, TEXT('=')); if (destKey) { *destKey = 0; destKey ++; } } }
if (!destNode || (destNode [0] == 0)) { // We need to use the src node, there was no specification of
// the node where the INI file is supposed to end up.
if (!destFile || (destFile [0] == 0)) { // destFile is not specified. Let's filter the whole thing
baseNodeHandle = IsmCreateObjectHandle (srcNode, srcFile); if (baseNodeHandle) { newBaseNode = IsmFilterObject ( g_FileType | PLATFORM_SOURCE, baseNodeHandle, NULL, NULL, NULL ); if (newBaseNode) { IsmCreateObjectStringsFromHandle (newBaseNode, &node, &file); nodeAlloc = TRUE; fileAlloc = TRUE; IsmDestroyObjectHandle (newBaseNode); } else { node = srcNode; file = srcFile; } IsmDestroyObjectHandle (baseNodeHandle); } } else { // destFile is explicitely specified. Let's just filter the node
baseNodeHandle = IsmCreateObjectHandle (srcNode, NULL); if (baseNodeHandle) { newBaseNode = IsmFilterObject ( g_FileType | PLATFORM_SOURCE, baseNodeHandle, NULL, NULL, NULL ); if (newBaseNode) { IsmCreateObjectStringsFromHandle (newBaseNode, &node, &tempStr); nodeAlloc = TRUE; MYASSERT (!tempStr); IsmDestroyObjectString (tempStr); IsmDestroyObjectHandle (newBaseNode); } else { node = IsmDuplicateString (srcNode); } IsmDestroyObjectHandle (baseNodeHandle); } } }
if (!node) { if (destNode && (destNode [0] != 0)) { node = destNode; } else { node = srcNode; } }
if (!file) { if (destFile && (destFile [0] != 0)) { file = destFile; } else { file = srcFile; } }
if (!destSect || (destSect [0] == 0)) { destSect = srcSect; }
if (!destKey || (destKey [0] == 0)) { destKey = srcKey; }
destSectKey = JoinTextEx (NULL, destSect, destKey, TEXT("="), 0, NULL);
destLeaf = JoinPaths (file, destSectKey);
OutputData->NewObject.ObjectName = IsmCreateObjectHandle (node, destLeaf);
FreePathString (destLeaf); destLeaf = NULL; FreeText (destSectKey); destSectKey = NULL; } __finally { IsmDestroyObjectString (srcNode); IsmDestroyObjectString (srcFile); IsmDestroyObjectString (baseNode); IsmDestroyObjectString (baseFile); IsmDestroyObjectString (destNode); IsmDestroyObjectString (destFile); if (fileAlloc) { IsmDestroyObjectString (file); } if (nodeAlloc) { IsmDestroyObjectString (node); } }
return TRUE; }
BOOL WINAPI FilterDelete ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { //
// Mark the output data as deleted. That will be sufficient to
// cause the object to be deleted (even if it was also marked as
// "save")
//
OutputData->Deleted = TRUE;
return TRUE; }
BOOL WINAPI FilterRegAutoFilter ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PCTSTR node = NULL; PCTSTR leaf = NULL; // NTRAID#NTBUG9-153275-2000/08/01-jimschm Static buffer size
TCHAR newNode[MAX_PATH * 4]; TCHAR newLeaf[MAX_PATH * 4]; BOOL change = FALSE;
//
// Filter the object name
//
IsmCreateObjectStringsFromHandle ( InputData->CurrentObject.ObjectName, &node, &leaf );
if (node) { if (MappingSearchAndReplaceEx ( g_RegNodeFilterMap, // map handle
node, // source string
newNode, // dest buffer
0, // source string bytes (0=unspecified)
NULL, // dest bytes required
ARRAYSIZE(newNode), // dest buffer size
0, // flags
NULL, // extra data value
NULL // end of string
)) { IsmDestroyObjectString (node); node = newNode; change = TRUE; } }
if (leaf) { if (MappingSearchAndReplaceEx ( g_RegLeafFilterMap, leaf, newLeaf, 0, NULL, ARRAYSIZE(newLeaf), 0, NULL, NULL )) { IsmDestroyObjectString (leaf); leaf = newLeaf; change = TRUE; } }
if (change) { OutputData->NewObject.ObjectName = IsmCreateObjectHandle (node, leaf); }
if (node != newNode) { IsmDestroyObjectString (node); }
if (leaf != newLeaf) { IsmDestroyObjectString (leaf); }
return TRUE; }
BOOL WINAPI FilterIniAutoFilter ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { // This function will split the INI object, filter the INI file
// so we know where it ends up, get section and key through the
// mapping so they can be potentially changed and rebuild the
// object name.
PCTSTR srcNode = NULL; PCTSTR srcFile = NULL; PTSTR srcSect = NULL; PTSTR srcKey = NULL; PCTSTR newNode = NULL; PCTSTR newFile = NULL; PCTSTR newSect = NULL; PCTSTR newKey = NULL; // NTRAID#NTBUG9-153275-2000/08/01-jimschm Static buffer size
TCHAR sectBuff [MAXINISIZE]; TCHAR keyBuff [MAXINISIZE]; MIG_OBJECTSTRINGHANDLE iniFile = NULL; MIG_OBJECTSTRINGHANDLE newIniFile = NULL; PCTSTR sectKey = NULL; PCTSTR newLeaf = NULL; BOOL orgDeleted = FALSE; BOOL orgReplaced = FALSE; BOOL change = FALSE;
//
// Filter the object name
//
IsmCreateObjectStringsFromHandle ( InputData->CurrentObject.ObjectName, &srcNode, &srcFile );
if (srcNode && srcFile) { srcSect = _tcschr (srcFile, TEXT('\\')); if (srcSect) { *srcSect = 0; srcSect ++; srcKey = _tcsrchr (srcSect, TEXT('=')); if (srcKey) { *srcKey = 0; srcKey ++; // let's see if the section is replaced
if (MappingSearchAndReplaceEx ( g_IniSectFilterMap, // map handle
srcSect, // source string
sectBuff, // dest buffer
0, // source string bytes (0=unspecified)
NULL, // dest bytes required
ARRAYSIZE(sectBuff), // dest buffer size
0, // flags
NULL, // extra data value
NULL // end of string
)) { newSect = sectBuff; change = TRUE; } // let's see if the key is replaced
if (MappingSearchAndReplaceEx ( g_IniSectFilterMap, // map handle
srcKey, // source string
keyBuff, // dest buffer
0, // source string bytes (0=unspecified)
NULL, // dest bytes required
ARRAYSIZE(keyBuff), // dest buffer size
0, // flags
NULL, // extra data value
NULL // end of string
)) { newKey = keyBuff; change = TRUE; }
iniFile = IsmCreateObjectHandle (srcNode, srcFile); if (iniFile) { newIniFile = IsmFilterObject ( g_FileType | PLATFORM_SOURCE, iniFile, NULL, &orgDeleted, &orgReplaced ); if (newIniFile) { if (IsmCreateObjectStringsFromHandle (newIniFile, &newNode, &newFile)) { change = TRUE; } IsmDestroyObjectHandle (newIniFile); } IsmDestroyObjectHandle (iniFile); } } } }
if (change) { sectKey = JoinTextEx (NULL, newSect?newSect:srcSect, newKey?newKey:srcKey, TEXT("="), 0, NULL); if (sectKey) { newLeaf = JoinPaths (newFile?newFile:srcFile, sectKey); if (newLeaf) { OutputData->NewObject.ObjectName = IsmCreateObjectHandle (newNode?newNode:srcNode, newLeaf); FreePathString (newLeaf); newLeaf = NULL; } FreeText (sectKey); sectKey = NULL; } }
IsmDestroyObjectString (srcNode); IsmDestroyObjectString (srcFile); if (newNode) { IsmDestroyObjectString (newNode); newNode = NULL; } if (newFile) { IsmDestroyObjectString (newFile); newFile = NULL; }
return TRUE; }
BOOL pOpmFindFile ( IN PCTSTR FileName ) { MIG_OBJECTSTRINGHANDLE objectName; PTSTR node, leaf, leafPtr; BOOL result = FALSE;
objectName = IsmCreateObjectHandle (FileName, NULL); if (objectName) { if (IsmGetObjectIdFromName (MIG_FILE_TYPE | PLATFORM_SOURCE, objectName, TRUE) != 0) { result = TRUE; } IsmDestroyObjectHandle (objectName); } if (!result) { node = DuplicateText (FileName); leaf = _tcsrchr (node, TEXT('\\')); if (leaf) { leafPtr = (PTSTR) leaf; leaf = _tcsinc (leaf); *leafPtr = 0; objectName = IsmCreateObjectHandle (node, leaf); if (objectName) { if (IsmGetObjectIdFromName (MIG_FILE_TYPE | PLATFORM_SOURCE, objectName, TRUE) != 0) { result = TRUE; } IsmDestroyObjectHandle (objectName); } *leafPtr = TEXT('\\'); } FreeText (node); }
return result; }
BOOL pOpmSearchPath ( IN PCTSTR FileName, IN DWORD BufferLength, OUT PTSTR Buffer ) { return FALSE; }
MIG_OBJECTSTRINGHANDLE pSimpleTryHandle ( IN PCTSTR FullPath ) { PCTSTR buffer; PTSTR leafPtr, leaf; MIG_OBJECTSTRINGHANDLE source = NULL; MIG_OBJECTSTRINGHANDLE result = NULL; PTSTR workingPath; PCTSTR sanitizedPath; BOOL orgDeleted = FALSE; BOOL orgReplaced = FALSE; PCTSTR saved = NULL;
sanitizedPath = SanitizePath (FullPath); if (!sanitizedPath) { return NULL; }
source = IsmCreateObjectHandle (sanitizedPath, NULL); if (source) { result = IsmFilterObject ( g_FileType | PLATFORM_SOURCE, source, NULL, &orgDeleted, &orgReplaced ); // we do not want replaced directories
// since they can be false hits
if (orgDeleted) { if (result) { saved = result; result = NULL; } } if (!result && !orgDeleted) { result = source; } else { IsmDestroyObjectHandle (source); source = NULL; } }
if (result) { goto exit; }
buffer = DuplicatePathString (sanitizedPath, 0);
leaf = _tcsrchr (buffer, TEXT('\\'));
if (leaf) { leafPtr = leaf; leaf = _tcsinc (leaf); *leafPtr = 0; source = IsmCreateObjectHandle (buffer, leaf); *leafPtr = TEXT('\\'); }
FreePathString (buffer);
if (source) { result = IsmFilterObject ( g_FileType | PLATFORM_SOURCE, source, NULL, &orgDeleted, &orgReplaced ); if (!result && !orgDeleted) { result = source; } else { if (!result) { result = saved; } IsmDestroyObjectHandle (source); source = NULL; } }
if (result != saved) { IsmDestroyObjectHandle (saved); saved = NULL; }
exit: FreePathString (sanitizedPath); return result; }
MIG_OBJECTSTRINGHANDLE pTryHandle ( IN PCTSTR FullPath, IN PCTSTR Hint, OUT PCTSTR *TrimmedResult ) { PATH_ENUM pathEnum; PCTSTR newPath; MIG_OBJECTSTRINGHANDLE result = NULL; PCTSTR nativeName = NULL; PCTSTR lastSegPtr;
if (TrimmedResult) { *TrimmedResult = NULL; }
result = pSimpleTryHandle (FullPath); if (result || (!Hint)) { return result; } if (EnumFirstPathEx (&pathEnum, Hint, NULL, NULL, FALSE)) { do { newPath = JoinPaths (pathEnum.PtrCurrPath, FullPath); result = pSimpleTryHandle (newPath); if (result) { AbortPathEnum (&pathEnum); FreePathString (newPath); // now, if the initial FullPath did not have any wack in it
// we will take the last segment of the result and put it
// in TrimmedResult
if (TrimmedResult && (!_tcschr (FullPath, TEXT('\\')))) { nativeName = IsmGetNativeObjectName (g_FileType, result); if (nativeName) { lastSegPtr = _tcsrchr (nativeName, TEXT('\\')); if (lastSegPtr) { lastSegPtr = _tcsinc (lastSegPtr); if (lastSegPtr) { *TrimmedResult = DuplicatePathString (lastSegPtr, 0); } } } } return result; } FreePathString (newPath); } while (EnumNextPath (&pathEnum)); } AbortPathEnum (&pathEnum); return NULL; }
BOOL WINAPI DoRegAutoFilter ( IN MIG_OBJECTTYPEID SrcObjectTypeId, IN MIG_OBJECTSTRINGHANDLE SrcObjectName, IN PCMIG_CONTENT OriginalContent, IN PCMIG_CONTENT CurrentContent, OUT PMIG_CONTENT NewContent, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PTSTR leafPtr = NULL; PDWORD valueType; MIG_OBJECTSTRINGHANDLE source; MIG_OBJECTSTRINGHANDLE destination; PCTSTR leaf; TCHAR expandBuffer[4096]; TCHAR hintBuffer[4096]; PTSTR buffer; GROWBUFFER result = INIT_GROWBUFFER; GROWBUFFER cmdLineBuffer = INIT_GROWBUFFER; PCMDLINE cmdLine; UINT u; PCTSTR data, p, end; PCTSTR nativeDest; PCTSTR newData, oldData; BOOL parsable; BOOL replaced = FALSE; BOOL orgDeleted = FALSE; BOOL orgReplaced = FALSE; PCTSTR trimmedResult = NULL; BOOL newContent = TRUE; PCTSTR destResult = NULL;
//
// Filter the data for any references to %windir%
//
if (!CurrentContent->ContentInFile) {
parsable = FALSE; valueType = (PDWORD)(CurrentContent->Details.DetailsData); if (valueType) { if (*valueType == REG_EXPAND_SZ || *valueType == REG_SZ ) {
parsable = TRUE; } } else { parsable = IsmIsObjectHandleNodeOnly (SrcObjectName); }
if (parsable) {
data = (PTSTR) CurrentContent->MemoryContent.ContentBytes; end = (PCTSTR) (CurrentContent->MemoryContent.ContentBytes + CurrentContent->MemoryContent.ContentSize);
while (data < end) { if (*data == 0) { break; }
data = _tcsinc (data); }
if (data >= end) { parsable = FALSE; } }
if (parsable) {
data = (PTSTR) CurrentContent->MemoryContent.ContentBytes;
if ((*valueType == REG_EXPAND_SZ) || (*valueType == REG_SZ) ) { //
// Expand the data
//
MappingSearchAndReplaceEx ( g_EnvMap, data, expandBuffer, 0, NULL, ARRAYSIZE(expandBuffer), 0, NULL, NULL );
data = expandBuffer; }
*hintBuffer = 0; if (DestinationOperationData && (DestinationOperationData->Type == BLOBTYPE_STRING) && (DestinationOperationData->String) ) { MappingSearchAndReplaceEx ( g_EnvMap, DestinationOperationData->String, hintBuffer, 0, NULL, ARRAYSIZE(hintBuffer), 0, NULL, NULL ); }
destination = pTryHandle (data, *hintBuffer?hintBuffer:NULL, &trimmedResult);
if (destination) { replaced = TRUE; if (trimmedResult) { GbAppendString (&result, trimmedResult); FreePathString (trimmedResult); } else { nativeDest = IsmGetNativeObjectName (g_FileType, destination); GbAppendString (&result, nativeDest); IsmReleaseMemory (nativeDest); } }
// finally, if we failed we are going to assume it's a command line
if (!replaced) { newData = DuplicatePathString (data, 0); cmdLine = ParseCmdLineEx (data, NULL, &pOpmFindFile, &pOpmSearchPath, &cmdLineBuffer); if (cmdLine) {
//
// Find the file referenced in the list or command line
//
for (u = 0 ; u < cmdLine->ArgCount ; u++) { p = cmdLine->Args[u].CleanedUpArg;
// first we try it as is
destination = pTryHandle (p, *hintBuffer?hintBuffer:NULL, &trimmedResult);
// maybe we have something like /m:c:\foo.txt
// we need to go forward until we find a sequence of
// <alpha>:\<something>
if (!destination && p[0] && p[1]) {
while (p[2]) { if (_istalpha ((CHARTYPE) _tcsnextc (p)) && p[1] == TEXT(':') && p[2] == TEXT('\\') ) {
destination = pTryHandle (p, *hintBuffer?hintBuffer:NULL, &trimmedResult);
if (destination) { break; } } p ++; } } if (destination) { replaced = TRUE; if (trimmedResult) { oldData = StringSearchAndReplace (newData, p, trimmedResult); if (oldData) { FreePathString (newData); newData = oldData; } FreePathString (trimmedResult); } else { nativeDest = IsmGetNativeObjectName (g_FileType, destination); oldData = StringSearchAndReplace (newData, p, nativeDest); if (oldData) { FreePathString (newData); newData = oldData; } IsmReleaseMemory (nativeDest); } IsmDestroyObjectHandle (destination); destination = NULL; } } } GbFree (&cmdLineBuffer); if (!replaced) { if (newData) { FreePathString (newData); } } else { if (newData) { GbAppendString (&result, newData); FreePathString (newData); } } }
if (destination) { IsmDestroyObjectHandle (destination); destination = NULL; }
if (replaced && result.Buf) { // looks like we have new content
// Let's do one more check. If this is a REG_EXPAND_SZ we will do our best to
// keep the stuff unexpanded. So if the source string expanded on the destination
// machine is the same as the destination string we won't do anything.
newContent = TRUE; if (*valueType == REG_EXPAND_SZ) { destResult = IsmExpandEnvironmentString ( PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, (PCTSTR) CurrentContent->MemoryContent.ContentBytes, NULL ); if (destResult && StringIMatch (destResult, (PCTSTR)result.Buf)) { newContent = FALSE; } if (destResult) { IsmReleaseMemory (destResult); destResult = NULL; } } if (newContent) { NewContent->MemoryContent.ContentSize = SizeOfString ((PCTSTR)result.Buf); NewContent->MemoryContent.ContentBytes = IsmGetMemory (NewContent->MemoryContent.ContentSize); CopyMemory ((PTSTR)NewContent->MemoryContent.ContentBytes, result.Buf, NewContent->MemoryContent.ContentSize); } }
GbFree (&result); } }
return TRUE; }
BOOL WINAPI DoIniAutoFilter ( IN MIG_OBJECTTYPEID SrcObjectTypeId, IN MIG_OBJECTSTRINGHANDLE SrcObjectName, IN PCMIG_CONTENT OriginalContent, IN PCMIG_CONTENT CurrentContent, OUT PMIG_CONTENT NewContent, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { // This function will get the content of an INI key and see if there is
// a path there somewhere. If yes, it will attempt to find the new
// location for the file and replace it in the INI key content.
PTSTR leafPtr = NULL; PDWORD valueType; MIG_OBJECTSTRINGHANDLE source; MIG_OBJECTSTRINGHANDLE destination; PCTSTR leaf; TCHAR expandBuffer[4096]; TCHAR hintBuffer[4096]; PTSTR buffer; GROWBUFFER result = INIT_GROWBUFFER; GROWBUFFER cmdLineBuffer = INIT_GROWBUFFER; PCMDLINE cmdLine; UINT u; PCTSTR data, p, end; PCTSTR nativeDest; PCTSTR newData, oldData; BOOL parsable; BOOL replaced = FALSE; BOOL orgDeleted = FALSE; BOOL orgReplaced = FALSE; PCTSTR trimmedResult = NULL; BOOL newContent = TRUE; PCTSTR destResult = NULL;
//
// Filter the data for any references to %windir%
//
if (!CurrentContent->ContentInFile) {
data = (PTSTR) CurrentContent->MemoryContent.ContentBytes; end = (PCTSTR) (CurrentContent->MemoryContent.ContentBytes + CurrentContent->MemoryContent.ContentSize);
parsable = TRUE;
while (data < end) { if (*data == 0) { break; }
data = _tcsinc (data); }
if (data >= end) { parsable = FALSE; }
if (parsable) {
data = (PTSTR) CurrentContent->MemoryContent.ContentBytes;
MappingSearchAndReplaceEx ( g_EnvMap, data, expandBuffer, 0, NULL, ARRAYSIZE(expandBuffer), 0, NULL, NULL );
data = expandBuffer;
*hintBuffer = 0; if (DestinationOperationData && (DestinationOperationData->Type == BLOBTYPE_STRING) && (DestinationOperationData->String) ) { MappingSearchAndReplaceEx ( g_EnvMap, DestinationOperationData->String, hintBuffer, 0, NULL, ARRAYSIZE(hintBuffer), 0, NULL, NULL ); }
destination = pTryHandle (data, *hintBuffer?hintBuffer:NULL, &trimmedResult);
if (destination) { replaced = TRUE; if (trimmedResult) { GbAppendString (&result, trimmedResult); FreePathString (trimmedResult); } else { nativeDest = IsmGetNativeObjectName (g_FileType, destination); GbAppendString (&result, nativeDest); IsmReleaseMemory (nativeDest); } }
// finally, if we failed we are going to assume it's a command line
if (!replaced) { newData = DuplicatePathString (data, 0); cmdLine = ParseCmdLineEx (data, NULL, &pOpmFindFile, &pOpmSearchPath, &cmdLineBuffer); if (cmdLine) {
//
// Find the file referenced in the list or command line
//
for (u = 0 ; u < cmdLine->ArgCount ; u++) { p = cmdLine->Args[u].CleanedUpArg;
// first we try it as is
destination = pTryHandle (p, *hintBuffer?hintBuffer:NULL, &trimmedResult);
// maybe we have something like /m:c:\foo.txt
// we need to go forward until we find a sequence of
// <alpha>:\<something>
if (!destination && p[0] && p[1]) {
while (p[2]) { if (_istalpha ((CHARTYPE) _tcsnextc (p)) && p[1] == TEXT(':') && p[2] == TEXT('\\') ) {
destination = pTryHandle (p, *hintBuffer?hintBuffer:NULL, &trimmedResult);
if (destination) { break; } } p ++; } } if (destination) { replaced = TRUE; if (trimmedResult) { oldData = StringSearchAndReplace (newData, p, trimmedResult); if (oldData) { FreePathString (newData); newData = oldData; } FreePathString (trimmedResult); } else { nativeDest = IsmGetNativeObjectName (g_FileType, destination); oldData = StringSearchAndReplace (newData, p, nativeDest); if (oldData) { FreePathString (newData); newData = oldData; } IsmReleaseMemory (nativeDest); } IsmDestroyObjectHandle (destination); destination = NULL; } } } GbFree (&cmdLineBuffer); if (!replaced) { if (newData) { FreePathString (newData); } } else { if (newData) { GbAppendString (&result, newData); FreePathString (newData); } } }
if (destination) { IsmDestroyObjectHandle (destination); destination = NULL; }
if (replaced && result.Buf) { // looks like we have new content
// Let's do one more check. If the source string has environment variables in it,
// we will do our best to keep the stuff unexpanded. So if the source string
// expanded on the destination machine is the same as the destination string
// we won't do anything.
newContent = TRUE; destResult = IsmExpandEnvironmentString ( PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, (PCTSTR) CurrentContent->MemoryContent.ContentBytes, NULL ); if (destResult && StringIMatch (destResult, (PCTSTR)result.Buf)) { newContent = FALSE; } if (destResult) { IsmReleaseMemory (destResult); destResult = NULL; } if (newContent) { NewContent->MemoryContent.ContentSize = SizeOfString ((PCTSTR)result.Buf); NewContent->MemoryContent.ContentBytes = IsmGetMemory (NewContent->MemoryContent.ContentSize); CopyMemory ((PTSTR)NewContent->MemoryContent.ContentBytes, result.Buf, NewContent->MemoryContent.ContentSize); } }
GbFree (&result); } }
return TRUE; }
BOOL WINAPI DoFixDefaultIcon ( IN MIG_OBJECTTYPEID SrcObjectTypeId, IN MIG_OBJECTSTRINGHANDLE SrcObjectName, IN PCMIG_CONTENT OriginalContent, IN PCMIG_CONTENT CurrentContent, OUT PMIG_CONTENT NewContent, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { MIG_PROPERTYDATAID propDataId; MIG_BLOBTYPE propDataType; UINT requiredSize; PDWORD valueType; PICON_GROUP iconGroup = NULL; ICON_SGROUP iconSGroup = {0, NULL}; PTSTR iconLibPath = NULL; INT iconNumber = 0; PTSTR dataCopy;
if (CurrentContent->ContentInFile) { return TRUE; } valueType = (PDWORD)(CurrentContent->Details.DetailsData); if (*valueType != REG_SZ && *valueType != REG_EXPAND_SZ) { return TRUE; } // let's see if we have our property attached
propDataId = IsmGetPropertyFromObject (SrcObjectTypeId, SrcObjectName, g_DefaultIconData); if (!propDataId) { return TRUE; } if (!IsmGetPropertyData (propDataId, NULL, 0, &requiredSize, &propDataType)) { return TRUE; } iconSGroup.DataSize = requiredSize; iconSGroup.Data = IsmGetMemory (requiredSize); if (!IsmGetPropertyData (propDataId, (PBYTE)iconSGroup.Data, requiredSize, NULL, &propDataType)) { IsmReleaseMemory (iconSGroup.Data); return TRUE; } if (!iconSGroup.DataSize) { IsmReleaseMemory (iconSGroup.Data); return TRUE; } iconGroup = IcoDeSerializeIconGroup (&iconSGroup); if (!iconGroup) { IsmReleaseMemory (iconSGroup.Data); return TRUE; } if (IsmGetEnvironmentString ( PLATFORM_DESTINATION, NULL, S_ENV_ICONLIB, NULL, 0, &requiredSize )) { iconLibPath = IsmGetMemory (requiredSize); if (IsmGetEnvironmentString ( PLATFORM_DESTINATION, NULL, S_ENV_ICONLIB, iconLibPath, requiredSize, NULL )) { if (IcoWriteIconGroupToPeFile (iconLibPath, iconGroup, NULL, &iconNumber)) { // finally we wrote the icon, fix the content and tell scanstate that
// we iconlib was used
dataCopy = IsmGetMemory (SizeOfString (iconLibPath) + sizeof (TCHAR) + 20 * sizeof (TCHAR)); wsprintf (dataCopy, TEXT("%s,%d"), iconLibPath, iconNumber); NewContent->MemoryContent.ContentSize = SizeOfString (dataCopy); NewContent->MemoryContent.ContentBytes = (PBYTE) dataCopy; IsmSetEnvironmentFlag (PLATFORM_DESTINATION, NULL, S_ENV_SAVE_ICONLIB); } } IsmReleaseMemory (iconLibPath); } IcoReleaseIconGroup (iconGroup); IsmReleaseMemory (iconSGroup.Data);
return TRUE; }
BOOL pDoesDestObjectExist ( IN MIG_OBJECTSTRINGHANDLE ObjectName ) { PCTSTR nativeName; BOOL result = FALSE;
nativeName = IsmGetNativeObjectName (PLATFORM_DESTINATION | MIG_FILE_TYPE, ObjectName); if (nativeName) { if (IsmGetRealPlatform () == PLATFORM_DESTINATION) { result = DoesFileExist (nativeName); } IsmReleaseMemory (nativeName); nativeName = NULL; }
return result; }
BOOL WINAPI FilterFileAutoFilter ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PCTSTR node, nodeWack; PCTSTR leaf; // NTRAID#NTBUG9-153275-2000/08/01-jimschm Static buffer size
TCHAR newNode[MAX_PATH * 4]; TCHAR newLeaf[MAX_PATH * 4]; BOOL fullChanged = FALSE; PCTSTR nativeName; PTSTR leafPtr; BOOL changed = FALSE;
if (InputData && InputData->OriginalObject.ObjectName && InputData->CurrentObject.ObjectName && (InputData->OriginalObject.ObjectName != InputData->CurrentObject.ObjectName) ) { // this was already modified. Let's not touch it.
return TRUE; }
//
// Filter the object name
//
IsmCreateObjectStringsFromHandle ( InputData->CurrentObject.ObjectName, &node, &leaf );
/*
// I am taking this out. The point is,
// even if we are not restoring the file,
// we should get the best guess as to where
// this file would end up in case it would
// get moved.
if (NoRestoreObject && leaf) { IsmDestroyObjectString (node); IsmDestroyObjectString (leaf); return TRUE; } */
if (node && leaf) { // let's do a trick here. Let's build the native name and
// see if we can find an env replacement for the entire
// path
nativeName = IsmGetNativeObjectName (InputData->CurrentObject.ObjectTypeId, InputData->CurrentObject.ObjectName); if (nativeName) { if (MappingSearchAndReplaceEx ( g_FileNodeFilterMap, // map handle
nativeName, // source string
newNode, // dest buffer
0, // source string bytes (0=unspecified)
NULL, // dest bytes required
ARRAYSIZE(newNode), // dest buffer size
STRMAP_COMPLETE_MATCH_ONLY, // flags
NULL, // extra data value
NULL // end of string
)) { // we have a replacement. Let's split it into node and leaf
leafPtr = _tcsrchr (newNode, TEXT('\\')); if (leafPtr) { *leafPtr = 0; leafPtr ++; StringCopy (newLeaf, leafPtr); IsmDestroyObjectString (node); node = newNode; IsmDestroyObjectString (leaf); leaf = newLeaf; fullChanged = TRUE; } } IsmReleaseMemory (nativeName); nativeName = NULL; } }
if (!fullChanged && node) { nodeWack = JoinPaths (node, TEXT("")); if (MappingSearchAndReplaceEx ( g_FileNodeFilterMap, // map handle
nodeWack, // source string
newNode, // dest buffer
0, // source string bytes (0=unspecified)
NULL, // dest bytes required
ARRAYSIZE(newNode), // dest buffer size
STRMAP_FIRST_CHAR_MUST_MATCH| STRMAP_RETURN_AFTER_FIRST_REPLACE| STRMAP_REQUIRE_WACK_OR_NUL, // flags
NULL, // extra data value
NULL // end of string
)) { IsmDestroyObjectString (node); node = newNode; changed = TRUE; } else { if (MappingSearchAndReplaceEx ( g_FileNodeFilterMap, // map handle
node, // source string
newNode, // dest buffer
0, // source string bytes (0=unspecified)
NULL, // dest bytes required
ARRAYSIZE(newNode), // dest buffer size
STRMAP_FIRST_CHAR_MUST_MATCH| STRMAP_RETURN_AFTER_FIRST_REPLACE| STRMAP_REQUIRE_WACK_OR_NUL, // flags
NULL, // extra data value
NULL // end of string
)) { IsmDestroyObjectString (node); node = newNode; changed = TRUE; } }
FreePathString (nodeWack); nodeWack = NULL; }
if (!fullChanged && leaf) { if (MappingSearchAndReplaceEx ( g_FileLeafFilterMap, leaf, newLeaf, 0, NULL, ARRAYSIZE(newLeaf), 0, NULL, NULL )) { IsmDestroyObjectString (leaf); leaf = newLeaf; changed = TRUE; } }
if (fullChanged || changed) { OutputData->NewObject.ObjectName = IsmCreateObjectHandle (node, leaf); } OutputData->Replaced = (NoRestoreObject||OutputData->Deleted)?pDoesDestObjectExist (OutputData->NewObject.ObjectName):0;
if (node != newNode) { IsmDestroyObjectString (node); }
if (leaf != newLeaf) { IsmDestroyObjectString (leaf); }
return TRUE; }
PCTSTR pProcessRenameExMacro ( IN PCTSTR Node, IN PCTSTR Leaf, OPTIONAL IN BOOL ZeroBase ) { PCTSTR workingStr; PTSTR macroStartPtr = NULL; PTSTR macroEndPtr = NULL; PTSTR macroCopy = NULL; DWORD macroLength = 0; PTSTR macroParsePtr = NULL; TCHAR macroBuffer [MAX_PATH]; HRESULT hr; MIG_OBJECTSTRINGHANDLE testHandle = NULL;
UINT index; PTSTR newString = NULL;
// If Leaf is supplied, we are working only on the Leaf
workingStr = Leaf ? Leaf : Node;
// Extract macro
macroStartPtr = _tcschr (workingStr, S_RENAMEEX_START_CHAR); if (macroStartPtr) { macroEndPtr = _tcschr (macroStartPtr + 1, S_RENAMEEX_END_CHAR); } if (macroEndPtr) { macroCopy = DuplicateText (macroStartPtr + 1); macroCopy[macroEndPtr-macroStartPtr-1] = 0; }
if (macroCopy) { // Build a possible destination
if (ZeroBase) { index = 0; } else { index = 1; }
do { if (newString) { FreeText (newString); newString = NULL; } IsmDestroyObjectHandle (testHandle);
__try { hr = StringCbPrintf (macroBuffer, sizeof (macroBuffer), macroCopy, index); } __except (EXCEPTION_EXECUTE_HANDLER) { // something went wrong. The pattern might have been terribly wrong
hr = S_FALSE; } if (hr != S_OK) { // something is wrong with the rename pattern. Let's just get out of here.
break; } newString = AllocText ( (HALF_PTR) (macroStartPtr - workingStr) + TcharCount (macroBuffer) + TcharCount (macroEndPtr) + 1 ); if (newString) { StringCopyTcharCount (newString, workingStr, (HALF_PTR) (macroStartPtr - workingStr) + 1); StringCat (newString, macroBuffer); StringCat (newString, macroEndPtr + 1); }
if (Leaf) { testHandle = IsmCreateObjectHandle (Node, newString); } else { testHandle = IsmCreateObjectHandle (newString, NULL); } index++; } while (pDoesDifferentRegExist (testHandle) || HtFindString (g_RegCollisionDestTable, testHandle));
if (testHandle) { IsmDestroyObjectHandle (testHandle); } FreeText (macroCopy); }
if (!newString) { newString = DuplicateText (workingStr); }
return newString; }
BOOL WINAPI FilterRenameExFilter ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PCTSTR doNode = NULL; PCTSTR doLeaf = NULL; PCTSTR destNode = NULL; PCTSTR newNode = NULL; PCTSTR rootNode; PCTSTR destLeaf = NULL; PCTSTR srcNode = NULL; PCTSTR srcLeaf = NULL; // NTRAID#NTBUG9-153274-2000/08/01-jimschm Static buffer size
TCHAR newSrcNode[MAX_PATH * 4]; TCHAR newSrcLeaf[MAX_PATH * 4]; HASHITEM hashItem; MIG_OBJECTSTRINGHANDLE storeHandle; MIG_OBJECTSTRINGHANDLE testHandle; MIG_OBJECTSTRINGHANDLE nodeHandle; PTSTR ptr = NULL; PTSTR ptr2; PTSTR workingStr; BOOL fFoundMatch = FALSE; BOOL zeroBase;
IsmCreateObjectStringsFromHandle ( InputData->CurrentObject.ObjectName, &srcNode, &srcLeaf );
if (srcNode) { if (MappingSearchAndReplaceEx ( g_RegNodeFilterMap, srcNode, newSrcNode, 0, NULL, ARRAYSIZE(newSrcNode), 0, NULL, NULL )) { IsmDestroyObjectString (srcNode); srcNode = newSrcNode; } }
if (srcLeaf) { if (MappingSearchAndReplaceEx ( g_RegLeafFilterMap, srcLeaf, newSrcLeaf, 0, NULL, ARRAYSIZE(newSrcLeaf), 0, NULL, NULL )) { IsmDestroyObjectString (srcLeaf); srcLeaf = newSrcLeaf; } }
if (HtFindStringEx (g_RegCollisionSrcTable, InputData->OriginalObject.ObjectName, (PVOID)(&hashItem), FALSE)) { // We've already renamed this object
HtCopyStringData (g_RegCollisionDestTable, hashItem, (PVOID)(&testHandle)); IsmCreateObjectStringsFromHandle (testHandle, &destNode, &destLeaf);
// Do not free testHandle here because it is a pointer into the hash table data
OutputData->NewObject.ObjectName = IsmCreateObjectHandle (destNode, destLeaf); IsmDestroyObjectString (destNode); IsmDestroyObjectString (destLeaf); destNode; destLeaf = NULL; } else { // We've never seen this object yet
IsmCreateObjectStringsFromHandle (DestinationOperationData->String, &doNode, &doLeaf);
// Pick a new node
// First check to see if this object's node has already been processed
workingStr = DuplicateText(srcNode); if (workingStr) { do { nodeHandle = IsmCreateObjectHandle (workingStr, NULL); if (HtFindStringEx (g_RegCollisionSrcTable, nodeHandle, (PVOID)(&hashItem), FALSE)) {
HtCopyStringData (g_RegCollisionDestTable, hashItem, (PVOID)(&testHandle)); IsmCreateObjectStringsFromHandle (testHandle, &rootNode, NULL); // Do not free testHandle here because it is a pointer into the hash table data
if (ptr) { // if ptr is valid it means we found a match for a subkey
*ptr = TEXT('\\'); newNode = JoinText(rootNode, ptr); } else { // if ptr is NULL, we found a match for the full keyname
newNode = DuplicateText(rootNode); } IsmDestroyObjectString(rootNode); fFoundMatch = TRUE; } else { ptr2 = ptr; ptr = (PTSTR)FindLastWack (workingStr); if (ptr2) { *ptr2 = TEXT('\\'); } if (ptr) { *ptr = 0; } } IsmDestroyObjectHandle(nodeHandle); } while (FALSE == fFoundMatch && ptr); FreeText(workingStr); }
zeroBase = (SourceOperationData && SourceOperationData->Type == BLOBTYPE_BINARY && SourceOperationData->BinarySize == sizeof(PCBYTE) && (BOOL)SourceOperationData->BinaryData == TRUE);
if (FALSE == fFoundMatch) { // Nope, let's process the node
destNode = pProcessRenameExMacro (doNode, NULL, zeroBase); newNode = DuplicateText(destNode); IsmDestroyObjectHandle(destNode); }
// Now process the leaf, if the original object had a leaf
if (srcLeaf) { if (doLeaf) { destLeaf = pProcessRenameExMacro (newNode, doLeaf, zeroBase); IsmDestroyObjectString (doLeaf); } } IsmDestroyObjectString (doNode);
// Add this in the collision table
testHandle = IsmCreateObjectHandle (newNode, destLeaf ? destLeaf : srcLeaf); storeHandle = DuplicateText (testHandle); hashItem = HtAddStringEx (g_RegCollisionDestTable, storeHandle, &storeHandle, FALSE); HtAddStringEx (g_RegCollisionSrcTable, InputData->OriginalObject.ObjectName, &hashItem, FALSE);
// Update the output
OutputData->NewObject.ObjectName = testHandle; }
if (srcNode != NULL) { IsmDestroyObjectString (srcNode); } if (srcLeaf != NULL) { IsmDestroyObjectString (srcLeaf); } if (destLeaf != NULL) { IsmDestroyObjectString (destLeaf); } if (newNode != NULL) { FreeText(newNode); }
return TRUE; }
BOOL WINAPI FilterRenameIniExFilter ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { // we should never get here since there is no INF rule
// that would trigger this filter
MYASSERT(FALSE);
// As we said, we should never get here. If we do however, we
// will just continue
return TRUE; }
BOOL WINAPI FilterPartitionMove ( IN PCMIG_FILTERINPUT InputData, OUT PMIG_FILTEROUTPUT OutputData, IN BOOL NoRestoreObject, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PCTSTR node = NULL; PCTSTR leaf = NULL;
IsmCreateObjectStringsFromHandle (DestinationOperationData->String, &node, &leaf);
OutputData->NewObject.ObjectName = IsmCreateObjectHandle (node, leaf);
IsmDestroyObjectString (node); IsmDestroyObjectString (leaf);
return TRUE; }
BOOL WINAPI DoDestAddObject ( IN MIG_OBJECTTYPEID SrcObjectTypeId, IN MIG_OBJECTSTRINGHANDLE SrcObjectName, IN PCMIG_CONTENT OriginalContent, IN PCMIG_CONTENT CurrentContent, OUT PMIG_CONTENT NewContent, IN PCMIG_BLOB SourceOperationData, OPTIONAL IN PCMIG_BLOB DestinationOperationData OPTIONAL ) { PMIG_CONTENT finalContent;
if (DestinationOperationData == NULL) { return TRUE; } if (DestinationOperationData->Type != BLOBTYPE_BINARY) { return TRUE; } if (DestinationOperationData->BinarySize != sizeof (MIG_CONTENT)) { return TRUE; }
finalContent = (PMIG_CONTENT) DestinationOperationData->BinaryData; CopyMemory (NewContent, finalContent, sizeof (MIG_CONTENT));
return TRUE; }
VOID OEWarning ( VOID ) { ERRUSER_EXTRADATA extraData;
if (TRUE == g_OERulesMigrated) { // Send warning to app
extraData.Error = ERRUSER_WARNING_OERULES; extraData.ErrorArea = ERRUSER_AREA_RESTORE; extraData.ObjectTypeId = 0; extraData.ObjectName = NULL; IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
// Add to log
LOG ((LOG_WARNING, (PCSTR) MSG_OE_RULES)); } }
VOID OutlookWarning ( VOID ) { PCTSTR expandedPath; MIG_OBJECT_ENUM objectEnum; PCTSTR enumPattern; ERRUSER_EXTRADATA extraData;
expandedPath = IsmExpandEnvironmentString (PLATFORM_SOURCE, S_SYSENVVAR_GROUP, TEXT("%CSIDL_APPDATA%\\Microsoft\\Outlook"), NULL); if (expandedPath) { enumPattern = IsmCreateSimpleObjectPattern (expandedPath, FALSE, TEXT("*.rwz"), TRUE); if (enumPattern) { if (IsmEnumFirstSourceObject (&objectEnum, g_FileType, enumPattern)) { // Send warning to app
extraData.Error = ERRUSER_WARNING_OUTLOOKRULES; extraData.ErrorArea = ERRUSER_AREA_RESTORE; extraData.ObjectTypeId = 0; extraData.ObjectName = NULL; IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
// Add to log
LOG ((LOG_WARNING, (PCSTR) MSG_OUTLOOK_RULES));
IsmAbortObjectEnum (&objectEnum); } IsmDestroyObjectHandle (enumPattern); } IsmReleaseMemory (expandedPath); }
}
VOID WINAPI ScriptOpmTerminate ( VOID ) { //
// Temporary place to trigger setting refresh/upgrade
//
if (!IsmCheckCancel()) { OEFixLastUser(); WABMerge(); OE4MergeStoreFolder(); OE5MergeStoreFolders(); OEWarning(); OutlookWarning(); }
TerminateRestoreCallback (); TerminateSpecialRename(); TerminateSpecialConversion();
// LEAK: need to loop through table and FreeText the extra data
HtFree (g_RegCollisionDestTable); g_RegCollisionDestTable = NULL;
HtFree (g_RegCollisionSrcTable); g_RegCollisionSrcTable = NULL;
DestroyStringMapping (g_RegNodeFilterMap); g_RegNodeFilterMap = NULL;
DestroyStringMapping (g_RegLeafFilterMap); g_RegLeafFilterMap = NULL;
DestroyStringMapping (g_FileNodeFilterMap); g_FileNodeFilterMap = NULL;
DestroyStringMapping (g_FileLeafFilterMap); g_FileLeafFilterMap = NULL;
DestroyStringMapping (g_IniSectFilterMap); g_IniSectFilterMap = NULL;
DestroyStringMapping (g_IniKeyFilterMap); g_IniKeyFilterMap = NULL;
DestroyStringMapping (g_DestEnvMap); g_DestEnvMap = NULL; }
|