1724 lines
42 KiB
C
1724 lines
42 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
app.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Implements a set of functions to manage data for an application section.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Jim Schmidt (jimschm) 05-Jun-2000
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
<alias> <date> <comments>
|
||
|
|
||
|
--*/
|
||
|
|
||
|
//
|
||
|
// Includes
|
||
|
//
|
||
|
|
||
|
#include "pch.h"
|
||
|
#include "v1p.h"
|
||
|
|
||
|
#define DBG_FOO "Foo"
|
||
|
|
||
|
//
|
||
|
// Strings
|
||
|
//
|
||
|
|
||
|
// None
|
||
|
|
||
|
//
|
||
|
// Constants
|
||
|
//
|
||
|
|
||
|
#define MAX_EXPANDED_STRING 4096
|
||
|
|
||
|
//
|
||
|
// Macros
|
||
|
//
|
||
|
|
||
|
// None
|
||
|
|
||
|
//
|
||
|
// Types
|
||
|
//
|
||
|
|
||
|
// None
|
||
|
|
||
|
//
|
||
|
// Globals
|
||
|
//
|
||
|
|
||
|
PMHANDLE g_AppPool;
|
||
|
extern BOOL g_VcmMode; // in sgmqueue.c
|
||
|
GROWLIST g_SectionStack = INIT_GROWLIST;
|
||
|
|
||
|
//
|
||
|
// Macro expansion list
|
||
|
//
|
||
|
|
||
|
// None
|
||
|
|
||
|
//
|
||
|
// Private function prototypes
|
||
|
//
|
||
|
|
||
|
BOOL
|
||
|
pParseAppEnvSection (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN HINF InfFile,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR Section
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Macro expansion definition
|
||
|
//
|
||
|
|
||
|
// None
|
||
|
|
||
|
//
|
||
|
// Code
|
||
|
//
|
||
|
|
||
|
|
||
|
VOID
|
||
|
InitAppModule (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
g_AppPool = PmCreateNamedPool ("v1 App");
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
TerminateAppModule (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
PmDestroyPool (g_AppPool);
|
||
|
INVALID_POINTER (g_AppPool);
|
||
|
}
|
||
|
|
||
|
|
||
|
UINT
|
||
|
pSafeTcharCount (
|
||
|
IN PCTSTR String
|
||
|
)
|
||
|
{
|
||
|
if (String) {
|
||
|
return TcharCount (String);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
PCTSTR
|
||
|
GetMostSpecificSection (
|
||
|
IN PINFSTRUCT InfStruct,
|
||
|
IN HINF InfFile,
|
||
|
IN PCTSTR BaseSection
|
||
|
)
|
||
|
{
|
||
|
PTSTR specificSection;
|
||
|
MIG_OSVERSIONINFO versionInfo;
|
||
|
UINT tchars;
|
||
|
|
||
|
if (!IsmGetOsVersionInfo (PLATFORM_SOURCE, &versionInfo)) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
tchars = TcharCount (BaseSection) + 1;
|
||
|
tchars += pSafeTcharCount (versionInfo.OsTypeName) + 1;
|
||
|
tchars += pSafeTcharCount (versionInfo.OsMajorVersionName) + 1;
|
||
|
tchars += pSafeTcharCount (versionInfo.OsMinorVersionName) + 1;
|
||
|
|
||
|
specificSection = AllocText (tchars);
|
||
|
|
||
|
if (versionInfo.OsTypeName &&
|
||
|
versionInfo.OsMajorVersionName &&
|
||
|
versionInfo.OsMinorVersionName
|
||
|
) {
|
||
|
wsprintf (
|
||
|
specificSection,
|
||
|
TEXT("%s.%s.%s.%s"),
|
||
|
BaseSection,
|
||
|
versionInfo.OsTypeName,
|
||
|
versionInfo.OsMajorVersionName,
|
||
|
versionInfo.OsMinorVersionName
|
||
|
);
|
||
|
|
||
|
if (InfFindFirstLine (InfFile, specificSection, NULL, InfStruct)) {
|
||
|
return specificSection;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (versionInfo.OsTypeName &&
|
||
|
versionInfo.OsMajorVersionName
|
||
|
) {
|
||
|
wsprintf (
|
||
|
specificSection,
|
||
|
TEXT("%s.%s.%s"),
|
||
|
BaseSection,
|
||
|
versionInfo.OsTypeName,
|
||
|
versionInfo.OsMajorVersionName
|
||
|
);
|
||
|
|
||
|
if (InfFindFirstLine (InfFile, specificSection, NULL, InfStruct)) {
|
||
|
return specificSection;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (versionInfo.OsTypeName) {
|
||
|
wsprintf (
|
||
|
specificSection,
|
||
|
TEXT("%s.%s"),
|
||
|
BaseSection,
|
||
|
versionInfo.OsTypeName
|
||
|
);
|
||
|
|
||
|
if (InfFindFirstLine (InfFile, specificSection, NULL, InfStruct)) {
|
||
|
return specificSection;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FreeText (specificSection);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
pCheckForRecursion (
|
||
|
IN PCTSTR Section
|
||
|
)
|
||
|
{
|
||
|
UINT count;
|
||
|
UINT u;
|
||
|
|
||
|
|
||
|
count = GlGetSize (&g_SectionStack);
|
||
|
for (u = 0 ; u < count ; u++) {
|
||
|
if (StringIMatch (GlGetString (&g_SectionStack, u), Section)) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
pPushSection (
|
||
|
IN PCTSTR Section
|
||
|
)
|
||
|
{
|
||
|
GlAppendString (&g_SectionStack, Section);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
pPopSection (
|
||
|
IN PCTSTR Section
|
||
|
)
|
||
|
{
|
||
|
UINT u;
|
||
|
|
||
|
u = GlGetSize (&g_SectionStack);
|
||
|
|
||
|
while (u > 0) {
|
||
|
u--;
|
||
|
|
||
|
if (StringIMatch (GlGetString (&g_SectionStack, u), Section)) {
|
||
|
GlDeleteItem (&g_SectionStack, u);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MYASSERT (FALSE);
|
||
|
}
|
||
|
|
||
|
UINT
|
||
|
pGetDisplayTypeFromString (
|
||
|
IN PCTSTR String
|
||
|
)
|
||
|
{
|
||
|
if (!String) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (StringIMatch (String, TEXT("EXT"))) {
|
||
|
return COMPONENT_EXTENSION;
|
||
|
}
|
||
|
|
||
|
if (StringIMatch (String, TEXT("FILE"))) {
|
||
|
return COMPONENT_FILE;
|
||
|
}
|
||
|
|
||
|
if (StringIMatch (String, TEXT("DIR"))) {
|
||
|
return COMPONENT_FOLDER;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
pAddFilesAndFoldersComponent (
|
||
|
IN PCTSTR ComponentString, OPTIONAL
|
||
|
IN PCTSTR TypeString,
|
||
|
IN PCTSTR MultiSz,
|
||
|
IN UINT MasterGroup,
|
||
|
IN OUT PBOOL MarkAsPreferred
|
||
|
)
|
||
|
{
|
||
|
MULTISZ_ENUM e;
|
||
|
TCHAR expandBuffer[MAX_PATH];
|
||
|
UINT displayType;
|
||
|
|
||
|
displayType = pGetDisplayTypeFromString (TypeString);
|
||
|
if (!displayType) {
|
||
|
LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_FNF_TYPE, TypeString));
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
if (EnumFirstMultiSz (&e, MultiSz)) {
|
||
|
do {
|
||
|
|
||
|
//
|
||
|
// Expand e.CurrentString
|
||
|
//
|
||
|
|
||
|
MappingSearchAndReplaceEx (
|
||
|
g_EnvMap,
|
||
|
e.CurrentString,
|
||
|
expandBuffer,
|
||
|
0,
|
||
|
NULL,
|
||
|
ARRAYSIZE(expandBuffer),
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Add component
|
||
|
//
|
||
|
|
||
|
IsmAddComponentAlias (
|
||
|
ComponentString,
|
||
|
MasterGroup,
|
||
|
expandBuffer,
|
||
|
displayType,
|
||
|
FALSE
|
||
|
);
|
||
|
|
||
|
if (ComponentString && *MarkAsPreferred) {
|
||
|
IsmSelectPreferredAlias (ComponentString, expandBuffer, displayType);
|
||
|
*MarkAsPreferred = FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
} while (EnumNextMultiSz (&e));
|
||
|
|
||
|
} else {
|
||
|
LOG ((LOG_WARNING, (PCSTR) MSG_EMPTY_FNF_SPEC, TypeString));
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
pAddFilesAndFoldersSection (
|
||
|
IN HINF InfFile,
|
||
|
IN PCTSTR Section,
|
||
|
IN UINT MasterGroup,
|
||
|
IN BOOL GroupAllUnderSection,
|
||
|
IN PBOOL MarkAsPreferred
|
||
|
)
|
||
|
{
|
||
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
||
|
PCTSTR type;
|
||
|
PCTSTR multiSz;
|
||
|
BOOL result = TRUE;
|
||
|
PCTSTR decoratedSection = NULL;
|
||
|
|
||
|
if (GroupAllUnderSection) {
|
||
|
decoratedSection = JoinText (TEXT("$"), Section);
|
||
|
}
|
||
|
|
||
|
if (InfFindFirstLine (InfFile, Section, NULL, &is)) {
|
||
|
do {
|
||
|
|
||
|
InfResetInfStruct (&is);
|
||
|
|
||
|
type = InfGetStringField (&is, 1);
|
||
|
multiSz = InfGetMultiSzField (&is, 2);
|
||
|
|
||
|
result = pAddFilesAndFoldersComponent (
|
||
|
decoratedSection,
|
||
|
type,
|
||
|
multiSz,
|
||
|
MasterGroup,
|
||
|
MarkAsPreferred
|
||
|
);
|
||
|
|
||
|
} while (result && InfFindNextLine (&is));
|
||
|
}
|
||
|
|
||
|
InfCleanUpInfStruct (&is);
|
||
|
FreeText (decoratedSection);
|
||
|
|
||
|
if (!result) {
|
||
|
LOG ((LOG_ERROR, (PCSTR) MSG_SECTION_ERROR, Section));
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
pAddFilesAndFoldersComponentOrSection (
|
||
|
IN HINF InfFile,
|
||
|
IN PCTSTR ComponentString, OPTIONAL
|
||
|
IN PCTSTR TypeString,
|
||
|
IN PCTSTR MultiSz,
|
||
|
IN UINT MasterGroup,
|
||
|
IN PBOOL MarkAsPreferred
|
||
|
)
|
||
|
{
|
||
|
MULTISZ_ENUM e;
|
||
|
BOOL result = TRUE;
|
||
|
|
||
|
if (StringIMatch (TypeString, TEXT("Section"))) {
|
||
|
if (EnumFirstMultiSz (&e, MultiSz)) {
|
||
|
do {
|
||
|
result = pAddFilesAndFoldersSection (InfFile, e.CurrentString, MasterGroup, TRUE, MarkAsPreferred);
|
||
|
|
||
|
} while (result && EnumNextMultiSz (&e));
|
||
|
}
|
||
|
} else {
|
||
|
result = pAddFilesAndFoldersComponent (ComponentString, TypeString, MultiSz, MasterGroup, MarkAsPreferred);
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
AddAppSpecificEnvVar (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN PCTSTR AppTag,
|
||
|
IN PCTSTR VariableName,
|
||
|
IN PCTSTR VariableData OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
TCHAR destBuffer[MAX_TCHAR_PATH * 4];
|
||
|
PMAPSTRUCT mapArray[1];
|
||
|
UINT mapCount = 0;
|
||
|
BOOL updated;
|
||
|
PTSTR buffer;
|
||
|
PTSTR p;
|
||
|
PTSTR q;
|
||
|
BOOL ignoreLastPercent = FALSE;
|
||
|
PCTSTR undefText;
|
||
|
|
||
|
//
|
||
|
// Verify VariableName is legal
|
||
|
//
|
||
|
|
||
|
if (_tcsnextc (VariableName) == TEXT('%')) {
|
||
|
VariableName++;
|
||
|
ignoreLastPercent = TRUE;
|
||
|
}
|
||
|
|
||
|
if (*VariableName == 0) {
|
||
|
LOG ((LOG_WARNING, (PCSTR) MSG_EMPTY_APP_ENV_VAR));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Transfer VariableName into %<VariableName>%
|
||
|
//
|
||
|
|
||
|
buffer = AllocText (SizeOfString (VariableName) + 2);
|
||
|
MYASSERT (buffer);
|
||
|
if (!buffer) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
p = buffer;
|
||
|
|
||
|
*p++ = TEXT('%');
|
||
|
*p = 0;
|
||
|
p = StringCat (p, VariableName);
|
||
|
|
||
|
if (ignoreLastPercent) {
|
||
|
q = _tcsdec (buffer, p);
|
||
|
if (q) {
|
||
|
if (_tcsnextc (q) == TEXT('%')) {
|
||
|
p = q;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*p++ = TEXT('%');
|
||
|
*p = 0;
|
||
|
|
||
|
//
|
||
|
// Add %<VariableName>% -> VariableData to string mapping table
|
||
|
//
|
||
|
|
||
|
if (VariableData) {
|
||
|
|
||
|
if (Platform == PLATFORM_SOURCE) {
|
||
|
// let's see if this already exists
|
||
|
mapArray[mapCount] = g_EnvMap;
|
||
|
updated = MappingMultiTableSearchAndReplaceEx (
|
||
|
mapArray,
|
||
|
mapCount + 1,
|
||
|
buffer,
|
||
|
destBuffer,
|
||
|
0,
|
||
|
NULL,
|
||
|
ARRAYSIZE (destBuffer),
|
||
|
STRMAP_COMPLETE_MATCH_ONLY,
|
||
|
NULL,
|
||
|
NULL
|
||
|
);
|
||
|
if (updated) {
|
||
|
LOG ((LOG_ERROR, (PCSTR) MSG_DUPLICATE_ENV_VAR, buffer));
|
||
|
}
|
||
|
IsmSetEnvironmentString (PLATFORM_SOURCE, S_SYSENVVAR_GROUP, VariableName, VariableData);
|
||
|
AddStringMappingPair (g_EnvMap, buffer, VariableData);
|
||
|
} else {
|
||
|
MYASSERT (Platform == PLATFORM_DESTINATION);
|
||
|
// let's see if this already exists
|
||
|
mapArray[mapCount] = g_DestEnvMap;
|
||
|
updated = MappingMultiTableSearchAndReplaceEx (
|
||
|
mapArray,
|
||
|
mapCount + 1,
|
||
|
buffer,
|
||
|
destBuffer,
|
||
|
0,
|
||
|
NULL,
|
||
|
ARRAYSIZE (destBuffer),
|
||
|
STRMAP_COMPLETE_MATCH_ONLY,
|
||
|
NULL,
|
||
|
NULL
|
||
|
);
|
||
|
if (updated) {
|
||
|
LOG ((LOG_ERROR, (PCSTR) MSG_DUPLICATE_ENV_VAR, buffer));
|
||
|
}
|
||
|
AddRemappingEnvVar (g_DestEnvMap, g_FileNodeFilterMap, NULL, VariableName, VariableData);
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
LOG ((LOG_INFORMATION, (PCSTR) MSG_UNDEF_APP_VAR, buffer));
|
||
|
|
||
|
undefText = JoinTextEx (NULL, TEXT("--> "), TEXT(" <--"), buffer, 0, NULL);
|
||
|
|
||
|
AddStringMappingPair (g_UndefMap, buffer, undefText);
|
||
|
|
||
|
FreeText (undefText);
|
||
|
}
|
||
|
|
||
|
FreeText (buffer);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
AppCheckAndLogUndefVariables (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR UnexpandedString
|
||
|
)
|
||
|
{
|
||
|
TCHAR buffer[MAX_TCHAR_PATH * 4];
|
||
|
PMAPSTRUCT mapArray[1];
|
||
|
UINT mapCount = 0;
|
||
|
BOOL updated;
|
||
|
|
||
|
mapArray[mapCount] = g_UndefMap;
|
||
|
|
||
|
updated = MappingMultiTableSearchAndReplaceEx (
|
||
|
mapArray,
|
||
|
mapCount + 1,
|
||
|
UnexpandedString,
|
||
|
buffer,
|
||
|
0,
|
||
|
NULL,
|
||
|
ARRAYSIZE(buffer),
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if (updated) {
|
||
|
if (buffer [0]) {
|
||
|
LOG ((LOG_INFORMATION, (PCSTR) MSG_UNDEF_BUT_GOOD_VAR, buffer));
|
||
|
}
|
||
|
} else {
|
||
|
if (buffer [0]) {
|
||
|
LOG ((LOG_INFORMATION, (PCSTR) MSG_ENV_VAR_COULD_BE_BAD, buffer));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return updated;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
AppSearchAndReplace (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR UnexpandedString,
|
||
|
OUT PTSTR ExpandedString,
|
||
|
IN UINT ExpandedStringTchars
|
||
|
)
|
||
|
{
|
||
|
PMAPSTRUCT mapArray[1];
|
||
|
UINT mapCount = 0;
|
||
|
BOOL updated;
|
||
|
PCTSTR newString = NULL;
|
||
|
PCTSTR percent;
|
||
|
PCTSTR endPercent;
|
||
|
PCTSTR equals;
|
||
|
BOOL result = TRUE;
|
||
|
|
||
|
//
|
||
|
// Let's expand the incoming string by using the source machine defined environment variables.
|
||
|
//
|
||
|
newString = IsmExpandEnvironmentString (Platform, S_SYSENVVAR_GROUP, UnexpandedString, NULL);
|
||
|
|
||
|
if (Platform == PLATFORM_SOURCE) {
|
||
|
mapArray[mapCount] = g_EnvMap;
|
||
|
} else {
|
||
|
MYASSERT (Platform == PLATFORM_DESTINATION);
|
||
|
mapArray[mapCount] = g_DestEnvMap;
|
||
|
}
|
||
|
|
||
|
updated = MappingMultiTableSearchAndReplaceEx (
|
||
|
mapArray,
|
||
|
mapCount + 1,
|
||
|
newString,
|
||
|
ExpandedString,
|
||
|
0,
|
||
|
NULL,
|
||
|
ExpandedStringTchars,
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if (newString) {
|
||
|
IsmReleaseMemory (newString);
|
||
|
newString = NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Alert the user to an unexpanded environment variable
|
||
|
//
|
||
|
|
||
|
if (!updated) {
|
||
|
percent = ExpandedString;
|
||
|
|
||
|
do {
|
||
|
percent = _tcschr (percent, TEXT('%'));
|
||
|
|
||
|
if (percent) {
|
||
|
percent = _tcsinc (percent);
|
||
|
endPercent = _tcschr (percent, TEXT('%'));
|
||
|
|
||
|
if (endPercent > percent) {
|
||
|
|
||
|
equals = percent;
|
||
|
while (equals < endPercent) {
|
||
|
if (_tcsnextc (equals) == TEXT('=')) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
equals = _tcsinc (equals);
|
||
|
}
|
||
|
|
||
|
if (equals >= endPercent) {
|
||
|
result = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} while (percent && endPercent);
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
pGetDataFromObjectSpec (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR InfObjectType,
|
||
|
IN PCTSTR InfObjectName,
|
||
|
IN PCTSTR ArgumentMultiSz, OPTIONAL
|
||
|
OUT PTSTR OutContentBuffer, OPTIONAL
|
||
|
IN UINT OutContentBufferTchars,
|
||
|
OUT PBOOL TestResults OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
ATTRIB_DATA attribData;
|
||
|
BOOL test;
|
||
|
|
||
|
MYASSERT (Application);
|
||
|
MYASSERT (InfObjectType);
|
||
|
MYASSERT (InfObjectName);
|
||
|
|
||
|
ZeroMemory (&attribData, sizeof (ATTRIB_DATA));
|
||
|
attribData.Platform = Platform;
|
||
|
attribData.ScriptSpecifiedType = InfObjectType;
|
||
|
attribData.ScriptSpecifiedObject = InfObjectName;
|
||
|
attribData.ApplicationName = Application;
|
||
|
|
||
|
if (AllocScriptType (&attribData)) {
|
||
|
if (g_VcmMode && attribData.ObjectName) {
|
||
|
if (IsmDoesObjectExist (attribData.ObjectTypeId, attribData.ObjectName)) {
|
||
|
IsmMakePersistentObject (attribData.ObjectTypeId, attribData.ObjectName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (attribData.ReturnString) {
|
||
|
if (OutContentBuffer) {
|
||
|
StringCopyTcharCount (
|
||
|
OutContentBuffer,
|
||
|
attribData.ReturnString,
|
||
|
OutContentBufferTchars
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
if (TestResults) {
|
||
|
if (ArgumentMultiSz) {
|
||
|
test = TestAttributes (g_AppPool, ArgumentMultiSz, &attribData);
|
||
|
} else {
|
||
|
test = (attribData.ReturnString != NULL);
|
||
|
}
|
||
|
|
||
|
*TestResults = test;
|
||
|
}
|
||
|
FreeScriptType (&attribData);
|
||
|
} else {
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
pAddPlatformEnvVar (
|
||
|
IN HINF InfFile,
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR Section,
|
||
|
IN PCTSTR Variable,
|
||
|
IN PCTSTR Type,
|
||
|
IN PCTSTR Data,
|
||
|
IN PCTSTR ArgMultiSz,
|
||
|
IN PINFSTRUCT InfStruct
|
||
|
)
|
||
|
{
|
||
|
BOOL exists;
|
||
|
BOOL validString;
|
||
|
PCTSTR p;
|
||
|
PCTSTR end;
|
||
|
TCHAR variableData[MAX_PATH + 1];
|
||
|
PCTSTR varDataLong = NULL;
|
||
|
|
||
|
ZeroMemory (&variableData, sizeof (variableData));
|
||
|
|
||
|
//
|
||
|
// Variable data is specified in the object represented by <data>
|
||
|
//
|
||
|
|
||
|
if (!pGetDataFromObjectSpec (
|
||
|
Platform,
|
||
|
Application,
|
||
|
Type,
|
||
|
Data,
|
||
|
ArgMultiSz,
|
||
|
variableData,
|
||
|
ARRAYSIZE(variableData) - 1,
|
||
|
&exists
|
||
|
)) {
|
||
|
|
||
|
switch (GetLastError()) {
|
||
|
|
||
|
case ERROR_INVALID_DATA:
|
||
|
LOG ((
|
||
|
LOG_WARNING,
|
||
|
(PCSTR) MSG_DETECT_DATA_OBJECT_IS_BAD,
|
||
|
Data,
|
||
|
Variable
|
||
|
));
|
||
|
InfLogContext (LOG_WARNING, InfFile, InfStruct);
|
||
|
break;
|
||
|
|
||
|
case ERROR_INVALID_DATATYPE:
|
||
|
LOG ((
|
||
|
LOG_ERROR,
|
||
|
(PCSTR) MSG_DETECT_DATA_TYPE_IS_BAD,
|
||
|
Type,
|
||
|
Variable
|
||
|
));
|
||
|
InfLogContext (LOG_ERROR, InfFile, InfStruct);
|
||
|
break;
|
||
|
}
|
||
|
} else {
|
||
|
validString = FALSE;
|
||
|
|
||
|
if (exists) {
|
||
|
|
||
|
p = variableData;
|
||
|
end = variableData + MAX_PATH;
|
||
|
|
||
|
while (p < end) {
|
||
|
if (_tcsnextc (p) < 32) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
p = _tcsinc (p);
|
||
|
}
|
||
|
|
||
|
if (*p == 0 && p < end && p > variableData) {
|
||
|
validString = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (validString) {
|
||
|
if (IsValidFileSpec (variableData)) {
|
||
|
varDataLong = BfGetLongFileName (variableData);
|
||
|
} else {
|
||
|
varDataLong = variableData;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!validString && exists) {
|
||
|
LOG ((LOG_INFORMATION, (PCSTR) MSG_DATA_IS_NOT_A_STRING, Variable));
|
||
|
} else {
|
||
|
LOG_IF ((
|
||
|
validString,
|
||
|
LOG_INFORMATION,
|
||
|
(PCSTR) MSG_APP_ENV_DEF_INFO,
|
||
|
Variable,
|
||
|
Type,
|
||
|
Data,
|
||
|
variableData
|
||
|
));
|
||
|
|
||
|
LOG_IF ((
|
||
|
!validString,
|
||
|
LOG_INFORMATION,
|
||
|
(PCSTR) MSG_NUL_APP_ENV_DEF_INFO,
|
||
|
Variable,
|
||
|
Type,
|
||
|
Data
|
||
|
));
|
||
|
|
||
|
AddAppSpecificEnvVar (
|
||
|
Platform,
|
||
|
Application,
|
||
|
Variable,
|
||
|
validString ? varDataLong : NULL
|
||
|
);
|
||
|
|
||
|
}
|
||
|
|
||
|
if (varDataLong && (varDataLong != variableData)) {
|
||
|
FreePathString (varDataLong);
|
||
|
varDataLong = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
PCTSTR
|
||
|
pProcessArgEnvironmentVars (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR Args,
|
||
|
IN BOOL MultiSz,
|
||
|
OUT PGROWBUFFER UpdatedData
|
||
|
)
|
||
|
{
|
||
|
MULTISZ_ENUM e;
|
||
|
TCHAR buffer[MAX_EXPANDED_STRING];
|
||
|
|
||
|
UpdatedData->End = 0;
|
||
|
|
||
|
if (MultiSz) {
|
||
|
if (EnumFirstMultiSz (&e, Args)) {
|
||
|
|
||
|
do {
|
||
|
|
||
|
AppSearchAndReplace (
|
||
|
Platform,
|
||
|
Application,
|
||
|
e.CurrentString,
|
||
|
buffer,
|
||
|
MAX_EXPANDED_STRING
|
||
|
);
|
||
|
|
||
|
GbMultiSzAppend (UpdatedData, buffer);
|
||
|
|
||
|
} while (EnumNextMultiSz (&e));
|
||
|
}
|
||
|
} else {
|
||
|
AppSearchAndReplace (
|
||
|
Platform,
|
||
|
Application,
|
||
|
Args,
|
||
|
buffer,
|
||
|
MAX_EXPANDED_STRING
|
||
|
);
|
||
|
|
||
|
GbMultiSzAppend (UpdatedData, buffer);
|
||
|
}
|
||
|
|
||
|
return (PCTSTR) UpdatedData->Buf;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
pParseAppEnvSectionWorker (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN PINFSTRUCT InfStruct,
|
||
|
IN HINF InfFile,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR Section
|
||
|
)
|
||
|
{
|
||
|
BOOL result = FALSE;
|
||
|
PCTSTR variable;
|
||
|
PCTSTR type;
|
||
|
PCTSTR data;
|
||
|
PCTSTR args;
|
||
|
PCTSTR updatedData;
|
||
|
PCTSTR updatedArgs;
|
||
|
PTSTR lastChar;
|
||
|
GROWBUFFER dataBuf = INIT_GROWBUFFER;
|
||
|
GROWBUFFER argBuf = INIT_GROWBUFFER;
|
||
|
|
||
|
//
|
||
|
// Section must not be on the stack
|
||
|
//
|
||
|
|
||
|
if (pCheckForRecursion (Section)) {
|
||
|
LOG ((LOG_ERROR, (PCSTR) MSG_ENV_SECTION_RECURSION, Section));
|
||
|
// Assume success
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Format is
|
||
|
//
|
||
|
// <variable> = <type>, <data> [, <arguments>]
|
||
|
//
|
||
|
// <type> specifies one of the supported parse types (see parse.c),
|
||
|
// or "Text" when <data> is arbitrary text
|
||
|
//
|
||
|
// <data> is specific to <type>
|
||
|
//
|
||
|
// <arguments> specify qualifiers. If they evaluate to FALSE, then
|
||
|
// the variable is not set.
|
||
|
//
|
||
|
|
||
|
__try {
|
||
|
if (InfFindFirstLine (InfFile, Section, NULL, InfStruct)) {
|
||
|
do {
|
||
|
|
||
|
if (IsmCheckCancel()) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
InfResetInfStruct (InfStruct);
|
||
|
|
||
|
variable = InfGetStringField (InfStruct, 0);
|
||
|
type = InfGetStringField (InfStruct, 1);
|
||
|
|
||
|
if (variable && StringIMatch (variable, TEXT("ProcessSection"))) {
|
||
|
if (type && *type) {
|
||
|
pPushSection (Section);
|
||
|
result = pParseAppEnvSection (Platform, InfFile, Application, type);
|
||
|
pPopSection (Section);
|
||
|
|
||
|
if (!result) {
|
||
|
__leave;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
data = InfGetStringField (InfStruct, 2);
|
||
|
args = InfGetMultiSzField (InfStruct, 3);
|
||
|
|
||
|
if (variable) {
|
||
|
//
|
||
|
// Remove %s from the variable name
|
||
|
//
|
||
|
|
||
|
if (_tcsnextc (variable) == TEXT('%')) {
|
||
|
lastChar = _tcsdec2 (variable, GetEndOfString (variable));
|
||
|
|
||
|
if (lastChar > variable && _tcsnextc (lastChar) == TEXT('%')) {
|
||
|
variable = _tcsinc (variable);
|
||
|
*lastChar = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!variable || !(*variable) || !type || !(*type) || !data) {
|
||
|
LOG ((LOG_WARNING, (PCSTR) MSG_GARBAGE_LINE_IN_INF, Section));
|
||
|
InfLogContext (LOG_WARNING, InfFile, InfStruct);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Update all environment variables in data and args
|
||
|
//
|
||
|
|
||
|
updatedData = pProcessArgEnvironmentVars (
|
||
|
Platform,
|
||
|
Application,
|
||
|
data,
|
||
|
FALSE,
|
||
|
&dataBuf
|
||
|
);
|
||
|
|
||
|
if (args && *args) {
|
||
|
updatedArgs = pProcessArgEnvironmentVars (
|
||
|
Platform,
|
||
|
Application,
|
||
|
args,
|
||
|
TRUE,
|
||
|
&argBuf
|
||
|
);
|
||
|
} else {
|
||
|
updatedArgs = NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Add the app-specific environment variables. If we are
|
||
|
// on the destination, add both a source and destination
|
||
|
// value (as they might be different).
|
||
|
//
|
||
|
|
||
|
pAddPlatformEnvVar (
|
||
|
InfFile,
|
||
|
Platform,
|
||
|
Application,
|
||
|
Section,
|
||
|
variable,
|
||
|
type,
|
||
|
updatedData,
|
||
|
updatedArgs,
|
||
|
InfStruct
|
||
|
);
|
||
|
|
||
|
} while (InfFindNextLine (InfStruct));
|
||
|
}
|
||
|
|
||
|
result = TRUE;
|
||
|
|
||
|
}
|
||
|
__finally {
|
||
|
GbFree (&dataBuf);
|
||
|
GbFree (&argBuf);
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
pParseAppEnvSection (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN HINF InfFile,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR Section
|
||
|
)
|
||
|
{
|
||
|
PCTSTR osSpecificSection;
|
||
|
BOOL b;
|
||
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
||
|
|
||
|
b = pParseAppEnvSectionWorker (Platform, &is, InfFile, Application, Section);
|
||
|
|
||
|
if (b) {
|
||
|
osSpecificSection = GetMostSpecificSection (&is, InfFile, Section);
|
||
|
if (osSpecificSection) {
|
||
|
b = pParseAppEnvSectionWorker (Platform, &is, InfFile, Application, osSpecificSection);
|
||
|
FreeText (osSpecificSection);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
InfCleanUpInfStruct (&is);
|
||
|
return b;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
pParseAppDetectSectionPart (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN PINFSTRUCT InfStruct,
|
||
|
IN HINF InfFile,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR Section
|
||
|
)
|
||
|
{
|
||
|
BOOL result = TRUE;
|
||
|
PCTSTR type;
|
||
|
PCTSTR data;
|
||
|
PCTSTR args;
|
||
|
GROWBUFFER dataBuf = INIT_GROWBUFFER;
|
||
|
GROWBUFFER argBuf = INIT_GROWBUFFER;
|
||
|
PCTSTR updatedData;
|
||
|
PCTSTR updatedArgs;
|
||
|
PTSTR buffer;
|
||
|
BOOL test;
|
||
|
|
||
|
//
|
||
|
// Section must not be on the stack
|
||
|
//
|
||
|
|
||
|
if (pCheckForRecursion (Section)) {
|
||
|
LOG ((LOG_ERROR, (PCSTR) MSG_DETECT_SECTION_RECURSION, Section));
|
||
|
// Assume successful detection
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Format is
|
||
|
//
|
||
|
// <type>, <data> [, <arguments>]
|
||
|
//
|
||
|
// <type> specifies one of the supported parse types (see parse.c),
|
||
|
// and may include environment variables specified in the
|
||
|
// app's [App.Environment] section.
|
||
|
//
|
||
|
// <data> is specific to <type>. If <data> begins with a !, then the
|
||
|
// existence of the object fails the detect test
|
||
|
//
|
||
|
// <arguments> specify qualifiers
|
||
|
//
|
||
|
|
||
|
__try {
|
||
|
|
||
|
buffer = AllocText (MAX_EXPANDED_STRING); // arbitrary big text buffer
|
||
|
|
||
|
if (InfFindFirstLine (InfFile, Section, NULL, InfStruct)) {
|
||
|
|
||
|
do {
|
||
|
|
||
|
if (IsmCheckCancel()) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
InfResetInfStruct (InfStruct);
|
||
|
|
||
|
//
|
||
|
// Obtain the line data
|
||
|
//
|
||
|
|
||
|
type = InfGetStringField (InfStruct, 0);
|
||
|
|
||
|
if (type && StringIMatch (type, TEXT("ProcessSection"))) {
|
||
|
data = InfGetStringField (InfStruct, 1);
|
||
|
if (data && *data) {
|
||
|
pPushSection (Section);
|
||
|
result = ParseAppDetectSection (Platform, InfFile, Application, data);
|
||
|
pPopSection (Section);
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type = InfGetStringField (InfStruct, 1);
|
||
|
data = InfGetStringField (InfStruct, 2);
|
||
|
args = InfGetMultiSzField (InfStruct, 3);
|
||
|
|
||
|
if (!type || !data) {
|
||
|
LOG ((LOG_WARNING, (PCSTR) MSG_GARBAGE_LINE_IN_INF, Section));
|
||
|
InfLogContext (LOG_WARNING, InfFile, InfStruct);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Update all environment variables in data and args
|
||
|
//
|
||
|
|
||
|
updatedData = pProcessArgEnvironmentVars (
|
||
|
PLATFORM_SOURCE,
|
||
|
Application,
|
||
|
data,
|
||
|
FALSE,
|
||
|
&dataBuf
|
||
|
);
|
||
|
|
||
|
if (args && *args) {
|
||
|
updatedArgs = pProcessArgEnvironmentVars (
|
||
|
PLATFORM_SOURCE,
|
||
|
Application,
|
||
|
args,
|
||
|
TRUE,
|
||
|
&argBuf
|
||
|
);
|
||
|
} else {
|
||
|
updatedArgs = NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Now try to obtain the data
|
||
|
//
|
||
|
|
||
|
if (pGetDataFromObjectSpec (
|
||
|
Platform,
|
||
|
Application,
|
||
|
type,
|
||
|
updatedData,
|
||
|
updatedArgs,
|
||
|
NULL,
|
||
|
0,
|
||
|
&test
|
||
|
)) {
|
||
|
|
||
|
if (test) {
|
||
|
LOG ((LOG_INFORMATION, (PCSTR) MSG_DETECT_INFO, type, updatedData));
|
||
|
} else {
|
||
|
LOG ((LOG_INFORMATION, (PCSTR) MSG_NOT_DETECT_INFO, type, updatedData));
|
||
|
result = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
} else {
|
||
|
result = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} while (result && InfFindNextLine (InfStruct));
|
||
|
}
|
||
|
}
|
||
|
__finally {
|
||
|
FreeText (buffer);
|
||
|
GbFree (&dataBuf);
|
||
|
GbFree (&argBuf);
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
pParseOsAppDetectSection (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN PINFSTRUCT InfStruct,
|
||
|
IN HINF InfFile,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR Section
|
||
|
)
|
||
|
{
|
||
|
PCTSTR osSpecificSection;
|
||
|
BOOL b;
|
||
|
|
||
|
b = pParseAppDetectSectionPart (Platform, InfStruct, InfFile, Application, Section);
|
||
|
|
||
|
if (b) {
|
||
|
osSpecificSection = GetMostSpecificSection (InfStruct, InfFile, Section);
|
||
|
if (osSpecificSection) {
|
||
|
b = pParseAppDetectSectionPart (Platform, InfStruct, InfFile, Application, osSpecificSection);
|
||
|
FreeText (osSpecificSection);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return b;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
ParseAppDetectSection (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN HINF InfFile,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR Section
|
||
|
)
|
||
|
{
|
||
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
||
|
TCHAR number[32];
|
||
|
PCTSTR orSection;
|
||
|
UINT count;
|
||
|
BOOL orSectionProcessed = FALSE;
|
||
|
BOOL detected = FALSE;
|
||
|
BOOL done = FALSE;
|
||
|
|
||
|
//
|
||
|
// Process all "or" sections
|
||
|
//
|
||
|
|
||
|
count = 0;
|
||
|
|
||
|
do {
|
||
|
|
||
|
count++;
|
||
|
wsprintf (number, TEXT(".%u"), count);
|
||
|
|
||
|
orSection = JoinText (Section, number);
|
||
|
|
||
|
if (orSection) {
|
||
|
|
||
|
if (InfFindFirstLine (InfFile, orSection, NULL, &is)) {
|
||
|
|
||
|
orSectionProcessed = TRUE;
|
||
|
|
||
|
if (pParseOsAppDetectSection (Platform, &is, InfFile, Application, orSection)) {
|
||
|
detected = TRUE;
|
||
|
done = TRUE;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
done = TRUE;
|
||
|
}
|
||
|
|
||
|
FreeText (orSection);
|
||
|
INVALID_POINTER (orSection);
|
||
|
|
||
|
} else {
|
||
|
done = TRUE;
|
||
|
}
|
||
|
|
||
|
} while (!done);
|
||
|
|
||
|
//
|
||
|
// If no "or" sections, process Section itself
|
||
|
//
|
||
|
|
||
|
if (!orSectionProcessed) {
|
||
|
|
||
|
detected = pParseOsAppDetectSection (Platform, &is, InfFile, Application, Section);
|
||
|
}
|
||
|
|
||
|
InfCleanUpInfStruct (&is);
|
||
|
|
||
|
return detected;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
pDoesAppSectionExists (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN HINF InfFile,
|
||
|
IN PCTSTR Application
|
||
|
)
|
||
|
{
|
||
|
PCTSTR osSpecificSection;
|
||
|
BOOL b;
|
||
|
INFSTRUCT is = INITINFSTRUCT_GROWBUFFER;
|
||
|
|
||
|
b = InfFindFirstLine (InfFile, Application, NULL, &is);
|
||
|
|
||
|
if (!b) {
|
||
|
osSpecificSection = GetMostSpecificSection (&is, InfFile, Application);
|
||
|
|
||
|
if (osSpecificSection) {
|
||
|
b = TRUE;
|
||
|
FreeText (osSpecificSection);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
InfCleanUpInfStruct (&is);
|
||
|
return b;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
pParseOneDestInstruction (
|
||
|
IN HINF InfHandle,
|
||
|
IN PCTSTR Type,
|
||
|
IN PCTSTR SectionMultiSz,
|
||
|
IN PINFSTRUCT InfStruct,
|
||
|
IN PCTSTR Application OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
MULTISZ_ENUM e;
|
||
|
BOOL result = TRUE;
|
||
|
|
||
|
//
|
||
|
// First thing: look for nested sections
|
||
|
//
|
||
|
if (StringIMatch (Type, TEXT("ProcessSection"))) {
|
||
|
if (EnumFirstMultiSz (&e, SectionMultiSz)) {
|
||
|
do {
|
||
|
result = result & ParseOneApplication (
|
||
|
PLATFORM_DESTINATION,
|
||
|
InfHandle,
|
||
|
Application,
|
||
|
FALSE,
|
||
|
0,
|
||
|
e.CurrentString,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL
|
||
|
);
|
||
|
} while (EnumNextMultiSz (&e));
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
pParseDestInfInstructionsWorker (
|
||
|
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 = pParseOneDestInstruction (InfHandle, type, sections, InfStruct, Application);
|
||
|
|
||
|
} while (result && InfFindNextLine (InfStruct));
|
||
|
}
|
||
|
|
||
|
InfCleanUpInfStruct (InfStruct);
|
||
|
|
||
|
GbFree (&multiSz);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
ParseDestInfInstructions (
|
||
|
IN HINF InfHandle,
|
||
|
IN PCTSTR Application, OPTIONAL
|
||
|
IN PCTSTR Section
|
||
|
)
|
||
|
{
|
||
|
PCTSTR osSpecificSection;
|
||
|
BOOL b;
|
||
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
||
|
PTSTR instrSection;
|
||
|
|
||
|
b = pParseDestInfInstructionsWorker (&is, InfHandle, Application, Section);
|
||
|
|
||
|
if (b) {
|
||
|
osSpecificSection = GetMostSpecificSection (&is, InfHandle, Section);
|
||
|
|
||
|
if (osSpecificSection) {
|
||
|
b = pParseDestInfInstructionsWorker (&is, InfHandle, Application, osSpecificSection);
|
||
|
FreeText (osSpecificSection);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
InfCleanUpInfStruct (&is);
|
||
|
|
||
|
return b;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
ParseOneApplication (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN HINF Inf,
|
||
|
IN PCTSTR Section,
|
||
|
IN BOOL PreParse,
|
||
|
IN UINT MasterGroup,
|
||
|
IN PCTSTR Application,
|
||
|
IN PCTSTR LocSection,
|
||
|
IN PCTSTR AliasType,
|
||
|
IN PCTSTR MultiSz
|
||
|
)
|
||
|
{
|
||
|
PCTSTR appSection = NULL;
|
||
|
BOOL detected = FALSE;
|
||
|
PCTSTR appEnvVar;
|
||
|
PCTSTR decoratedSection;
|
||
|
BOOL componentized = FALSE;
|
||
|
BOOL executeSection = FALSE;
|
||
|
BOOL markAsPreferred;
|
||
|
|
||
|
__try {
|
||
|
if (LocSection || AliasType) {
|
||
|
componentized = TRUE;
|
||
|
} else {
|
||
|
componentized = FALSE;
|
||
|
}
|
||
|
|
||
|
if (!Application) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
decoratedSection = JoinText (TEXT("$"), Application);
|
||
|
|
||
|
if (Platform == PLATFORM_SOURCE) {
|
||
|
|
||
|
//
|
||
|
// locSection exists for all applications we want to send to
|
||
|
// the UI for approval. PreParse builds the list of apps we
|
||
|
// send to the UI. Only do detection if this is PreParsing
|
||
|
// localized apps, or not preparsing non-localized apps
|
||
|
//
|
||
|
|
||
|
if ((PreParse && componentized) ||
|
||
|
(!PreParse && !componentized)
|
||
|
) {
|
||
|
|
||
|
appSection = JoinText (Application, TEXT(".Environment"));
|
||
|
if (!pParseAppEnvSection (PLATFORM_SOURCE, Inf, Application, appSection)) {
|
||
|
__leave;
|
||
|
}
|
||
|
FreeText (appSection);
|
||
|
appSection = NULL;
|
||
|
GlFree (&g_SectionStack);
|
||
|
|
||
|
appSection = JoinText (Application, TEXT(".Detect"));
|
||
|
detected = ParseAppDetectSection (Platform, Inf, Application, appSection);
|
||
|
FreeText (appSection);
|
||
|
appSection = NULL;
|
||
|
GlFree (&g_SectionStack);
|
||
|
|
||
|
if (!detected && pDoesAppSectionExists (Platform, Inf, Application)) {
|
||
|
detected = TRUE;
|
||
|
} else if (!detected) {
|
||
|
LOG ((LOG_INFORMATION, (PCSTR) MSG_APP_NOT_DETECT_INFO, Application));
|
||
|
} else {
|
||
|
LOG ((LOG_INFORMATION, (PCSTR) MSG_APP_DETECT_INFO, Application));
|
||
|
appEnvVar = JoinTextEx (NULL, Section, Application, TEXT("."), 0, NULL);
|
||
|
IsmSetEnvironmentFlag (PLATFORM_SOURCE, NULL, appEnvVar);
|
||
|
FreeText (appEnvVar);
|
||
|
}
|
||
|
|
||
|
if (componentized && detected) {
|
||
|
|
||
|
//
|
||
|
// we should put it in the selection list
|
||
|
//
|
||
|
|
||
|
if (LocSection) {
|
||
|
IsmAddComponentAlias (
|
||
|
decoratedSection,
|
||
|
MasterGroup,
|
||
|
LocSection,
|
||
|
COMPONENT_NAME,
|
||
|
FALSE
|
||
|
);
|
||
|
|
||
|
IsmSelectPreferredAlias (decoratedSection, LocSection, COMPONENT_NAME);
|
||
|
}
|
||
|
|
||
|
if (AliasType) {
|
||
|
markAsPreferred = (LocSection == NULL);
|
||
|
pAddFilesAndFoldersComponentOrSection (
|
||
|
Inf,
|
||
|
decoratedSection,
|
||
|
AliasType,
|
||
|
MultiSz,
|
||
|
MasterGroup,
|
||
|
&markAsPreferred
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
executeSection = (!PreParse) && detected;
|
||
|
} else {
|
||
|
executeSection = (!PreParse) && IsmIsComponentSelected (decoratedSection, 0);
|
||
|
}
|
||
|
|
||
|
// Now actually load the application instructions if it's not preparsing
|
||
|
if (executeSection) {
|
||
|
|
||
|
appSection = DuplicateText (Application);
|
||
|
if (!ParseInfInstructions (Inf, Application, appSection)) {
|
||
|
__leave;
|
||
|
}
|
||
|
FreeText (appSection);
|
||
|
appSection = NULL;
|
||
|
appEnvVar = JoinTextEx (NULL, Section, Application, TEXT("."), 0, NULL);
|
||
|
if (IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, appEnvVar)) {
|
||
|
appSection = JoinText (Application, TEXT(".Instructions"));
|
||
|
if (!ParseInfInstructions (Inf, Application, appSection)) {
|
||
|
__leave;
|
||
|
}
|
||
|
FreeText (appSection);
|
||
|
appSection = NULL;
|
||
|
}
|
||
|
FreeText (appEnvVar);
|
||
|
} else {
|
||
|
if (!PreParse) {
|
||
|
appEnvVar = JoinTextEx (NULL, Section, Application, TEXT("."), 0, NULL);
|
||
|
IsmDeleteEnvironmentVariable (PLATFORM_SOURCE, NULL, appEnvVar);
|
||
|
FreeText (appEnvVar);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
MYASSERT (Platform == PLATFORM_DESTINATION);
|
||
|
|
||
|
appSection = JoinText (Application, TEXT(".Environment"));
|
||
|
if (!pParseAppEnvSection (PLATFORM_DESTINATION, Inf, Application, appSection)) {
|
||
|
__leave;
|
||
|
}
|
||
|
FreeText (appSection);
|
||
|
appSection = NULL;
|
||
|
GlFree (&g_SectionStack);
|
||
|
|
||
|
appEnvVar = JoinTextEx (NULL, Section, Application, TEXT("."), 0, NULL);
|
||
|
if (IsmIsEnvironmentFlagSet (PLATFORM_SOURCE, NULL, appEnvVar)) {
|
||
|
appSection = DuplicateText (Application);
|
||
|
if (!ParseDestInfInstructions (Inf, Application, appSection)) {
|
||
|
__leave;
|
||
|
}
|
||
|
FreeText (appSection);
|
||
|
appSection = NULL;
|
||
|
appSection = JoinText (Application, TEXT(".Instructions"));
|
||
|
if (!ParseDestInfInstructions (Inf, Application, appSection)) {
|
||
|
__leave;
|
||
|
}
|
||
|
FreeText (appSection);
|
||
|
appSection = NULL;
|
||
|
}
|
||
|
FreeText (appEnvVar);
|
||
|
}
|
||
|
|
||
|
FreeText (decoratedSection);
|
||
|
decoratedSection = NULL;
|
||
|
}
|
||
|
__finally {
|
||
|
if (appSection) {
|
||
|
FreeText (appSection);
|
||
|
appSection = NULL;
|
||
|
}
|
||
|
GlFree (&g_SectionStack);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
ParseApplications (
|
||
|
IN MIG_PLATFORMTYPEID Platform,
|
||
|
IN HINF Inf,
|
||
|
IN PCTSTR Section,
|
||
|
IN BOOL PreParse,
|
||
|
IN UINT MasterGroup
|
||
|
)
|
||
|
{
|
||
|
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
|
||
|
PCTSTR application;
|
||
|
BOOL result = FALSE;
|
||
|
PCTSTR locSection;
|
||
|
PCTSTR aliasType;
|
||
|
PCTSTR multiSz;
|
||
|
|
||
|
__try {
|
||
|
if (InfFindFirstLine (Inf, Section, NULL, &is)) {
|
||
|
do {
|
||
|
|
||
|
if (IsmCheckCancel()) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
InfResetInfStruct (&is);
|
||
|
|
||
|
application = InfGetStringField (&is, 1);
|
||
|
locSection = InfGetStringField (&is, 2);
|
||
|
aliasType = InfGetStringField (&is, 3);
|
||
|
multiSz = InfGetMultiSzField (&is, 4);
|
||
|
|
||
|
if (application && !application[0]) {
|
||
|
application = NULL;
|
||
|
}
|
||
|
|
||
|
if (locSection && !locSection[0]) {
|
||
|
locSection = NULL;
|
||
|
}
|
||
|
|
||
|
if (aliasType && !aliasType[0]) {
|
||
|
aliasType = NULL;
|
||
|
}
|
||
|
|
||
|
if (multiSz && !multiSz[0]) {
|
||
|
multiSz = NULL;
|
||
|
}
|
||
|
|
||
|
if (!aliasType || !multiSz) {
|
||
|
aliasType = NULL;
|
||
|
multiSz = NULL;
|
||
|
}
|
||
|
|
||
|
ParseOneApplication (
|
||
|
Platform,
|
||
|
Inf,
|
||
|
Section,
|
||
|
PreParse,
|
||
|
MasterGroup,
|
||
|
application,
|
||
|
locSection,
|
||
|
aliasType,
|
||
|
multiSz
|
||
|
);
|
||
|
|
||
|
} while (InfFindNextLine (&is));
|
||
|
|
||
|
}
|
||
|
|
||
|
result = TRUE;
|
||
|
|
||
|
} __finally {
|
||
|
InfCleanUpInfStruct (&is);
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
ProcessFilesAndFolders (
|
||
|
IN HINF InfHandle,
|
||
|
IN PCTSTR Section,
|
||
|
IN BOOL PreParse
|
||
|
)
|
||
|
{
|
||
|
BOOL b = TRUE;
|
||
|
BOOL markAsPreferred = TRUE;
|
||
|
|
||
|
if (PreParse) {
|
||
|
b = pAddFilesAndFoldersSection (InfHandle, Section, MASTERGROUP_FILES_AND_FOLDERS, FALSE, &markAsPreferred);
|
||
|
}
|
||
|
|
||
|
return b;
|
||
|
}
|
||
|
|