2942 lines
84 KiB
C
2942 lines
84 KiB
C
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sgmqueue.c
|
|
|
|
Abstract:
|
|
|
|
Parses the v1 script, builds rules and queues enumeration callbacks.
|
|
|
|
Author:
|
|
|
|
Jim Schmidt (jimschm) 12-Mar-2000
|
|
|
|
Revision History:
|
|
|
|
<alias> <date> <comments>
|
|
|
|
--*/
|
|
|
|
//
|
|
// Includes
|
|
//
|
|
|
|
#include "pch.h"
|
|
#include "v2app.h"
|
|
#include "v1p.h"
|
|
|
|
#define DBG_SCRIPT "Script"
|
|
|
|
//
|
|
// Strings
|
|
//
|
|
|
|
// None
|
|
|
|
//
|
|
// Constants
|
|
//
|
|
|
|
// none
|
|
|
|
//
|
|
// Macros
|
|
//
|
|
|
|
// None
|
|
|
|
//
|
|
// Types
|
|
//
|
|
|
|
// None
|
|
|
|
//
|
|
// Globals
|
|
//
|
|
|
|
MIG_OPERATIONID g_RenameFileExOp;
|
|
MIG_OPERATIONID g_RenameFileOp;
|
|
MIG_OPERATIONID g_RenameExOp;
|
|
MIG_OPERATIONID g_RenameOp;
|
|
BOOL g_VcmMode;
|
|
BOOL g_PreParse;
|
|
|
|
//
|
|
// Macro expansion list
|
|
//
|
|
|
|
// None
|
|
|
|
//
|
|
// Private function prototypes
|
|
//
|
|
|
|
VCMPARSE ScriptVcmParse;
|
|
VCMQUEUEENUMERATION ScriptVcmQueueEnumeration;
|
|
SGMPARSE ScriptSgmParse;
|
|
SGMQUEUEENUMERATION ScriptSgmQueueEnumeration;
|
|
|
|
BOOL
|
|
pSelectFilesAndFolders (
|
|
VOID
|
|
);
|
|
|
|
BOOL
|
|
pParseAllInfs (
|
|
IN BOOL PreParse
|
|
);
|
|
|
|
//
|
|
// Macro expansion definition
|
|
//
|
|
|
|
// None
|
|
|
|
//
|
|
// Code
|
|
//
|
|
|
|
BOOL
|
|
pCommonQueueEnumeration (
|
|
IN BOOL PreParse
|
|
)
|
|
{
|
|
MIG_OBJECTSTRINGHANDLE objectHandle;
|
|
ACTION_STRUCT actionStruct;
|
|
BOOL b = FALSE;
|
|
|
|
//
|
|
// INF-based inclusion/exclusion mechanism. We are called first to pre-parse
|
|
// the INF (to allow the UI to alter the results). Then we are called to
|
|
// queue the enumeration.
|
|
//
|
|
|
|
if (PreParse) {
|
|
g_RenameFileExOp = IsmRegisterOperation (S_OPERATION_V1_FILEMOVEEX, TRUE);
|
|
g_RenameFileOp = IsmRegisterOperation (S_OPERATION_V1_FILEMOVE, TRUE);
|
|
g_RenameOp = IsmRegisterOperation (S_OPERATION_MOVE, 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_RegAutoFilterOp = IsmRegisterOperation (S_OPERATION_REG_AUTO_FILTER, FALSE);
|
|
|
|
return pParseAllInfs (TRUE);
|
|
}
|
|
|
|
//
|
|
// Now queue enumeration
|
|
//
|
|
|
|
MYASSERT (g_RenameFileExOp);
|
|
MYASSERT (g_RenameFileOp);
|
|
MYASSERT (g_RenameOp);
|
|
MYASSERT (g_RegAutoFilterOp);
|
|
|
|
//
|
|
// From the sgm point of view, the v1 tool supports the following:
|
|
//
|
|
// - Optional transfer of the entire HKCU
|
|
// - Optional transfer of the entire HKLM
|
|
// - Optional transfer of all files except for OS files
|
|
// - INF-based inclusion/exclusion mechanism
|
|
// - Specialized migration of certain settings (RAS, printers)
|
|
//
|
|
// This SGM implements this functionality set.
|
|
//
|
|
|
|
__try {
|
|
|
|
//
|
|
// Component-based inclusion mechanism
|
|
//
|
|
|
|
if (!pSelectFilesAndFolders ()) {
|
|
__leave;
|
|
}
|
|
|
|
//
|
|
// INF-based inclusion/exclusion mechanism
|
|
//
|
|
|
|
if (!pParseAllInfs (FALSE)) {
|
|
__leave;
|
|
}
|
|
|
|
//
|
|
// If the /u was specified at the command line we want to suck and apply all HKR
|
|
// like if we had a rule in the script: AddReg=HKR\*
|
|
//
|
|
if (IsmIsEnvironmentFlagSet (IsmGetRealPlatform(), NULL, S_ENV_HKCU_V1)) {
|
|
|
|
ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
|
|
|
|
objectHandle = TurnRegStringIntoHandle (TEXT("HKCU\\*"), TRUE, NULL);
|
|
MYASSERT (objectHandle);
|
|
|
|
actionStruct.ObjectBase = TurnRegStringIntoHandle (TEXT("HKCU\\*"), FALSE, NULL);
|
|
MYASSERT (actionStruct.ObjectBase);
|
|
|
|
//
|
|
// Add this rule
|
|
//
|
|
|
|
if (AddRule (
|
|
g_RegType,
|
|
actionStruct.ObjectBase,
|
|
objectHandle,
|
|
ACTIONGROUP_INCLUDE,
|
|
ACTION_PERSIST,
|
|
&actionStruct
|
|
)) {
|
|
|
|
AddRuleEx (
|
|
g_RegType,
|
|
actionStruct.ObjectBase,
|
|
objectHandle,
|
|
ACTIONGROUP_DEFAULTPRIORITY,
|
|
ACTION_PRIORITYDEST,
|
|
NULL,
|
|
RULEGROUP_PRIORITY
|
|
);
|
|
|
|
IsmHookEnumeration (
|
|
g_RegType,
|
|
objectHandle,
|
|
ObjectPriority,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// Queue enumeration for include patterns
|
|
//
|
|
|
|
IsmQueueEnumeration (
|
|
g_RegType,
|
|
objectHandle,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
IsmDestroyObjectHandle (objectHandle);
|
|
}
|
|
|
|
b = TRUE;
|
|
|
|
}
|
|
__finally {
|
|
}
|
|
|
|
return b;
|
|
}
|
|
|
|
|
|
VOID
|
|
QueueAllFiles (
|
|
VOID
|
|
)
|
|
{
|
|
static BOOL done = FALSE;
|
|
MIG_OBJECTSTRINGHANDLE objectHandle;
|
|
MIG_SEGMENTS nodeSeg[2];
|
|
|
|
if (done) {
|
|
return;
|
|
}
|
|
|
|
done = TRUE;
|
|
|
|
nodeSeg[0].Segment = TEXT("*");
|
|
nodeSeg[0].IsPattern = TRUE ;
|
|
|
|
objectHandle = IsmCreateObjectPattern (nodeSeg, 1, ALL_PATTERN, 0);
|
|
|
|
IsmQueueEnumeration (g_FileType, objectHandle, NulCallback, 0, NULL);
|
|
IsmDestroyObjectHandle (objectHandle);
|
|
}
|
|
|
|
|
|
VOID
|
|
pQueueAllReg (
|
|
VOID
|
|
)
|
|
{
|
|
static BOOL done = FALSE;
|
|
MIG_OBJECTSTRINGHANDLE objectHandle;
|
|
MIG_SEGMENTS nodeSeg[2];
|
|
MIG_PLATFORMTYPEID platform = IsmGetRealPlatform();
|
|
|
|
if (done) {
|
|
return;
|
|
}
|
|
|
|
done = TRUE;
|
|
|
|
//
|
|
// Optional transfer of entire HKCU
|
|
//
|
|
|
|
if (IsmIsEnvironmentFlagSet (platform, NULL, S_ENV_HKCU_ON)) {
|
|
|
|
nodeSeg[0].Segment = TEXT("HKCU\\");
|
|
nodeSeg[0].IsPattern = FALSE;
|
|
|
|
nodeSeg[1].Segment = TEXT("*");
|
|
nodeSeg[1].IsPattern = TRUE;
|
|
|
|
objectHandle = IsmCreateObjectPattern (nodeSeg, 2, ALL_PATTERN, 0);
|
|
IsmQueueEnumeration (g_RegType, objectHandle, NulCallback, 0, NULL);
|
|
IsmDestroyObjectHandle (objectHandle);
|
|
}
|
|
|
|
//
|
|
// Optional transfer of entire HKLM
|
|
//
|
|
|
|
if (IsmIsEnvironmentFlagSet (platform, NULL, S_ENV_HKLM_ON)) {
|
|
|
|
nodeSeg[0].Segment = TEXT("HKLM\\");
|
|
nodeSeg[0].IsPattern = FALSE;
|
|
|
|
nodeSeg[1].Segment = TEXT("*");
|
|
nodeSeg[1].IsPattern = TRUE;
|
|
|
|
objectHandle = IsmCreateObjectPattern (nodeSeg, 2, ALL_PATTERN, 0);
|
|
IsmQueueEnumeration (g_RegType, objectHandle, NulCallback, 0, NULL);
|
|
IsmDestroyObjectHandle (objectHandle);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
BOOL
|
|
WINAPI
|
|
ScriptSgmParse (
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
return pCommonQueueEnumeration (TRUE);
|
|
}
|
|
|
|
|
|
BOOL
|
|
WINAPI
|
|
ScriptSgmQueueEnumeration (
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
BOOL result;
|
|
|
|
result = pCommonQueueEnumeration (FALSE);
|
|
OEAddComplexRules();
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
WINAPI
|
|
ScriptVcmParse (
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
g_VcmMode = TRUE;
|
|
return pCommonQueueEnumeration (TRUE);
|
|
}
|
|
|
|
|
|
BOOL
|
|
WINAPI
|
|
ScriptVcmQueueEnumeration (
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
g_VcmMode = TRUE;
|
|
return pCommonQueueEnumeration (FALSE);
|
|
}
|
|
|
|
|
|
PCTSTR
|
|
pFixDestination (
|
|
IN PCTSTR Source,
|
|
IN PCTSTR Destination
|
|
)
|
|
{
|
|
PTSTR result = (PTSTR)Source;
|
|
PTSTR tempPtr;
|
|
PTSTR sKey;
|
|
PTSTR sSubKey;
|
|
PTSTR sValueName;
|
|
PTSTR dKey;
|
|
PTSTR dSubKey;
|
|
PTSTR dValueName;
|
|
UINT size;
|
|
BOOL sTree = FALSE;
|
|
|
|
sKey = DuplicatePathString (Source, 0);
|
|
sValueName = _tcschr (sKey, TEXT('['));
|
|
if (sValueName) {
|
|
tempPtr = _tcschr (sValueName, TEXT(']'));
|
|
if (tempPtr) {
|
|
*tempPtr = 0;
|
|
}
|
|
tempPtr = sValueName;
|
|
sValueName = _tcsinc (sValueName);
|
|
*tempPtr = 0;
|
|
tempPtr = _tcsdec2 (sKey, tempPtr);
|
|
if (tempPtr) {
|
|
if (_tcsnextc (tempPtr) == TEXT('\\')) {
|
|
*tempPtr = 0;
|
|
}
|
|
if (_tcsnextc (tempPtr) == TEXT(' ')) {
|
|
*tempPtr = 0;
|
|
}
|
|
}
|
|
}
|
|
sSubKey = _tcsrchr (sKey, TEXT('\\'));
|
|
if (sSubKey) {
|
|
tempPtr = _tcsinc (sSubKey);
|
|
if (_tcsnextc (tempPtr) == TEXT('*')) {
|
|
*sSubKey = 0;
|
|
sTree = TRUE;
|
|
}
|
|
}
|
|
sSubKey = _tcsrchr (sKey, TEXT('\\'));
|
|
if (sSubKey) {
|
|
tempPtr = sSubKey;
|
|
sSubKey = _tcsinc (sSubKey);
|
|
*tempPtr = 0;
|
|
}
|
|
|
|
dKey = DuplicatePathString (Destination, 0);
|
|
dValueName = _tcschr (dKey, TEXT('['));
|
|
if (dValueName) {
|
|
tempPtr = _tcschr (dValueName, TEXT(']'));
|
|
if (tempPtr) {
|
|
*tempPtr = 0;
|
|
}
|
|
tempPtr = dValueName;
|
|
dValueName = _tcsinc (dValueName);
|
|
*tempPtr = 0;
|
|
tempPtr = _tcsdec2 (dKey, tempPtr);
|
|
if (tempPtr) {
|
|
if (_tcsnextc (tempPtr) == TEXT('\\')) {
|
|
*tempPtr = 0;
|
|
}
|
|
if (_tcsnextc (tempPtr) == TEXT(' ')) {
|
|
*tempPtr = 0;
|
|
}
|
|
}
|
|
}
|
|
dSubKey = _tcsrchr (dKey, TEXT('\\'));
|
|
if (dSubKey) {
|
|
tempPtr = _tcsinc (dSubKey);
|
|
if (_tcsnextc (tempPtr) == TEXT('*')) {
|
|
*dSubKey = 0;
|
|
}
|
|
}
|
|
dSubKey = _tcsrchr (dKey, TEXT('\\'));
|
|
if (dSubKey) {
|
|
tempPtr = dSubKey;
|
|
dSubKey = _tcsinc (dSubKey);
|
|
*tempPtr = 0;
|
|
}
|
|
if (!dSubKey) {
|
|
dSubKey = dKey;
|
|
dKey = NULL;
|
|
}
|
|
|
|
size = 0;
|
|
|
|
if (dKey && *dKey) {
|
|
size += TcharCount (dKey) + 1;
|
|
} else if (sKey && *sKey) {
|
|
size += TcharCount (sKey) + 1;
|
|
}
|
|
|
|
if (dSubKey && *dSubKey) {
|
|
size += TcharCount (dSubKey) + 1;
|
|
} else if (sSubKey && *sSubKey) {
|
|
size += TcharCount (sSubKey) + 1;
|
|
}
|
|
|
|
if (dValueName && *dValueName) {
|
|
size += TcharCount (dValueName) + ARRAYSIZE(TEXT(" []")) - 1;
|
|
} else if (sValueName && *sValueName) {
|
|
size += TcharCount (sValueName) + ARRAYSIZE(TEXT(" []")) - 1;
|
|
}
|
|
|
|
if (sTree) {
|
|
size += ARRAYSIZE(TEXT("\\*")) - 1;
|
|
}
|
|
size += 1;
|
|
|
|
result = AllocPathString (size);
|
|
*result = 0;
|
|
|
|
if (dKey && *dKey) {
|
|
StringCat (result, dKey);
|
|
} else if (sKey && *sKey) {
|
|
StringCat (result, sKey);
|
|
}
|
|
|
|
if (dSubKey && *dSubKey) {
|
|
StringCat (result, TEXT("\\"));
|
|
StringCat (result, dSubKey);
|
|
} else if (sSubKey && *sSubKey) {
|
|
StringCat (result, TEXT("\\"));
|
|
StringCat (result, sSubKey);
|
|
}
|
|
|
|
if (sTree) {
|
|
StringCat (result, TEXT("\\*"));
|
|
}
|
|
|
|
if (dValueName && *dValueName) {
|
|
StringCat (result, TEXT(" ["));
|
|
StringCat (result, dValueName);
|
|
StringCat (result, TEXT("]"));
|
|
} else if (sValueName && *sValueName) {
|
|
StringCat (result, TEXT(" ["));
|
|
StringCat (result, sValueName);
|
|
StringCat (result, TEXT("]"));
|
|
}
|
|
|
|
if (sKey) {
|
|
FreePathString (sKey);
|
|
}
|
|
|
|
if (dKey) {
|
|
FreePathString (dKey);
|
|
} else if (dSubKey) {
|
|
FreePathString (dSubKey);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
BOOL
|
|
pParseRegEx1 (
|
|
IN HINF Inf,
|
|
IN PCTSTR Section,
|
|
IN ACTIONGROUP ActionGroup,
|
|
IN DWORD ActionFlags,
|
|
IN PCTSTR Application OPTIONAL
|
|
)
|
|
{
|
|
// This function handles RenregEx and RegFileEx rules only
|
|
|
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
|
PTSTR srcNode;
|
|
PTSTR srcLeaf;
|
|
PTSTR destNode;
|
|
PTSTR destLeaf;
|
|
BOOL result = FALSE;
|
|
MIG_OBJECTSTRINGHANDLE srcPattern = NULL;
|
|
MIG_OBJECTSTRINGHANDLE destPattern = NULL;
|
|
MIG_OBJECTSTRINGHANDLE objectBase = NULL;
|
|
ACTION_STRUCT actionStruct;
|
|
PCTSTR filesDest;
|
|
PCTSTR newDest = NULL;
|
|
|
|
if (InfFindFirstLine (Inf, Section, NULL, &is)) {
|
|
do {
|
|
if (IsmCheckCancel()) {
|
|
break;
|
|
}
|
|
|
|
__try {
|
|
ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
|
|
|
|
srcNode = InfGetStringField (&is, 1);
|
|
srcLeaf = InfGetStringField (&is, 2);
|
|
if (!srcNode && !srcLeaf) {
|
|
LOG ((LOG_WARNING, (PCSTR) MSG_EMPTY_RENREGEX));
|
|
__leave;
|
|
}
|
|
|
|
srcPattern = CreatePatternFromNodeLeaf (srcNode, srcLeaf);
|
|
if (!srcPattern) {
|
|
__leave;
|
|
}
|
|
|
|
actionStruct.ObjectBase = srcPattern;
|
|
|
|
objectBase = MakeRegExBase (srcNode, srcLeaf);
|
|
|
|
destNode = InfGetStringField (&is, 3);
|
|
destLeaf = InfGetStringField (&is, 4);
|
|
|
|
destPattern = CreatePatternFromNodeLeaf (destNode, destLeaf);
|
|
|
|
if (destPattern) {
|
|
actionStruct.ObjectDest = destPattern;
|
|
} else {
|
|
LOG ((
|
|
LOG_ERROR,
|
|
(PCSTR) MSG_REG_SPEC_BAD_DEST,
|
|
srcNode ? srcNode : TEXT(""),
|
|
srcLeaf ? srcLeaf : TEXT(""),
|
|
destNode ? destNode : TEXT(""),
|
|
destLeaf ? destLeaf : TEXT("")
|
|
));
|
|
|
|
__leave;
|
|
}
|
|
|
|
if (ActionGroup == ACTIONGROUP_REGFILEEX &&
|
|
ActionFlags & ACTION_PERSIST_PATH_IN_DATA) {
|
|
|
|
filesDest = InfGetStringField (&is, 5);
|
|
|
|
if (filesDest && *filesDest) {
|
|
newDest = SanitizePath (filesDest);
|
|
|
|
if (newDest) {
|
|
actionStruct.AddnlDest = TurnFileStringIntoHandle (
|
|
newDest,
|
|
PFF_COMPUTE_BASE|
|
|
PFF_NO_SUBDIR_PATTERN|
|
|
PFF_NO_PATTERNS_ALLOWED|
|
|
PFF_NO_LEAF_AT_ALL
|
|
);
|
|
FreePathString (newDest);
|
|
newDest = NULL;
|
|
}
|
|
|
|
if (!actionStruct.AddnlDest) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD_DEST, filesDest));
|
|
}
|
|
}
|
|
|
|
actionStruct.ObjectHint = InfGetStringField (&is, 6);
|
|
if (actionStruct.ObjectHint && !(*actionStruct.ObjectHint)) {
|
|
actionStruct.ObjectHint = NULL;
|
|
}
|
|
}
|
|
|
|
if (!AddRule (
|
|
g_RegType,
|
|
objectBase,
|
|
srcPattern,
|
|
ACTIONGROUP_RENAMEEX,
|
|
ActionFlags,
|
|
&actionStruct
|
|
)) {
|
|
DEBUGMSG ((DBG_ERROR, "Error processing registry rules"));
|
|
__leave;
|
|
}
|
|
AddRuleEx (
|
|
g_RegType,
|
|
objectBase,
|
|
srcPattern,
|
|
ACTIONGROUP_DEFAULTPRIORITY,
|
|
ACTION_PRIORITYSRC,
|
|
NULL,
|
|
RULEGROUP_PRIORITY
|
|
);
|
|
|
|
IsmHookEnumeration (
|
|
g_RegType,
|
|
srcPattern,
|
|
ObjectPriority,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
|
|
if (IsmIsObjectHandleLeafOnly (srcPattern)) {
|
|
pQueueAllReg();
|
|
IsmHookEnumeration (
|
|
g_RegType,
|
|
srcPattern,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
} else {
|
|
if (actionStruct.ObjectBase) {
|
|
IsmQueueEnumeration (
|
|
g_RegType,
|
|
actionStruct.ObjectBase,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
IsmQueueEnumeration (
|
|
g_RegType,
|
|
srcPattern,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
}
|
|
__finally {
|
|
if (objectBase) {
|
|
IsmDestroyObjectHandle (objectBase);
|
|
objectBase = NULL;
|
|
}
|
|
|
|
if (srcPattern) {
|
|
IsmDestroyObjectHandle (srcPattern);
|
|
srcPattern = NULL;
|
|
}
|
|
|
|
if (destPattern) {
|
|
IsmDestroyObjectHandle (destPattern);
|
|
destPattern = NULL;
|
|
}
|
|
}
|
|
} while (InfFindNextLine (&is));
|
|
|
|
result = !IsmCheckCancel();
|
|
} else {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_EMPTY_OR_MISSING_SECTION, Section));
|
|
}
|
|
|
|
InfCleanUpInfStruct (&is);
|
|
|
|
return result;
|
|
}
|
|
|
|
BOOL
|
|
pParseRegEx (
|
|
IN HINF Inf,
|
|
IN PCTSTR Section,
|
|
IN ACTIONGROUP ActionGroup,
|
|
IN DWORD ActionFlags,
|
|
IN PCTSTR Application OPTIONAL
|
|
)
|
|
{
|
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
|
PCTSTR srcNode;
|
|
PCTSTR srcLeaf;
|
|
MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
|
|
PCTSTR destNode;
|
|
PCTSTR destLeaf;
|
|
PCTSTR filesDest;
|
|
PCTSTR newDest = NULL;
|
|
ACTION_STRUCT actionStruct;
|
|
BOOL result = FALSE;
|
|
|
|
if (InfFindFirstLine (Inf, Section, NULL, &is)) {
|
|
do {
|
|
if (IsmCheckCancel()) {
|
|
break;
|
|
}
|
|
|
|
__try {
|
|
ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
|
|
|
|
srcNode = InfGetStringField (&is, 1);
|
|
srcLeaf = InfGetStringField (&is, 2);
|
|
if (!srcNode && !srcLeaf) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_EMPTY_RENREGEX));
|
|
__leave;
|
|
}
|
|
|
|
// Validate rule
|
|
if (!StringIMatchTcharCount (srcNode, S_HKLM, ARRAYSIZE(S_HKLM) - 1) &&
|
|
!StringIMatchTcharCount (srcNode, S_HKR, ARRAYSIZE(S_HKR) - 1) &&
|
|
!StringIMatchTcharCount (srcNode, S_HKCC, ARRAYSIZE(S_HKCC) - 1)
|
|
) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_REGROOT, srcNode));
|
|
__leave;
|
|
}
|
|
|
|
srcHandle = CreatePatternFromNodeLeaf (srcNode, srcLeaf);
|
|
if (!srcHandle) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD, srcNode));
|
|
__leave;
|
|
}
|
|
|
|
actionStruct.ObjectBase = MakeRegExBase (srcNode, srcLeaf);
|
|
if (!actionStruct.ObjectBase) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD, srcNode));
|
|
__leave;
|
|
}
|
|
|
|
if (ActionGroup == ACTIONGROUP_RENAMEEX) {
|
|
|
|
destNode = InfGetStringField (&is, 3);
|
|
destLeaf = InfGetStringField (&is, 4);
|
|
if (!destNode && !destLeaf) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_MISSING_DEST, srcNode));
|
|
__leave;
|
|
}
|
|
|
|
actionStruct.ObjectDest = CreatePatternFromNodeLeaf (destNode, destLeaf);
|
|
if (!actionStruct.ObjectDest) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD_DEST, destNode));
|
|
__leave;
|
|
}
|
|
}
|
|
|
|
if (ActionGroup == ACTIONGROUP_REGFILEEX ||
|
|
ActionGroup == ACTIONGROUP_REGFOLDEREX ||
|
|
ActionGroup == ACTIONGROUP_REGICONEX
|
|
) {
|
|
|
|
destNode = InfGetStringField (&is, 3);
|
|
destLeaf = InfGetStringField (&is, 4);
|
|
if (destNode && destLeaf &&
|
|
*destNode && *destLeaf) {
|
|
actionStruct.ObjectDest = CreatePatternFromNodeLeaf (destNode, destLeaf);
|
|
if (!actionStruct.ObjectDest) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD_DEST, destNode));
|
|
__leave;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((ActionGroup == ACTIONGROUP_REGFILEEX ||
|
|
ActionGroup == ACTIONGROUP_REGFOLDEREX ||
|
|
ActionGroup == ACTIONGROUP_REGICONEX
|
|
) &&
|
|
((ActionFlags & ACTION_PERSIST_PATH_IN_DATA) ||
|
|
(ActionFlags & ACTION_PERSIST_ICON_IN_DATA)
|
|
)
|
|
) {
|
|
|
|
filesDest = InfGetStringField (&is, 5);
|
|
|
|
if (filesDest && *filesDest) {
|
|
|
|
newDest = SanitizePath (filesDest);
|
|
|
|
if (newDest) {
|
|
actionStruct.AddnlDest = TurnFileStringIntoHandle (
|
|
newDest,
|
|
PFF_COMPUTE_BASE|
|
|
PFF_NO_SUBDIR_PATTERN|
|
|
PFF_NO_PATTERNS_ALLOWED|
|
|
PFF_NO_LEAF_AT_ALL
|
|
);
|
|
FreePathString (newDest);
|
|
newDest = NULL;
|
|
}
|
|
|
|
if (!actionStruct.AddnlDest) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD_DEST, filesDest));
|
|
}
|
|
}
|
|
|
|
actionStruct.ObjectHint = InfGetStringField (&is, 6);
|
|
if (actionStruct.ObjectHint && !(*actionStruct.ObjectHint)) {
|
|
actionStruct.ObjectHint = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add this rule
|
|
//
|
|
|
|
if (!AddRule (
|
|
g_RegType,
|
|
actionStruct.ObjectBase,
|
|
srcHandle,
|
|
ActionGroup,
|
|
ActionFlags,
|
|
&actionStruct
|
|
)) {
|
|
DEBUGMSG ((DBG_ERROR, "Error processing registry rules for %s", srcNode));
|
|
}
|
|
|
|
AddRuleEx (
|
|
g_RegType,
|
|
actionStruct.ObjectBase,
|
|
srcHandle,
|
|
ACTIONGROUP_DEFAULTPRIORITY,
|
|
ACTION_PRIORITYSRC,
|
|
NULL,
|
|
RULEGROUP_PRIORITY
|
|
);
|
|
|
|
IsmHookEnumeration (
|
|
g_RegType,
|
|
srcHandle,
|
|
ObjectPriority,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// Queue enumeration for include patterns
|
|
//
|
|
|
|
if ((ActionGroup == ACTIONGROUP_INCLUDEEX) ||
|
|
(ActionGroup == ACTIONGROUP_RENAMEEX) ||
|
|
(ActionGroup == ACTIONGROUP_REGFILEEX) ||
|
|
(ActionGroup == ACTIONGROUP_REGFOLDEREX) ||
|
|
(ActionGroup == ACTIONGROUP_REGICONEX)
|
|
) {
|
|
|
|
if (IsmIsObjectHandleLeafOnly (srcHandle)) {
|
|
pQueueAllReg();
|
|
IsmHookEnumeration (
|
|
g_RegType,
|
|
srcHandle,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
} else {
|
|
IsmQueueEnumeration (
|
|
g_RegType,
|
|
srcHandle,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
}
|
|
|
|
if (ActionGroup == ACTIONGROUP_DELREGKEY) {
|
|
IsmHookEnumeration (g_RegType, srcHandle, ExcludeKeyIfValueExists, 0, NULL);
|
|
IsmRegisterTypePostEnumerationCallback (g_RegType, PostDelregKeyCallback, NULL);
|
|
}
|
|
}
|
|
__finally {
|
|
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
|
|
IsmDestroyObjectHandle (actionStruct.ObjectBase);
|
|
actionStruct.ObjectBase = NULL;
|
|
|
|
IsmDestroyObjectHandle (actionStruct.ObjectDest);
|
|
actionStruct.ObjectDest = NULL;
|
|
|
|
IsmDestroyObjectHandle (actionStruct.AddnlDest);
|
|
actionStruct.AddnlDest = NULL;
|
|
}
|
|
|
|
} while (InfFindNextLine (&is));
|
|
|
|
result = !IsmCheckCancel();
|
|
} else {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_EMPTY_OR_MISSING_SECTION, Section));
|
|
}
|
|
|
|
InfCleanUpInfStruct (&is);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pParseReg (
|
|
IN HINF Inf,
|
|
IN PCTSTR Section,
|
|
IN ACTIONGROUP ActionGroup,
|
|
IN DWORD ActionFlags,
|
|
IN BOOL FixDestination,
|
|
IN PCTSTR Application OPTIONAL
|
|
)
|
|
{
|
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
|
PCTSTR pattern;
|
|
MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
|
|
PCTSTR destination;
|
|
PCTSTR newDestination;
|
|
PCTSTR filesDest;
|
|
PCTSTR newDest = NULL;
|
|
ACTION_STRUCT actionStruct;
|
|
BOOL hadLeaf = FALSE;
|
|
BOOL result = FALSE;
|
|
|
|
if (InfFindFirstLine (Inf, Section, NULL, &is)) {
|
|
do {
|
|
if (IsmCheckCancel()) {
|
|
break;
|
|
}
|
|
|
|
__try {
|
|
ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
|
|
srcHandle = NULL;
|
|
|
|
pattern = InfGetStringField (&is, 0);
|
|
|
|
if (!pattern) {
|
|
pattern = InfGetStringField (&is, 1);
|
|
if (!pattern) {
|
|
LOG ((LOG_WARNING, (PCSTR) MSG_EMPTY_RENREG));
|
|
__leave;
|
|
}
|
|
}
|
|
|
|
// Validate rule
|
|
if (!StringIMatchTcharCount (pattern, S_HKLM, ARRAYSIZE(S_HKLM) - 1) &&
|
|
!StringIMatchTcharCount (pattern, S_HKR, ARRAYSIZE(S_HKR) - 1) &&
|
|
!StringIMatchTcharCount (pattern, S_HKCC, ARRAYSIZE(S_HKCC) - 1)
|
|
) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_REGROOT, pattern));
|
|
__leave;
|
|
}
|
|
|
|
srcHandle = TurnRegStringIntoHandle (pattern, TRUE, &hadLeaf);
|
|
if (!srcHandle) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD, pattern));
|
|
__leave;
|
|
}
|
|
|
|
actionStruct.ObjectBase = TurnRegStringIntoHandle (pattern, FALSE, NULL);
|
|
if (!actionStruct.ObjectBase) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD, pattern));
|
|
__leave;
|
|
}
|
|
|
|
if (ActionGroup == ACTIONGROUP_RENAME) {
|
|
|
|
destination = InfGetStringField (&is, 1);
|
|
|
|
if (destination && *destination) {
|
|
|
|
if (FixDestination) {
|
|
newDestination = pFixDestination (pattern, destination);
|
|
} else {
|
|
newDestination = destination;
|
|
}
|
|
|
|
actionStruct.ObjectDest = TurnRegStringIntoHandle (newDestination, FALSE, NULL);
|
|
|
|
if (newDestination != destination) {
|
|
FreePathString (newDestination);
|
|
}
|
|
|
|
if (!actionStruct.ObjectDest) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD_DEST, destination));
|
|
__leave;
|
|
}
|
|
|
|
} else {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_MISSING_DEST, pattern));
|
|
__leave;
|
|
}
|
|
}
|
|
|
|
if (ActionGroup == ACTIONGROUP_REGFILE ||
|
|
ActionGroup == ACTIONGROUP_REGFOLDER ||
|
|
ActionGroup == ACTIONGROUP_REGICON
|
|
) {
|
|
|
|
destination = InfGetStringField (&is, 1);
|
|
|
|
if (destination && *destination) {
|
|
|
|
if (FixDestination) {
|
|
newDestination = pFixDestination (pattern, destination);
|
|
} else {
|
|
newDestination = destination;
|
|
}
|
|
|
|
actionStruct.ObjectDest = TurnRegStringIntoHandle (newDestination, FALSE, NULL);
|
|
|
|
if (newDestination != destination) {
|
|
FreePathString (newDestination);
|
|
}
|
|
|
|
if (!actionStruct.ObjectDest) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD_DEST, destination));
|
|
__leave;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((ActionGroup == ACTIONGROUP_REGFILE ||
|
|
ActionGroup == ACTIONGROUP_REGFOLDER ||
|
|
ActionGroup == ACTIONGROUP_REGICON
|
|
) &&
|
|
((ActionFlags & ACTION_PERSIST_PATH_IN_DATA) ||
|
|
(ActionFlags & ACTION_PERSIST_ICON_IN_DATA)
|
|
)
|
|
) {
|
|
|
|
filesDest = InfGetStringField (&is, 2);
|
|
|
|
if (filesDest && *filesDest) {
|
|
|
|
newDest = SanitizePath (filesDest);
|
|
|
|
if (newDest) {
|
|
actionStruct.AddnlDest = TurnFileStringIntoHandle (
|
|
newDest,
|
|
PFF_COMPUTE_BASE|
|
|
PFF_NO_SUBDIR_PATTERN|
|
|
PFF_NO_PATTERNS_ALLOWED|
|
|
PFF_NO_LEAF_AT_ALL
|
|
);
|
|
FreePathString (newDest);
|
|
newDest = NULL;
|
|
}
|
|
|
|
if (!actionStruct.AddnlDest) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD_DEST, filesDest));
|
|
}
|
|
}
|
|
|
|
actionStruct.ObjectHint = InfGetStringField (&is, 3);
|
|
if (actionStruct.ObjectHint && !(*actionStruct.ObjectHint)) {
|
|
actionStruct.ObjectHint = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add this rule
|
|
//
|
|
|
|
if (!AddRule (
|
|
g_RegType,
|
|
actionStruct.ObjectBase,
|
|
srcHandle,
|
|
ActionGroup,
|
|
ActionFlags,
|
|
&actionStruct
|
|
)) {
|
|
DEBUGMSG ((DBG_ERROR, "Error processing registry rules for %s", pattern));
|
|
}
|
|
|
|
AddRuleEx (
|
|
g_RegType,
|
|
actionStruct.ObjectBase,
|
|
srcHandle,
|
|
ACTIONGROUP_DEFAULTPRIORITY,
|
|
ACTION_PRIORITYSRC,
|
|
NULL,
|
|
RULEGROUP_PRIORITY
|
|
);
|
|
|
|
IsmHookEnumeration (
|
|
g_RegType,
|
|
srcHandle,
|
|
ObjectPriority,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// Queue enumeration for include patterns
|
|
//
|
|
|
|
if ((ActionGroup == ACTIONGROUP_INCLUDE) ||
|
|
(ActionGroup == ACTIONGROUP_RENAME) ||
|
|
(ActionGroup == ACTIONGROUP_REGFILE) ||
|
|
(ActionGroup == ACTIONGROUP_REGFOLDER) ||
|
|
(ActionGroup == ACTIONGROUP_REGICON)
|
|
) {
|
|
|
|
if (IsmIsObjectHandleLeafOnly (srcHandle)) {
|
|
pQueueAllReg();
|
|
IsmHookEnumeration (
|
|
g_RegType,
|
|
srcHandle,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
} else {
|
|
if ((!hadLeaf) && actionStruct.ObjectBase) {
|
|
IsmQueueEnumeration (
|
|
g_RegType,
|
|
actionStruct.ObjectBase,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
IsmQueueEnumeration (
|
|
g_RegType,
|
|
srcHandle,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
}
|
|
|
|
if (ActionGroup == ACTIONGROUP_DELREGKEY) {
|
|
IsmHookEnumeration (g_RegType, srcHandle, ExcludeKeyIfValueExists, 0, NULL);
|
|
IsmRegisterTypePostEnumerationCallback (g_RegType, PostDelregKeyCallback, NULL);
|
|
}
|
|
}
|
|
__finally {
|
|
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
|
|
IsmDestroyObjectHandle (actionStruct.ObjectBase);
|
|
actionStruct.ObjectBase = NULL;
|
|
|
|
IsmDestroyObjectHandle (actionStruct.ObjectDest);
|
|
actionStruct.ObjectDest = NULL;
|
|
|
|
IsmDestroyObjectHandle (actionStruct.AddnlDest);
|
|
actionStruct.AddnlDest = NULL;
|
|
}
|
|
|
|
} while (InfFindNextLine (&is));
|
|
|
|
result = !IsmCheckCancel();
|
|
} else {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_EMPTY_OR_MISSING_SECTION, Section));
|
|
}
|
|
|
|
InfCleanUpInfStruct (&is);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pParseFiles (
|
|
IN HINF Inf,
|
|
IN PCTSTR Section,
|
|
IN ACTIONGROUP ActionGroup,
|
|
IN DWORD ActionFlags,
|
|
IN PCTSTR Application OPTIONAL
|
|
)
|
|
{
|
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
|
PCTSTR pattern;
|
|
PCTSTR newPattern = NULL;
|
|
PCTSTR dirText;
|
|
BOOL tree;
|
|
MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
|
|
PCTSTR destination;
|
|
PCTSTR leafDest;
|
|
TCHAR buffer1[MAX_TCHAR_PATH * 2];
|
|
ACTION_STRUCT actionStruct;
|
|
BOOL result = FALSE;
|
|
PCTSTR msgNode;
|
|
PCTSTR msgLeaf;
|
|
PCTSTR newDest = NULL;
|
|
BOOL expandResult = TRUE;
|
|
|
|
if (InfFindFirstLine (Inf, Section, NULL, &is)) {
|
|
do {
|
|
|
|
if (IsmCheckCancel()) {
|
|
break;
|
|
}
|
|
|
|
ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
|
|
|
|
dirText = InfGetStringField (&is, 0);
|
|
pattern = InfGetStringField (&is, 1);
|
|
|
|
if (!pattern) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Expand environment variables in pattern (the left-side file spec)
|
|
//
|
|
|
|
expandResult = AppSearchAndReplace (
|
|
PLATFORM_SOURCE,
|
|
Application,
|
|
pattern,
|
|
buffer1,
|
|
ARRAYSIZE(buffer1)
|
|
);
|
|
|
|
if (!expandResult) {
|
|
// the line contains at least one unexpandable env. variables
|
|
expandResult = AppCheckAndLogUndefVariables (
|
|
PLATFORM_SOURCE,
|
|
Application,
|
|
pattern
|
|
);
|
|
if (expandResult) {
|
|
// the line contains known but undefined env. variables
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fix the pattern
|
|
//
|
|
|
|
newPattern = SanitizePath(buffer1);
|
|
if(!newPattern) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Test for dir specification
|
|
//
|
|
|
|
if (dirText && StringIMatch (dirText, TEXT("Dir")) && !StringIMatch (pattern, TEXT("Dir"))) {
|
|
tree = TRUE;
|
|
} else {
|
|
tree = FALSE;
|
|
}
|
|
|
|
// require full spec or leaf only
|
|
if (!IsValidFileSpec (newPattern) && _tcschr (newPattern, TEXT('\\'))) {
|
|
if (expandResult) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
|
|
}
|
|
continue;
|
|
}
|
|
|
|
srcHandle = TurnFileStringIntoHandle (newPattern, tree ? PFF_PATTERN_IS_DIR : 0);
|
|
|
|
if (!srcHandle) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
|
|
continue;
|
|
}
|
|
|
|
actionStruct.ObjectBase = TurnFileStringIntoHandle (
|
|
newPattern,
|
|
PFF_COMPUTE_BASE|
|
|
PFF_NO_SUBDIR_PATTERN|
|
|
(tree?PFF_NO_LEAF_AT_ALL:PFF_NO_LEAF_PATTERN)
|
|
);
|
|
|
|
if (actionStruct.ObjectBase && !StringIMatch (actionStruct.ObjectBase, srcHandle)) {
|
|
|
|
IsmCreateObjectStringsFromHandle (actionStruct.ObjectBase, &msgNode, &msgLeaf);
|
|
MYASSERT (!msgLeaf);
|
|
|
|
LOG ((LOG_INFORMATION, (PCSTR) MSG_FILE_MOVE_BASE_INFO, newPattern, msgNode));
|
|
|
|
IsmDestroyObjectString (msgNode);
|
|
IsmDestroyObjectString (msgLeaf);
|
|
}
|
|
|
|
if (ActionFlags & ACTION_PERSIST) {
|
|
if (ActionGroup == ACTIONGROUP_INCLUDE ||
|
|
ActionGroup == ACTIONGROUP_INCLUDEEX ||
|
|
ActionGroup == ACTIONGROUP_RENAME ||
|
|
ActionGroup == ACTIONGROUP_RENAMEEX ||
|
|
ActionGroup == ACTIONGROUP_INCLUDERELEVANT ||
|
|
ActionGroup == ACTIONGROUP_INCLUDERELEVANTEX ||
|
|
ActionGroup == ACTIONGROUP_RENAMERELEVANT ||
|
|
ActionGroup == ACTIONGROUP_RENAMERELEVANTEX
|
|
) {
|
|
|
|
//
|
|
// For the CopyFiles and CopyFilesFiltered sections, get the
|
|
// optional destination. If destination is specified, move
|
|
// all of the files into that destination.
|
|
//
|
|
|
|
destination = InfGetStringField (&is, 2);
|
|
|
|
if (destination && *destination) {
|
|
|
|
if (ActionGroup == ACTIONGROUP_INCLUDE) {
|
|
ActionGroup = ACTIONGROUP_RENAME;
|
|
}
|
|
|
|
if (ActionGroup == ACTIONGROUP_INCLUDEEX) {
|
|
ActionGroup = ACTIONGROUP_RENAMEEX;
|
|
}
|
|
|
|
if (ActionGroup == ACTIONGROUP_INCLUDERELEVANT) {
|
|
ActionGroup = ACTIONGROUP_RENAMERELEVANT;
|
|
}
|
|
|
|
if (ActionGroup == ACTIONGROUP_INCLUDERELEVANTEX) {
|
|
ActionGroup = ACTIONGROUP_RENAMERELEVANTEX;
|
|
}
|
|
|
|
newDest = SanitizePath (destination);
|
|
|
|
if (newDest) {
|
|
actionStruct.ObjectDest = TurnFileStringIntoHandle (
|
|
newDest,
|
|
PFF_COMPUTE_BASE|
|
|
PFF_NO_SUBDIR_PATTERN|
|
|
PFF_NO_PATTERNS_ALLOWED|
|
|
PFF_NO_LEAF_AT_ALL
|
|
);
|
|
FreePathString (newDest);
|
|
newDest = NULL;
|
|
}
|
|
|
|
if ((ActionGroup == ACTIONGROUP_RENAMEEX) ||
|
|
(ActionGroup == ACTIONGROUP_RENAMERELEVANTEX)
|
|
) {
|
|
// we might have an extra field for the leaf name
|
|
leafDest = InfGetStringField (&is, 3);
|
|
if (leafDest && *leafDest) {
|
|
// we have to rebuild actionStruct.ObjectDest
|
|
IsmCreateObjectStringsFromHandle (actionStruct.ObjectDest, &msgNode, &msgLeaf);
|
|
IsmDestroyObjectHandle (actionStruct.ObjectDest);
|
|
actionStruct.ObjectDest = IsmCreateObjectHandle (msgNode, leafDest);
|
|
IsmDestroyObjectString (msgNode);
|
|
IsmDestroyObjectString (msgLeaf);
|
|
}
|
|
}
|
|
|
|
if (!actionStruct.ObjectDest) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD_DEST, destination));
|
|
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add this rule
|
|
//
|
|
|
|
if (!AddRule (
|
|
g_FileType,
|
|
actionStruct.ObjectBase,
|
|
srcHandle,
|
|
ActionGroup,
|
|
ActionFlags,
|
|
&actionStruct
|
|
)) {
|
|
DEBUGMSG ((DBG_ERROR, "Error processing file rules"));
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Queue enumeration for include patterns
|
|
//
|
|
|
|
if ((ActionGroup == ACTIONGROUP_INCLUDE) ||
|
|
(ActionGroup == ACTIONGROUP_INCLUDEEX) ||
|
|
(ActionGroup == ACTIONGROUP_RENAME) ||
|
|
(ActionGroup == ACTIONGROUP_RENAMEEX) ||
|
|
(ActionGroup == ACTIONGROUP_INCLUDERELEVANT) ||
|
|
(ActionGroup == ACTIONGROUP_INCLUDERELEVANTEX) ||
|
|
(ActionGroup == ACTIONGROUP_RENAMERELEVANT) ||
|
|
(ActionGroup == ACTIONGROUP_RENAMERELEVANTEX)
|
|
) {
|
|
|
|
//
|
|
// Queue the enumeration callback
|
|
//
|
|
|
|
if (IsmIsObjectHandleLeafOnly (srcHandle)) {
|
|
|
|
DEBUGMSG ((DBG_SCRIPT, "Pattern %s triggered enumeration of entire file system", pattern));
|
|
|
|
QueueAllFiles();
|
|
IsmHookEnumeration (
|
|
g_FileType,
|
|
srcHandle,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
} else {
|
|
if (tree && actionStruct.ObjectBase) {
|
|
IsmQueueEnumeration (
|
|
g_FileType,
|
|
actionStruct.ObjectBase,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
IsmQueueEnumeration (
|
|
g_FileType,
|
|
srcHandle,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
}
|
|
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
|
|
IsmDestroyObjectHandle (actionStruct.ObjectBase);
|
|
actionStruct.ObjectBase = NULL;
|
|
|
|
IsmDestroyObjectHandle (actionStruct.ObjectDest);
|
|
actionStruct.ObjectDest = NULL;
|
|
|
|
FreePathString(newPattern);
|
|
|
|
} while (InfFindNextLine (&is));
|
|
|
|
result = !IsmCheckCancel();
|
|
}
|
|
|
|
InfCleanUpInfStruct (&is);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pParseLockPartition (
|
|
IN HINF Inf,
|
|
IN PCTSTR Section
|
|
)
|
|
{
|
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
|
PCTSTR pattern;
|
|
MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
|
|
BOOL result = FALSE;
|
|
|
|
if (InfFindFirstLine (Inf, Section, NULL, &is)) {
|
|
do {
|
|
if (IsmCheckCancel()) {
|
|
break;
|
|
}
|
|
|
|
pattern = InfGetStringField (&is, 0);
|
|
if (!pattern) {
|
|
LOG ((LOG_WARNING, (PCSTR) MSG_EMPTY_FILE_SPEC));
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
continue;
|
|
}
|
|
|
|
srcHandle = TurnFileStringIntoHandle (pattern, 0);
|
|
if (!srcHandle) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
continue;
|
|
}
|
|
|
|
IsmHookEnumeration (
|
|
g_FileType,
|
|
srcHandle,
|
|
LockPartition,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
|
|
} while (InfFindNextLine (&is));
|
|
result = !IsmCheckCancel();
|
|
}
|
|
InfCleanUpInfStruct (&is);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pParseRegPriority (
|
|
IN HINF Inf,
|
|
IN PCTSTR Section,
|
|
IN DWORD ActionFlags,
|
|
IN PCTSTR Application, OPTIONAL
|
|
IN BOOL ExtendedPattern
|
|
)
|
|
{
|
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
|
PCTSTR pattern = NULL;
|
|
PCTSTR patternLeaf = NULL;
|
|
PCTSTR baseNode = NULL;
|
|
PCTSTR nodeCopy = NULL;
|
|
PTSTR ptr;
|
|
MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
|
|
MIG_OBJECTSTRINGHANDLE baseHandle = NULL;
|
|
BOOL result = FALSE;
|
|
|
|
if (InfFindFirstLine (Inf, Section, NULL, &is)) {
|
|
do {
|
|
|
|
if (IsmCheckCancel()) {
|
|
break;
|
|
}
|
|
|
|
pattern = InfGetStringField (&is, 1);
|
|
|
|
if (!pattern) {
|
|
LOG ((LOG_WARNING, (PCSTR) MSG_EMPTY_RENREG));
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
continue;
|
|
}
|
|
|
|
if (ExtendedPattern) {
|
|
patternLeaf = InfGetStringField (&is, 2);
|
|
}
|
|
|
|
if (ExtendedPattern) {
|
|
srcHandle = CreatePatternFromNodeLeaf (pattern, patternLeaf?patternLeaf:TEXT("*"));
|
|
} else {
|
|
srcHandle = TurnRegStringIntoHandle (pattern, TRUE, NULL);
|
|
}
|
|
if (!srcHandle) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD, pattern));
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
continue;
|
|
}
|
|
|
|
if (ExtendedPattern) {
|
|
ptr = _tcschr (pattern, TEXT('\\'));
|
|
if (ptr) {
|
|
if (StringIPrefix (pattern, TEXT("HKR\\"))) {
|
|
nodeCopy = JoinText (TEXT("HKCU"), ptr);
|
|
} else {
|
|
nodeCopy = DuplicateText (pattern);
|
|
}
|
|
baseNode = GetPatternBase (nodeCopy);
|
|
if (baseNode) {
|
|
baseHandle = IsmCreateObjectHandle (baseNode, NULL);
|
|
FreePathString (baseNode);
|
|
}
|
|
FreeText (nodeCopy);
|
|
}
|
|
} else {
|
|
baseHandle = TurnRegStringIntoHandle (pattern, FALSE, NULL);
|
|
}
|
|
|
|
AddRuleEx (
|
|
g_RegType,
|
|
baseHandle,
|
|
srcHandle,
|
|
ACTIONGROUP_SPECIFICPRIORITY,
|
|
ActionFlags,
|
|
NULL,
|
|
RULEGROUP_PRIORITY
|
|
);
|
|
|
|
IsmHookEnumeration (
|
|
g_RegType,
|
|
srcHandle,
|
|
ObjectPriority,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
IsmDestroyObjectHandle (baseHandle);
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
|
|
} while (InfFindNextLine (&is));
|
|
|
|
result = !IsmCheckCancel();
|
|
}
|
|
|
|
InfCleanUpInfStruct (&is);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pParseFilePriority (
|
|
IN HINF Inf,
|
|
IN PCTSTR Section,
|
|
IN DWORD ActionFlags,
|
|
IN PCTSTR Application OPTIONAL
|
|
)
|
|
{
|
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
|
PCTSTR newPattern = NULL;
|
|
PCTSTR pattern;
|
|
PCTSTR dirText;
|
|
BOOL tree;
|
|
MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
|
|
MIG_OBJECTSTRINGHANDLE baseHandle = NULL;
|
|
TCHAR buffer1[MAX_TCHAR_PATH * 2];
|
|
BOOL result = FALSE;
|
|
BOOL expandResult = TRUE;
|
|
|
|
if (InfFindFirstLine (Inf, Section, NULL, &is)) {
|
|
do {
|
|
|
|
if (IsmCheckCancel()) {
|
|
break;
|
|
}
|
|
|
|
dirText = InfGetStringField (&is, 0);
|
|
pattern = InfGetStringField (&is, 1);
|
|
|
|
if (!pattern) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Expand environment variables in pattern (the left-side file spec)
|
|
//
|
|
|
|
expandResult = AppSearchAndReplace (
|
|
PLATFORM_SOURCE,
|
|
Application,
|
|
pattern,
|
|
buffer1,
|
|
ARRAYSIZE(buffer1)
|
|
);
|
|
|
|
if (!expandResult) {
|
|
// the line contains at least one unexpandable env. variables
|
|
expandResult = AppCheckAndLogUndefVariables (
|
|
PLATFORM_SOURCE,
|
|
Application,
|
|
pattern
|
|
);
|
|
if (expandResult) {
|
|
// the line contains known but undefined env. variables
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fix the pattern
|
|
//
|
|
|
|
newPattern = SanitizePath(buffer1);
|
|
if(!newPattern) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Test for dir specification
|
|
//
|
|
|
|
if (dirText && StringIMatch (dirText, TEXT("Dir"))) {
|
|
tree = TRUE;
|
|
} else {
|
|
tree = FALSE;
|
|
}
|
|
|
|
// require full spec
|
|
if (!IsValidFileSpec (newPattern)) {
|
|
if (expandResult) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
|
|
}
|
|
FreePathString (newPattern);
|
|
newPattern = NULL;
|
|
continue;
|
|
}
|
|
|
|
srcHandle = TurnFileStringIntoHandle (newPattern, tree ? PFF_PATTERN_IS_DIR : 0);
|
|
|
|
if (!srcHandle) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
|
|
FreePathString (newPattern);
|
|
newPattern = NULL;
|
|
continue;
|
|
}
|
|
|
|
baseHandle = TurnFileStringIntoHandle (
|
|
newPattern,
|
|
PFF_COMPUTE_BASE|
|
|
PFF_NO_SUBDIR_PATTERN|
|
|
(tree?PFF_NO_LEAF_AT_ALL:PFF_NO_LEAF_PATTERN)
|
|
);
|
|
|
|
AddRuleEx (
|
|
g_FileType,
|
|
baseHandle,
|
|
srcHandle,
|
|
ACTIONGROUP_SPECIFICPRIORITY,
|
|
ActionFlags,
|
|
NULL,
|
|
RULEGROUP_PRIORITY
|
|
);
|
|
|
|
IsmHookEnumeration (
|
|
g_FileType,
|
|
srcHandle,
|
|
ObjectPriority,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
IsmDestroyObjectHandle (baseHandle);
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
|
|
FreePathString (newPattern);
|
|
newPattern = NULL;
|
|
|
|
} while (InfFindNextLine (&is));
|
|
|
|
result = !IsmCheckCancel();
|
|
}
|
|
|
|
InfCleanUpInfStruct (&is);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pParseFileCollisionPattern (
|
|
IN HINF Inf,
|
|
IN PCTSTR Section,
|
|
IN PCTSTR Application OPTIONAL
|
|
)
|
|
{
|
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
|
PCTSTR pattern;
|
|
PCTSTR newPattern = NULL;
|
|
PCTSTR dirText;
|
|
BOOL tree;
|
|
MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
|
|
PCTSTR collPattern;
|
|
TCHAR buffer1[MAX_TCHAR_PATH * 2];
|
|
ACTION_STRUCT actionStruct;
|
|
BOOL result = FALSE;
|
|
PCTSTR msgNode;
|
|
PCTSTR msgLeaf;
|
|
BOOL expandResult = TRUE;
|
|
|
|
if (InfFindFirstLine (Inf, Section, NULL, &is)) {
|
|
do {
|
|
|
|
if (IsmCheckCancel()) {
|
|
break;
|
|
}
|
|
|
|
ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
|
|
|
|
dirText = InfGetStringField (&is, 0);
|
|
pattern = InfGetStringField (&is, 1);
|
|
|
|
if (!pattern) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Expand environment variables in pattern (the left-side file spec)
|
|
//
|
|
|
|
expandResult = AppSearchAndReplace (
|
|
PLATFORM_SOURCE,
|
|
Application,
|
|
pattern,
|
|
buffer1,
|
|
ARRAYSIZE(buffer1)
|
|
);
|
|
|
|
if (!expandResult) {
|
|
// the line contains at least one unexpandable env. variables
|
|
expandResult = AppCheckAndLogUndefVariables (
|
|
PLATFORM_SOURCE,
|
|
Application,
|
|
pattern
|
|
);
|
|
if (expandResult) {
|
|
// the line contains known but undefined env. variables
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fix the pattern
|
|
//
|
|
|
|
newPattern = SanitizePath(buffer1);
|
|
if(!newPattern) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Test for dir specification
|
|
//
|
|
|
|
if (dirText && StringIMatch (dirText, TEXT("Dir")) && !StringIMatch (pattern, TEXT("Dir"))) {
|
|
tree = TRUE;
|
|
} else {
|
|
tree = FALSE;
|
|
}
|
|
|
|
// require full spec or leaf only
|
|
if (!IsValidFileSpec (newPattern) && _tcschr (newPattern, TEXT('\\'))) {
|
|
if (expandResult) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
|
|
}
|
|
continue;
|
|
}
|
|
|
|
srcHandle = TurnFileStringIntoHandle (newPattern, tree ? PFF_PATTERN_IS_DIR : 0);
|
|
|
|
if (!srcHandle) {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
|
|
continue;
|
|
}
|
|
|
|
actionStruct.ObjectBase = TurnFileStringIntoHandle (
|
|
newPattern,
|
|
PFF_COMPUTE_BASE|
|
|
PFF_NO_SUBDIR_PATTERN|
|
|
(tree?PFF_NO_LEAF_AT_ALL:PFF_NO_LEAF_PATTERN)
|
|
);
|
|
|
|
collPattern = InfGetStringField (&is, 2);
|
|
|
|
if ((!collPattern) || (!(*collPattern))) {
|
|
// we have no collision pattern, let's get out
|
|
continue;
|
|
}
|
|
|
|
actionStruct.ObjectHint = IsmDuplicateString (collPattern);
|
|
|
|
//
|
|
// Add this rule
|
|
//
|
|
|
|
if (!AddRuleEx (
|
|
g_FileType,
|
|
actionStruct.ObjectBase,
|
|
srcHandle,
|
|
ACTIONGROUP_FILECOLLPATTERN,
|
|
0,
|
|
&actionStruct,
|
|
RULEGROUP_COLLPATTERN
|
|
)) {
|
|
DEBUGMSG ((DBG_ERROR, "Error processing file rules"));
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Queue the enumeration callback
|
|
//
|
|
|
|
if (IsmIsObjectHandleLeafOnly (srcHandle)) {
|
|
|
|
DEBUGMSG ((DBG_SCRIPT, "Pattern %s triggered enumeration of entire file system", pattern));
|
|
|
|
IsmHookEnumeration (
|
|
g_FileType,
|
|
srcHandle,
|
|
FileCollPattern,
|
|
0,
|
|
NULL
|
|
);
|
|
} else {
|
|
if (tree && actionStruct.ObjectBase) {
|
|
IsmHookEnumeration (
|
|
g_FileType,
|
|
actionStruct.ObjectBase,
|
|
FileCollPattern,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
IsmHookEnumeration (
|
|
g_FileType,
|
|
srcHandle,
|
|
FileCollPattern,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
srcHandle = NULL;
|
|
|
|
IsmDestroyObjectHandle (actionStruct.ObjectBase);
|
|
actionStruct.ObjectBase = NULL;
|
|
|
|
IsmReleaseMemory (actionStruct.ObjectHint);
|
|
actionStruct.ObjectHint = NULL;
|
|
|
|
FreePathString(newPattern);
|
|
|
|
} while (InfFindNextLine (&is));
|
|
|
|
result = !IsmCheckCancel();
|
|
}
|
|
|
|
InfCleanUpInfStruct (&is);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pParseOneInstruction (
|
|
IN HINF InfHandle,
|
|
IN PCTSTR Type,
|
|
IN PCTSTR SectionMultiSz,
|
|
IN PINFSTRUCT InfStruct,
|
|
IN PCTSTR Application OPTIONAL
|
|
)
|
|
{
|
|
ACTIONGROUP actionGroup;
|
|
DWORD actionFlags;
|
|
MULTISZ_ENUM e;
|
|
BOOL result = TRUE;
|
|
MIG_PLATFORMTYPEID platform = IsmGetRealPlatform();
|
|
|
|
//
|
|
// First thing: look for nested sections
|
|
//
|
|
if (StringIMatch (Type, TEXT("ProcessSection"))) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
do {
|
|
result = result & ParseOneApplication (
|
|
PLATFORM_SOURCE,
|
|
InfHandle,
|
|
Application,
|
|
FALSE,
|
|
0,
|
|
e.CurrentString,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse registry sections
|
|
//
|
|
|
|
actionGroup = ACTIONGROUP_NONE;
|
|
actionFlags = 0;
|
|
|
|
if (StringIMatch (Type, TEXT("AddReg"))) {
|
|
actionGroup = ACTIONGROUP_INCLUDE;
|
|
actionFlags = ACTION_PERSIST;
|
|
} else if (StringIMatch (Type, TEXT("RenReg"))) {
|
|
actionGroup = ACTIONGROUP_RENAME;
|
|
actionFlags = ACTION_PERSIST;
|
|
} else if (StringIMatch (Type, TEXT("DelReg"))) {
|
|
actionGroup = ACTIONGROUP_EXCLUDE;
|
|
actionFlags = 0;
|
|
} else if (StringIMatch (Type, TEXT("RegFile"))) {
|
|
actionGroup = ACTIONGROUP_REGFILE;
|
|
actionFlags = ACTION_PERSIST_PATH_IN_DATA;
|
|
} else if (StringIMatch (Type, TEXT("RegFolder"))) {
|
|
actionGroup = ACTIONGROUP_REGFOLDER;
|
|
actionFlags = ACTION_PERSIST_PATH_IN_DATA;
|
|
} else if (StringIMatch (Type, TEXT("RegIcon"))) {
|
|
actionGroup = ACTIONGROUP_REGICON;
|
|
actionFlags = ACTION_PERSIST_ICON_IN_DATA;
|
|
} else if (StringIMatch (Type, TEXT("DelRegKey"))) {
|
|
actionGroup = ACTIONGROUP_DELREGKEY;
|
|
actionFlags = 0;
|
|
}
|
|
|
|
if (actionGroup != ACTIONGROUP_NONE) {
|
|
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
if (!pParseReg (
|
|
InfHandle,
|
|
e.CurrentString,
|
|
actionGroup,
|
|
actionFlags,
|
|
TRUE,
|
|
Application
|
|
)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse file sections
|
|
//
|
|
|
|
if (StringIMatch (Type, TEXT("CopyFilesFiltered"))) {
|
|
actionGroup = ACTIONGROUP_INCLUDERELEVANT;
|
|
actionFlags = ACTION_PERSIST;
|
|
} else if (StringIMatch (Type, TEXT("CopyFilesFilteredEx"))) {
|
|
actionGroup = ACTIONGROUP_INCLUDERELEVANTEX;
|
|
actionFlags = ACTION_PERSIST;
|
|
} else if (StringIMatch (Type, TEXT("CopyFiles"))) {
|
|
actionGroup = ACTIONGROUP_INCLUDE;
|
|
actionFlags = ACTION_PERSIST;
|
|
} else if (StringIMatch (Type, TEXT("CopyFilesEx"))) {
|
|
actionGroup = ACTIONGROUP_INCLUDEEX;
|
|
actionFlags = ACTION_PERSIST;
|
|
} else if (StringIMatch (Type, TEXT("DelFiles"))) {
|
|
actionGroup = ACTIONGROUP_EXCLUDE;
|
|
actionFlags = 0;
|
|
}
|
|
|
|
if (actionGroup != ACTIONGROUP_NONE) {
|
|
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
if (IsmIsEnvironmentFlagSet (platform, NULL, S_ENV_ALL_FILES)) {
|
|
if (!pParseFiles (
|
|
InfHandle,
|
|
e.CurrentString,
|
|
actionGroup,
|
|
actionFlags,
|
|
Application
|
|
)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
LOG ((
|
|
LOG_INFORMATION,
|
|
(PCSTR) MSG_IGNORING_FILE_SECTION,
|
|
e.CurrentString
|
|
));
|
|
}
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse registry priority
|
|
//
|
|
|
|
if (StringIMatch (Type, TEXT("ForceDestRegEx"))) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
if (!pParseRegPriority (InfHandle, e.CurrentString, ACTION_PRIORITYDEST, Application, TRUE)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
if (StringIMatch (Type, TEXT("ForceDestReg"))) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
if (!pParseRegPriority (InfHandle, e.CurrentString, ACTION_PRIORITYDEST, Application, FALSE)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
if (StringIMatch (Type, TEXT("ForceSrcRegEx"))) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
if (!pParseRegPriority (InfHandle, e.CurrentString, ACTION_PRIORITYSRC, Application, TRUE)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
if (StringIMatch (Type, TEXT("ForceSrcReg"))) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
if (!pParseRegPriority (InfHandle, e.CurrentString, ACTION_PRIORITYSRC, Application, FALSE)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse file collision rules (default is %s(%d).%s)
|
|
//
|
|
if (StringIMatch (Type, TEXT("FileCollisionPattern"))) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
if (!pParseFileCollisionPattern (InfHandle, e.CurrentString, Application)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse restore callback rule
|
|
//
|
|
|
|
if (StringIMatch (Type, TEXT("RestoreCallback"))) {
|
|
if (!g_VcmMode) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_DEST_RESTORE, e.CurrentString);
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse destination rule
|
|
//
|
|
|
|
if (StringIMatch (Type, TEXT("DestDelReg"))) {
|
|
if (!g_VcmMode) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_DEST_DELREG, e.CurrentString);
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
if (StringIMatch (Type, TEXT("DestDelRegEx"))) {
|
|
if (!g_VcmMode) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_DEST_DELREGEX, e.CurrentString);
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse destination detect rules
|
|
//
|
|
|
|
if (StringIMatch (Type, TEXT("DestCheckDetect"))) {
|
|
if (!g_VcmMode) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_DEST_CHECKDETECT, e.CurrentString);
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse destination AddObject rule
|
|
//
|
|
|
|
if (StringIMatch (Type, TEXT("DestAddObject"))) {
|
|
if (!g_VcmMode) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_DEST_ADDOBJECT, e.CurrentString);
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse execute rule
|
|
//
|
|
|
|
if (StringIMatch (Type, TEXT("Execute"))) {
|
|
if (!g_VcmMode) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_SCRIPT_EXECUTE, e.CurrentString);
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse file priority
|
|
//
|
|
|
|
if (StringIMatch (Type, TEXT("ForceDestFile"))) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
if (IsmIsEnvironmentFlagSet (platform, NULL, S_ENV_ALL_FILES)) {
|
|
if (!pParseFilePriority (InfHandle, e.CurrentString, ACTION_PRIORITYDEST, Application)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
LOG ((
|
|
LOG_INFORMATION,
|
|
(PCSTR) MSG_IGNORING_FILE_SECTION,
|
|
e.CurrentString
|
|
));
|
|
}
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
if (StringIMatch (Type, TEXT("ForceSrcFile"))) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
if (IsmIsEnvironmentFlagSet (platform, NULL, S_ENV_ALL_FILES)) {
|
|
if (!pParseFilePriority (InfHandle, e.CurrentString, ACTION_PRIORITYSRC, Application)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
|
|
}
|
|
} else {
|
|
LOG ((
|
|
LOG_INFORMATION,
|
|
(PCSTR) MSG_IGNORING_FILE_SECTION,
|
|
e.CurrentString
|
|
));
|
|
}
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse special conversion
|
|
//
|
|
|
|
if (StringIMatch (Type, TEXT("Conversion"))) {
|
|
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
if (!DoRegistrySpecialConversion (InfHandle, e.CurrentString)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
if (StringIMatch (Type, TEXT("RenRegFn"))) {
|
|
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
|
|
do {
|
|
if (!DoRegistrySpecialRename (InfHandle, e.CurrentString)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse enhanced renreg
|
|
//
|
|
|
|
actionGroup = ACTIONGROUP_NONE;
|
|
actionFlags = 0;
|
|
|
|
if (StringIMatch (Type, TEXT("AddRegEx"))) {
|
|
actionGroup = ACTIONGROUP_INCLUDEEX;
|
|
actionFlags = ACTION_PERSIST;
|
|
} else if (StringIMatch (Type, TEXT("RenRegEx"))) {
|
|
actionGroup = ACTIONGROUP_RENAMEEX;
|
|
actionFlags = ACTION_PERSIST;
|
|
} else if (StringIMatch (Type, TEXT("DelRegEx"))) {
|
|
actionGroup = ACTIONGROUP_EXCLUDEEX;
|
|
actionFlags = 0;
|
|
} else if (StringIMatch (Type, TEXT("RegFileEx"))) {
|
|
actionGroup = ACTIONGROUP_REGFILEEX;
|
|
actionFlags = ACTION_PERSIST_PATH_IN_DATA;
|
|
} else if (StringIMatch (Type, TEXT("RegFolderEx"))) {
|
|
actionGroup = ACTIONGROUP_REGFOLDEREX;
|
|
actionFlags = ACTION_PERSIST_PATH_IN_DATA;
|
|
} else if (StringIMatch (Type, TEXT("RegIconEx"))) {
|
|
actionGroup = ACTIONGROUP_REGICONEX;
|
|
actionFlags = ACTION_PERSIST_ICON_IN_DATA;
|
|
}
|
|
|
|
if (actionGroup != ACTIONGROUP_NONE) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
do {
|
|
if (!pParseRegEx (InfHandle, e.CurrentString, actionGroup, actionFlags, Application)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
if (StringIMatch (Type, TEXT("LockPartition"))) {
|
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
|
do {
|
|
if (!pParseLockPartition (InfHandle, e.CurrentString)) {
|
|
result = FALSE;
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
break;
|
|
}
|
|
} while (EnumNextMultiSz (&e));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Unknown section type
|
|
//
|
|
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_UNEXPECTED_SECTION_TYPE, Type));
|
|
|
|
if (InfStruct) {
|
|
InfLogContext (LOG_ERROR, InfHandle, InfStruct);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pParseInfInstructionsWorker (
|
|
IN PINFSTRUCT InfStruct,
|
|
IN HINF InfHandle,
|
|
IN PCTSTR Application, OPTIONAL
|
|
IN PCTSTR Section
|
|
)
|
|
{
|
|
PCTSTR type;
|
|
PCTSTR sections;
|
|
GROWBUFFER multiSz = INIT_GROWBUFFER;
|
|
BOOL result = TRUE;
|
|
|
|
if (InfFindFirstLine (InfHandle, Section, NULL, InfStruct)) {
|
|
do {
|
|
|
|
if (IsmCheckCancel()) {
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
|
|
InfResetInfStruct (InfStruct);
|
|
|
|
type = InfGetStringField (InfStruct, 0);
|
|
sections = InfGetMultiSzField (InfStruct, 1);
|
|
|
|
if (!type || !sections) {
|
|
LOG ((LOG_WARNING, (PCSTR) MSG_BAD_INF_LINE, Section));
|
|
InfLogContext (LOG_WARNING, InfHandle, InfStruct);
|
|
continue;
|
|
}
|
|
|
|
result = pParseOneInstruction (InfHandle, type, sections, InfStruct, Application);
|
|
|
|
} while (result && InfFindNextLine (InfStruct));
|
|
}
|
|
|
|
InfCleanUpInfStruct (InfStruct);
|
|
|
|
GbFree (&multiSz);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ParseInfInstructions (
|
|
IN HINF InfHandle,
|
|
IN PCTSTR Application, OPTIONAL
|
|
IN PCTSTR Section
|
|
)
|
|
{
|
|
PCTSTR osSpecificSection;
|
|
BOOL b;
|
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
|
PTSTR instrSection;
|
|
|
|
b = pParseInfInstructionsWorker (&is, InfHandle, Application, Section);
|
|
|
|
if (b) {
|
|
osSpecificSection = GetMostSpecificSection (&is, InfHandle, Section);
|
|
|
|
if (osSpecificSection) {
|
|
b = pParseInfInstructionsWorker (&is, InfHandle, Application, osSpecificSection);
|
|
FreeText (osSpecificSection);
|
|
}
|
|
}
|
|
|
|
InfCleanUpInfStruct (&is);
|
|
|
|
return b;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pParseInf (
|
|
IN HINF InfHandle,
|
|
IN BOOL PreParse
|
|
)
|
|
{
|
|
BOOL result = TRUE;
|
|
|
|
if (InfHandle == INVALID_HANDLE_VALUE) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Process the application sections
|
|
//
|
|
|
|
if (!ParseApplications (PLATFORM_SOURCE, InfHandle, TEXT("Applications"), PreParse, MASTERGROUP_APP)) {
|
|
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_APP_PARSE_FAILURE));
|
|
IsmSetCancel();
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Process system settings
|
|
//
|
|
|
|
if (!ParseApplications (PLATFORM_SOURCE, InfHandle, TEXT("System Settings"), PreParse, MASTERGROUP_SYSTEM)) {
|
|
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_SYSTEM_PARSE_FAILURE));
|
|
IsmSetCancel();
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Process user settings
|
|
//
|
|
|
|
if (!ParseApplications (PLATFORM_SOURCE, InfHandle, TEXT("User Settings"), PreParse, MASTERGROUP_USER)) {
|
|
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_USER_PARSE_FAILURE));
|
|
IsmSetCancel();
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Process files and folders settings
|
|
//
|
|
|
|
if (!ProcessFilesAndFolders (InfHandle, TEXT("Files and Folders"), PreParse)) {
|
|
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_FNF_PARSE_FAILURE));
|
|
IsmSetCancel();
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Process the administrator script sections
|
|
//
|
|
|
|
if (!ParseApplications (PLATFORM_SOURCE, InfHandle, TEXT("Administrator Scripts"), PreParse, MASTERGROUP_SCRIPT)) {
|
|
LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_SCRIPT_PARSE_FAILURE));
|
|
IsmSetCancel();
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pAddFileSpec (
|
|
IN PCTSTR Node, OPTIONAL
|
|
IN PCTSTR Leaf, OPTIONAL
|
|
IN BOOL IncludeSubDirs,
|
|
IN BOOL LeafIsPattern,
|
|
IN ACTIONGROUP ActionGroup,
|
|
IN DWORD ActionFlags,
|
|
IN BOOL DefaultPriority,
|
|
IN BOOL SrcPriority
|
|
)
|
|
{
|
|
MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
|
|
MIG_OBJECTSTRINGHANDLE srcBaseHandle = NULL;
|
|
BOOL result = FALSE;
|
|
ACTION_STRUCT actionStruct;
|
|
|
|
__try {
|
|
//
|
|
// Build object string
|
|
//
|
|
|
|
MYASSERT (Node || Leaf);
|
|
|
|
srcHandle = IsmCreateSimpleObjectPattern (Node, IncludeSubDirs, Leaf, LeafIsPattern);
|
|
|
|
if (!srcHandle) {
|
|
__leave;
|
|
}
|
|
|
|
if (Node) {
|
|
srcBaseHandle = IsmCreateObjectHandle (Node, NULL);
|
|
}
|
|
|
|
//
|
|
// Add this rule
|
|
//
|
|
|
|
ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
|
|
actionStruct.ObjectBase = srcBaseHandle;
|
|
|
|
if (!AddRule (
|
|
g_FileType,
|
|
actionStruct.ObjectBase,
|
|
srcHandle,
|
|
ActionGroup,
|
|
ActionFlags,
|
|
&actionStruct
|
|
)) {
|
|
__leave;
|
|
}
|
|
|
|
if (!DefaultPriority) {
|
|
|
|
AddRuleEx (
|
|
g_FileType,
|
|
actionStruct.ObjectBase,
|
|
srcHandle,
|
|
ACTIONGROUP_SPECIFICPRIORITY,
|
|
SrcPriority?ACTION_PRIORITYSRC:ACTION_PRIORITYDEST,
|
|
NULL,
|
|
RULEGROUP_PRIORITY
|
|
);
|
|
|
|
IsmHookEnumeration (
|
|
g_RegType,
|
|
srcHandle,
|
|
ObjectPriority,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
//
|
|
// Queue enumeration for include patterns
|
|
//
|
|
|
|
if (ActionGroup == ACTIONGROUP_INCLUDE) {
|
|
|
|
if (IsmIsObjectHandleLeafOnly (srcHandle)) {
|
|
|
|
DEBUGMSG ((
|
|
DBG_SCRIPT,
|
|
"File node %s leaf %s triggered enumeration of entire file system",
|
|
Node,
|
|
Leaf
|
|
));
|
|
|
|
QueueAllFiles();
|
|
IsmHookEnumeration (
|
|
g_FileType,
|
|
srcHandle,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
} else {
|
|
IsmQueueEnumeration (
|
|
g_FileType,
|
|
srcHandle,
|
|
g_VcmMode ? GatherVirtualComputer : PrepareActions,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
}
|
|
|
|
result = TRUE;
|
|
}
|
|
__finally {
|
|
IsmDestroyObjectHandle (srcHandle);
|
|
INVALID_POINTER (srcHandle);
|
|
|
|
IsmDestroyObjectHandle (srcBaseHandle);
|
|
INVALID_POINTER (srcBaseHandle);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pParseFilesAndFolders (
|
|
IN UINT Group,
|
|
IN ACTIONGROUP ActionGroup,
|
|
IN DWORD ActionFlags,
|
|
IN BOOL HasNode,
|
|
IN BOOL HasLeaf,
|
|
IN BOOL HasPriority
|
|
)
|
|
{
|
|
MIG_COMPONENT_ENUM e;
|
|
BOOL result = FALSE;
|
|
PCTSTR node;
|
|
PCTSTR leaf;
|
|
PTSTR copyOfData = NULL;
|
|
PTSTR p;
|
|
BOOL defaultPriority = TRUE;
|
|
BOOL srcPriority = FALSE;
|
|
|
|
__try {
|
|
//
|
|
// Enumerate all the components
|
|
//
|
|
|
|
if (IsmEnumFirstComponent (&e, COMPONENTENUM_ENABLED|COMPONENTENUM_ALIASES, Group)) {
|
|
do {
|
|
//
|
|
// Parse string into node/leaf format
|
|
//
|
|
|
|
if (e.MasterGroup != MASTERGROUP_FILES_AND_FOLDERS) {
|
|
continue;
|
|
}
|
|
|
|
copyOfData = DuplicateText (e.LocalizedAlias);
|
|
|
|
node = copyOfData;
|
|
leaf = NULL;
|
|
|
|
if (HasNode && HasLeaf) {
|
|
p = (PTSTR) FindLastWack (copyOfData);
|
|
if (p) {
|
|
leaf = _tcsinc (p);
|
|
*p = 0;
|
|
}
|
|
} else if (!HasNode) {
|
|
node = NULL;
|
|
leaf = JoinText (TEXT("*."), copyOfData);
|
|
}
|
|
|
|
//
|
|
// Add rule
|
|
//
|
|
|
|
if (!pAddFileSpec (
|
|
node,
|
|
leaf,
|
|
(HasNode && (!HasLeaf)),
|
|
(HasNode && (!HasLeaf)) || (!HasNode),
|
|
ActionGroup,
|
|
ActionFlags,
|
|
defaultPriority,
|
|
srcPriority
|
|
)) {
|
|
IsmAbortComponentEnum (&e);
|
|
__leave;
|
|
}
|
|
|
|
if (!HasNode) {
|
|
FreeText (leaf);
|
|
}
|
|
|
|
FreeText (copyOfData);
|
|
copyOfData = NULL;
|
|
|
|
} while (IsmEnumNextComponent (&e));
|
|
}
|
|
|
|
result = TRUE;
|
|
}
|
|
__finally {
|
|
FreeText (copyOfData);
|
|
|
|
if (!result) {
|
|
IsmAbortComponentEnum (&e);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pSelectFilesAndFolders (
|
|
VOID
|
|
)
|
|
{
|
|
if (!pParseFilesAndFolders (
|
|
COMPONENT_EXTENSION,
|
|
ACTIONGROUP_INCLUDE,
|
|
ACTION_PERSIST,
|
|
FALSE,
|
|
TRUE,
|
|
TRUE
|
|
)) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (!pParseFilesAndFolders (
|
|
COMPONENT_FOLDER,
|
|
ACTIONGROUP_INCLUDE,
|
|
ACTION_PERSIST,
|
|
TRUE,
|
|
FALSE,
|
|
TRUE
|
|
)) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (!pParseFilesAndFolders (
|
|
COMPONENT_FILE,
|
|
ACTIONGROUP_INCLUDE,
|
|
ACTION_PERSIST,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE
|
|
)) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
pParseAllInfs (
|
|
IN BOOL PreParse
|
|
)
|
|
{
|
|
PTSTR multiSz = NULL;
|
|
MULTISZ_ENUM e;
|
|
UINT sizeNeeded;
|
|
HINF infHandle = INVALID_HANDLE_VALUE;
|
|
ENVENTRY_TYPE dataType;
|
|
BOOL result = FALSE;
|
|
|
|
if (IsmGetEnvironmentValue (
|
|
IsmGetRealPlatform (),
|
|
NULL,
|
|
S_GLOBAL_INF_HANDLE,
|
|
(PBYTE)(&infHandle),
|
|
sizeof (HINF),
|
|
&sizeNeeded,
|
|
&dataType
|
|
) &&
|
|
(sizeNeeded == sizeof (HINF)) &&
|
|
(dataType == ENVENTRY_BINARY)
|
|
) {
|
|
|
|
if (pParseInf (infHandle, PreParse)) {
|
|
result = TRUE;
|
|
}
|
|
|
|
InfNameHandle (infHandle, NULL, 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) {
|
|
__leave;
|
|
}
|
|
|
|
if (!IsmGetEnvironmentValue (IsmGetRealPlatform (), NULL, S_INF_FILE_MULTISZ, (PBYTE) multiSz, sizeNeeded, NULL, NULL)) {
|
|
__leave;
|
|
}
|
|
|
|
if (EnumFirstMultiSz (&e, multiSz)) {
|
|
|
|
do {
|
|
|
|
infHandle = InfOpenInfFile (e.CurrentString);
|
|
if (infHandle != INVALID_HANDLE_VALUE) {
|
|
if (!pParseInf (infHandle, PreParse)) {
|
|
InfCloseInfFile (infHandle);
|
|
infHandle = INVALID_HANDLE_VALUE;
|
|
__leave;
|
|
}
|
|
} else {
|
|
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_INF, e.CurrentString));
|
|
}
|
|
InfCloseInfFile (infHandle);
|
|
infHandle = INVALID_HANDLE_VALUE;
|
|
} while (EnumNextMultiSz (&e));
|
|
|
|
}
|
|
|
|
result = TRUE;
|
|
}
|
|
__finally {
|
|
if (multiSz) {
|
|
FreeText (multiSz);
|
|
multiSz = NULL;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|