Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2042 lines
52 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. parse.c
  5. Abstract:
  6. Implements parsing of script entries.
  7. Author:
  8. Jim Schmidt (jimschm) 02-Jun-2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. //
  13. // Includes
  14. //
  15. #include "pch.h"
  16. #include "v1p.h"
  17. #define DBG_V1 "v1"
  18. //
  19. // Strings
  20. //
  21. // None
  22. //
  23. // Constants
  24. //
  25. // None
  26. //
  27. // Macros
  28. //
  29. // None
  30. //
  31. // Types
  32. //
  33. typedef BOOL (SCRIPTTYPE_ALLOC_FN)(
  34. IN OUT PATTRIB_DATA AttribData CALLER_INITIALIZED
  35. );
  36. typedef SCRIPTTYPE_ALLOC_FN *PSCRIPTTYPE_ALLOC_FN;
  37. typedef BOOL (SCRIPTTYPE_FREE_FN)(
  38. IN PATTRIB_DATA AttribData ZEROED
  39. );
  40. typedef SCRIPTTYPE_FREE_FN *PSCRIPTTYPE_FREE_FN;
  41. typedef struct {
  42. PCTSTR Tag;
  43. PSCRIPTTYPE_ALLOC_FN AllocFunction;
  44. PSCRIPTTYPE_FREE_FN FreeFunction;
  45. } TAG_TO_SCRIPTTYPEFN, *PTAG_TO_SCRIPTTYPEFN;
  46. //
  47. // Globals
  48. //
  49. // None
  50. //
  51. // Macro expansion list
  52. //
  53. #define SCRIPT_TYPES \
  54. DEFMAC(Registry, pAllocRegistryScriptType, pFreeIsmObjectScriptType) \
  55. DEFMAC(File, pAllocFileScriptType, pFreeIsmObjectScriptType) \
  56. DEFMAC(Directory, pAllocDirectoryScriptType, pFreeIsmObjectScriptType) \
  57. DEFMAC(Text, pAllocTextScriptType, pFreeTextScriptType) \
  58. DEFMAC(System, pAllocSystemScriptType, pFreeSystemScriptType) \
  59. DEFMAC(INIFile, pAllocIniFileScriptType, pFreeIniFileScriptType) \
  60. //
  61. // Private function prototypes
  62. //
  63. // None
  64. //
  65. // Macro expansion definition
  66. //
  67. #define DEFMAC(tag,fnA,fnF) SCRIPTTYPE_ALLOC_FN fnA; SCRIPTTYPE_FREE_FN fnF;
  68. SCRIPT_TYPES
  69. #undef DEFMAC
  70. #define DEFMAC(tag,fnA,fnF) {TEXT(#tag),fnA,fnF},
  71. TAG_TO_SCRIPTTYPEFN g_TagToScriptTypeFn[] = {
  72. SCRIPT_TYPES
  73. {NULL, NULL, NULL}
  74. };
  75. #undef DEFMAC
  76. //
  77. // Code
  78. //
  79. MIG_OBJECTSTRINGHANDLE
  80. MakeRegExBase (
  81. IN PCTSTR Node,
  82. IN PCTSTR Leaf
  83. )
  84. {
  85. MIG_OBJECTSTRINGHANDLE objectBase = NULL;
  86. PTSTR ptr;
  87. PTSTR nodeCopy = NULL;
  88. PCTSTR nodeBase = NULL;
  89. BOOL useLeaf = FALSE;
  90. if (Node) {
  91. ptr = _tcschr (Node, TEXT('\\'));
  92. if (!ptr) {
  93. return NULL;
  94. }
  95. if (StringIPrefix (Node, TEXT("HKR\\"))) {
  96. nodeCopy = JoinText (TEXT("HKCU"), ptr);
  97. } else {
  98. nodeCopy = DuplicateText (Node);
  99. }
  100. if (nodeCopy) {
  101. nodeBase = GetPatternBase (nodeCopy);
  102. if (nodeBase) {
  103. if (Leaf && !_tcschr (Leaf, TEXT('*'))) {
  104. useLeaf = TRUE;
  105. }
  106. objectBase = IsmCreateObjectHandle (nodeBase, useLeaf ? Leaf : NULL);
  107. FreePathString (nodeBase);
  108. }
  109. FreeText (nodeCopy);
  110. }
  111. }
  112. return objectBase;
  113. }
  114. MIG_OBJECTSTRINGHANDLE
  115. CreatePatternFromNodeLeaf (
  116. IN PCTSTR Node,
  117. IN PCTSTR Leaf
  118. )
  119. {
  120. MIG_OBJECTSTRINGHANDLE pattern;
  121. MIG_SEGMENTS nodeSegment;
  122. MIG_SEGMENTS leafSegment;
  123. PTSTR fixedNode = NULL;
  124. // let's do some trick for registry objects that start with HKR
  125. if (Node &&
  126. (StringIMatch (Node, S_HKR) ||
  127. StringIMatchTcharCount (Node, TEXT("HKR\\"), 4)
  128. )
  129. ) {
  130. fixedNode = JoinText (S_HKCU, Node + 3);
  131. nodeSegment.Segment = fixedNode;
  132. } else {
  133. nodeSegment.Segment = Node;
  134. }
  135. nodeSegment.IsPattern = TRUE;
  136. leafSegment.Segment = Leaf;
  137. leafSegment.IsPattern = TRUE;
  138. pattern = IsmCreateObjectPattern (&nodeSegment, Node ? 1 : 0, &leafSegment, Leaf ? 1 : 0);
  139. FreeText (fixedNode);
  140. return pattern;
  141. }
  142. MIG_OBJECTSTRINGHANDLE
  143. TurnRegStringIntoHandle (
  144. IN PCTSTR String,
  145. IN BOOL Pattern,
  146. OUT PBOOL HadLeaf OPTIONAL
  147. )
  148. /*++
  149. Routine Description:
  150. TurnRegStringIntoHandle converts the script's reg syntax into a cobra
  151. object.
  152. Arguments:
  153. String - Specifies the registry key and value in the script syntax.
  154. The string must be in the following format:
  155. <root>\<key>\* [<value>]
  156. Each part is optional.
  157. <root> specifies HKCU, HKR, HKLM or HKCC.
  158. <key> specifies a subkey (such as Software\Microsoft\Windows)
  159. * specifies all subkeys. If <value> is not specified, then all
  160. values and subvalues are also included.
  161. <value> specifies a specific value name
  162. Pattern - Specifies TRUE if the registry string can contain a pattern, or
  163. FALSE if it cannot.
  164. HadLeaf - Receives TRUE if String contains a leaf specification, FALSE
  165. otherwise
  166. Return Value:
  167. A handle to a cobra object string, or NULL if parsing failed.
  168. --*/
  169. {
  170. PTSTR strCopy;
  171. PTSTR p;
  172. PTSTR value = NULL;
  173. PTSTR valueEnd;
  174. PTSTR key;
  175. PTSTR keyEnd;
  176. BOOL tree = FALSE;
  177. MIG_SEGMENTS nodeSegment[2];
  178. UINT nodeCount;
  179. MIG_SEGMENTS leafSegment;
  180. UINT leafCount;
  181. MIG_OBJECTSTRINGHANDLE handle;
  182. BOOL noSubKeys;
  183. BOOL noWildcardLeaf;
  184. PCTSTR fixedKey = NULL;
  185. MYASSERT (String);
  186. if (!String) {
  187. return NULL;
  188. }
  189. if (Pattern) {
  190. noSubKeys = FALSE;
  191. noWildcardLeaf = FALSE;
  192. } else {
  193. noSubKeys = TRUE;
  194. noWildcardLeaf = TRUE;
  195. }
  196. //
  197. // Inbound syntax is key\* [value]
  198. //
  199. strCopy = DuplicateText (String);
  200. if (!strCopy) {
  201. return NULL;
  202. }
  203. key = (PTSTR) SkipSpace (strCopy);
  204. if (!key) {
  205. FreeText (strCopy);
  206. return NULL;
  207. }
  208. if (*key == TEXT('[')) {
  209. //
  210. // This is a value-only case
  211. //
  212. value = _tcsinc (key);
  213. key = NULL;
  214. } else {
  215. //
  216. // This is a key-value case, or key-only case
  217. //
  218. p = _tcschr (key, TEXT('['));
  219. if (p) {
  220. //
  221. // Save start of value
  222. //
  223. value = _tcsinc (p);
  224. } else {
  225. //
  226. // No value
  227. //
  228. p = GetEndOfString (key);
  229. }
  230. keyEnd = p;
  231. //
  232. // Find the true end of the key
  233. //
  234. p = _tcsdec2 (key, p);
  235. MYASSERT (p); // assert this is not a value-only case
  236. p = (PTSTR) SkipSpaceR (key, p);
  237. if (p) {
  238. keyEnd = _tcsinc (p);
  239. }
  240. //
  241. // Test for \* at the end
  242. //
  243. p = _tcsdec2 (key, keyEnd);
  244. MYASSERT (p);
  245. if (p && _tcsnextc (p) == TEXT('*')) {
  246. p = _tcsdec2 (key, p);
  247. if (p && _tcsnextc (p) == TEXT('\\')) {
  248. keyEnd = p;
  249. tree = (noSubKeys == FALSE);
  250. }
  251. }
  252. //
  253. // Trim the key
  254. //
  255. *keyEnd = 0;
  256. }
  257. //
  258. // Parse the value
  259. //
  260. if (value) {
  261. value = (PTSTR) SkipSpace (value);
  262. valueEnd = _tcschr (value, TEXT(']'));
  263. if (!valueEnd) {
  264. LOG ((LOG_ERROR, (PCSTR) MSG_INF_SYNTAX_ERROR, String));
  265. value = NULL;
  266. } else {
  267. //
  268. // Trim the space at the end of value
  269. //
  270. p = _tcsdec2 (value, valueEnd);
  271. if (p) {
  272. p = (PTSTR) SkipSpaceR (value, p);
  273. if (p) {
  274. valueEnd = _tcsinc (p);
  275. }
  276. }
  277. *valueEnd = 0;
  278. }
  279. }
  280. //
  281. // Create parsed pattern. Start with the node.
  282. //
  283. nodeSegment[0].Segment = key;
  284. nodeSegment[0].IsPattern = FALSE;
  285. nodeSegment[1].Segment = TEXT("\\*");
  286. nodeSegment[1].IsPattern = TRUE;
  287. if (tree) {
  288. nodeCount = 2;
  289. } else {
  290. nodeCount = 1;
  291. }
  292. //
  293. // compute the leaf
  294. //
  295. if (value) {
  296. leafSegment.Segment = value;
  297. leafSegment.IsPattern = FALSE;
  298. } else {
  299. leafSegment.Segment = TEXT("*");
  300. leafSegment.IsPattern = TRUE;
  301. }
  302. if (noWildcardLeaf && !value) {
  303. leafCount = 0;
  304. } else {
  305. leafCount = 1;
  306. }
  307. if (nodeCount && key &&
  308. (StringIMatch (key, S_HKR) ||
  309. StringIMatchTcharCount (key, TEXT("HKR\\"), 4)
  310. )
  311. ) {
  312. fixedKey = JoinText (S_HKCU, key + 3);
  313. nodeSegment[0].Segment = fixedKey;
  314. }
  315. handle = IsmCreateObjectPattern (
  316. nodeSegment,
  317. nodeCount,
  318. leafCount?&leafSegment:NULL,
  319. leafCount
  320. );
  321. FreeText (strCopy);
  322. FreeText (fixedKey);
  323. if (HadLeaf) {
  324. *HadLeaf = (value != NULL);
  325. }
  326. return handle;
  327. }
  328. PTSTR
  329. pCopyToDest (
  330. IN PTSTR Destination, OPTIONAL
  331. IN CHARTYPE Char,
  332. IN PUINT CharNr
  333. )
  334. {
  335. UINT len = 1;
  336. #ifdef UNICODE
  337. if (Destination) {
  338. *Destination++ = Char;
  339. }
  340. (*CharNr) ++;
  341. return Destination;
  342. #else
  343. if (IsCharLeadByte ((INT) Char)) {
  344. len ++;
  345. }
  346. if (Destination) {
  347. CopyMemory (Destination, &Char, len);
  348. Destination += len;
  349. }
  350. (*CharNr) += len;
  351. return Destination;
  352. #endif
  353. }
  354. // 1->? (if node, no \ or ., if leaf, no .), 2->* (if node, no \ or ., if leaf, no .) 3->* (no \) 4->* (unlimited)
  355. UINT
  356. pGetMode (
  357. IN PCTSTR Source,
  358. IN BOOL NodePattern,
  359. IN BOOL PatternAfterWack,
  360. IN BOOL FirstChar
  361. )
  362. {
  363. UINT ch;
  364. BOOL end = FALSE;
  365. UINT mode = 0;
  366. ch = _tcsnextc (Source);
  367. while (ch) {
  368. switch (ch) {
  369. case TEXT('?'):
  370. if (mode < 1) {
  371. mode = 1;
  372. }
  373. break;
  374. case TEXT('*'):
  375. if (NodePattern) {
  376. if (mode < 3) {
  377. mode = 3;
  378. }
  379. } else {
  380. if (mode < 4) {
  381. mode = 4;
  382. }
  383. }
  384. break;
  385. case TEXT('\\'):
  386. if (NodePattern) {
  387. if (mode < 2) {
  388. mode = 2;
  389. }
  390. }
  391. end = TRUE;
  392. break;
  393. case TEXT('.'):
  394. if (mode < 2) {
  395. mode = 2;
  396. }
  397. end = TRUE;
  398. break;
  399. default:
  400. end = TRUE;
  401. }
  402. if (end) {
  403. break;
  404. }
  405. Source = _tcsinc (Source);
  406. ch = _tcsnextc (Source);
  407. }
  408. if (!ch) {
  409. if ((PatternAfterWack || NodePattern) && (mode == 3)) {
  410. mode = 4;
  411. }
  412. if (mode < 2) {
  413. mode = 2;
  414. }
  415. }
  416. if (FirstChar && (mode == 3)) {
  417. mode = 4;
  418. }
  419. return mode;
  420. }
  421. BOOL
  422. pCopyPatternEx (
  423. IN UINT Mode,
  424. IN PCTSTR *Source,
  425. IN PTSTR *Destination,
  426. IN PUINT CharNr,
  427. IN BOOL NodePattern
  428. )
  429. {
  430. CHARTYPE ch;
  431. BOOL end = FALSE;
  432. INT numChars = 0;
  433. UINT chars;
  434. TCHAR buffer [MAX_PATH] = TEXT("");
  435. ch = (CHARTYPE) _tcsnextc (*Source);
  436. while (ch) {
  437. switch (ch) {
  438. case TEXT('*'):
  439. if (Mode == 1) {
  440. end = TRUE;
  441. break;
  442. }
  443. numChars = -1;
  444. break;
  445. case TEXT('?'):
  446. if (numChars >= 0) {
  447. numChars ++;
  448. }
  449. break;
  450. default:
  451. end = TRUE;
  452. break;
  453. }
  454. if (end) {
  455. break;
  456. }
  457. *Source = _tcsinc (*Source);
  458. ch = (CHARTYPE) _tcsnextc (*Source);
  459. }
  460. // 1->? (if node, no \ or ., if leaf, no .), 2->* (if node, no \ or ., if leaf, no .) 3->* (no \) 4->* (unlimited)
  461. switch (Mode) {
  462. case 1:
  463. if (NodePattern) {
  464. if (numChars > 0) {
  465. wsprintf (buffer, TEXT("?[%d:!(\\,.)]"), numChars);
  466. } else {
  467. wsprintf (buffer, TEXT("?[!(\\,.)]"));
  468. }
  469. } else {
  470. if (numChars > 0) {
  471. wsprintf (buffer, TEXT("?[%d:!(.)]"), numChars);
  472. } else {
  473. wsprintf (buffer, TEXT("?[!(.)]"));
  474. }
  475. }
  476. break;
  477. case 2:
  478. if (NodePattern) {
  479. if (numChars > 0) {
  480. wsprintf (buffer, TEXT("*[%d:!(\\,.)]"), numChars);
  481. } else {
  482. wsprintf (buffer, TEXT("*[!(\\,.)]"));
  483. }
  484. } else {
  485. if (numChars > 0) {
  486. wsprintf (buffer, TEXT("*[%d:!(.)]"), numChars);
  487. } else {
  488. wsprintf (buffer, TEXT("*[!(.)]"));
  489. }
  490. }
  491. break;
  492. case 3:
  493. if (numChars > 0) {
  494. wsprintf (buffer, TEXT("*[%d:!(\\)]"), numChars);
  495. } else {
  496. wsprintf (buffer, TEXT("*[!(\\)]"));
  497. }
  498. break;
  499. case 4:
  500. if (numChars > 0) {
  501. wsprintf (buffer, TEXT("*[%d:]"), numChars);
  502. } else {
  503. wsprintf (buffer, TEXT("*[]"));
  504. }
  505. break;
  506. default:
  507. MYASSERT (FALSE);
  508. }
  509. chars = TcharCount (buffer);
  510. if (CharNr) {
  511. *CharNr += chars;
  512. }
  513. if (Destination && *Destination) {
  514. StringCopy (*Destination, buffer);
  515. *Destination += chars;
  516. }
  517. return TRUE;
  518. }
  519. BOOL
  520. pCopyPattern (
  521. IN PCTSTR *Source,
  522. IN PTSTR *Destination,
  523. IN PUINT CharNr,
  524. IN BOOL NodePattern,
  525. IN BOOL PatternAfterWack,
  526. IN BOOL FirstChar
  527. )
  528. {
  529. // 1->? (if node, no \ or ., if leaf, no .), 2->* (if node, no \ or ., if leaf, no .) 3->* (no \) 4->* (unlimited)
  530. UINT mode = 0;
  531. PTSTR result = NULL;
  532. mode = pGetMode (*Source, NodePattern, PatternAfterWack, FirstChar);
  533. return pCopyPatternEx (mode, Source, Destination, CharNr, NodePattern);
  534. }
  535. BOOL
  536. pFixPattern (
  537. IN PCTSTR Source,
  538. OUT PTSTR Destination, OPTIONAL
  539. OUT PUINT DestinationChars, OPTIONAL
  540. IN BOOL PatternsNotAllowed,
  541. IN BOOL TruncateAtPattern,
  542. IN BOOL NodePattern
  543. )
  544. {
  545. UINT chars = 1;
  546. UINT lastChars = 0;
  547. PTSTR lastWack = NULL;
  548. BOOL end = FALSE;
  549. BOOL result = TRUE;
  550. BOOL patternAfterWack = FALSE;
  551. BOOL firstChar = TRUE;
  552. CHARTYPE ch;
  553. if (Destination) {
  554. *Destination = 0;
  555. }
  556. ch = (CHARTYPE) _tcsnextc (Source);
  557. while (ch) {
  558. switch (ch) {
  559. case TEXT('*'):
  560. case TEXT('?'):
  561. if (TruncateAtPattern) {
  562. if (lastWack) {
  563. *lastWack = 0;
  564. chars = lastChars;
  565. }
  566. end = TRUE;
  567. } else if (PatternsNotAllowed) {
  568. result = FALSE;
  569. Destination = pCopyToDest (Destination, TEXT('^'), &chars);
  570. Destination = pCopyToDest (Destination, ch, &chars);
  571. Source = _tcsinc (Source);
  572. } else {
  573. if (lastWack && (_tcsinc (lastWack) == Destination)) {
  574. patternAfterWack = TRUE;
  575. } else {
  576. patternAfterWack = FALSE;
  577. }
  578. pCopyPattern (&Source, Destination?&Destination:NULL, &chars, NodePattern, patternAfterWack, firstChar);
  579. }
  580. break;
  581. case TEXT('\020'):
  582. case TEXT('<'):
  583. case TEXT('>'):
  584. case TEXT(','):
  585. case TEXT('^'):
  586. Destination = pCopyToDest (Destination, TEXT('^'), &chars);
  587. Destination = pCopyToDest (Destination, ch, &chars);
  588. Source = _tcsinc (Source);
  589. break;
  590. case TEXT('\\'):
  591. if (NodePattern) {
  592. lastWack = Destination;
  593. lastChars = chars;
  594. }
  595. Destination = pCopyToDest (Destination, ch, &chars);
  596. Source = _tcsinc (Source);
  597. break;
  598. case TEXT('.'):
  599. if (!NodePattern) {
  600. lastWack = Destination;
  601. lastChars = chars;
  602. }
  603. Destination = pCopyToDest (Destination, ch, &chars);
  604. Source = _tcsinc (Source);
  605. break;
  606. default:
  607. Destination = pCopyToDest (Destination, ch, &chars);
  608. Source = _tcsinc (Source);
  609. break;
  610. }
  611. firstChar = FALSE;
  612. if (end) {
  613. break;
  614. }
  615. ch = (CHARTYPE) _tcsnextc (Source);
  616. }
  617. if (Destination) {
  618. *Destination = 0;
  619. }
  620. if (DestinationChars) {
  621. *DestinationChars = chars;
  622. }
  623. return result;
  624. }
  625. MIG_OBJECTSTRINGHANDLE
  626. TurnFileStringIntoHandle (
  627. IN PCTSTR String,
  628. IN DWORD Flags
  629. )
  630. /*++
  631. Routine Description:
  632. TurnFileStringIntoHandle converts a file specification from the script
  633. syntax into a cobra object.
  634. Arguments:
  635. String - Specifies the file string in the script syntax.
  636. The string must be in the following format:
  637. <directory>\<file>
  638. Both parts are optional. The Flags member indicates how String
  639. is parsed.
  640. Flags - Specifies zero or more of the following flags:
  641. PFF_NO_PATTERNS_ALLOWED - String cannot contain any wildcard
  642. characters.
  643. PFF_COMPUTE_BASE - Returns the directory portion of the string,
  644. and truncates the directory at the first
  645. wildcard if necessary. Truncation is done
  646. at the backslashes only.
  647. PFF_NO_SUBDIR_PATTERN - Do not include a trailing \*, even if
  648. it was specified in String.
  649. PFF_NO_LEAF_PATTERN - Do not include a * for the leaf when
  650. String does not contain a file name.
  651. If a file name is specified, include it.
  652. PFF_PATTERN_IS_DIR - String does not specify a file name. It
  653. is a directory only. The leaf portion of
  654. the object string will be a *.
  655. PFF_NO_LEAF_AT_ALL - Will return an object string that has a
  656. node only, and no leaf specified at all.
  657. Return Value:
  658. A cobra object handle, or NULL if conversion failed.
  659. --*/
  660. {
  661. PTSTR p;
  662. PTSTR fileCopy = NULL;
  663. MIG_SEGMENTS nodeSegment[2];
  664. MIG_SEGMENTS leafSegment;
  665. MIG_OBJECTSTRINGHANDLE result = NULL;
  666. BOOL tree = FALSE;
  667. PTSTR file = NULL;
  668. UINT nodeCount;
  669. UINT leafCount;
  670. UINT charsInPattern;
  671. BOOL noPatternsAllowed;
  672. BOOL computeBaseNode;
  673. BOOL noSubDirPattern;
  674. BOOL noLeafPattern;
  675. BOOL forceLeafToStar;
  676. PCTSTR node;
  677. PCTSTR leaf = NULL;
  678. PTSTR fixedNode = NULL;
  679. PTSTR fixedLeaf = NULL;
  680. PTSTR tempCopy;
  681. BOOL patternError = FALSE;
  682. noPatternsAllowed = (Flags & PFF_NO_PATTERNS_ALLOWED) == PFF_NO_PATTERNS_ALLOWED;
  683. computeBaseNode = (Flags & PFF_COMPUTE_BASE) == PFF_COMPUTE_BASE;
  684. noSubDirPattern = (Flags & PFF_NO_SUBDIR_PATTERN) == PFF_NO_SUBDIR_PATTERN;
  685. noLeafPattern = (Flags & PFF_NO_LEAF_PATTERN) == PFF_NO_LEAF_PATTERN;
  686. forceLeafToStar = (Flags & PFF_PATTERN_IS_DIR) == PFF_PATTERN_IS_DIR;
  687. //
  688. // Divide pattern into node and leaf
  689. //
  690. tempCopy = DuplicateText (SkipSpace (String));
  691. p = (PTSTR) SkipSpaceR (tempCopy, NULL);
  692. if (p) {
  693. p = _tcsinc (p);
  694. *p = 0;
  695. }
  696. node = tempCopy;
  697. if (!forceLeafToStar) {
  698. p = (PTSTR) FindLastWack (tempCopy);
  699. if (p) {
  700. leaf = SkipSpace (p + 1);
  701. *p = 0;
  702. p = (PTSTR) SkipSpaceR (tempCopy, NULL);
  703. if (p) {
  704. p = _tcsinc (p);
  705. *p = 0;
  706. }
  707. } else {
  708. if (!_tcschr (tempCopy, TEXT(':'))) {
  709. node = NULL;
  710. leaf = tempCopy;
  711. }
  712. }
  713. }
  714. //
  715. // Convert all ? wildcard chars to be compatibile with NT's file system
  716. // Escape all [ characters that follow wildcards
  717. //
  718. if (node) {
  719. p = (PTSTR) GetEndOfString (node);
  720. p = _tcsdec2 (node, p);
  721. if (p) {
  722. if (_tcsnextc (p) == TEXT('*')) {
  723. tree = TRUE;
  724. p = _tcsdec2 (node, p);
  725. if (p && _tcsnextc (p) == TEXT('\\')) {
  726. *p = 0;
  727. } else {
  728. tree = FALSE;
  729. }
  730. }
  731. }
  732. if (!pFixPattern (
  733. node,
  734. NULL,
  735. &charsInPattern,
  736. noPatternsAllowed,
  737. computeBaseNode,
  738. TRUE
  739. )) {
  740. patternError = TRUE;
  741. }
  742. if (charsInPattern) {
  743. fixedNode = AllocText (charsInPattern + 1);
  744. pFixPattern (
  745. node,
  746. fixedNode,
  747. NULL,
  748. noPatternsAllowed,
  749. computeBaseNode,
  750. TRUE
  751. );
  752. }
  753. }
  754. if (leaf && !computeBaseNode) {
  755. if (!pFixPattern (
  756. leaf,
  757. NULL,
  758. &charsInPattern,
  759. noPatternsAllowed,
  760. FALSE,
  761. FALSE
  762. )) {
  763. patternError = TRUE;
  764. }
  765. if (charsInPattern) {
  766. fixedLeaf = AllocText (charsInPattern + 1);
  767. pFixPattern (
  768. leaf,
  769. fixedLeaf,
  770. NULL,
  771. noPatternsAllowed,
  772. FALSE,
  773. FALSE
  774. );
  775. }
  776. }
  777. FreeText (tempCopy);
  778. INVALID_POINTER (tempCopy);
  779. //
  780. // Create the pattern string. Start by preparing the node segments.
  781. //
  782. nodeSegment[0].Segment = fixedNode;
  783. nodeSegment[0].IsPattern = TRUE; // normally FALSE, but because the pattern charset is
  784. // exclusive of the valid filename charset, we allow
  785. // patterns to be in the node
  786. nodeSegment[1].Segment = TEXT("\\*");
  787. nodeSegment[1].IsPattern = TRUE;
  788. if (!fixedNode) {
  789. nodeCount = 0;
  790. } else if (!tree || noSubDirPattern || noPatternsAllowed) {
  791. nodeCount = 1; // just the node, not its subnodes
  792. } else {
  793. nodeCount = 2; // the node and its subnodes
  794. }
  795. //
  796. // Prepare the leaf segments. We want all leaves, a specific leaf, or
  797. // no leaf at all.
  798. //
  799. leafSegment.Segment = fixedLeaf;
  800. leafSegment.IsPattern = TRUE;
  801. leafCount = 1;
  802. MYASSERT (!forceLeafToStar || !fixedLeaf);
  803. if (!fixedLeaf) {
  804. if (noLeafPattern || noPatternsAllowed) {
  805. leafCount = 0;
  806. } else {
  807. leafSegment.Segment = TEXT("*");
  808. }
  809. }
  810. if (nodeCount || leafCount) {
  811. if ((fixedNode && *fixedNode) || (fixedLeaf && *fixedLeaf)) {
  812. result = IsmCreateObjectPattern (
  813. nodeCount ? nodeSegment : NULL,
  814. nodeCount,
  815. leafCount ? &leafSegment : NULL,
  816. leafCount
  817. );
  818. }
  819. }
  820. FreeText (fixedNode);
  821. FreeText (fixedLeaf);
  822. return result;
  823. }
  824. MIG_OBJECTSTRINGHANDLE
  825. TurnIniSpecIntoHandle (
  826. IN PCTSTR IniFile,
  827. IN PCTSTR Section,
  828. IN PCTSTR Key,
  829. IN BOOL NodePatternsAllowed,
  830. IN BOOL LeafPatternsAllowed
  831. )
  832. /*++
  833. Routine Description:
  834. TurnIniSpecIntoHandle converts a ini file specification from the script
  835. syntax into a cobra object.
  836. Arguments:
  837. IniFile- Specifies the ini file in the script syntax.
  838. The string must be a full INI file specification
  839. Section- Specifies the full section or the section pattern
  840. Key - Specifies the full key or the key pattern
  841. PatternsAllowed - if not, the function will compute the base object
  842. Return Value:
  843. A cobra object handle, or NULL if conversion failed.
  844. --*/
  845. {
  846. UINT charsInPattern = 0;
  847. PTSTR iniNode = NULL;
  848. PTSTR iniLeaf = NULL;
  849. PTSTR fixedIniNode = NULL;
  850. PTSTR fixedIniLeaf = NULL;
  851. PTSTR fixedSect = NULL;
  852. PTSTR fixedKey = NULL;
  853. PCTSTR sectKey = NULL;
  854. PCTSTR leaf = NULL;
  855. MIG_SEGMENTS nodePat[1];
  856. MIG_SEGMENTS leafPat[1];
  857. UINT nrSegNode = 0;
  858. UINT nrSegLeaf = 0;
  859. MIG_OBJECTSTRINGHANDLE result = NULL;
  860. if (IniFile) {
  861. iniNode = DuplicatePathString (IniFile, 0);
  862. if (!iniNode) {
  863. // out of memory?
  864. return NULL;
  865. }
  866. iniLeaf = _tcsrchr (iniNode, TEXT('\\'));
  867. if (iniLeaf) {
  868. *iniLeaf = 0;
  869. iniLeaf ++;
  870. } else {
  871. // this was only a leaf specification
  872. iniLeaf = iniNode;
  873. iniNode = NULL;
  874. }
  875. }
  876. if (iniNode) {
  877. // let's fix the iniNode.
  878. if (!pFixPattern (
  879. iniNode,
  880. NULL,
  881. &charsInPattern,
  882. !NodePatternsAllowed,
  883. !NodePatternsAllowed,
  884. TRUE
  885. )) {
  886. // something is wrong with this INI node specification.
  887. // The rule is likely invalid
  888. return NULL;
  889. }
  890. fixedIniNode = AllocText (charsInPattern + 1);
  891. if (!fixedIniNode) {
  892. return NULL;
  893. }
  894. if (!pFixPattern (
  895. iniNode,
  896. fixedIniNode,
  897. NULL,
  898. !NodePatternsAllowed,
  899. !NodePatternsAllowed,
  900. TRUE
  901. )) {
  902. return NULL;
  903. }
  904. }
  905. if (iniLeaf) {
  906. // let's fix the iniLeaf.
  907. if (!pFixPattern (
  908. iniLeaf,
  909. NULL,
  910. &charsInPattern,
  911. !LeafPatternsAllowed,
  912. !LeafPatternsAllowed,
  913. FALSE
  914. )) {
  915. // something is wrong with this INI dir specification.
  916. // The rule is likely invalid
  917. return NULL;
  918. }
  919. fixedIniLeaf = AllocText (charsInPattern + 1);
  920. if (!fixedIniLeaf) {
  921. return NULL;
  922. }
  923. if (!pFixPattern (
  924. iniLeaf,
  925. fixedIniLeaf,
  926. NULL,
  927. !LeafPatternsAllowed,
  928. !LeafPatternsAllowed,
  929. FALSE
  930. )) {
  931. return NULL;
  932. }
  933. }
  934. // now let's fix the section specification. If it contains any pattern and patterns
  935. // are not allowed we will leave it NULL
  936. if (Section) {
  937. if (pFixPattern (
  938. Section,
  939. NULL,
  940. &charsInPattern,
  941. !LeafPatternsAllowed,
  942. FALSE,
  943. FALSE
  944. )) {
  945. fixedSect = AllocText (charsInPattern + 1);
  946. if (fixedSect) {
  947. pFixPattern (
  948. Section,
  949. fixedSect,
  950. NULL,
  951. !LeafPatternsAllowed,
  952. FALSE,
  953. FALSE
  954. );
  955. }
  956. }
  957. }
  958. // now let's fix the key specification. If it contains any pattern and patterns
  959. // are not allowed we will leave it NULL
  960. if (Key) {
  961. if (pFixPattern (
  962. Key,
  963. NULL,
  964. &charsInPattern,
  965. !LeafPatternsAllowed,
  966. FALSE,
  967. FALSE
  968. )) {
  969. fixedKey = AllocText (charsInPattern + 1);
  970. if (fixedKey) {
  971. pFixPattern (
  972. Key,
  973. fixedKey,
  974. NULL,
  975. !LeafPatternsAllowed,
  976. FALSE,
  977. FALSE
  978. );
  979. }
  980. }
  981. }
  982. // finally let's build the object name
  983. sectKey = JoinTextEx (NULL, fixedSect?fixedSect:TEXT(""), (fixedSect && fixedKey)?fixedKey:TEXT(""), TEXT("="), 0, NULL);
  984. if (!sectKey) {
  985. // something went wrong, let's get out of here
  986. FreeText (fixedIniLeaf);
  987. FreeText (fixedIniNode);
  988. if (fixedSect) {
  989. FreeText (fixedSect);
  990. fixedSect = NULL;
  991. }
  992. if (fixedKey) {
  993. FreeText (fixedKey);
  994. fixedKey = NULL;
  995. }
  996. return NULL;
  997. }
  998. if (!LeafPatternsAllowed) {
  999. if (iniLeaf && fixedIniLeaf && StringIMatch (fixedIniLeaf, iniLeaf)) {
  1000. leaf = JoinTextEx (NULL, fixedIniLeaf, sectKey, TEXT("\\"), 0, NULL);
  1001. } else {
  1002. leaf = JoinTextEx (NULL, TEXT(""), sectKey, TEXT("\\"), 0, NULL);
  1003. }
  1004. } else {
  1005. if (fixedIniLeaf) {
  1006. leaf = JoinTextEx (NULL, fixedIniLeaf, sectKey, TEXT("\\"), 0, NULL);
  1007. } else {
  1008. leaf = JoinTextEx (NULL, TEXT(""), sectKey, TEXT("\\"), 0, NULL);
  1009. }
  1010. }
  1011. if (!leaf) {
  1012. // something went wrong, let's get out of here
  1013. FreeText (fixedIniLeaf);
  1014. FreeText (fixedIniNode);
  1015. FreeText (sectKey);
  1016. if (fixedSect) {
  1017. FreeText (fixedSect);
  1018. fixedSect = NULL;
  1019. }
  1020. if (fixedKey) {
  1021. FreeText (fixedKey);
  1022. fixedKey = NULL;
  1023. }
  1024. return NULL;
  1025. }
  1026. nodePat [0].Segment = fixedIniNode?fixedIniNode:TEXT("");
  1027. nodePat [0].IsPattern = TRUE;
  1028. nrSegNode ++;
  1029. leafPat [0].Segment = leaf;
  1030. leafPat [0].IsPattern = TRUE;
  1031. nrSegLeaf ++;
  1032. result = IsmCreateObjectPattern (nodePat, nrSegNode, leafPat, nrSegLeaf);
  1033. if (fixedIniLeaf) {
  1034. FreeText (fixedIniLeaf);
  1035. fixedIniLeaf = NULL;
  1036. }
  1037. if (fixedIniNode) {
  1038. FreeText (fixedIniNode);
  1039. fixedIniNode = NULL;
  1040. }
  1041. FreeText (sectKey);
  1042. FreeText (leaf);
  1043. if (fixedSect) {
  1044. FreeText (fixedSect);
  1045. fixedSect = NULL;
  1046. }
  1047. if (fixedKey) {
  1048. FreeText (fixedKey);
  1049. fixedKey = NULL;
  1050. }
  1051. if (iniNode) {
  1052. FreePathString (iniNode);
  1053. iniNode = NULL;
  1054. } else {
  1055. if (iniLeaf) {
  1056. FreePathString (iniLeaf);
  1057. iniLeaf = NULL;
  1058. }
  1059. }
  1060. return result;
  1061. }
  1062. MIG_OBJECTSTRINGHANDLE
  1063. TurnCertSpecIntoHandle (
  1064. IN PCTSTR CertStore,
  1065. IN PCTSTR CertName,
  1066. IN BOOL PatternsAllowed
  1067. )
  1068. /*++
  1069. Routine Description:
  1070. TurnIniSpecIntoHandle converts a ini file specification from the script
  1071. syntax into a cobra object.
  1072. Arguments:
  1073. IniFile- Specifies the ini file in the script syntax.
  1074. The string must be a full INI file specification
  1075. Section- Specifies the full section or the section pattern
  1076. Key - Specifies the full key or the key pattern
  1077. PatternsAllowed - if not, the function will compute the base object
  1078. Return Value:
  1079. A cobra object handle, or NULL if conversion failed.
  1080. --*/
  1081. {
  1082. UINT charsInPattern = 0;
  1083. PTSTR fixedStore = NULL;
  1084. PTSTR fixedName = NULL;
  1085. PCTSTR leaf = NULL;
  1086. MIG_OBJECTSTRINGHANDLE result = NULL;
  1087. // let's fix the certificate store. We know that no patterns are allowed here,
  1088. // so we will just return NULL if we detect some pattern
  1089. if (!pFixPattern (
  1090. CertStore,
  1091. NULL,
  1092. &charsInPattern,
  1093. TRUE,
  1094. TRUE,
  1095. TRUE
  1096. )) {
  1097. // something is wrong with this store specification.
  1098. // The rule is likely invalid
  1099. return NULL;
  1100. }
  1101. if (charsInPattern != (TcharCount (CertStore) + 1)) {
  1102. // something is wrong with this store specification.
  1103. // The rule is likely invalid
  1104. return NULL;
  1105. }
  1106. fixedStore = AllocText (charsInPattern + 1);
  1107. pFixPattern (
  1108. CertStore,
  1109. fixedStore,
  1110. NULL,
  1111. TRUE,
  1112. TRUE,
  1113. TRUE
  1114. );
  1115. if (!StringIMatch (CertStore, fixedStore)) {
  1116. // something is wrong with this store specification.
  1117. // The rule is likely invalid
  1118. return NULL;
  1119. }
  1120. FreeText (fixedStore);
  1121. // now let's fix the certificate specification. If it contains any pattern and patterns
  1122. // are not allowed we will leave it NULL
  1123. if (CertName) {
  1124. if (pFixPattern (
  1125. CertName,
  1126. NULL,
  1127. &charsInPattern,
  1128. !PatternsAllowed,
  1129. FALSE,
  1130. FALSE
  1131. )) {
  1132. fixedName = AllocText (charsInPattern + 1);
  1133. if (fixedName) {
  1134. pFixPattern (
  1135. CertName,
  1136. fixedName,
  1137. NULL,
  1138. !PatternsAllowed,
  1139. FALSE,
  1140. FALSE
  1141. );
  1142. }
  1143. }
  1144. }
  1145. result = IsmCreateSimpleObjectPattern (CertStore, FALSE, fixedName?fixedName:TEXT(""), TRUE);
  1146. if (fixedName) {
  1147. FreeText (fixedName);
  1148. fixedName = NULL;
  1149. }
  1150. return result;
  1151. }
  1152. BOOL
  1153. pAllocRegistryScriptType (
  1154. IN OUT PATTRIB_DATA AttribData
  1155. )
  1156. {
  1157. TCHAR expandBuffer[4096];
  1158. MIG_CONTENT objectContent;
  1159. DWORD type;
  1160. DWORD size;
  1161. MULTISZ_ENUM multiSzEnum;
  1162. PTSTR ptr;
  1163. if (!AttribData) {
  1164. SetLastError (ERROR_INVALID_DATA);
  1165. return FALSE;
  1166. }
  1167. // verify that we have some registry
  1168. if (!AttribData->ScriptSpecifiedObject) {
  1169. SetLastError (ERROR_INVALID_DATA);
  1170. return FALSE;
  1171. }
  1172. // try to create encoded string
  1173. AttribData->ObjectTypeId = g_RegType;
  1174. AttribData->ObjectName = TurnRegStringIntoHandle (
  1175. AttribData->ScriptSpecifiedObject,
  1176. FALSE,
  1177. NULL
  1178. );
  1179. if (!AttribData->ObjectName) {
  1180. if (GetLastError() == ERROR_SUCCESS) {
  1181. SetLastError (ERROR_INVALID_DATA);
  1182. }
  1183. return FALSE;
  1184. }
  1185. // try to acqure the object
  1186. if (IsmAcquireObject (
  1187. AttribData->ObjectTypeId,
  1188. AttribData->ObjectName,
  1189. &objectContent
  1190. )) {
  1191. AttribData->ObjectContent = IsmGetMemory (sizeof (MIG_CONTENT));
  1192. CopyMemory (AttribData->ObjectContent, &objectContent, sizeof (MIG_CONTENT));
  1193. // finally, we want to prepare the return string
  1194. if (!AttribData->ObjectContent->ContentInFile &&
  1195. (AttribData->ObjectContent->Details.DetailsSize == sizeof (DWORD)) &&
  1196. AttribData->ObjectContent->MemoryContent.ContentBytes
  1197. ) {
  1198. type = *((PDWORD) AttribData->ObjectContent->Details.DetailsData);
  1199. switch (type) {
  1200. case REG_SZ:
  1201. size = SizeOfString ((PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes);
  1202. AttribData->ReturnString = (PCTSTR) IsmGetMemory (size);
  1203. StringCopy (
  1204. (PTSTR) AttribData->ReturnString,
  1205. (PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes
  1206. );
  1207. break;
  1208. case REG_EXPAND_SZ:
  1209. // we need to expand the content. This will be the return string
  1210. AttribData->ReturnString = IsmExpandEnvironmentString (
  1211. AttribData->Platform,
  1212. S_SYSENVVAR_GROUP,
  1213. (PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes,
  1214. NULL
  1215. );
  1216. if (!AttribData->ReturnString) {
  1217. AttribData->ReturnString = IsmDuplicateString ((PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes);
  1218. }
  1219. break;
  1220. case REG_MULTI_SZ:
  1221. size = SizeOfMultiSz ((PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes);
  1222. AttribData->ReturnString = (PCTSTR) IsmGetMemory (size);
  1223. ((PTSTR)AttribData->ReturnString) [0] = 0;
  1224. if (EnumFirstMultiSz (&multiSzEnum, (PCTSTR) AttribData->ObjectContent->MemoryContent.ContentBytes)) {
  1225. do {
  1226. StringCat (
  1227. (PTSTR)AttribData->ReturnString,
  1228. multiSzEnum.CurrentString
  1229. );
  1230. StringCat (
  1231. (PTSTR)AttribData->ReturnString,
  1232. TEXT(";")
  1233. );
  1234. } while (EnumNextMultiSz (&multiSzEnum));
  1235. }
  1236. break;
  1237. case REG_DWORD:
  1238. case REG_DWORD_BIG_ENDIAN:
  1239. AttribData->ReturnString = (PCTSTR) IsmGetMemory ((sizeof (DWORD) * 2 + 3) * sizeof (TCHAR));
  1240. wsprintf (
  1241. (PTSTR) AttribData->ReturnString,
  1242. TEXT("0x%08X"),
  1243. *((PDWORD) AttribData->ObjectContent->MemoryContent.ContentBytes)
  1244. );
  1245. break;
  1246. default:
  1247. AttribData->ReturnString = (PCTSTR) IsmGetMemory ((AttribData->ObjectContent->
  1248. MemoryContent.ContentSize * 3 *
  1249. sizeof (TCHAR)) + sizeof (TCHAR)
  1250. );
  1251. ptr = (PTSTR) AttribData->ReturnString;
  1252. *ptr = 0;
  1253. size = 0;
  1254. while (size < AttribData->ObjectContent->MemoryContent.ContentSize) {
  1255. wsprintf (ptr, TEXT("%02X"), *(AttribData->ObjectContent->MemoryContent.ContentBytes + size));
  1256. size ++;
  1257. ptr = GetEndOfString (ptr);
  1258. if (size < AttribData->ObjectContent->MemoryContent.ContentSize) {
  1259. StringCopy (ptr, TEXT(","));
  1260. ptr = GetEndOfString (ptr);
  1261. }
  1262. }
  1263. }
  1264. } else if (IsmIsObjectHandleNodeOnly (AttribData->ObjectName)) {
  1265. //
  1266. // Node only case
  1267. //
  1268. AttribData->ReturnString = (PCTSTR) IsmGetMemory (sizeof (TCHAR));
  1269. ptr = (PTSTR) AttribData->ReturnString;
  1270. *ptr = 0;
  1271. }
  1272. }
  1273. return TRUE;
  1274. }
  1275. BOOL
  1276. pAllocFileScriptType (
  1277. IN OUT PATTRIB_DATA AttribData
  1278. )
  1279. {
  1280. MIG_OBJECTSTRINGHANDLE objectName;
  1281. MIG_OBJECTSTRINGHANDLE objectNameLong;
  1282. PCTSTR nativeNameLong;
  1283. MIG_CONTENT objectContent;
  1284. PCTSTR sanitizedPath = NULL;
  1285. PCTSTR longFileName = NULL;
  1286. if (!AttribData) {
  1287. SetLastError (ERROR_INVALID_DATA);
  1288. return FALSE;
  1289. }
  1290. // verify that we have some registry
  1291. if (!AttribData->ScriptSpecifiedObject) {
  1292. SetLastError (ERROR_INVALID_DATA);
  1293. return FALSE;
  1294. }
  1295. sanitizedPath = SanitizePath (AttribData->ScriptSpecifiedObject);
  1296. if (!sanitizedPath) {
  1297. if (GetLastError() == ERROR_SUCCESS) {
  1298. SetLastError (ERROR_INVALID_DATA);
  1299. }
  1300. return FALSE;
  1301. }
  1302. longFileName = sanitizedPath;
  1303. // let's get the long file name for this. We need to call
  1304. // ISM for this because we might be on the wrong platform
  1305. objectName = TurnFileStringIntoHandle (
  1306. longFileName,
  1307. PFF_NO_LEAF_PATTERN
  1308. );
  1309. if (objectName) {
  1310. objectNameLong = IsmGetLongName (MIG_FILE_TYPE|AttribData->Platform, objectName);
  1311. if (objectNameLong) {
  1312. nativeNameLong = IsmGetNativeObjectName (MIG_FILE_TYPE|AttribData->Platform, objectNameLong);
  1313. if (nativeNameLong) {
  1314. longFileName = DuplicatePathString (nativeNameLong, 0);
  1315. IsmReleaseMemory (nativeNameLong);
  1316. }
  1317. IsmDestroyObjectHandle (objectNameLong);
  1318. }
  1319. IsmDestroyObjectHandle (objectName);
  1320. }
  1321. // try to create encoded string
  1322. AttribData->ObjectTypeId = g_FileType;
  1323. AttribData->ObjectName = TurnFileStringIntoHandle (
  1324. longFileName,
  1325. PFF_NO_LEAF_PATTERN
  1326. );
  1327. if (!AttribData->ObjectName) {
  1328. if (longFileName != sanitizedPath) {
  1329. FreePathString (longFileName);
  1330. longFileName = NULL;
  1331. }
  1332. FreePathString (sanitizedPath);
  1333. if (GetLastError() == ERROR_SUCCESS) {
  1334. SetLastError (ERROR_INVALID_DATA);
  1335. }
  1336. return FALSE;
  1337. }
  1338. // try to acqure the object
  1339. if (IsmAcquireObject (
  1340. AttribData->ObjectTypeId,
  1341. AttribData->ObjectName,
  1342. &objectContent
  1343. )) {
  1344. AttribData->ObjectContent = IsmGetMemory (sizeof (MIG_CONTENT));
  1345. CopyMemory (AttribData->ObjectContent, &objectContent, sizeof (MIG_CONTENT));
  1346. AttribData->ReturnString = IsmGetMemory (SizeOfString (longFileName));
  1347. StringCopy ((PTSTR) AttribData->ReturnString, longFileName);
  1348. }
  1349. if (longFileName != sanitizedPath) {
  1350. FreePathString (longFileName);
  1351. longFileName = NULL;
  1352. }
  1353. FreePathString (sanitizedPath);
  1354. return TRUE;
  1355. }
  1356. BOOL
  1357. pAllocDirectoryScriptType (
  1358. IN OUT PATTRIB_DATA AttribData
  1359. )
  1360. {
  1361. MIG_OBJECTSTRINGHANDLE objectName;
  1362. MIG_OBJECTSTRINGHANDLE objectNameLong;
  1363. PCTSTR nativeNameLong;
  1364. MIG_CONTENT objectContent;
  1365. PCTSTR sanitizedPath;
  1366. PCTSTR longFileName = NULL;
  1367. if (!AttribData) {
  1368. SetLastError (ERROR_INVALID_DATA);
  1369. return FALSE;
  1370. }
  1371. // verify that we have some registry
  1372. if (!AttribData->ScriptSpecifiedObject) {
  1373. SetLastError (ERROR_INVALID_DATA);
  1374. return FALSE;
  1375. }
  1376. sanitizedPath = SanitizePath (AttribData->ScriptSpecifiedObject);
  1377. if (!sanitizedPath) {
  1378. SetLastError (ERROR_INVALID_DATA);
  1379. return FALSE;
  1380. }
  1381. longFileName = sanitizedPath;
  1382. // let's get the long file name for this. We need to call
  1383. // ISM for this because we might be on the wrong platform
  1384. objectName = TurnFileStringIntoHandle (
  1385. sanitizedPath,
  1386. PFF_PATTERN_IS_DIR | PFF_NO_LEAF_AT_ALL
  1387. );
  1388. if (objectName) {
  1389. objectNameLong = IsmGetLongName (MIG_FILE_TYPE|AttribData->Platform, objectName);
  1390. if (objectNameLong) {
  1391. nativeNameLong = IsmGetNativeObjectName (MIG_FILE_TYPE|AttribData->Platform, objectNameLong);
  1392. if (nativeNameLong) {
  1393. longFileName = DuplicatePathString (nativeNameLong, 0);
  1394. IsmReleaseMemory (nativeNameLong);
  1395. }
  1396. IsmDestroyObjectHandle (objectNameLong);
  1397. }
  1398. IsmDestroyObjectHandle (objectName);
  1399. }
  1400. // try to create encoded string
  1401. AttribData->ObjectTypeId = g_FileType;
  1402. AttribData->ObjectName = TurnFileStringIntoHandle (
  1403. sanitizedPath,
  1404. PFF_PATTERN_IS_DIR | PFF_NO_LEAF_AT_ALL
  1405. );
  1406. if (!AttribData->ObjectName) {
  1407. if (longFileName != sanitizedPath) {
  1408. FreePathString (longFileName);
  1409. longFileName = NULL;
  1410. }
  1411. FreePathString (sanitizedPath);
  1412. if (GetLastError() == ERROR_SUCCESS) {
  1413. SetLastError (ERROR_INVALID_DATA);
  1414. }
  1415. return FALSE;
  1416. }
  1417. // try to acqure the object
  1418. if (IsmAcquireObject (
  1419. AttribData->ObjectTypeId,
  1420. AttribData->ObjectName,
  1421. &objectContent
  1422. )) {
  1423. AttribData->ObjectContent = IsmGetMemory (sizeof (MIG_CONTENT));
  1424. CopyMemory (AttribData->ObjectContent, &objectContent, sizeof (MIG_CONTENT));
  1425. AttribData->ReturnString = IsmGetMemory (SizeOfString (longFileName));
  1426. StringCopy ((PTSTR) AttribData->ReturnString, longFileName);
  1427. }
  1428. if (longFileName != sanitizedPath) {
  1429. FreePathString (longFileName);
  1430. longFileName = NULL;
  1431. }
  1432. FreePathString (sanitizedPath);
  1433. return TRUE;
  1434. }
  1435. BOOL
  1436. pFreeIsmObjectScriptType (
  1437. IN OUT PATTRIB_DATA AttribData
  1438. )
  1439. {
  1440. if (AttribData->ReturnString) {
  1441. IsmReleaseMemory (AttribData->ReturnString);
  1442. AttribData->ReturnString = NULL;
  1443. }
  1444. AttribData->ObjectTypeId = 0;
  1445. if (AttribData->ObjectName) {
  1446. IsmDestroyObjectHandle (AttribData->ObjectName);
  1447. AttribData->ObjectName = NULL;
  1448. }
  1449. if (AttribData->ObjectContent) {
  1450. IsmReleaseObject (AttribData->ObjectContent);
  1451. IsmReleaseMemory (AttribData->ObjectContent);
  1452. AttribData->ObjectContent = NULL;
  1453. }
  1454. return TRUE;
  1455. }
  1456. BOOL
  1457. pAllocTextScriptType (
  1458. IN OUT PATTRIB_DATA AttribData
  1459. )
  1460. {
  1461. if (!AttribData) {
  1462. SetLastError (ERROR_INVALID_DATA);
  1463. return FALSE;
  1464. }
  1465. // verify that we have some registry
  1466. if (!AttribData->ScriptSpecifiedObject) {
  1467. SetLastError (ERROR_INVALID_DATA);
  1468. return FALSE;
  1469. }
  1470. AttribData->ReturnString = IsmGetMemory (SizeOfString (AttribData->ScriptSpecifiedObject));
  1471. StringCopy ((PTSTR) AttribData->ReturnString, AttribData->ScriptSpecifiedObject);
  1472. return TRUE;
  1473. }
  1474. BOOL
  1475. pFreeTextScriptType (
  1476. IN OUT PATTRIB_DATA AttribData
  1477. )
  1478. {
  1479. if (AttribData->ReturnString) {
  1480. IsmReleaseMemory (AttribData->ReturnString);
  1481. AttribData->ReturnString = NULL;
  1482. }
  1483. return TRUE;
  1484. }
  1485. BOOL
  1486. pAllocSystemScriptType (
  1487. IN OUT PATTRIB_DATA AttribData
  1488. )
  1489. {
  1490. PTSTR specificSection = NULL;
  1491. MIG_OSVERSIONINFO versionInfo;
  1492. UINT tchars;
  1493. BOOL detected = FALSE;
  1494. if (!AttribData) {
  1495. SetLastError (ERROR_INVALID_DATA);
  1496. return FALSE;
  1497. }
  1498. // verify that we have some registry
  1499. if (!AttribData->ScriptSpecifiedObject) {
  1500. SetLastError (ERROR_INVALID_DATA);
  1501. return FALSE;
  1502. }
  1503. if (!IsmGetOsVersionInfo (PLATFORM_SOURCE, &versionInfo)) {
  1504. return FALSE;
  1505. }
  1506. tchars = 1;
  1507. if (versionInfo.OsTypeName) {
  1508. tchars += TcharCount (versionInfo.OsTypeName) + 1;
  1509. }
  1510. if (versionInfo.OsMajorVersionName) {
  1511. tchars += TcharCount (versionInfo.OsMajorVersionName) + 1;
  1512. }
  1513. if (versionInfo.OsMinorVersionName) {
  1514. tchars += TcharCount (versionInfo.OsMinorVersionName);
  1515. }
  1516. specificSection = AllocText (tchars);
  1517. if (!specificSection) {
  1518. return FALSE;
  1519. }
  1520. if (!detected && versionInfo.OsTypeName) {
  1521. wsprintf (
  1522. specificSection,
  1523. TEXT("%s"),
  1524. versionInfo.OsTypeName
  1525. );
  1526. if (StringIMatch (AttribData->ScriptSpecifiedObject, specificSection)) {
  1527. detected = TRUE;
  1528. }
  1529. if (!detected && versionInfo.OsMajorVersionName) {
  1530. wsprintf (
  1531. specificSection,
  1532. TEXT("%s.%s"),
  1533. versionInfo.OsTypeName,
  1534. versionInfo.OsMajorVersionName
  1535. );
  1536. if (StringIMatch (AttribData->ScriptSpecifiedObject, specificSection)) {
  1537. detected = TRUE;
  1538. }
  1539. if (!detected && versionInfo.OsMinorVersionName) {
  1540. wsprintf (
  1541. specificSection,
  1542. TEXT("%s.%s.%s"),
  1543. versionInfo.OsTypeName,
  1544. versionInfo.OsMajorVersionName,
  1545. versionInfo.OsMinorVersionName
  1546. );
  1547. if (StringIMatch (AttribData->ScriptSpecifiedObject, specificSection)) {
  1548. detected = TRUE;
  1549. }
  1550. }
  1551. }
  1552. }
  1553. if (detected) {
  1554. AttribData->ReturnString = IsmGetMemory (SizeOfString (AttribData->ScriptSpecifiedObject));
  1555. StringCopy ((PTSTR) AttribData->ReturnString, AttribData->ScriptSpecifiedObject);
  1556. }
  1557. FreeText (specificSection);
  1558. specificSection = NULL;
  1559. return TRUE;
  1560. }
  1561. BOOL
  1562. pFreeSystemScriptType (
  1563. IN OUT PATTRIB_DATA AttribData
  1564. )
  1565. {
  1566. if (AttribData->ReturnString) {
  1567. IsmReleaseMemory (AttribData->ReturnString);
  1568. AttribData->ReturnString = NULL;
  1569. }
  1570. return TRUE;
  1571. }
  1572. BOOL
  1573. pAllocIniFileScriptType (
  1574. IN OUT PATTRIB_DATA AttribData
  1575. )
  1576. {
  1577. PTSTR fileName = NULL;
  1578. PTSTR sectName = NULL;
  1579. PTSTR keyName = NULL;
  1580. PTSTR charPtr = NULL;
  1581. PTSTR result = NULL;
  1582. DWORD allocatedChars;
  1583. DWORD chars;
  1584. if (!AttribData) {
  1585. SetLastError (ERROR_INVALID_DATA);
  1586. return FALSE;
  1587. }
  1588. // verify that we have something specified
  1589. if (!AttribData->ScriptSpecifiedObject) {
  1590. SetLastError (ERROR_INVALID_DATA);
  1591. return FALSE;
  1592. }
  1593. // Now, let's extract the INI file name, section and key
  1594. fileName = DuplicatePathString (AttribData->ScriptSpecifiedObject, 0);
  1595. if (!fileName) {
  1596. return FALSE;
  1597. }
  1598. charPtr = _tcschr (fileName, TEXT('/'));
  1599. if (charPtr) {
  1600. sectName = _tcsinc (charPtr);
  1601. *charPtr = 0;
  1602. if (sectName) {
  1603. charPtr = _tcschr (sectName, TEXT('/'));
  1604. if (charPtr) {
  1605. keyName = _tcsinc (charPtr);
  1606. *charPtr = 0;
  1607. }
  1608. }
  1609. }
  1610. result = NULL;
  1611. allocatedChars = 256;
  1612. do {
  1613. if (result) {
  1614. FreePathString (result);
  1615. }
  1616. allocatedChars *= 2;
  1617. result = AllocPathString (allocatedChars);
  1618. if (!result) {
  1619. return FALSE;
  1620. }
  1621. chars = GetPrivateProfileString (
  1622. sectName,
  1623. keyName,
  1624. TEXT(""),
  1625. result,
  1626. allocatedChars,
  1627. fileName
  1628. );
  1629. } while (chars >= allocatedChars - 1);
  1630. if (chars) {
  1631. AttribData->ReturnString = IsmGetMemory (SizeOfString (result));
  1632. StringCopy ((PTSTR) AttribData->ReturnString, result);
  1633. FreePathString (result);
  1634. result = NULL;
  1635. return TRUE;
  1636. }
  1637. FreePathString (result);
  1638. result = NULL;
  1639. FreePathString (fileName);
  1640. fileName = NULL;
  1641. return FALSE;
  1642. }
  1643. BOOL
  1644. pFreeIniFileScriptType (
  1645. IN OUT PATTRIB_DATA AttribData
  1646. )
  1647. {
  1648. if (AttribData->ReturnString) {
  1649. IsmReleaseMemory (AttribData->ReturnString);
  1650. AttribData->ReturnString = NULL;
  1651. }
  1652. return TRUE;
  1653. }
  1654. BOOL
  1655. AllocScriptType (
  1656. IN OUT PATTRIB_DATA AttribData CALLER_INITIALIZED
  1657. )
  1658. {
  1659. PTAG_TO_SCRIPTTYPEFN scriptFn = g_TagToScriptTypeFn;
  1660. while (scriptFn->Tag) {
  1661. if (StringIMatch (scriptFn->Tag, AttribData->ScriptSpecifiedType)) {
  1662. break;
  1663. }
  1664. scriptFn ++;
  1665. }
  1666. if (scriptFn->Tag) {
  1667. return (scriptFn->AllocFunction (AttribData));
  1668. } else {
  1669. return FALSE;
  1670. }
  1671. }
  1672. BOOL
  1673. FreeScriptType (
  1674. IN PATTRIB_DATA AttribData ZEROED
  1675. )
  1676. {
  1677. PTAG_TO_SCRIPTTYPEFN scriptFn = g_TagToScriptTypeFn;
  1678. while (scriptFn->Tag) {
  1679. if (StringIMatch (scriptFn->Tag, AttribData->ScriptSpecifiedType)) {
  1680. break;
  1681. }
  1682. scriptFn ++;
  1683. }
  1684. if (scriptFn->Tag) {
  1685. return (scriptFn->FreeFunction (AttribData));
  1686. } else {
  1687. return FALSE;
  1688. }
  1689. }