|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
parse.c
Abstract:
Implements parsing of script entries.
Author:
Jim Schmidt (jimschm) 02-Jun-2000
Revision History:
<alias> <date> <comments>
--*/
//
// Includes
//
#include "pch.h"
#include "v1p.h"
#define DBG_V1 "v1"
//
// Strings
//
// None
//
// Constants
//
// None
//
// Macros
//
// None
//
// Types
//
typedef BOOL (SCRIPTTYPE_ALLOC_FN)( IN OUT PATTRIB_DATA AttribData CALLER_INITIALIZED ); typedef SCRIPTTYPE_ALLOC_FN *PSCRIPTTYPE_ALLOC_FN;
typedef BOOL (SCRIPTTYPE_FREE_FN)( IN PATTRIB_DATA AttribData ZEROED ); typedef SCRIPTTYPE_FREE_FN *PSCRIPTTYPE_FREE_FN;
typedef struct { PCTSTR Tag; PSCRIPTTYPE_ALLOC_FN AllocFunction; PSCRIPTTYPE_FREE_FN FreeFunction; } TAG_TO_SCRIPTTYPEFN, *PTAG_TO_SCRIPTTYPEFN;
//
// Globals
//
// None
//
// Macro expansion list
//
#define SCRIPT_TYPES \
DEFMAC(Registry, pAllocRegistryScriptType, pFreeIsmObjectScriptType) \ DEFMAC(File, pAllocFileScriptType, pFreeIsmObjectScriptType) \ DEFMAC(Directory, pAllocDirectoryScriptType, pFreeIsmObjectScriptType) \ DEFMAC(Text, pAllocTextScriptType, pFreeTextScriptType) \ DEFMAC(System, pAllocSystemScriptType, pFreeSystemScriptType) \ DEFMAC(INIFile, pAllocIniFileScriptType, pFreeIniFileScriptType) \
//
// Private function prototypes
//
// None
//
// Macro expansion definition
//
#define DEFMAC(tag,fnA,fnF) SCRIPTTYPE_ALLOC_FN fnA; SCRIPTTYPE_FREE_FN fnF;
SCRIPT_TYPES
#undef DEFMAC
#define DEFMAC(tag,fnA,fnF) {TEXT(#tag),fnA,fnF},
TAG_TO_SCRIPTTYPEFN g_TagToScriptTypeFn[] = { SCRIPT_TYPES {NULL, NULL, NULL} };
#undef DEFMAC
//
// Code
//
MIG_OBJECTSTRINGHANDLE MakeRegExBase ( IN PCTSTR Node, IN PCTSTR Leaf ) { MIG_OBJECTSTRINGHANDLE objectBase = NULL; PTSTR ptr; PTSTR nodeCopy = NULL; PCTSTR nodeBase = NULL; BOOL useLeaf = FALSE;
if (Node) { ptr = _tcschr (Node, TEXT('\\')); if (!ptr) { return NULL; }
if (StringIPrefix (Node, TEXT("HKR\\"))) { nodeCopy = JoinText (TEXT("HKCU"), ptr); } else { nodeCopy = DuplicateText (Node); }
if (nodeCopy) { nodeBase = GetPatternBase (nodeCopy);
if (nodeBase) { if (Leaf && !_tcschr (Leaf, TEXT('*'))) { useLeaf = TRUE; } objectBase = IsmCreateObjectHandle (nodeBase, useLeaf ? Leaf : NULL); FreePathString (nodeBase); } FreeText (nodeCopy); } }
return objectBase; }
MIG_OBJECTSTRINGHANDLE CreatePatternFromNodeLeaf ( IN PCTSTR Node, IN PCTSTR Leaf ) { MIG_OBJECTSTRINGHANDLE pattern; MIG_SEGMENTS nodeSegment; MIG_SEGMENTS leafSegment; PTSTR fixedNode = NULL;
// let's do some trick for registry objects that start with HKR
if (Node && (StringIMatch (Node, S_HKR) || StringIMatchTcharCount (Node, TEXT("HKR\\"), 4) ) ) { fixedNode = JoinText (S_HKCU, Node + 3); nodeSegment.Segment = fixedNode; } else { nodeSegment.Segment = Node; }
nodeSegment.IsPattern = TRUE; leafSegment.Segment = Leaf; leafSegment.IsPattern = TRUE;
pattern = IsmCreateObjectPattern (&nodeSegment, Node ? 1 : 0, &leafSegment, Leaf ? 1 : 0);
FreeText (fixedNode);
return pattern; }
MIG_OBJECTSTRINGHANDLE TurnRegStringIntoHandle ( IN PCTSTR String, IN BOOL Pattern, OUT PBOOL HadLeaf OPTIONAL )
/*++
Routine Description:
TurnRegStringIntoHandle converts the script's reg syntax into a cobra object.
Arguments:
String - Specifies the registry key and value in the script syntax. The string must be in the following format:
<root>\<key>\* [<value>]
Each part is optional.
<root> specifies HKCU, HKR, HKLM or HKCC.
<key> specifies a subkey (such as Software\Microsoft\Windows)
* specifies all subkeys. If <value> is not specified, then all values and subvalues are also included.
<value> specifies a specific value name
Pattern - Specifies TRUE if the registry string can contain a pattern, or FALSE if it cannot.
HadLeaf - Receives TRUE if String contains a leaf specification, FALSE otherwise
Return Value:
A handle to a cobra object string, or NULL if parsing failed.
--*/
{ PTSTR strCopy; PTSTR p; PTSTR value = NULL; PTSTR valueEnd; PTSTR key; PTSTR keyEnd; BOOL tree = FALSE; MIG_SEGMENTS nodeSegment[2]; UINT nodeCount; MIG_SEGMENTS leafSegment; UINT leafCount; MIG_OBJECTSTRINGHANDLE handle; BOOL noSubKeys; BOOL noWildcardLeaf; PCTSTR fixedKey = NULL;
MYASSERT (String); if (!String) { return NULL; }
if (Pattern) { noSubKeys = FALSE; noWildcardLeaf = FALSE; } else { noSubKeys = TRUE; noWildcardLeaf = TRUE; }
//
// Inbound syntax is key\* [value]
//
strCopy = DuplicateText (String); if (!strCopy) { return NULL; }
key = (PTSTR) SkipSpace (strCopy); if (!key) { FreeText (strCopy); return NULL; }
if (*key == TEXT('[')) { //
// This is a value-only case
//
value = _tcsinc (key); key = NULL;
} else { //
// This is a key-value case, or key-only case
//
p = _tcschr (key, TEXT('['));
if (p) { //
// Save start of value
//
value = _tcsinc (p); } else { //
// No value
//
p = GetEndOfString (key); }
keyEnd = p;
//
// Find the true end of the key
//
p = _tcsdec2 (key, p); MYASSERT (p); // assert this is not a value-only case
p = (PTSTR) SkipSpaceR (key, p);
if (p) { keyEnd = _tcsinc (p); }
//
// Test for \* at the end
//
p = _tcsdec2 (key, keyEnd); MYASSERT (p);
if (p && _tcsnextc (p) == TEXT('*')) { p = _tcsdec2 (key, p); if (p && _tcsnextc (p) == TEXT('\\')) { keyEnd = p; tree = (noSubKeys == FALSE); } }
//
// Trim the key
//
*keyEnd = 0; }
//
// Parse the value
//
if (value) { value = (PTSTR) SkipSpace (value); valueEnd = _tcschr (value, TEXT(']'));
if (!valueEnd) { LOG ((LOG_ERROR, (PCSTR) MSG_INF_SYNTAX_ERROR, String)); value = NULL; } else { //
// Trim the space at the end of value
//
p = _tcsdec2 (value, valueEnd); if (p) { p = (PTSTR) SkipSpaceR (value, p); if (p) { valueEnd = _tcsinc (p); } }
*valueEnd = 0; } }
//
// Create parsed pattern. Start with the node.
//
nodeSegment[0].Segment = key; nodeSegment[0].IsPattern = FALSE;
nodeSegment[1].Segment = TEXT("\\*"); nodeSegment[1].IsPattern = TRUE;
if (tree) { nodeCount = 2; } else { nodeCount = 1; }
//
// compute the leaf
//
if (value) { leafSegment.Segment = value; leafSegment.IsPattern = FALSE; } else { leafSegment.Segment = TEXT("*"); leafSegment.IsPattern = TRUE; }
if (noWildcardLeaf && !value) { leafCount = 0; } else { leafCount = 1; }
if (nodeCount && key && (StringIMatch (key, S_HKR) || StringIMatchTcharCount (key, TEXT("HKR\\"), 4) ) ) { fixedKey = JoinText (S_HKCU, key + 3); nodeSegment[0].Segment = fixedKey; }
handle = IsmCreateObjectPattern ( nodeSegment, nodeCount, leafCount?&leafSegment:NULL, leafCount );
FreeText (strCopy); FreeText (fixedKey);
if (HadLeaf) { *HadLeaf = (value != NULL); }
return handle; }
PTSTR pCopyToDest ( IN PTSTR Destination, OPTIONAL IN CHARTYPE Char, IN PUINT CharNr ) { UINT len = 1;
#ifdef UNICODE
if (Destination) { *Destination++ = Char; }
(*CharNr) ++; return Destination;
#else
if (IsCharLeadByte ((INT) Char)) { len ++; }
if (Destination) { CopyMemory (Destination, &Char, len); Destination += len; }
(*CharNr) += len; return Destination;
#endif
}
// 1->? (if node, no \ or ., if leaf, no .), 2->* (if node, no \ or ., if leaf, no .) 3->* (no \) 4->* (unlimited)
UINT pGetMode ( IN PCTSTR Source, IN BOOL NodePattern, IN BOOL PatternAfterWack, IN BOOL FirstChar ) { UINT ch; BOOL end = FALSE; UINT mode = 0;
ch = _tcsnextc (Source);
while (ch) {
switch (ch) {
case TEXT('?'): if (mode < 1) { mode = 1; } break;
case TEXT('*'): if (NodePattern) { if (mode < 3) { mode = 3; } } else { if (mode < 4) { mode = 4; } } break;
case TEXT('\\'): if (NodePattern) { if (mode < 2) { mode = 2; } } end = TRUE; break;
case TEXT('.'): if (mode < 2) { mode = 2; } end = TRUE; break;
default: end = TRUE; }
if (end) { break; }
Source = _tcsinc (Source); ch = _tcsnextc (Source); }
if (!ch) { if ((PatternAfterWack || NodePattern) && (mode == 3)) { mode = 4; }
if (mode < 2) { mode = 2; } }
if (FirstChar && (mode == 3)) { mode = 4; }
return mode; }
BOOL pCopyPatternEx ( IN UINT Mode, IN PCTSTR *Source, IN PTSTR *Destination, IN PUINT CharNr, IN BOOL NodePattern ) { CHARTYPE ch; BOOL end = FALSE; INT numChars = 0; UINT chars; TCHAR buffer [MAX_PATH] = TEXT("");
ch = (CHARTYPE) _tcsnextc (*Source);
while (ch) {
switch (ch) {
case TEXT('*'): if (Mode == 1) { end = TRUE; break; }
numChars = -1; break;
case TEXT('?'): if (numChars >= 0) { numChars ++; }
break;
default: end = TRUE; break; }
if (end) { break; }
*Source = _tcsinc (*Source); ch = (CHARTYPE) _tcsnextc (*Source); }
// 1->? (if node, no \ or ., if leaf, no .), 2->* (if node, no \ or ., if leaf, no .) 3->* (no \) 4->* (unlimited)
switch (Mode) {
case 1: if (NodePattern) { if (numChars > 0) { wsprintf (buffer, TEXT("?[%d:!(\\,.)]"), numChars); } else { wsprintf (buffer, TEXT("?[!(\\,.)]")); } } else { if (numChars > 0) { wsprintf (buffer, TEXT("?[%d:!(.)]"), numChars); } else { wsprintf (buffer, TEXT("?[!(.)]")); } } break;
case 2: if (NodePattern) { if (numChars > 0) { wsprintf (buffer, TEXT("*[%d:!(\\,.)]"), numChars); } else { wsprintf (buffer, TEXT("*[!(\\,.)]")); } } else { if (numChars > 0) { wsprintf (buffer, TEXT("*[%d:!(.)]"), numChars); } else { wsprintf (buffer, TEXT("*[!(.)]")); } } break;
case 3: if (numChars > 0) { wsprintf (buffer, TEXT("*[%d:!(\\)]"), numChars); } else { wsprintf (buffer, TEXT("*[!(\\)]")); } break;
case 4: if (numChars > 0) { wsprintf (buffer, TEXT("*[%d:]"), numChars); } else { wsprintf (buffer, TEXT("*[]")); } break;
default: MYASSERT (FALSE); }
chars = TcharCount (buffer); if (CharNr) { *CharNr += chars; }
if (Destination && *Destination) { StringCopy (*Destination, buffer); *Destination += chars; }
return TRUE; }
BOOL pCopyPattern ( IN PCTSTR *Source, IN PTSTR *Destination, IN PUINT CharNr, IN BOOL NodePattern, IN BOOL PatternAfterWack, IN BOOL FirstChar ) { // 1->? (if node, no \ or ., if leaf, no .), 2->* (if node, no \ or ., if leaf, no .) 3->* (no \) 4->* (unlimited)
UINT mode = 0; PTSTR result = NULL;
mode = pGetMode (*Source, NodePattern, PatternAfterWack, FirstChar);
return pCopyPatternEx (mode, Source, Destination, CharNr, NodePattern); }
BOOL pFixPattern ( IN PCTSTR Source, OUT PTSTR Destination, OPTIONAL OUT PUINT DestinationChars, OPTIONAL IN BOOL PatternsNotAllowed, IN BOOL TruncateAtPattern, IN BOOL NodePattern ) { UINT chars = 1; UINT lastChars = 0; PTSTR lastWack = NULL; BOOL end = FALSE; BOOL result = TRUE; BOOL patternAfterWack = FALSE; BOOL firstChar = TRUE; CHARTYPE ch;
if (Destination) { *Destination = 0; }
ch = (CHARTYPE) _tcsnextc (Source); while (ch) {
switch (ch) { case TEXT('*'): case TEXT('?'): if (TruncateAtPattern) { if (lastWack) { *lastWack = 0; chars = lastChars; } end = TRUE; } else if (PatternsNotAllowed) { result = FALSE; Destination = pCopyToDest (Destination, TEXT('^'), &chars); Destination = pCopyToDest (Destination, ch, &chars); Source = _tcsinc (Source); } else { if (lastWack && (_tcsinc (lastWack) == Destination)) { patternAfterWack = TRUE; } else { patternAfterWack = FALSE; } pCopyPattern (&Source, Destination?&Destination:NULL, &chars, NodePattern, patternAfterWack, firstChar); } break;
case TEXT('\020'): case TEXT('<'): case TEXT('>'): case TEXT(','): case TEXT('^'): Destination = pCopyToDest (Destination, TEXT('^'), &chars); Destination = pCopyToDest (Destination, ch, &chars); Source = _tcsinc (Source); break;
case TEXT('\\'): if (NodePattern) { lastWack = Destination; lastChars = chars; }
Destination = pCopyToDest (Destination, ch, &chars); Source = _tcsinc (Source); break;
case TEXT('.'): if (!NodePattern) { lastWack = Destination; lastChars = chars; }
Destination = pCopyToDest (Destination, ch, &chars); Source = _tcsinc (Source); break;
default: Destination = pCopyToDest (Destination, ch, &chars); Source = _tcsinc (Source); break; }
firstChar = FALSE;
if (end) { break; }
ch = (CHARTYPE) _tcsnextc (Source); }
if (Destination) { *Destination = 0; }
if (DestinationChars) { *DestinationChars = chars; }
return result; }
MIG_OBJECTSTRINGHANDLE TurnFileStringIntoHandle ( IN PCTSTR String, IN DWORD Flags )
/*++
Routine Description:
TurnFileStringIntoHandle converts a file specification from the script syntax into a cobra object.
Arguments:
String - Specifies the file string in the script syntax. The string must be in the following format:
<directory>\<file>
Both parts are optional. The Flags member indicates how String is parsed.
Flags - Specifies zero or more of the following flags:
PFF_NO_PATTERNS_ALLOWED - String cannot contain any wildcard characters.
PFF_COMPUTE_BASE - Returns the directory portion of the string, and truncates the directory at the first wildcard if necessary. Truncation is done at the backslashes only.
PFF_NO_SUBDIR_PATTERN - Do not include a trailing \*, even if it was specified in String.
PFF_NO_LEAF_PATTERN - Do not include a * for the leaf when String does not contain a file name. If a file name is specified, include it.
PFF_PATTERN_IS_DIR - String does not specify a file name. It is a directory only. The leaf portion of the object string will be a *.
PFF_NO_LEAF_AT_ALL - Will return an object string that has a node only, and no leaf specified at all.
Return Value:
A cobra object handle, or NULL if conversion failed.
--*/
{ PTSTR p; PTSTR fileCopy = NULL; MIG_SEGMENTS nodeSegment[2]; MIG_SEGMENTS leafSegment; MIG_OBJECTSTRINGHANDLE result = NULL; BOOL tree = FALSE; PTSTR file = NULL; UINT nodeCount; UINT leafCount; UINT charsInPattern; BOOL noPatternsAllowed; BOOL computeBaseNode; BOOL noSubDirPattern; BOOL noLeafPattern; BOOL forceLeafToStar; PCTSTR node; PCTSTR leaf = NULL; PTSTR fixedNode = NULL; PTSTR fixedLeaf = NULL; PTSTR tempCopy; BOOL patternError = FALSE;
noPatternsAllowed = (Flags & PFF_NO_PATTERNS_ALLOWED) == PFF_NO_PATTERNS_ALLOWED; computeBaseNode = (Flags & PFF_COMPUTE_BASE) == PFF_COMPUTE_BASE; noSubDirPattern = (Flags & PFF_NO_SUBDIR_PATTERN) == PFF_NO_SUBDIR_PATTERN; noLeafPattern = (Flags & PFF_NO_LEAF_PATTERN) == PFF_NO_LEAF_PATTERN; forceLeafToStar = (Flags & PFF_PATTERN_IS_DIR) == PFF_PATTERN_IS_DIR;
//
// Divide pattern into node and leaf
//
tempCopy = DuplicateText (SkipSpace (String)); p = (PTSTR) SkipSpaceR (tempCopy, NULL); if (p) { p = _tcsinc (p); *p = 0; }
node = tempCopy;
if (!forceLeafToStar) { p = (PTSTR) FindLastWack (tempCopy);
if (p) {
leaf = SkipSpace (p + 1); *p = 0;
p = (PTSTR) SkipSpaceR (tempCopy, NULL); if (p) { p = _tcsinc (p); *p = 0; }
} else { if (!_tcschr (tempCopy, TEXT(':'))) { node = NULL; leaf = tempCopy; } } }
//
// Convert all ? wildcard chars to be compatibile with NT's file system
// Escape all [ characters that follow wildcards
//
if (node) {
p = (PTSTR) GetEndOfString (node); p = _tcsdec2 (node, p);
if (p) { if (_tcsnextc (p) == TEXT('*')) { tree = TRUE;
p = _tcsdec2 (node, p); if (p && _tcsnextc (p) == TEXT('\\')) { *p = 0; } else { tree = FALSE; } } }
if (!pFixPattern ( node, NULL, &charsInPattern, noPatternsAllowed, computeBaseNode, TRUE )) { patternError = TRUE; }
if (charsInPattern) { fixedNode = AllocText (charsInPattern + 1);
pFixPattern ( node, fixedNode, NULL, noPatternsAllowed, computeBaseNode, TRUE ); } }
if (leaf && !computeBaseNode) {
if (!pFixPattern ( leaf, NULL, &charsInPattern, noPatternsAllowed, FALSE, FALSE )) { patternError = TRUE; }
if (charsInPattern) { fixedLeaf = AllocText (charsInPattern + 1);
pFixPattern ( leaf, fixedLeaf, NULL, noPatternsAllowed, FALSE, FALSE ); } }
FreeText (tempCopy); INVALID_POINTER (tempCopy);
//
// Create the pattern string. Start by preparing the node segments.
//
nodeSegment[0].Segment = fixedNode; nodeSegment[0].IsPattern = TRUE; // normally FALSE, but because the pattern charset is
// exclusive of the valid filename charset, we allow
// patterns to be in the node
nodeSegment[1].Segment = TEXT("\\*"); nodeSegment[1].IsPattern = TRUE;
if (!fixedNode) { nodeCount = 0; } else if (!tree || noSubDirPattern || noPatternsAllowed) { nodeCount = 1; // just the node, not its subnodes
} else { nodeCount = 2; // the node and its subnodes
}
//
// Prepare the leaf segments. We want all leaves, a specific leaf, or
// no leaf at all.
//
leafSegment.Segment = fixedLeaf; leafSegment.IsPattern = TRUE; leafCount = 1;
MYASSERT (!forceLeafToStar || !fixedLeaf);
if (!fixedLeaf) { if (noLeafPattern || noPatternsAllowed) { leafCount = 0; } else { leafSegment.Segment = TEXT("*"); } }
if (nodeCount || leafCount) {
if ((fixedNode && *fixedNode) || (fixedLeaf && *fixedLeaf)) { result = IsmCreateObjectPattern ( nodeCount ? nodeSegment : NULL, nodeCount, leafCount ? &leafSegment : NULL, leafCount ); } }
FreeText (fixedNode); FreeText (fixedLeaf);
return result; }
MIG_OBJECTSTRINGHANDLE TurnIniSpecIntoHandle ( IN PCTSTR IniFile, IN PCTSTR Section, IN PCTSTR Key, IN BOOL NodePatternsAllowed, IN BOOL LeafPatternsAllowed )
/*++
Routine Description:
TurnIniSpecIntoHandle converts a ini file specification from the script syntax into a cobra object.
Arguments:
IniFile- Specifies the ini file in the script syntax. The string must be a full INI file specification
Section- Specifies the full section or the section pattern
Key - Specifies the full key or the key pattern
PatternsAllowed - if not, the function will compute the base object
Return Value:
A cobra object handle, or NULL if conversion failed.
--*/
{ UINT charsInPattern = 0; PTSTR iniNode = NULL; PTSTR iniLeaf = NULL; PTSTR fixedIniNode = NULL; PTSTR fixedIniLeaf = NULL; PTSTR fixedSect = NULL; PTSTR fixedKey = NULL; PCTSTR sectKey = NULL; PCTSTR leaf = NULL; MIG_SEGMENTS nodePat[1]; MIG_SEGMENTS leafPat[1]; UINT nrSegNode = 0; UINT nrSegLeaf = 0; MIG_OBJECTSTRINGHANDLE result = NULL;
if (IniFile) { iniNode = DuplicatePathString (IniFile, 0); if (!iniNode) { // out of memory?
return NULL; }
iniLeaf = _tcsrchr (iniNode, TEXT('\\')); if (iniLeaf) { *iniLeaf = 0; iniLeaf ++; } else { // this was only a leaf specification
iniLeaf = iniNode; iniNode = NULL; } }
if (iniNode) { // let's fix the iniNode.
if (!pFixPattern ( iniNode, NULL, &charsInPattern, !NodePatternsAllowed, !NodePatternsAllowed, TRUE )) { // something is wrong with this INI node specification.
// The rule is likely invalid
return NULL; }
fixedIniNode = AllocText (charsInPattern + 1); if (!fixedIniNode) { return NULL; }
if (!pFixPattern ( iniNode, fixedIniNode, NULL, !NodePatternsAllowed, !NodePatternsAllowed, TRUE )) { return NULL; } }
if (iniLeaf) { // let's fix the iniLeaf.
if (!pFixPattern ( iniLeaf, NULL, &charsInPattern, !LeafPatternsAllowed, !LeafPatternsAllowed, FALSE )) { // something is wrong with this INI dir specification.
// The rule is likely invalid
return NULL; }
fixedIniLeaf = AllocText (charsInPattern + 1); if (!fixedIniLeaf) { return NULL; }
if (!pFixPattern ( iniLeaf, fixedIniLeaf, NULL, !LeafPatternsAllowed, !LeafPatternsAllowed, FALSE )) { return NULL; } }
// now let's fix the section specification. If it contains any pattern and patterns
// are not allowed we will leave it NULL
if (Section) { if (pFixPattern ( Section, NULL, &charsInPattern, !LeafPatternsAllowed, FALSE, FALSE )) { fixedSect = AllocText (charsInPattern + 1); if (fixedSect) { pFixPattern ( Section, fixedSect, NULL, !LeafPatternsAllowed, FALSE, FALSE ); } } }
// now let's fix the key specification. If it contains any pattern and patterns
// are not allowed we will leave it NULL
if (Key) { if (pFixPattern ( Key, NULL, &charsInPattern, !LeafPatternsAllowed, FALSE, FALSE )) { fixedKey = AllocText (charsInPattern + 1); if (fixedKey) { pFixPattern ( Key, fixedKey, NULL, !LeafPatternsAllowed, FALSE, FALSE ); } } }
// finally let's build the object name
sectKey = JoinTextEx (NULL, fixedSect?fixedSect:TEXT(""), (fixedSect && fixedKey)?fixedKey:TEXT(""), TEXT("="), 0, NULL); if (!sectKey) { // something went wrong, let's get out of here
FreeText (fixedIniLeaf); FreeText (fixedIniNode); if (fixedSect) { FreeText (fixedSect); fixedSect = NULL; } if (fixedKey) { FreeText (fixedKey); fixedKey = NULL; } return NULL; } if (!LeafPatternsAllowed) { if (iniLeaf && fixedIniLeaf && StringIMatch (fixedIniLeaf, iniLeaf)) { leaf = JoinTextEx (NULL, fixedIniLeaf, sectKey, TEXT("\\"), 0, NULL); } else { leaf = JoinTextEx (NULL, TEXT(""), sectKey, TEXT("\\"), 0, NULL); } } else { if (fixedIniLeaf) { leaf = JoinTextEx (NULL, fixedIniLeaf, sectKey, TEXT("\\"), 0, NULL); } else { leaf = JoinTextEx (NULL, TEXT(""), sectKey, TEXT("\\"), 0, NULL); } } if (!leaf) { // something went wrong, let's get out of here
FreeText (fixedIniLeaf); FreeText (fixedIniNode); FreeText (sectKey); if (fixedSect) { FreeText (fixedSect); fixedSect = NULL; } if (fixedKey) { FreeText (fixedKey); fixedKey = NULL; } return NULL; }
nodePat [0].Segment = fixedIniNode?fixedIniNode:TEXT(""); nodePat [0].IsPattern = TRUE; nrSegNode ++; leafPat [0].Segment = leaf; leafPat [0].IsPattern = TRUE; nrSegLeaf ++; result = IsmCreateObjectPattern (nodePat, nrSegNode, leafPat, nrSegLeaf);
if (fixedIniLeaf) { FreeText (fixedIniLeaf); fixedIniLeaf = NULL; } if (fixedIniNode) { FreeText (fixedIniNode); fixedIniNode = NULL; } FreeText (sectKey); FreeText (leaf); if (fixedSect) { FreeText (fixedSect); fixedSect = NULL; } if (fixedKey) { FreeText (fixedKey); fixedKey = NULL; }
if (iniNode) { FreePathString (iniNode); iniNode = NULL; } else { if (iniLeaf) { FreePathString (iniLeaf); iniLeaf = NULL; } }
return result; }
MIG_OBJECTSTRINGHANDLE TurnCertSpecIntoHandle ( IN PCTSTR CertStore, IN PCTSTR CertName, IN BOOL PatternsAllowed )
/*++
Routine Description:
TurnIniSpecIntoHandle converts a ini file specification from the script syntax into a cobra object.
Arguments:
IniFile- Specifies the ini file in the script syntax. The string must be a full INI file specification
Section- Specifies the full section or the section pattern
Key - Specifies the full key or the key pattern
PatternsAllowed - if not, the function will compute the base object
Return Value:
A cobra object handle, or NULL if conversion failed.
--*/
{ UINT charsInPattern = 0; PTSTR fixedStore = NULL; PTSTR fixedName = NULL; PCTSTR leaf = NULL; MIG_OBJECTSTRINGHANDLE result = NULL;
// let's fix the certificate store. We know that no patterns are allowed here,
// so we will just return NULL if we detect some pattern
if (!pFixPattern ( CertStore, NULL, &charsInPattern, TRUE, TRUE, TRUE )) { // something is wrong with this store specification.
// The rule is likely invalid
return NULL; }
if (charsInPattern != (TcharCount (CertStore) + 1)) { // something is wrong with this store specification.
// The rule is likely invalid
return NULL; }
fixedStore = AllocText (charsInPattern + 1);
pFixPattern ( CertStore, fixedStore, NULL, TRUE, TRUE, TRUE );
if (!StringIMatch (CertStore, fixedStore)) { // something is wrong with this store specification.
// The rule is likely invalid
return NULL; }
FreeText (fixedStore);
// now let's fix the certificate specification. If it contains any pattern and patterns
// are not allowed we will leave it NULL
if (CertName) { if (pFixPattern ( CertName, NULL, &charsInPattern, !PatternsAllowed, FALSE, FALSE )) { fixedName = AllocText (charsInPattern + 1); if (fixedName) { pFixPattern ( CertName, fixedName, NULL, !PatternsAllowed, FALSE, FALSE ); } } }
result = IsmCreateSimpleObjectPattern (CertStore, FALSE, fixedName?fixedName:TEXT(""), TRUE); if (fixedName) { FreeText (fixedName); fixedName = NULL; }
return result; }
BOOL pAllocRegistryScriptType ( IN OUT PATTRIB_DATA AttribData ) { TCHAR expandBuffer[4096]; MIG_CONTENT objectContent; DWORD type; DWORD size; MULTISZ_ENUM multiSzEnum; PTSTR ptr;
if (!AttribData) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
// verify that we have some registry
if (!AttribData->ScriptSpecifiedObject) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
// try to create encoded string
AttribData->ObjectTypeId = g_RegType; AttribData->ObjectName = TurnRegStringIntoHandle ( AttribData->ScriptSpecifiedObject, FALSE, NULL );
if (!AttribData->ObjectName) { if (GetLastError() == ERROR_SUCCESS) { SetLastError (ERROR_INVALID_DATA); } return FALSE; }
// try to acqure the object
if (IsmAcquireObject ( AttribData->ObjectTypeId, AttribData->ObjectName, &objectContent )) {
AttribData->ObjectContent = IsmGetMemory (sizeof (MIG_CONTENT)); CopyMemory (AttribData->ObjectContent, &objectContent, sizeof (MIG_CONTENT));
// finally, we want to prepare the return string
if (!AttribData->ObjectContent->ContentInFile && (AttribData->ObjectContent->Details.DetailsSize == sizeof (DWORD)) && AttribData->ObjectContent->MemoryContent.ContentBytes ) {
type = *((PDWORD) AttribData->ObjectContent->Details.DetailsData);
switch (type) { case REG_SZ: size = SizeOfString ((PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes); AttribData->ReturnString = (PCTSTR) IsmGetMemory (size); StringCopy ( (PTSTR) AttribData->ReturnString, (PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes ); break; case REG_EXPAND_SZ: // we need to expand the content. This will be the return string
AttribData->ReturnString = IsmExpandEnvironmentString ( AttribData->Platform, S_SYSENVVAR_GROUP, (PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes, NULL ); if (!AttribData->ReturnString) { AttribData->ReturnString = IsmDuplicateString ((PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes); } break; case REG_MULTI_SZ: size = SizeOfMultiSz ((PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes); AttribData->ReturnString = (PCTSTR) IsmGetMemory (size); ((PTSTR)AttribData->ReturnString) [0] = 0; if (EnumFirstMultiSz (&multiSzEnum, (PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes)) { do { StringCat ( (PTSTR)AttribData->ReturnString, multiSzEnum.CurrentString ); StringCat ( (PTSTR)AttribData->ReturnString, TEXT(";") ); } while (EnumNextMultiSz (&multiSzEnum)); } break; case REG_DWORD: case REG_DWORD_BIG_ENDIAN: AttribData->ReturnString = (PCTSTR) IsmGetMemory ((sizeof (DWORD) * 2 + 3) * sizeof (TCHAR)); wsprintf ( (PTSTR) AttribData->ReturnString, TEXT("0x%08X"), *((PDWORD) AttribData->ObjectContent->MemoryContent.ContentBytes) ); break; default: AttribData->ReturnString = (PCTSTR) IsmGetMemory ((AttribData->ObjectContent-> MemoryContent.ContentSize * 3 * sizeof (TCHAR)) + sizeof (TCHAR) ); ptr = (PTSTR) AttribData->ReturnString; *ptr = 0; size = 0; while (size < AttribData->ObjectContent->MemoryContent.ContentSize) { wsprintf (ptr, TEXT("%02X"), *(AttribData->ObjectContent->MemoryContent.ContentBytes + size)); size ++; ptr = GetEndOfString (ptr); if (size < AttribData->ObjectContent->MemoryContent.ContentSize) { StringCopy (ptr, TEXT(",")); ptr = GetEndOfString (ptr); } } } } else if (IsmIsObjectHandleNodeOnly (AttribData->ObjectName)) { //
// Node only case
//
AttribData->ReturnString = (PCTSTR) IsmGetMemory (sizeof (TCHAR)); ptr = (PTSTR) AttribData->ReturnString; *ptr = 0; } }
return TRUE; }
BOOL pAllocFileScriptType ( IN OUT PATTRIB_DATA AttribData ) { MIG_OBJECTSTRINGHANDLE objectName; MIG_OBJECTSTRINGHANDLE objectNameLong; PCTSTR nativeNameLong; MIG_CONTENT objectContent; PCTSTR sanitizedPath = NULL; PCTSTR longFileName = NULL;
if (!AttribData) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
// verify that we have some registry
if (!AttribData->ScriptSpecifiedObject) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
sanitizedPath = SanitizePath (AttribData->ScriptSpecifiedObject); if (!sanitizedPath) { if (GetLastError() == ERROR_SUCCESS) { SetLastError (ERROR_INVALID_DATA); } return FALSE; }
longFileName = sanitizedPath;
// let's get the long file name for this. We need to call
// ISM for this because we might be on the wrong platform
objectName = TurnFileStringIntoHandle ( longFileName, PFF_NO_LEAF_PATTERN ); if (objectName) { objectNameLong = IsmGetLongName (MIG_FILE_TYPE|AttribData->Platform, objectName); if (objectNameLong) { nativeNameLong = IsmGetNativeObjectName (MIG_FILE_TYPE|AttribData->Platform, objectNameLong); if (nativeNameLong) { longFileName = DuplicatePathString (nativeNameLong, 0); IsmReleaseMemory (nativeNameLong); } IsmDestroyObjectHandle (objectNameLong); } IsmDestroyObjectHandle (objectName); }
// try to create encoded string
AttribData->ObjectTypeId = g_FileType; AttribData->ObjectName = TurnFileStringIntoHandle ( longFileName, PFF_NO_LEAF_PATTERN );
if (!AttribData->ObjectName) { if (longFileName != sanitizedPath) { FreePathString (longFileName); longFileName = NULL; } FreePathString (sanitizedPath); if (GetLastError() == ERROR_SUCCESS) { SetLastError (ERROR_INVALID_DATA); } return FALSE; }
// try to acqure the object
if (IsmAcquireObject ( AttribData->ObjectTypeId, AttribData->ObjectName, &objectContent )) {
AttribData->ObjectContent = IsmGetMemory (sizeof (MIG_CONTENT)); CopyMemory (AttribData->ObjectContent, &objectContent, sizeof (MIG_CONTENT));
AttribData->ReturnString = IsmGetMemory (SizeOfString (longFileName)); StringCopy ((PTSTR) AttribData->ReturnString, longFileName); }
if (longFileName != sanitizedPath) { FreePathString (longFileName); longFileName = NULL; } FreePathString (sanitizedPath);
return TRUE; }
BOOL pAllocDirectoryScriptType ( IN OUT PATTRIB_DATA AttribData ) { MIG_OBJECTSTRINGHANDLE objectName; MIG_OBJECTSTRINGHANDLE objectNameLong; PCTSTR nativeNameLong; MIG_CONTENT objectContent; PCTSTR sanitizedPath; PCTSTR longFileName = NULL;
if (!AttribData) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
// verify that we have some registry
if (!AttribData->ScriptSpecifiedObject) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
sanitizedPath = SanitizePath (AttribData->ScriptSpecifiedObject);
if (!sanitizedPath) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
longFileName = sanitizedPath;
// let's get the long file name for this. We need to call
// ISM for this because we might be on the wrong platform
objectName = TurnFileStringIntoHandle ( sanitizedPath, PFF_PATTERN_IS_DIR | PFF_NO_LEAF_AT_ALL ); if (objectName) { objectNameLong = IsmGetLongName (MIG_FILE_TYPE|AttribData->Platform, objectName); if (objectNameLong) { nativeNameLong = IsmGetNativeObjectName (MIG_FILE_TYPE|AttribData->Platform, objectNameLong); if (nativeNameLong) { longFileName = DuplicatePathString (nativeNameLong, 0); IsmReleaseMemory (nativeNameLong); } IsmDestroyObjectHandle (objectNameLong); } IsmDestroyObjectHandle (objectName); }
// try to create encoded string
AttribData->ObjectTypeId = g_FileType; AttribData->ObjectName = TurnFileStringIntoHandle ( sanitizedPath, PFF_PATTERN_IS_DIR | PFF_NO_LEAF_AT_ALL );
if (!AttribData->ObjectName) { if (longFileName != sanitizedPath) { FreePathString (longFileName); longFileName = NULL; } FreePathString (sanitizedPath); if (GetLastError() == ERROR_SUCCESS) { SetLastError (ERROR_INVALID_DATA); } return FALSE; }
// try to acqure the object
if (IsmAcquireObject ( AttribData->ObjectTypeId, AttribData->ObjectName, &objectContent )) {
AttribData->ObjectContent = IsmGetMemory (sizeof (MIG_CONTENT)); CopyMemory (AttribData->ObjectContent, &objectContent, sizeof (MIG_CONTENT));
AttribData->ReturnString = IsmGetMemory (SizeOfString (longFileName)); StringCopy ((PTSTR) AttribData->ReturnString, longFileName); }
if (longFileName != sanitizedPath) { FreePathString (longFileName); longFileName = NULL; } FreePathString (sanitizedPath);
return TRUE; }
BOOL pFreeIsmObjectScriptType ( IN OUT PATTRIB_DATA AttribData ) { if (AttribData->ReturnString) { IsmReleaseMemory (AttribData->ReturnString); AttribData->ReturnString = NULL; } AttribData->ObjectTypeId = 0; if (AttribData->ObjectName) { IsmDestroyObjectHandle (AttribData->ObjectName); AttribData->ObjectName = NULL; } if (AttribData->ObjectContent) { IsmReleaseObject (AttribData->ObjectContent); IsmReleaseMemory (AttribData->ObjectContent); AttribData->ObjectContent = NULL; } return TRUE; }
BOOL pAllocTextScriptType ( IN OUT PATTRIB_DATA AttribData ) { if (!AttribData) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
// verify that we have some registry
if (!AttribData->ScriptSpecifiedObject) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
AttribData->ReturnString = IsmGetMemory (SizeOfString (AttribData->ScriptSpecifiedObject)); StringCopy ((PTSTR) AttribData->ReturnString, AttribData->ScriptSpecifiedObject);
return TRUE; }
BOOL pFreeTextScriptType ( IN OUT PATTRIB_DATA AttribData ) { if (AttribData->ReturnString) { IsmReleaseMemory (AttribData->ReturnString); AttribData->ReturnString = NULL; } return TRUE; }
BOOL pAllocSystemScriptType ( IN OUT PATTRIB_DATA AttribData ) { PTSTR specificSection = NULL; MIG_OSVERSIONINFO versionInfo; UINT tchars; BOOL detected = FALSE;
if (!AttribData) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
// verify that we have some registry
if (!AttribData->ScriptSpecifiedObject) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
if (!IsmGetOsVersionInfo (PLATFORM_SOURCE, &versionInfo)) { return FALSE; }
tchars = 1; if (versionInfo.OsTypeName) { tchars += TcharCount (versionInfo.OsTypeName) + 1; } if (versionInfo.OsMajorVersionName) { tchars += TcharCount (versionInfo.OsMajorVersionName) + 1; } if (versionInfo.OsMinorVersionName) { tchars += TcharCount (versionInfo.OsMinorVersionName); }
specificSection = AllocText (tchars); if (!specificSection) { return FALSE; }
if (!detected && versionInfo.OsTypeName) {
wsprintf ( specificSection, TEXT("%s"), versionInfo.OsTypeName ); if (StringIMatch (AttribData->ScriptSpecifiedObject, specificSection)) { detected = TRUE; }
if (!detected && versionInfo.OsMajorVersionName) {
wsprintf ( specificSection, TEXT("%s.%s"), versionInfo.OsTypeName, versionInfo.OsMajorVersionName ); if (StringIMatch (AttribData->ScriptSpecifiedObject, specificSection)) { detected = TRUE; }
if (!detected && versionInfo.OsMinorVersionName) { wsprintf ( specificSection, TEXT("%s.%s.%s"), versionInfo.OsTypeName, versionInfo.OsMajorVersionName, versionInfo.OsMinorVersionName ); if (StringIMatch (AttribData->ScriptSpecifiedObject, specificSection)) { detected = TRUE; } } } }
if (detected) { AttribData->ReturnString = IsmGetMemory (SizeOfString (AttribData->ScriptSpecifiedObject)); StringCopy ((PTSTR) AttribData->ReturnString, AttribData->ScriptSpecifiedObject); }
FreeText (specificSection); specificSection = NULL;
return TRUE; }
BOOL pFreeSystemScriptType ( IN OUT PATTRIB_DATA AttribData ) { if (AttribData->ReturnString) { IsmReleaseMemory (AttribData->ReturnString); AttribData->ReturnString = NULL; } return TRUE; }
BOOL pAllocIniFileScriptType ( IN OUT PATTRIB_DATA AttribData ) { PTSTR fileName = NULL; PTSTR sectName = NULL; PTSTR keyName = NULL; PTSTR charPtr = NULL; PTSTR result = NULL; DWORD allocatedChars; DWORD chars;
if (!AttribData) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
// verify that we have something specified
if (!AttribData->ScriptSpecifiedObject) { SetLastError (ERROR_INVALID_DATA); return FALSE; }
// Now, let's extract the INI file name, section and key
fileName = DuplicatePathString (AttribData->ScriptSpecifiedObject, 0); if (!fileName) { return FALSE; }
charPtr = _tcschr (fileName, TEXT('/')); if (charPtr) { sectName = _tcsinc (charPtr); *charPtr = 0; if (sectName) { charPtr = _tcschr (sectName, TEXT('/')); if (charPtr) { keyName = _tcsinc (charPtr); *charPtr = 0; } } }
result = NULL; allocatedChars = 256; do { if (result) { FreePathString (result); } allocatedChars *= 2; result = AllocPathString (allocatedChars); if (!result) { return FALSE; } chars = GetPrivateProfileString ( sectName, keyName, TEXT(""), result, allocatedChars, fileName ); } while (chars >= allocatedChars - 1);
if (chars) { AttribData->ReturnString = IsmGetMemory (SizeOfString (result)); StringCopy ((PTSTR) AttribData->ReturnString, result); FreePathString (result); result = NULL; return TRUE; } FreePathString (result); result = NULL; FreePathString (fileName); fileName = NULL; return FALSE; }
BOOL pFreeIniFileScriptType ( IN OUT PATTRIB_DATA AttribData ) { if (AttribData->ReturnString) { IsmReleaseMemory (AttribData->ReturnString); AttribData->ReturnString = NULL; } return TRUE; }
BOOL AllocScriptType ( IN OUT PATTRIB_DATA AttribData CALLER_INITIALIZED ) { PTAG_TO_SCRIPTTYPEFN scriptFn = g_TagToScriptTypeFn;
while (scriptFn->Tag) { if (StringIMatch (scriptFn->Tag, AttribData->ScriptSpecifiedType)) { break; } scriptFn ++; } if (scriptFn->Tag) { return (scriptFn->AllocFunction (AttribData)); } else { return FALSE; } }
BOOL FreeScriptType ( IN PATTRIB_DATA AttribData ZEROED ) { PTAG_TO_SCRIPTTYPEFN scriptFn = g_TagToScriptTypeFn;
while (scriptFn->Tag) { if (StringIMatch (scriptFn->Tag, AttribData->ScriptSpecifiedType)) { break; } scriptFn ++; } if (scriptFn->Tag) { return (scriptFn->FreeFunction (AttribData)); } else { return FALSE; } }
|