Source code of Windows XP (NT5)
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.

2941 lines
84 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. sgmqueue.c
  5. Abstract:
  6. Parses the v1 script, builds rules and queues enumeration callbacks.
  7. Author:
  8. Jim Schmidt (jimschm) 12-Mar-2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. //
  13. // Includes
  14. //
  15. #include "pch.h"
  16. #include "v2app.h"
  17. #include "v1p.h"
  18. #define DBG_SCRIPT "Script"
  19. //
  20. // Strings
  21. //
  22. // None
  23. //
  24. // Constants
  25. //
  26. // none
  27. //
  28. // Macros
  29. //
  30. // None
  31. //
  32. // Types
  33. //
  34. // None
  35. //
  36. // Globals
  37. //
  38. MIG_OPERATIONID g_RenameFileExOp;
  39. MIG_OPERATIONID g_RenameFileOp;
  40. MIG_OPERATIONID g_RenameExOp;
  41. MIG_OPERATIONID g_RenameOp;
  42. BOOL g_VcmMode;
  43. BOOL g_PreParse;
  44. //
  45. // Macro expansion list
  46. //
  47. // None
  48. //
  49. // Private function prototypes
  50. //
  51. VCMPARSE ScriptVcmParse;
  52. VCMQUEUEENUMERATION ScriptVcmQueueEnumeration;
  53. SGMPARSE ScriptSgmParse;
  54. SGMQUEUEENUMERATION ScriptSgmQueueEnumeration;
  55. BOOL
  56. pSelectFilesAndFolders (
  57. VOID
  58. );
  59. BOOL
  60. pParseAllInfs (
  61. IN BOOL PreParse
  62. );
  63. //
  64. // Macro expansion definition
  65. //
  66. // None
  67. //
  68. // Code
  69. //
  70. BOOL
  71. pCommonQueueEnumeration (
  72. IN BOOL PreParse
  73. )
  74. {
  75. MIG_OBJECTSTRINGHANDLE objectHandle;
  76. ACTION_STRUCT actionStruct;
  77. BOOL b = FALSE;
  78. //
  79. // INF-based inclusion/exclusion mechanism. We are called first to pre-parse
  80. // the INF (to allow the UI to alter the results). Then we are called to
  81. // queue the enumeration.
  82. //
  83. if (PreParse) {
  84. g_RenameFileExOp = IsmRegisterOperation (S_OPERATION_V1_FILEMOVEEX, TRUE);
  85. g_RenameFileOp = IsmRegisterOperation (S_OPERATION_V1_FILEMOVE, TRUE);
  86. g_RenameOp = IsmRegisterOperation (S_OPERATION_MOVE, FALSE);
  87. g_DefaultIconOp = IsmRegisterOperation (S_OPERATION_DEFICON_FIXCONTENT, FALSE);
  88. g_DefaultIconData = IsmRegisterProperty (S_V1PROP_ICONDATA, FALSE);
  89. g_FileCollPatternData = IsmRegisterProperty (S_V1PROP_FILECOLLPATTERN, FALSE);
  90. g_RenameExOp = IsmRegisterOperation (S_OPERATION_ENHANCED_MOVE, FALSE);
  91. g_RegAutoFilterOp = IsmRegisterOperation (S_OPERATION_REG_AUTO_FILTER, FALSE);
  92. return pParseAllInfs (TRUE);
  93. }
  94. //
  95. // Now queue enumeration
  96. //
  97. MYASSERT (g_RenameFileExOp);
  98. MYASSERT (g_RenameFileOp);
  99. MYASSERT (g_RenameOp);
  100. MYASSERT (g_RegAutoFilterOp);
  101. //
  102. // From the sgm point of view, the v1 tool supports the following:
  103. //
  104. // - Optional transfer of the entire HKCU
  105. // - Optional transfer of the entire HKLM
  106. // - Optional transfer of all files except for OS files
  107. // - INF-based inclusion/exclusion mechanism
  108. // - Specialized migration of certain settings (RAS, printers)
  109. //
  110. // This SGM implements this functionality set.
  111. //
  112. __try {
  113. //
  114. // Component-based inclusion mechanism
  115. //
  116. if (!pSelectFilesAndFolders ()) {
  117. __leave;
  118. }
  119. //
  120. // INF-based inclusion/exclusion mechanism
  121. //
  122. if (!pParseAllInfs (FALSE)) {
  123. __leave;
  124. }
  125. //
  126. // If the /u was specified at the command line we want to suck and apply all HKR
  127. // like if we had a rule in the script: AddReg=HKR\*
  128. //
  129. if (IsmIsEnvironmentFlagSet (IsmGetRealPlatform(), NULL, S_ENV_HKCU_V1)) {
  130. ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
  131. objectHandle = TurnRegStringIntoHandle (TEXT("HKCU\\*"), TRUE, NULL);
  132. MYASSERT (objectHandle);
  133. actionStruct.ObjectBase = TurnRegStringIntoHandle (TEXT("HKCU\\*"), FALSE, NULL);
  134. MYASSERT (actionStruct.ObjectBase);
  135. //
  136. // Add this rule
  137. //
  138. if (AddRule (
  139. g_RegType,
  140. actionStruct.ObjectBase,
  141. objectHandle,
  142. ACTIONGROUP_INCLUDE,
  143. ACTION_PERSIST,
  144. &actionStruct
  145. )) {
  146. AddRuleEx (
  147. g_RegType,
  148. actionStruct.ObjectBase,
  149. objectHandle,
  150. ACTIONGROUP_DEFAULTPRIORITY,
  151. ACTION_PRIORITYDEST,
  152. NULL,
  153. RULEGROUP_PRIORITY
  154. );
  155. IsmHookEnumeration (
  156. g_RegType,
  157. objectHandle,
  158. ObjectPriority,
  159. 0,
  160. NULL
  161. );
  162. //
  163. // Queue enumeration for include patterns
  164. //
  165. IsmQueueEnumeration (
  166. g_RegType,
  167. objectHandle,
  168. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  169. 0,
  170. NULL
  171. );
  172. }
  173. IsmDestroyObjectHandle (objectHandle);
  174. }
  175. b = TRUE;
  176. }
  177. __finally {
  178. }
  179. return b;
  180. }
  181. VOID
  182. QueueAllFiles (
  183. VOID
  184. )
  185. {
  186. static BOOL done = FALSE;
  187. MIG_OBJECTSTRINGHANDLE objectHandle;
  188. MIG_SEGMENTS nodeSeg[2];
  189. if (done) {
  190. return;
  191. }
  192. done = TRUE;
  193. nodeSeg[0].Segment = TEXT("*");
  194. nodeSeg[0].IsPattern = TRUE ;
  195. objectHandle = IsmCreateObjectPattern (nodeSeg, 1, ALL_PATTERN, 0);
  196. IsmQueueEnumeration (g_FileType, objectHandle, NulCallback, 0, NULL);
  197. IsmDestroyObjectHandle (objectHandle);
  198. }
  199. VOID
  200. pQueueAllReg (
  201. VOID
  202. )
  203. {
  204. static BOOL done = FALSE;
  205. MIG_OBJECTSTRINGHANDLE objectHandle;
  206. MIG_SEGMENTS nodeSeg[2];
  207. MIG_PLATFORMTYPEID platform = IsmGetRealPlatform();
  208. if (done) {
  209. return;
  210. }
  211. done = TRUE;
  212. //
  213. // Optional transfer of entire HKCU
  214. //
  215. if (IsmIsEnvironmentFlagSet (platform, NULL, S_ENV_HKCU_ON)) {
  216. nodeSeg[0].Segment = TEXT("HKCU\\");
  217. nodeSeg[0].IsPattern = FALSE;
  218. nodeSeg[1].Segment = TEXT("*");
  219. nodeSeg[1].IsPattern = TRUE;
  220. objectHandle = IsmCreateObjectPattern (nodeSeg, 2, ALL_PATTERN, 0);
  221. IsmQueueEnumeration (g_RegType, objectHandle, NulCallback, 0, NULL);
  222. IsmDestroyObjectHandle (objectHandle);
  223. }
  224. //
  225. // Optional transfer of entire HKLM
  226. //
  227. if (IsmIsEnvironmentFlagSet (platform, NULL, S_ENV_HKLM_ON)) {
  228. nodeSeg[0].Segment = TEXT("HKLM\\");
  229. nodeSeg[0].IsPattern = FALSE;
  230. nodeSeg[1].Segment = TEXT("*");
  231. nodeSeg[1].IsPattern = TRUE;
  232. objectHandle = IsmCreateObjectPattern (nodeSeg, 2, ALL_PATTERN, 0);
  233. IsmQueueEnumeration (g_RegType, objectHandle, NulCallback, 0, NULL);
  234. IsmDestroyObjectHandle (objectHandle);
  235. }
  236. }
  237. BOOL
  238. WINAPI
  239. ScriptSgmParse (
  240. IN PVOID Reserved
  241. )
  242. {
  243. return pCommonQueueEnumeration (TRUE);
  244. }
  245. BOOL
  246. WINAPI
  247. ScriptSgmQueueEnumeration (
  248. IN PVOID Reserved
  249. )
  250. {
  251. BOOL result;
  252. result = pCommonQueueEnumeration (FALSE);
  253. OEAddComplexRules();
  254. return result;
  255. }
  256. BOOL
  257. WINAPI
  258. ScriptVcmParse (
  259. IN PVOID Reserved
  260. )
  261. {
  262. g_VcmMode = TRUE;
  263. return pCommonQueueEnumeration (TRUE);
  264. }
  265. BOOL
  266. WINAPI
  267. ScriptVcmQueueEnumeration (
  268. IN PVOID Reserved
  269. )
  270. {
  271. g_VcmMode = TRUE;
  272. return pCommonQueueEnumeration (FALSE);
  273. }
  274. PCTSTR
  275. pFixDestination (
  276. IN PCTSTR Source,
  277. IN PCTSTR Destination
  278. )
  279. {
  280. PTSTR result = (PTSTR)Source;
  281. PTSTR tempPtr;
  282. PTSTR sKey;
  283. PTSTR sSubKey;
  284. PTSTR sValueName;
  285. PTSTR dKey;
  286. PTSTR dSubKey;
  287. PTSTR dValueName;
  288. UINT size;
  289. BOOL sTree = FALSE;
  290. sKey = DuplicatePathString (Source, 0);
  291. sValueName = _tcschr (sKey, TEXT('['));
  292. if (sValueName) {
  293. tempPtr = _tcschr (sValueName, TEXT(']'));
  294. if (tempPtr) {
  295. *tempPtr = 0;
  296. }
  297. tempPtr = sValueName;
  298. sValueName = _tcsinc (sValueName);
  299. *tempPtr = 0;
  300. tempPtr = _tcsdec2 (sKey, tempPtr);
  301. if (tempPtr) {
  302. if (_tcsnextc (tempPtr) == TEXT('\\')) {
  303. *tempPtr = 0;
  304. }
  305. if (_tcsnextc (tempPtr) == TEXT(' ')) {
  306. *tempPtr = 0;
  307. }
  308. }
  309. }
  310. sSubKey = _tcsrchr (sKey, TEXT('\\'));
  311. if (sSubKey) {
  312. tempPtr = _tcsinc (sSubKey);
  313. if (_tcsnextc (tempPtr) == TEXT('*')) {
  314. *sSubKey = 0;
  315. sTree = TRUE;
  316. }
  317. }
  318. sSubKey = _tcsrchr (sKey, TEXT('\\'));
  319. if (sSubKey) {
  320. tempPtr = sSubKey;
  321. sSubKey = _tcsinc (sSubKey);
  322. *tempPtr = 0;
  323. }
  324. dKey = DuplicatePathString (Destination, 0);
  325. dValueName = _tcschr (dKey, TEXT('['));
  326. if (dValueName) {
  327. tempPtr = _tcschr (dValueName, TEXT(']'));
  328. if (tempPtr) {
  329. *tempPtr = 0;
  330. }
  331. tempPtr = dValueName;
  332. dValueName = _tcsinc (dValueName);
  333. *tempPtr = 0;
  334. tempPtr = _tcsdec2 (dKey, tempPtr);
  335. if (tempPtr) {
  336. if (_tcsnextc (tempPtr) == TEXT('\\')) {
  337. *tempPtr = 0;
  338. }
  339. if (_tcsnextc (tempPtr) == TEXT(' ')) {
  340. *tempPtr = 0;
  341. }
  342. }
  343. }
  344. dSubKey = _tcsrchr (dKey, TEXT('\\'));
  345. if (dSubKey) {
  346. tempPtr = _tcsinc (dSubKey);
  347. if (_tcsnextc (tempPtr) == TEXT('*')) {
  348. *dSubKey = 0;
  349. }
  350. }
  351. dSubKey = _tcsrchr (dKey, TEXT('\\'));
  352. if (dSubKey) {
  353. tempPtr = dSubKey;
  354. dSubKey = _tcsinc (dSubKey);
  355. *tempPtr = 0;
  356. }
  357. if (!dSubKey) {
  358. dSubKey = dKey;
  359. dKey = NULL;
  360. }
  361. size = 0;
  362. if (dKey && *dKey) {
  363. size += TcharCount (dKey) + 1;
  364. } else if (sKey && *sKey) {
  365. size += TcharCount (sKey) + 1;
  366. }
  367. if (dSubKey && *dSubKey) {
  368. size += TcharCount (dSubKey) + 1;
  369. } else if (sSubKey && *sSubKey) {
  370. size += TcharCount (sSubKey) + 1;
  371. }
  372. if (dValueName && *dValueName) {
  373. size += TcharCount (dValueName) + ARRAYSIZE(TEXT(" []")) - 1;
  374. } else if (sValueName && *sValueName) {
  375. size += TcharCount (sValueName) + ARRAYSIZE(TEXT(" []")) - 1;
  376. }
  377. if (sTree) {
  378. size += ARRAYSIZE(TEXT("\\*")) - 1;
  379. }
  380. size += 1;
  381. result = AllocPathString (size);
  382. *result = 0;
  383. if (dKey && *dKey) {
  384. StringCat (result, dKey);
  385. } else if (sKey && *sKey) {
  386. StringCat (result, sKey);
  387. }
  388. if (dSubKey && *dSubKey) {
  389. StringCat (result, TEXT("\\"));
  390. StringCat (result, dSubKey);
  391. } else if (sSubKey && *sSubKey) {
  392. StringCat (result, TEXT("\\"));
  393. StringCat (result, sSubKey);
  394. }
  395. if (sTree) {
  396. StringCat (result, TEXT("\\*"));
  397. }
  398. if (dValueName && *dValueName) {
  399. StringCat (result, TEXT(" ["));
  400. StringCat (result, dValueName);
  401. StringCat (result, TEXT("]"));
  402. } else if (sValueName && *sValueName) {
  403. StringCat (result, TEXT(" ["));
  404. StringCat (result, sValueName);
  405. StringCat (result, TEXT("]"));
  406. }
  407. if (sKey) {
  408. FreePathString (sKey);
  409. }
  410. if (dKey) {
  411. FreePathString (dKey);
  412. } else if (dSubKey) {
  413. FreePathString (dSubKey);
  414. }
  415. return result;
  416. }
  417. BOOL
  418. pParseRegEx1 (
  419. IN HINF Inf,
  420. IN PCTSTR Section,
  421. IN ACTIONGROUP ActionGroup,
  422. IN DWORD ActionFlags,
  423. IN PCTSTR Application OPTIONAL
  424. )
  425. {
  426. // This function handles RenregEx and RegFileEx rules only
  427. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  428. PTSTR srcNode;
  429. PTSTR srcLeaf;
  430. PTSTR destNode;
  431. PTSTR destLeaf;
  432. BOOL result = FALSE;
  433. MIG_OBJECTSTRINGHANDLE srcPattern = NULL;
  434. MIG_OBJECTSTRINGHANDLE destPattern = NULL;
  435. MIG_OBJECTSTRINGHANDLE objectBase = NULL;
  436. ACTION_STRUCT actionStruct;
  437. PCTSTR filesDest;
  438. PCTSTR newDest = NULL;
  439. if (InfFindFirstLine (Inf, Section, NULL, &is)) {
  440. do {
  441. if (IsmCheckCancel()) {
  442. break;
  443. }
  444. __try {
  445. ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
  446. srcNode = InfGetStringField (&is, 1);
  447. srcLeaf = InfGetStringField (&is, 2);
  448. if (!srcNode && !srcLeaf) {
  449. LOG ((LOG_WARNING, (PCSTR) MSG_EMPTY_RENREGEX));
  450. __leave;
  451. }
  452. srcPattern = CreatePatternFromNodeLeaf (srcNode, srcLeaf);
  453. if (!srcPattern) {
  454. __leave;
  455. }
  456. actionStruct.ObjectBase = srcPattern;
  457. objectBase = MakeRegExBase (srcNode, srcLeaf);
  458. destNode = InfGetStringField (&is, 3);
  459. destLeaf = InfGetStringField (&is, 4);
  460. destPattern = CreatePatternFromNodeLeaf (destNode, destLeaf);
  461. if (destPattern) {
  462. actionStruct.ObjectDest = destPattern;
  463. } else {
  464. LOG ((
  465. LOG_ERROR,
  466. (PCSTR) MSG_REG_SPEC_BAD_DEST,
  467. srcNode ? srcNode : TEXT(""),
  468. srcLeaf ? srcLeaf : TEXT(""),
  469. destNode ? destNode : TEXT(""),
  470. destLeaf ? destLeaf : TEXT("")
  471. ));
  472. __leave;
  473. }
  474. if (ActionGroup == ACTIONGROUP_REGFILEEX &&
  475. ActionFlags & ACTION_PERSIST_PATH_IN_DATA) {
  476. filesDest = InfGetStringField (&is, 5);
  477. if (filesDest && *filesDest) {
  478. newDest = SanitizePath (filesDest);
  479. if (newDest) {
  480. actionStruct.AddnlDest = TurnFileStringIntoHandle (
  481. newDest,
  482. PFF_COMPUTE_BASE|
  483. PFF_NO_SUBDIR_PATTERN|
  484. PFF_NO_PATTERNS_ALLOWED|
  485. PFF_NO_LEAF_AT_ALL
  486. );
  487. FreePathString (newDest);
  488. newDest = NULL;
  489. }
  490. if (!actionStruct.AddnlDest) {
  491. LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD_DEST, filesDest));
  492. }
  493. }
  494. actionStruct.ObjectHint = InfGetStringField (&is, 6);
  495. if (actionStruct.ObjectHint && !(*actionStruct.ObjectHint)) {
  496. actionStruct.ObjectHint = NULL;
  497. }
  498. }
  499. if (!AddRule (
  500. g_RegType,
  501. objectBase,
  502. srcPattern,
  503. ACTIONGROUP_RENAMEEX,
  504. ActionFlags,
  505. &actionStruct
  506. )) {
  507. DEBUGMSG ((DBG_ERROR, "Error processing registry rules"));
  508. __leave;
  509. }
  510. AddRuleEx (
  511. g_RegType,
  512. objectBase,
  513. srcPattern,
  514. ACTIONGROUP_DEFAULTPRIORITY,
  515. ACTION_PRIORITYSRC,
  516. NULL,
  517. RULEGROUP_PRIORITY
  518. );
  519. IsmHookEnumeration (
  520. g_RegType,
  521. srcPattern,
  522. ObjectPriority,
  523. 0,
  524. NULL
  525. );
  526. if (IsmIsObjectHandleLeafOnly (srcPattern)) {
  527. pQueueAllReg();
  528. IsmHookEnumeration (
  529. g_RegType,
  530. srcPattern,
  531. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  532. 0,
  533. NULL
  534. );
  535. } else {
  536. if (actionStruct.ObjectBase) {
  537. IsmQueueEnumeration (
  538. g_RegType,
  539. actionStruct.ObjectBase,
  540. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  541. 0,
  542. NULL
  543. );
  544. }
  545. IsmQueueEnumeration (
  546. g_RegType,
  547. srcPattern,
  548. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  549. 0,
  550. NULL
  551. );
  552. }
  553. }
  554. __finally {
  555. if (objectBase) {
  556. IsmDestroyObjectHandle (objectBase);
  557. objectBase = NULL;
  558. }
  559. if (srcPattern) {
  560. IsmDestroyObjectHandle (srcPattern);
  561. srcPattern = NULL;
  562. }
  563. if (destPattern) {
  564. IsmDestroyObjectHandle (destPattern);
  565. destPattern = NULL;
  566. }
  567. }
  568. } while (InfFindNextLine (&is));
  569. result = !IsmCheckCancel();
  570. } else {
  571. LOG ((LOG_ERROR, (PCSTR) MSG_EMPTY_OR_MISSING_SECTION, Section));
  572. }
  573. InfCleanUpInfStruct (&is);
  574. return result;
  575. }
  576. BOOL
  577. pParseRegEx (
  578. IN HINF Inf,
  579. IN PCTSTR Section,
  580. IN ACTIONGROUP ActionGroup,
  581. IN DWORD ActionFlags,
  582. IN PCTSTR Application OPTIONAL
  583. )
  584. {
  585. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  586. PCTSTR srcNode;
  587. PCTSTR srcLeaf;
  588. MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
  589. PCTSTR destNode;
  590. PCTSTR destLeaf;
  591. PCTSTR filesDest;
  592. PCTSTR newDest = NULL;
  593. ACTION_STRUCT actionStruct;
  594. BOOL result = FALSE;
  595. if (InfFindFirstLine (Inf, Section, NULL, &is)) {
  596. do {
  597. if (IsmCheckCancel()) {
  598. break;
  599. }
  600. __try {
  601. ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
  602. srcNode = InfGetStringField (&is, 1);
  603. srcLeaf = InfGetStringField (&is, 2);
  604. if (!srcNode && !srcLeaf) {
  605. LOG ((LOG_ERROR, (PCSTR) MSG_EMPTY_RENREGEX));
  606. __leave;
  607. }
  608. // Validate rule
  609. if (!StringIMatchTcharCount (srcNode, S_HKLM, ARRAYSIZE(S_HKLM) - 1) &&
  610. !StringIMatchTcharCount (srcNode, S_HKR, ARRAYSIZE(S_HKR) - 1) &&
  611. !StringIMatchTcharCount (srcNode, S_HKCC, ARRAYSIZE(S_HKCC) - 1)
  612. ) {
  613. LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_REGROOT, srcNode));
  614. __leave;
  615. }
  616. srcHandle = CreatePatternFromNodeLeaf (srcNode, srcLeaf);
  617. if (!srcHandle) {
  618. LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD, srcNode));
  619. __leave;
  620. }
  621. actionStruct.ObjectBase = MakeRegExBase (srcNode, srcLeaf);
  622. if (!actionStruct.ObjectBase) {
  623. LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD, srcNode));
  624. __leave;
  625. }
  626. if (ActionGroup == ACTIONGROUP_RENAMEEX) {
  627. destNode = InfGetStringField (&is, 3);
  628. destLeaf = InfGetStringField (&is, 4);
  629. if (!destNode && !destLeaf) {
  630. LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_MISSING_DEST, srcNode));
  631. __leave;
  632. }
  633. actionStruct.ObjectDest = CreatePatternFromNodeLeaf (destNode, destLeaf);
  634. if (!actionStruct.ObjectDest) {
  635. LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD_DEST, destNode));
  636. __leave;
  637. }
  638. }
  639. if (ActionGroup == ACTIONGROUP_REGFILEEX ||
  640. ActionGroup == ACTIONGROUP_REGFOLDEREX ||
  641. ActionGroup == ACTIONGROUP_REGICONEX
  642. ) {
  643. destNode = InfGetStringField (&is, 3);
  644. destLeaf = InfGetStringField (&is, 4);
  645. if (destNode && destLeaf &&
  646. *destNode && *destLeaf) {
  647. actionStruct.ObjectDest = CreatePatternFromNodeLeaf (destNode, destLeaf);
  648. if (!actionStruct.ObjectDest) {
  649. LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD_DEST, destNode));
  650. __leave;
  651. }
  652. }
  653. }
  654. if ((ActionGroup == ACTIONGROUP_REGFILEEX ||
  655. ActionGroup == ACTIONGROUP_REGFOLDEREX ||
  656. ActionGroup == ACTIONGROUP_REGICONEX
  657. ) &&
  658. ((ActionFlags & ACTION_PERSIST_PATH_IN_DATA) ||
  659. (ActionFlags & ACTION_PERSIST_ICON_IN_DATA)
  660. )
  661. ) {
  662. filesDest = InfGetStringField (&is, 5);
  663. if (filesDest && *filesDest) {
  664. newDest = SanitizePath (filesDest);
  665. if (newDest) {
  666. actionStruct.AddnlDest = TurnFileStringIntoHandle (
  667. newDest,
  668. PFF_COMPUTE_BASE|
  669. PFF_NO_SUBDIR_PATTERN|
  670. PFF_NO_PATTERNS_ALLOWED|
  671. PFF_NO_LEAF_AT_ALL
  672. );
  673. FreePathString (newDest);
  674. newDest = NULL;
  675. }
  676. if (!actionStruct.AddnlDest) {
  677. LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD_DEST, filesDest));
  678. }
  679. }
  680. actionStruct.ObjectHint = InfGetStringField (&is, 6);
  681. if (actionStruct.ObjectHint && !(*actionStruct.ObjectHint)) {
  682. actionStruct.ObjectHint = NULL;
  683. }
  684. }
  685. //
  686. // Add this rule
  687. //
  688. if (!AddRule (
  689. g_RegType,
  690. actionStruct.ObjectBase,
  691. srcHandle,
  692. ActionGroup,
  693. ActionFlags,
  694. &actionStruct
  695. )) {
  696. DEBUGMSG ((DBG_ERROR, "Error processing registry rules for %s", srcNode));
  697. }
  698. AddRuleEx (
  699. g_RegType,
  700. actionStruct.ObjectBase,
  701. srcHandle,
  702. ACTIONGROUP_DEFAULTPRIORITY,
  703. ACTION_PRIORITYSRC,
  704. NULL,
  705. RULEGROUP_PRIORITY
  706. );
  707. IsmHookEnumeration (
  708. g_RegType,
  709. srcHandle,
  710. ObjectPriority,
  711. 0,
  712. NULL
  713. );
  714. //
  715. // Queue enumeration for include patterns
  716. //
  717. if ((ActionGroup == ACTIONGROUP_INCLUDEEX) ||
  718. (ActionGroup == ACTIONGROUP_RENAMEEX) ||
  719. (ActionGroup == ACTIONGROUP_REGFILEEX) ||
  720. (ActionGroup == ACTIONGROUP_REGFOLDEREX) ||
  721. (ActionGroup == ACTIONGROUP_REGICONEX)
  722. ) {
  723. if (IsmIsObjectHandleLeafOnly (srcHandle)) {
  724. pQueueAllReg();
  725. IsmHookEnumeration (
  726. g_RegType,
  727. srcHandle,
  728. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  729. 0,
  730. NULL
  731. );
  732. } else {
  733. IsmQueueEnumeration (
  734. g_RegType,
  735. srcHandle,
  736. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  737. 0,
  738. NULL
  739. );
  740. }
  741. }
  742. if (ActionGroup == ACTIONGROUP_DELREGKEY) {
  743. IsmHookEnumeration (g_RegType, srcHandle, ExcludeKeyIfValueExists, 0, NULL);
  744. IsmRegisterTypePostEnumerationCallback (g_RegType, PostDelregKeyCallback, NULL);
  745. }
  746. }
  747. __finally {
  748. IsmDestroyObjectHandle (srcHandle);
  749. srcHandle = NULL;
  750. IsmDestroyObjectHandle (actionStruct.ObjectBase);
  751. actionStruct.ObjectBase = NULL;
  752. IsmDestroyObjectHandle (actionStruct.ObjectDest);
  753. actionStruct.ObjectDest = NULL;
  754. IsmDestroyObjectHandle (actionStruct.AddnlDest);
  755. actionStruct.AddnlDest = NULL;
  756. }
  757. } while (InfFindNextLine (&is));
  758. result = !IsmCheckCancel();
  759. } else {
  760. LOG ((LOG_ERROR, (PCSTR) MSG_EMPTY_OR_MISSING_SECTION, Section));
  761. }
  762. InfCleanUpInfStruct (&is);
  763. return result;
  764. }
  765. BOOL
  766. pParseReg (
  767. IN HINF Inf,
  768. IN PCTSTR Section,
  769. IN ACTIONGROUP ActionGroup,
  770. IN DWORD ActionFlags,
  771. IN BOOL FixDestination,
  772. IN PCTSTR Application OPTIONAL
  773. )
  774. {
  775. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  776. PCTSTR pattern;
  777. MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
  778. PCTSTR destination;
  779. PCTSTR newDestination;
  780. PCTSTR filesDest;
  781. PCTSTR newDest = NULL;
  782. ACTION_STRUCT actionStruct;
  783. BOOL hadLeaf = FALSE;
  784. BOOL result = FALSE;
  785. if (InfFindFirstLine (Inf, Section, NULL, &is)) {
  786. do {
  787. if (IsmCheckCancel()) {
  788. break;
  789. }
  790. __try {
  791. ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
  792. srcHandle = NULL;
  793. pattern = InfGetStringField (&is, 0);
  794. if (!pattern) {
  795. pattern = InfGetStringField (&is, 1);
  796. if (!pattern) {
  797. LOG ((LOG_WARNING, (PCSTR) MSG_EMPTY_RENREG));
  798. __leave;
  799. }
  800. }
  801. // Validate rule
  802. if (!StringIMatchTcharCount (pattern, S_HKLM, ARRAYSIZE(S_HKLM) - 1) &&
  803. !StringIMatchTcharCount (pattern, S_HKR, ARRAYSIZE(S_HKR) - 1) &&
  804. !StringIMatchTcharCount (pattern, S_HKCC, ARRAYSIZE(S_HKCC) - 1)
  805. ) {
  806. LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_REGROOT, pattern));
  807. __leave;
  808. }
  809. srcHandle = TurnRegStringIntoHandle (pattern, TRUE, &hadLeaf);
  810. if (!srcHandle) {
  811. LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD, pattern));
  812. __leave;
  813. }
  814. actionStruct.ObjectBase = TurnRegStringIntoHandle (pattern, FALSE, NULL);
  815. if (!actionStruct.ObjectBase) {
  816. LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD, pattern));
  817. __leave;
  818. }
  819. if (ActionGroup == ACTIONGROUP_RENAME) {
  820. destination = InfGetStringField (&is, 1);
  821. if (destination && *destination) {
  822. if (FixDestination) {
  823. newDestination = pFixDestination (pattern, destination);
  824. } else {
  825. newDestination = destination;
  826. }
  827. actionStruct.ObjectDest = TurnRegStringIntoHandle (newDestination, FALSE, NULL);
  828. if (newDestination != destination) {
  829. FreePathString (newDestination);
  830. }
  831. if (!actionStruct.ObjectDest) {
  832. LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD_DEST, destination));
  833. __leave;
  834. }
  835. } else {
  836. LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_MISSING_DEST, pattern));
  837. __leave;
  838. }
  839. }
  840. if (ActionGroup == ACTIONGROUP_REGFILE ||
  841. ActionGroup == ACTIONGROUP_REGFOLDER ||
  842. ActionGroup == ACTIONGROUP_REGICON
  843. ) {
  844. destination = InfGetStringField (&is, 1);
  845. if (destination && *destination) {
  846. if (FixDestination) {
  847. newDestination = pFixDestination (pattern, destination);
  848. } else {
  849. newDestination = destination;
  850. }
  851. actionStruct.ObjectDest = TurnRegStringIntoHandle (newDestination, FALSE, NULL);
  852. if (newDestination != destination) {
  853. FreePathString (newDestination);
  854. }
  855. if (!actionStruct.ObjectDest) {
  856. LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD_DEST, destination));
  857. __leave;
  858. }
  859. }
  860. }
  861. if ((ActionGroup == ACTIONGROUP_REGFILE ||
  862. ActionGroup == ACTIONGROUP_REGFOLDER ||
  863. ActionGroup == ACTIONGROUP_REGICON
  864. ) &&
  865. ((ActionFlags & ACTION_PERSIST_PATH_IN_DATA) ||
  866. (ActionFlags & ACTION_PERSIST_ICON_IN_DATA)
  867. )
  868. ) {
  869. filesDest = InfGetStringField (&is, 2);
  870. if (filesDest && *filesDest) {
  871. newDest = SanitizePath (filesDest);
  872. if (newDest) {
  873. actionStruct.AddnlDest = TurnFileStringIntoHandle (
  874. newDest,
  875. PFF_COMPUTE_BASE|
  876. PFF_NO_SUBDIR_PATTERN|
  877. PFF_NO_PATTERNS_ALLOWED|
  878. PFF_NO_LEAF_AT_ALL
  879. );
  880. FreePathString (newDest);
  881. newDest = NULL;
  882. }
  883. if (!actionStruct.AddnlDest) {
  884. LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD_DEST, filesDest));
  885. }
  886. }
  887. actionStruct.ObjectHint = InfGetStringField (&is, 3);
  888. if (actionStruct.ObjectHint && !(*actionStruct.ObjectHint)) {
  889. actionStruct.ObjectHint = NULL;
  890. }
  891. }
  892. //
  893. // Add this rule
  894. //
  895. if (!AddRule (
  896. g_RegType,
  897. actionStruct.ObjectBase,
  898. srcHandle,
  899. ActionGroup,
  900. ActionFlags,
  901. &actionStruct
  902. )) {
  903. DEBUGMSG ((DBG_ERROR, "Error processing registry rules for %s", pattern));
  904. }
  905. AddRuleEx (
  906. g_RegType,
  907. actionStruct.ObjectBase,
  908. srcHandle,
  909. ACTIONGROUP_DEFAULTPRIORITY,
  910. ACTION_PRIORITYSRC,
  911. NULL,
  912. RULEGROUP_PRIORITY
  913. );
  914. IsmHookEnumeration (
  915. g_RegType,
  916. srcHandle,
  917. ObjectPriority,
  918. 0,
  919. NULL
  920. );
  921. //
  922. // Queue enumeration for include patterns
  923. //
  924. if ((ActionGroup == ACTIONGROUP_INCLUDE) ||
  925. (ActionGroup == ACTIONGROUP_RENAME) ||
  926. (ActionGroup == ACTIONGROUP_REGFILE) ||
  927. (ActionGroup == ACTIONGROUP_REGFOLDER) ||
  928. (ActionGroup == ACTIONGROUP_REGICON)
  929. ) {
  930. if (IsmIsObjectHandleLeafOnly (srcHandle)) {
  931. pQueueAllReg();
  932. IsmHookEnumeration (
  933. g_RegType,
  934. srcHandle,
  935. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  936. 0,
  937. NULL
  938. );
  939. } else {
  940. if ((!hadLeaf) && actionStruct.ObjectBase) {
  941. IsmQueueEnumeration (
  942. g_RegType,
  943. actionStruct.ObjectBase,
  944. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  945. 0,
  946. NULL
  947. );
  948. }
  949. IsmQueueEnumeration (
  950. g_RegType,
  951. srcHandle,
  952. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  953. 0,
  954. NULL
  955. );
  956. }
  957. }
  958. if (ActionGroup == ACTIONGROUP_DELREGKEY) {
  959. IsmHookEnumeration (g_RegType, srcHandle, ExcludeKeyIfValueExists, 0, NULL);
  960. IsmRegisterTypePostEnumerationCallback (g_RegType, PostDelregKeyCallback, NULL);
  961. }
  962. }
  963. __finally {
  964. IsmDestroyObjectHandle (srcHandle);
  965. srcHandle = NULL;
  966. IsmDestroyObjectHandle (actionStruct.ObjectBase);
  967. actionStruct.ObjectBase = NULL;
  968. IsmDestroyObjectHandle (actionStruct.ObjectDest);
  969. actionStruct.ObjectDest = NULL;
  970. IsmDestroyObjectHandle (actionStruct.AddnlDest);
  971. actionStruct.AddnlDest = NULL;
  972. }
  973. } while (InfFindNextLine (&is));
  974. result = !IsmCheckCancel();
  975. } else {
  976. LOG ((LOG_ERROR, (PCSTR) MSG_EMPTY_OR_MISSING_SECTION, Section));
  977. }
  978. InfCleanUpInfStruct (&is);
  979. return result;
  980. }
  981. BOOL
  982. pParseFiles (
  983. IN HINF Inf,
  984. IN PCTSTR Section,
  985. IN ACTIONGROUP ActionGroup,
  986. IN DWORD ActionFlags,
  987. IN PCTSTR Application OPTIONAL
  988. )
  989. {
  990. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  991. PCTSTR pattern;
  992. PCTSTR newPattern = NULL;
  993. PCTSTR dirText;
  994. BOOL tree;
  995. MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
  996. PCTSTR destination;
  997. PCTSTR leafDest;
  998. TCHAR buffer1[MAX_TCHAR_PATH * 2];
  999. ACTION_STRUCT actionStruct;
  1000. BOOL result = FALSE;
  1001. PCTSTR msgNode;
  1002. PCTSTR msgLeaf;
  1003. PCTSTR newDest = NULL;
  1004. BOOL expandResult = TRUE;
  1005. if (InfFindFirstLine (Inf, Section, NULL, &is)) {
  1006. do {
  1007. if (IsmCheckCancel()) {
  1008. break;
  1009. }
  1010. ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
  1011. dirText = InfGetStringField (&is, 0);
  1012. pattern = InfGetStringField (&is, 1);
  1013. if (!pattern) {
  1014. continue;
  1015. }
  1016. //
  1017. // Expand environment variables in pattern (the left-side file spec)
  1018. //
  1019. expandResult = AppSearchAndReplace (
  1020. PLATFORM_SOURCE,
  1021. Application,
  1022. pattern,
  1023. buffer1,
  1024. ARRAYSIZE(buffer1)
  1025. );
  1026. if (!expandResult) {
  1027. // the line contains at least one unexpandable env. variables
  1028. expandResult = AppCheckAndLogUndefVariables (
  1029. PLATFORM_SOURCE,
  1030. Application,
  1031. pattern
  1032. );
  1033. if (expandResult) {
  1034. // the line contains known but undefined env. variables
  1035. continue;
  1036. }
  1037. }
  1038. //
  1039. // Fix the pattern
  1040. //
  1041. newPattern = SanitizePath(buffer1);
  1042. if(!newPattern) {
  1043. continue;
  1044. }
  1045. //
  1046. // Test for dir specification
  1047. //
  1048. if (dirText && StringIMatch (dirText, TEXT("Dir")) && !StringIMatch (pattern, TEXT("Dir"))) {
  1049. tree = TRUE;
  1050. } else {
  1051. tree = FALSE;
  1052. }
  1053. // require full spec or leaf only
  1054. if (!IsValidFileSpec (newPattern) && _tcschr (newPattern, TEXT('\\'))) {
  1055. if (expandResult) {
  1056. LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
  1057. }
  1058. continue;
  1059. }
  1060. srcHandle = TurnFileStringIntoHandle (newPattern, tree ? PFF_PATTERN_IS_DIR : 0);
  1061. if (!srcHandle) {
  1062. LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
  1063. continue;
  1064. }
  1065. actionStruct.ObjectBase = TurnFileStringIntoHandle (
  1066. newPattern,
  1067. PFF_COMPUTE_BASE|
  1068. PFF_NO_SUBDIR_PATTERN|
  1069. (tree?PFF_NO_LEAF_AT_ALL:PFF_NO_LEAF_PATTERN)
  1070. );
  1071. if (actionStruct.ObjectBase && !StringIMatch (actionStruct.ObjectBase, srcHandle)) {
  1072. IsmCreateObjectStringsFromHandle (actionStruct.ObjectBase, &msgNode, &msgLeaf);
  1073. MYASSERT (!msgLeaf);
  1074. LOG ((LOG_INFORMATION, (PCSTR) MSG_FILE_MOVE_BASE_INFO, newPattern, msgNode));
  1075. IsmDestroyObjectString (msgNode);
  1076. IsmDestroyObjectString (msgLeaf);
  1077. }
  1078. if (ActionFlags & ACTION_PERSIST) {
  1079. if (ActionGroup == ACTIONGROUP_INCLUDE ||
  1080. ActionGroup == ACTIONGROUP_INCLUDEEX ||
  1081. ActionGroup == ACTIONGROUP_RENAME ||
  1082. ActionGroup == ACTIONGROUP_RENAMEEX ||
  1083. ActionGroup == ACTIONGROUP_INCLUDERELEVANT ||
  1084. ActionGroup == ACTIONGROUP_INCLUDERELEVANTEX ||
  1085. ActionGroup == ACTIONGROUP_RENAMERELEVANT ||
  1086. ActionGroup == ACTIONGROUP_RENAMERELEVANTEX
  1087. ) {
  1088. //
  1089. // For the CopyFiles and CopyFilesFiltered sections, get the
  1090. // optional destination. If destination is specified, move
  1091. // all of the files into that destination.
  1092. //
  1093. destination = InfGetStringField (&is, 2);
  1094. if (destination && *destination) {
  1095. if (ActionGroup == ACTIONGROUP_INCLUDE) {
  1096. ActionGroup = ACTIONGROUP_RENAME;
  1097. }
  1098. if (ActionGroup == ACTIONGROUP_INCLUDEEX) {
  1099. ActionGroup = ACTIONGROUP_RENAMEEX;
  1100. }
  1101. if (ActionGroup == ACTIONGROUP_INCLUDERELEVANT) {
  1102. ActionGroup = ACTIONGROUP_RENAMERELEVANT;
  1103. }
  1104. if (ActionGroup == ACTIONGROUP_INCLUDERELEVANTEX) {
  1105. ActionGroup = ACTIONGROUP_RENAMERELEVANTEX;
  1106. }
  1107. newDest = SanitizePath (destination);
  1108. if (newDest) {
  1109. actionStruct.ObjectDest = TurnFileStringIntoHandle (
  1110. newDest,
  1111. PFF_COMPUTE_BASE|
  1112. PFF_NO_SUBDIR_PATTERN|
  1113. PFF_NO_PATTERNS_ALLOWED|
  1114. PFF_NO_LEAF_AT_ALL
  1115. );
  1116. FreePathString (newDest);
  1117. newDest = NULL;
  1118. }
  1119. if ((ActionGroup == ACTIONGROUP_RENAMEEX) ||
  1120. (ActionGroup == ACTIONGROUP_RENAMERELEVANTEX)
  1121. ) {
  1122. // we might have an extra field for the leaf name
  1123. leafDest = InfGetStringField (&is, 3);
  1124. if (leafDest && *leafDest) {
  1125. // we have to rebuild actionStruct.ObjectDest
  1126. IsmCreateObjectStringsFromHandle (actionStruct.ObjectDest, &msgNode, &msgLeaf);
  1127. IsmDestroyObjectHandle (actionStruct.ObjectDest);
  1128. actionStruct.ObjectDest = IsmCreateObjectHandle (msgNode, leafDest);
  1129. IsmDestroyObjectString (msgNode);
  1130. IsmDestroyObjectString (msgLeaf);
  1131. }
  1132. }
  1133. if (!actionStruct.ObjectDest) {
  1134. LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD_DEST, destination));
  1135. IsmDestroyObjectHandle (srcHandle);
  1136. srcHandle = NULL;
  1137. continue;
  1138. }
  1139. }
  1140. }
  1141. }
  1142. //
  1143. // Add this rule
  1144. //
  1145. if (!AddRule (
  1146. g_FileType,
  1147. actionStruct.ObjectBase,
  1148. srcHandle,
  1149. ActionGroup,
  1150. ActionFlags,
  1151. &actionStruct
  1152. )) {
  1153. DEBUGMSG ((DBG_ERROR, "Error processing file rules"));
  1154. break;
  1155. }
  1156. //
  1157. // Queue enumeration for include patterns
  1158. //
  1159. if ((ActionGroup == ACTIONGROUP_INCLUDE) ||
  1160. (ActionGroup == ACTIONGROUP_INCLUDEEX) ||
  1161. (ActionGroup == ACTIONGROUP_RENAME) ||
  1162. (ActionGroup == ACTIONGROUP_RENAMEEX) ||
  1163. (ActionGroup == ACTIONGROUP_INCLUDERELEVANT) ||
  1164. (ActionGroup == ACTIONGROUP_INCLUDERELEVANTEX) ||
  1165. (ActionGroup == ACTIONGROUP_RENAMERELEVANT) ||
  1166. (ActionGroup == ACTIONGROUP_RENAMERELEVANTEX)
  1167. ) {
  1168. //
  1169. // Queue the enumeration callback
  1170. //
  1171. if (IsmIsObjectHandleLeafOnly (srcHandle)) {
  1172. DEBUGMSG ((DBG_SCRIPT, "Pattern %s triggered enumeration of entire file system", pattern));
  1173. QueueAllFiles();
  1174. IsmHookEnumeration (
  1175. g_FileType,
  1176. srcHandle,
  1177. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  1178. 0,
  1179. NULL
  1180. );
  1181. } else {
  1182. if (tree && actionStruct.ObjectBase) {
  1183. IsmQueueEnumeration (
  1184. g_FileType,
  1185. actionStruct.ObjectBase,
  1186. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  1187. 0,
  1188. NULL
  1189. );
  1190. }
  1191. IsmQueueEnumeration (
  1192. g_FileType,
  1193. srcHandle,
  1194. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  1195. 0,
  1196. NULL
  1197. );
  1198. }
  1199. }
  1200. IsmDestroyObjectHandle (srcHandle);
  1201. srcHandle = NULL;
  1202. IsmDestroyObjectHandle (actionStruct.ObjectBase);
  1203. actionStruct.ObjectBase = NULL;
  1204. IsmDestroyObjectHandle (actionStruct.ObjectDest);
  1205. actionStruct.ObjectDest = NULL;
  1206. FreePathString(newPattern);
  1207. } while (InfFindNextLine (&is));
  1208. result = !IsmCheckCancel();
  1209. }
  1210. InfCleanUpInfStruct (&is);
  1211. return result;
  1212. }
  1213. BOOL
  1214. pParseLockPartition (
  1215. IN HINF Inf,
  1216. IN PCTSTR Section
  1217. )
  1218. {
  1219. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  1220. PCTSTR pattern;
  1221. MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
  1222. BOOL result = FALSE;
  1223. if (InfFindFirstLine (Inf, Section, NULL, &is)) {
  1224. do {
  1225. if (IsmCheckCancel()) {
  1226. break;
  1227. }
  1228. pattern = InfGetStringField (&is, 0);
  1229. if (!pattern) {
  1230. LOG ((LOG_WARNING, (PCSTR) MSG_EMPTY_FILE_SPEC));
  1231. IsmDestroyObjectHandle (srcHandle);
  1232. srcHandle = NULL;
  1233. continue;
  1234. }
  1235. srcHandle = TurnFileStringIntoHandle (pattern, 0);
  1236. if (!srcHandle) {
  1237. LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
  1238. IsmDestroyObjectHandle (srcHandle);
  1239. srcHandle = NULL;
  1240. continue;
  1241. }
  1242. IsmHookEnumeration (
  1243. g_FileType,
  1244. srcHandle,
  1245. LockPartition,
  1246. 0,
  1247. NULL
  1248. );
  1249. IsmDestroyObjectHandle (srcHandle);
  1250. srcHandle = NULL;
  1251. } while (InfFindNextLine (&is));
  1252. result = !IsmCheckCancel();
  1253. }
  1254. InfCleanUpInfStruct (&is);
  1255. return result;
  1256. }
  1257. BOOL
  1258. pParseRegPriority (
  1259. IN HINF Inf,
  1260. IN PCTSTR Section,
  1261. IN DWORD ActionFlags,
  1262. IN PCTSTR Application, OPTIONAL
  1263. IN BOOL ExtendedPattern
  1264. )
  1265. {
  1266. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  1267. PCTSTR pattern = NULL;
  1268. PCTSTR patternLeaf = NULL;
  1269. PCTSTR baseNode = NULL;
  1270. PCTSTR nodeCopy = NULL;
  1271. PTSTR ptr;
  1272. MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
  1273. MIG_OBJECTSTRINGHANDLE baseHandle = NULL;
  1274. BOOL result = FALSE;
  1275. if (InfFindFirstLine (Inf, Section, NULL, &is)) {
  1276. do {
  1277. if (IsmCheckCancel()) {
  1278. break;
  1279. }
  1280. pattern = InfGetStringField (&is, 1);
  1281. if (!pattern) {
  1282. LOG ((LOG_WARNING, (PCSTR) MSG_EMPTY_RENREG));
  1283. IsmDestroyObjectHandle (srcHandle);
  1284. srcHandle = NULL;
  1285. continue;
  1286. }
  1287. if (ExtendedPattern) {
  1288. patternLeaf = InfGetStringField (&is, 2);
  1289. }
  1290. if (ExtendedPattern) {
  1291. srcHandle = CreatePatternFromNodeLeaf (pattern, patternLeaf?patternLeaf:TEXT("*"));
  1292. } else {
  1293. srcHandle = TurnRegStringIntoHandle (pattern, TRUE, NULL);
  1294. }
  1295. if (!srcHandle) {
  1296. LOG ((LOG_ERROR, (PCSTR) MSG_REG_SPEC_BAD, pattern));
  1297. IsmDestroyObjectHandle (srcHandle);
  1298. srcHandle = NULL;
  1299. continue;
  1300. }
  1301. if (ExtendedPattern) {
  1302. ptr = _tcschr (pattern, TEXT('\\'));
  1303. if (ptr) {
  1304. if (StringIPrefix (pattern, TEXT("HKR\\"))) {
  1305. nodeCopy = JoinText (TEXT("HKCU"), ptr);
  1306. } else {
  1307. nodeCopy = DuplicateText (pattern);
  1308. }
  1309. baseNode = GetPatternBase (nodeCopy);
  1310. if (baseNode) {
  1311. baseHandle = IsmCreateObjectHandle (baseNode, NULL);
  1312. FreePathString (baseNode);
  1313. }
  1314. FreeText (nodeCopy);
  1315. }
  1316. } else {
  1317. baseHandle = TurnRegStringIntoHandle (pattern, FALSE, NULL);
  1318. }
  1319. AddRuleEx (
  1320. g_RegType,
  1321. baseHandle,
  1322. srcHandle,
  1323. ACTIONGROUP_SPECIFICPRIORITY,
  1324. ActionFlags,
  1325. NULL,
  1326. RULEGROUP_PRIORITY
  1327. );
  1328. IsmHookEnumeration (
  1329. g_RegType,
  1330. srcHandle,
  1331. ObjectPriority,
  1332. 0,
  1333. NULL
  1334. );
  1335. IsmDestroyObjectHandle (baseHandle);
  1336. IsmDestroyObjectHandle (srcHandle);
  1337. srcHandle = NULL;
  1338. } while (InfFindNextLine (&is));
  1339. result = !IsmCheckCancel();
  1340. }
  1341. InfCleanUpInfStruct (&is);
  1342. return result;
  1343. }
  1344. BOOL
  1345. pParseFilePriority (
  1346. IN HINF Inf,
  1347. IN PCTSTR Section,
  1348. IN DWORD ActionFlags,
  1349. IN PCTSTR Application OPTIONAL
  1350. )
  1351. {
  1352. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  1353. PCTSTR newPattern = NULL;
  1354. PCTSTR pattern;
  1355. PCTSTR dirText;
  1356. BOOL tree;
  1357. MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
  1358. MIG_OBJECTSTRINGHANDLE baseHandle = NULL;
  1359. TCHAR buffer1[MAX_TCHAR_PATH * 2];
  1360. BOOL result = FALSE;
  1361. BOOL expandResult = TRUE;
  1362. if (InfFindFirstLine (Inf, Section, NULL, &is)) {
  1363. do {
  1364. if (IsmCheckCancel()) {
  1365. break;
  1366. }
  1367. dirText = InfGetStringField (&is, 0);
  1368. pattern = InfGetStringField (&is, 1);
  1369. if (!pattern) {
  1370. continue;
  1371. }
  1372. //
  1373. // Expand environment variables in pattern (the left-side file spec)
  1374. //
  1375. expandResult = AppSearchAndReplace (
  1376. PLATFORM_SOURCE,
  1377. Application,
  1378. pattern,
  1379. buffer1,
  1380. ARRAYSIZE(buffer1)
  1381. );
  1382. if (!expandResult) {
  1383. // the line contains at least one unexpandable env. variables
  1384. expandResult = AppCheckAndLogUndefVariables (
  1385. PLATFORM_SOURCE,
  1386. Application,
  1387. pattern
  1388. );
  1389. if (expandResult) {
  1390. // the line contains known but undefined env. variables
  1391. continue;
  1392. }
  1393. }
  1394. //
  1395. // Fix the pattern
  1396. //
  1397. newPattern = SanitizePath(buffer1);
  1398. if(!newPattern) {
  1399. continue;
  1400. }
  1401. //
  1402. // Test for dir specification
  1403. //
  1404. if (dirText && StringIMatch (dirText, TEXT("Dir"))) {
  1405. tree = TRUE;
  1406. } else {
  1407. tree = FALSE;
  1408. }
  1409. // require full spec
  1410. if (!IsValidFileSpec (newPattern)) {
  1411. if (expandResult) {
  1412. LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
  1413. }
  1414. FreePathString (newPattern);
  1415. newPattern = NULL;
  1416. continue;
  1417. }
  1418. srcHandle = TurnFileStringIntoHandle (newPattern, tree ? PFF_PATTERN_IS_DIR : 0);
  1419. if (!srcHandle) {
  1420. LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
  1421. FreePathString (newPattern);
  1422. newPattern = NULL;
  1423. continue;
  1424. }
  1425. baseHandle = TurnFileStringIntoHandle (
  1426. newPattern,
  1427. PFF_COMPUTE_BASE|
  1428. PFF_NO_SUBDIR_PATTERN|
  1429. (tree?PFF_NO_LEAF_AT_ALL:PFF_NO_LEAF_PATTERN)
  1430. );
  1431. AddRuleEx (
  1432. g_FileType,
  1433. baseHandle,
  1434. srcHandle,
  1435. ACTIONGROUP_SPECIFICPRIORITY,
  1436. ActionFlags,
  1437. NULL,
  1438. RULEGROUP_PRIORITY
  1439. );
  1440. IsmHookEnumeration (
  1441. g_FileType,
  1442. srcHandle,
  1443. ObjectPriority,
  1444. 0,
  1445. NULL
  1446. );
  1447. IsmDestroyObjectHandle (baseHandle);
  1448. IsmDestroyObjectHandle (srcHandle);
  1449. srcHandle = NULL;
  1450. FreePathString (newPattern);
  1451. newPattern = NULL;
  1452. } while (InfFindNextLine (&is));
  1453. result = !IsmCheckCancel();
  1454. }
  1455. InfCleanUpInfStruct (&is);
  1456. return result;
  1457. }
  1458. BOOL
  1459. pParseFileCollisionPattern (
  1460. IN HINF Inf,
  1461. IN PCTSTR Section,
  1462. IN PCTSTR Application OPTIONAL
  1463. )
  1464. {
  1465. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  1466. PCTSTR pattern;
  1467. PCTSTR newPattern = NULL;
  1468. PCTSTR dirText;
  1469. BOOL tree;
  1470. MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
  1471. PCTSTR collPattern;
  1472. TCHAR buffer1[MAX_TCHAR_PATH * 2];
  1473. ACTION_STRUCT actionStruct;
  1474. BOOL result = FALSE;
  1475. PCTSTR msgNode;
  1476. PCTSTR msgLeaf;
  1477. BOOL expandResult = TRUE;
  1478. if (InfFindFirstLine (Inf, Section, NULL, &is)) {
  1479. do {
  1480. if (IsmCheckCancel()) {
  1481. break;
  1482. }
  1483. ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
  1484. dirText = InfGetStringField (&is, 0);
  1485. pattern = InfGetStringField (&is, 1);
  1486. if (!pattern) {
  1487. continue;
  1488. }
  1489. //
  1490. // Expand environment variables in pattern (the left-side file spec)
  1491. //
  1492. expandResult = AppSearchAndReplace (
  1493. PLATFORM_SOURCE,
  1494. Application,
  1495. pattern,
  1496. buffer1,
  1497. ARRAYSIZE(buffer1)
  1498. );
  1499. if (!expandResult) {
  1500. // the line contains at least one unexpandable env. variables
  1501. expandResult = AppCheckAndLogUndefVariables (
  1502. PLATFORM_SOURCE,
  1503. Application,
  1504. pattern
  1505. );
  1506. if (expandResult) {
  1507. // the line contains known but undefined env. variables
  1508. continue;
  1509. }
  1510. }
  1511. //
  1512. // Fix the pattern
  1513. //
  1514. newPattern = SanitizePath(buffer1);
  1515. if(!newPattern) {
  1516. continue;
  1517. }
  1518. //
  1519. // Test for dir specification
  1520. //
  1521. if (dirText && StringIMatch (dirText, TEXT("Dir")) && !StringIMatch (pattern, TEXT("Dir"))) {
  1522. tree = TRUE;
  1523. } else {
  1524. tree = FALSE;
  1525. }
  1526. // require full spec or leaf only
  1527. if (!IsValidFileSpec (newPattern) && _tcschr (newPattern, TEXT('\\'))) {
  1528. if (expandResult) {
  1529. LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
  1530. }
  1531. continue;
  1532. }
  1533. srcHandle = TurnFileStringIntoHandle (newPattern, tree ? PFF_PATTERN_IS_DIR : 0);
  1534. if (!srcHandle) {
  1535. LOG ((LOG_ERROR, (PCSTR) MSG_FILE_SPEC_BAD, pattern));
  1536. continue;
  1537. }
  1538. actionStruct.ObjectBase = TurnFileStringIntoHandle (
  1539. newPattern,
  1540. PFF_COMPUTE_BASE|
  1541. PFF_NO_SUBDIR_PATTERN|
  1542. (tree?PFF_NO_LEAF_AT_ALL:PFF_NO_LEAF_PATTERN)
  1543. );
  1544. collPattern = InfGetStringField (&is, 2);
  1545. if ((!collPattern) || (!(*collPattern))) {
  1546. // we have no collision pattern, let's get out
  1547. continue;
  1548. }
  1549. actionStruct.ObjectHint = IsmDuplicateString (collPattern);
  1550. //
  1551. // Add this rule
  1552. //
  1553. if (!AddRuleEx (
  1554. g_FileType,
  1555. actionStruct.ObjectBase,
  1556. srcHandle,
  1557. ACTIONGROUP_FILECOLLPATTERN,
  1558. 0,
  1559. &actionStruct,
  1560. RULEGROUP_COLLPATTERN
  1561. )) {
  1562. DEBUGMSG ((DBG_ERROR, "Error processing file rules"));
  1563. break;
  1564. }
  1565. //
  1566. // Queue the enumeration callback
  1567. //
  1568. if (IsmIsObjectHandleLeafOnly (srcHandle)) {
  1569. DEBUGMSG ((DBG_SCRIPT, "Pattern %s triggered enumeration of entire file system", pattern));
  1570. IsmHookEnumeration (
  1571. g_FileType,
  1572. srcHandle,
  1573. FileCollPattern,
  1574. 0,
  1575. NULL
  1576. );
  1577. } else {
  1578. if (tree && actionStruct.ObjectBase) {
  1579. IsmHookEnumeration (
  1580. g_FileType,
  1581. actionStruct.ObjectBase,
  1582. FileCollPattern,
  1583. 0,
  1584. NULL
  1585. );
  1586. }
  1587. IsmHookEnumeration (
  1588. g_FileType,
  1589. srcHandle,
  1590. FileCollPattern,
  1591. 0,
  1592. NULL
  1593. );
  1594. }
  1595. IsmDestroyObjectHandle (srcHandle);
  1596. srcHandle = NULL;
  1597. IsmDestroyObjectHandle (actionStruct.ObjectBase);
  1598. actionStruct.ObjectBase = NULL;
  1599. IsmReleaseMemory (actionStruct.ObjectHint);
  1600. actionStruct.ObjectHint = NULL;
  1601. FreePathString(newPattern);
  1602. } while (InfFindNextLine (&is));
  1603. result = !IsmCheckCancel();
  1604. }
  1605. InfCleanUpInfStruct (&is);
  1606. return result;
  1607. }
  1608. BOOL
  1609. pParseOneInstruction (
  1610. IN HINF InfHandle,
  1611. IN PCTSTR Type,
  1612. IN PCTSTR SectionMultiSz,
  1613. IN PINFSTRUCT InfStruct,
  1614. IN PCTSTR Application OPTIONAL
  1615. )
  1616. {
  1617. ACTIONGROUP actionGroup;
  1618. DWORD actionFlags;
  1619. MULTISZ_ENUM e;
  1620. BOOL result = TRUE;
  1621. MIG_PLATFORMTYPEID platform = IsmGetRealPlatform();
  1622. //
  1623. // First thing: look for nested sections
  1624. //
  1625. if (StringIMatch (Type, TEXT("ProcessSection"))) {
  1626. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1627. do {
  1628. result = result & ParseOneApplication (
  1629. PLATFORM_SOURCE,
  1630. InfHandle,
  1631. Application,
  1632. FALSE,
  1633. 0,
  1634. e.CurrentString,
  1635. NULL,
  1636. NULL,
  1637. NULL
  1638. );
  1639. } while (EnumNextMultiSz (&e));
  1640. }
  1641. return result;
  1642. }
  1643. //
  1644. // Parse registry sections
  1645. //
  1646. actionGroup = ACTIONGROUP_NONE;
  1647. actionFlags = 0;
  1648. if (StringIMatch (Type, TEXT("AddReg"))) {
  1649. actionGroup = ACTIONGROUP_INCLUDE;
  1650. actionFlags = ACTION_PERSIST;
  1651. } else if (StringIMatch (Type, TEXT("RenReg"))) {
  1652. actionGroup = ACTIONGROUP_RENAME;
  1653. actionFlags = ACTION_PERSIST;
  1654. } else if (StringIMatch (Type, TEXT("DelReg"))) {
  1655. actionGroup = ACTIONGROUP_EXCLUDE;
  1656. actionFlags = 0;
  1657. } else if (StringIMatch (Type, TEXT("RegFile"))) {
  1658. actionGroup = ACTIONGROUP_REGFILE;
  1659. actionFlags = ACTION_PERSIST_PATH_IN_DATA;
  1660. } else if (StringIMatch (Type, TEXT("RegFolder"))) {
  1661. actionGroup = ACTIONGROUP_REGFOLDER;
  1662. actionFlags = ACTION_PERSIST_PATH_IN_DATA;
  1663. } else if (StringIMatch (Type, TEXT("RegIcon"))) {
  1664. actionGroup = ACTIONGROUP_REGICON;
  1665. actionFlags = ACTION_PERSIST_ICON_IN_DATA;
  1666. } else if (StringIMatch (Type, TEXT("DelRegKey"))) {
  1667. actionGroup = ACTIONGROUP_DELREGKEY;
  1668. actionFlags = 0;
  1669. }
  1670. if (actionGroup != ACTIONGROUP_NONE) {
  1671. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1672. do {
  1673. if (!pParseReg (
  1674. InfHandle,
  1675. e.CurrentString,
  1676. actionGroup,
  1677. actionFlags,
  1678. TRUE,
  1679. Application
  1680. )) {
  1681. result = FALSE;
  1682. if (InfStruct) {
  1683. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1684. }
  1685. break;
  1686. }
  1687. } while (EnumNextMultiSz (&e));
  1688. }
  1689. return result;
  1690. }
  1691. //
  1692. // Parse file sections
  1693. //
  1694. if (StringIMatch (Type, TEXT("CopyFilesFiltered"))) {
  1695. actionGroup = ACTIONGROUP_INCLUDERELEVANT;
  1696. actionFlags = ACTION_PERSIST;
  1697. } else if (StringIMatch (Type, TEXT("CopyFilesFilteredEx"))) {
  1698. actionGroup = ACTIONGROUP_INCLUDERELEVANTEX;
  1699. actionFlags = ACTION_PERSIST;
  1700. } else if (StringIMatch (Type, TEXT("CopyFiles"))) {
  1701. actionGroup = ACTIONGROUP_INCLUDE;
  1702. actionFlags = ACTION_PERSIST;
  1703. } else if (StringIMatch (Type, TEXT("CopyFilesEx"))) {
  1704. actionGroup = ACTIONGROUP_INCLUDEEX;
  1705. actionFlags = ACTION_PERSIST;
  1706. } else if (StringIMatch (Type, TEXT("DelFiles"))) {
  1707. actionGroup = ACTIONGROUP_EXCLUDE;
  1708. actionFlags = 0;
  1709. }
  1710. if (actionGroup != ACTIONGROUP_NONE) {
  1711. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1712. do {
  1713. if (IsmIsEnvironmentFlagSet (platform, NULL, S_ENV_ALL_FILES)) {
  1714. if (!pParseFiles (
  1715. InfHandle,
  1716. e.CurrentString,
  1717. actionGroup,
  1718. actionFlags,
  1719. Application
  1720. )) {
  1721. result = FALSE;
  1722. if (InfStruct) {
  1723. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1724. }
  1725. break;
  1726. }
  1727. } else {
  1728. LOG ((
  1729. LOG_INFORMATION,
  1730. (PCSTR) MSG_IGNORING_FILE_SECTION,
  1731. e.CurrentString
  1732. ));
  1733. }
  1734. } while (EnumNextMultiSz (&e));
  1735. }
  1736. return result;
  1737. }
  1738. //
  1739. // Parse registry priority
  1740. //
  1741. if (StringIMatch (Type, TEXT("ForceDestRegEx"))) {
  1742. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1743. do {
  1744. if (!pParseRegPriority (InfHandle, e.CurrentString, ACTION_PRIORITYDEST, Application, TRUE)) {
  1745. result = FALSE;
  1746. if (InfStruct) {
  1747. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1748. }
  1749. break;
  1750. }
  1751. } while (EnumNextMultiSz (&e));
  1752. }
  1753. return result;
  1754. }
  1755. if (StringIMatch (Type, TEXT("ForceDestReg"))) {
  1756. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1757. do {
  1758. if (!pParseRegPriority (InfHandle, e.CurrentString, ACTION_PRIORITYDEST, Application, FALSE)) {
  1759. result = FALSE;
  1760. if (InfStruct) {
  1761. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1762. }
  1763. break;
  1764. }
  1765. } while (EnumNextMultiSz (&e));
  1766. }
  1767. return result;
  1768. }
  1769. if (StringIMatch (Type, TEXT("ForceSrcRegEx"))) {
  1770. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1771. do {
  1772. if (!pParseRegPriority (InfHandle, e.CurrentString, ACTION_PRIORITYSRC, Application, TRUE)) {
  1773. result = FALSE;
  1774. if (InfStruct) {
  1775. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1776. }
  1777. break;
  1778. }
  1779. } while (EnumNextMultiSz (&e));
  1780. }
  1781. return result;
  1782. }
  1783. if (StringIMatch (Type, TEXT("ForceSrcReg"))) {
  1784. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1785. do {
  1786. if (!pParseRegPriority (InfHandle, e.CurrentString, ACTION_PRIORITYSRC, Application, FALSE)) {
  1787. result = FALSE;
  1788. if (InfStruct) {
  1789. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1790. }
  1791. break;
  1792. }
  1793. } while (EnumNextMultiSz (&e));
  1794. }
  1795. return result;
  1796. }
  1797. //
  1798. // Parse file collision rules (default is %s(%d).%s)
  1799. //
  1800. if (StringIMatch (Type, TEXT("FileCollisionPattern"))) {
  1801. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1802. do {
  1803. if (!pParseFileCollisionPattern (InfHandle, e.CurrentString, Application)) {
  1804. result = FALSE;
  1805. if (InfStruct) {
  1806. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1807. }
  1808. break;
  1809. }
  1810. } while (EnumNextMultiSz (&e));
  1811. }
  1812. return result;
  1813. }
  1814. //
  1815. // Parse restore callback rule
  1816. //
  1817. if (StringIMatch (Type, TEXT("RestoreCallback"))) {
  1818. if (!g_VcmMode) {
  1819. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1820. do {
  1821. IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_DEST_RESTORE, e.CurrentString);
  1822. } while (EnumNextMultiSz (&e));
  1823. }
  1824. }
  1825. return result;
  1826. }
  1827. //
  1828. // Parse destination rule
  1829. //
  1830. if (StringIMatch (Type, TEXT("DestDelReg"))) {
  1831. if (!g_VcmMode) {
  1832. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1833. do {
  1834. IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_DEST_DELREG, e.CurrentString);
  1835. } while (EnumNextMultiSz (&e));
  1836. }
  1837. }
  1838. return result;
  1839. }
  1840. if (StringIMatch (Type, TEXT("DestDelRegEx"))) {
  1841. if (!g_VcmMode) {
  1842. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1843. do {
  1844. IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_DEST_DELREGEX, e.CurrentString);
  1845. } while (EnumNextMultiSz (&e));
  1846. }
  1847. }
  1848. return result;
  1849. }
  1850. //
  1851. // Parse destination detect rules
  1852. //
  1853. if (StringIMatch (Type, TEXT("DestCheckDetect"))) {
  1854. if (!g_VcmMode) {
  1855. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1856. do {
  1857. IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_DEST_CHECKDETECT, e.CurrentString);
  1858. } while (EnumNextMultiSz (&e));
  1859. }
  1860. }
  1861. return result;
  1862. }
  1863. //
  1864. // Parse destination AddObject rule
  1865. //
  1866. if (StringIMatch (Type, TEXT("DestAddObject"))) {
  1867. if (!g_VcmMode) {
  1868. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1869. do {
  1870. IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_DEST_ADDOBJECT, e.CurrentString);
  1871. } while (EnumNextMultiSz (&e));
  1872. }
  1873. }
  1874. return result;
  1875. }
  1876. //
  1877. // Parse execute rule
  1878. //
  1879. if (StringIMatch (Type, TEXT("Execute"))) {
  1880. if (!g_VcmMode) {
  1881. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1882. do {
  1883. IsmAppendEnvironmentString (PLATFORM_SOURCE, NULL, S_ENV_SCRIPT_EXECUTE, e.CurrentString);
  1884. } while (EnumNextMultiSz (&e));
  1885. }
  1886. }
  1887. return result;
  1888. }
  1889. //
  1890. // Parse file priority
  1891. //
  1892. if (StringIMatch (Type, TEXT("ForceDestFile"))) {
  1893. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1894. do {
  1895. if (IsmIsEnvironmentFlagSet (platform, NULL, S_ENV_ALL_FILES)) {
  1896. if (!pParseFilePriority (InfHandle, e.CurrentString, ACTION_PRIORITYDEST, Application)) {
  1897. result = FALSE;
  1898. if (InfStruct) {
  1899. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1900. }
  1901. break;
  1902. }
  1903. } else {
  1904. LOG ((
  1905. LOG_INFORMATION,
  1906. (PCSTR) MSG_IGNORING_FILE_SECTION,
  1907. e.CurrentString
  1908. ));
  1909. }
  1910. } while (EnumNextMultiSz (&e));
  1911. }
  1912. return result;
  1913. }
  1914. if (StringIMatch (Type, TEXT("ForceSrcFile"))) {
  1915. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1916. do {
  1917. if (IsmIsEnvironmentFlagSet (platform, NULL, S_ENV_ALL_FILES)) {
  1918. if (!pParseFilePriority (InfHandle, e.CurrentString, ACTION_PRIORITYSRC, Application)) {
  1919. result = FALSE;
  1920. if (InfStruct) {
  1921. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1922. }
  1923. break;
  1924. }
  1925. } else {
  1926. LOG ((
  1927. LOG_INFORMATION,
  1928. (PCSTR) MSG_IGNORING_FILE_SECTION,
  1929. e.CurrentString
  1930. ));
  1931. }
  1932. } while (EnumNextMultiSz (&e));
  1933. }
  1934. return result;
  1935. }
  1936. //
  1937. // Parse special conversion
  1938. //
  1939. if (StringIMatch (Type, TEXT("Conversion"))) {
  1940. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1941. do {
  1942. if (!DoRegistrySpecialConversion (InfHandle, e.CurrentString)) {
  1943. result = FALSE;
  1944. if (InfStruct) {
  1945. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1946. }
  1947. break;
  1948. }
  1949. } while (EnumNextMultiSz (&e));
  1950. }
  1951. return result;
  1952. }
  1953. if (StringIMatch (Type, TEXT("RenRegFn"))) {
  1954. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1955. do {
  1956. if (!DoRegistrySpecialRename (InfHandle, e.CurrentString)) {
  1957. result = FALSE;
  1958. if (InfStruct) {
  1959. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1960. }
  1961. break;
  1962. }
  1963. } while (EnumNextMultiSz (&e));
  1964. }
  1965. return result;
  1966. }
  1967. //
  1968. // Parse enhanced renreg
  1969. //
  1970. actionGroup = ACTIONGROUP_NONE;
  1971. actionFlags = 0;
  1972. if (StringIMatch (Type, TEXT("AddRegEx"))) {
  1973. actionGroup = ACTIONGROUP_INCLUDEEX;
  1974. actionFlags = ACTION_PERSIST;
  1975. } else if (StringIMatch (Type, TEXT("RenRegEx"))) {
  1976. actionGroup = ACTIONGROUP_RENAMEEX;
  1977. actionFlags = ACTION_PERSIST;
  1978. } else if (StringIMatch (Type, TEXT("DelRegEx"))) {
  1979. actionGroup = ACTIONGROUP_EXCLUDEEX;
  1980. actionFlags = 0;
  1981. } else if (StringIMatch (Type, TEXT("RegFileEx"))) {
  1982. actionGroup = ACTIONGROUP_REGFILEEX;
  1983. actionFlags = ACTION_PERSIST_PATH_IN_DATA;
  1984. } else if (StringIMatch (Type, TEXT("RegFolderEx"))) {
  1985. actionGroup = ACTIONGROUP_REGFOLDEREX;
  1986. actionFlags = ACTION_PERSIST_PATH_IN_DATA;
  1987. } else if (StringIMatch (Type, TEXT("RegIconEx"))) {
  1988. actionGroup = ACTIONGROUP_REGICONEX;
  1989. actionFlags = ACTION_PERSIST_ICON_IN_DATA;
  1990. }
  1991. if (actionGroup != ACTIONGROUP_NONE) {
  1992. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  1993. do {
  1994. if (!pParseRegEx (InfHandle, e.CurrentString, actionGroup, actionFlags, Application)) {
  1995. result = FALSE;
  1996. if (InfStruct) {
  1997. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  1998. }
  1999. break;
  2000. }
  2001. } while (EnumNextMultiSz (&e));
  2002. }
  2003. return result;
  2004. }
  2005. if (StringIMatch (Type, TEXT("LockPartition"))) {
  2006. if (EnumFirstMultiSz (&e, SectionMultiSz)) {
  2007. do {
  2008. if (!pParseLockPartition (InfHandle, e.CurrentString)) {
  2009. result = FALSE;
  2010. if (InfStruct) {
  2011. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  2012. }
  2013. break;
  2014. }
  2015. } while (EnumNextMultiSz (&e));
  2016. }
  2017. return result;
  2018. }
  2019. //
  2020. // Unknown section type
  2021. //
  2022. LOG ((LOG_ERROR, (PCSTR) MSG_UNEXPECTED_SECTION_TYPE, Type));
  2023. if (InfStruct) {
  2024. InfLogContext (LOG_ERROR, InfHandle, InfStruct);
  2025. }
  2026. return FALSE;
  2027. }
  2028. BOOL
  2029. pParseInfInstructionsWorker (
  2030. IN PINFSTRUCT InfStruct,
  2031. IN HINF InfHandle,
  2032. IN PCTSTR Application, OPTIONAL
  2033. IN PCTSTR Section
  2034. )
  2035. {
  2036. PCTSTR type;
  2037. PCTSTR sections;
  2038. GROWBUFFER multiSz = INIT_GROWBUFFER;
  2039. BOOL result = TRUE;
  2040. if (InfFindFirstLine (InfHandle, Section, NULL, InfStruct)) {
  2041. do {
  2042. if (IsmCheckCancel()) {
  2043. result = FALSE;
  2044. break;
  2045. }
  2046. InfResetInfStruct (InfStruct);
  2047. type = InfGetStringField (InfStruct, 0);
  2048. sections = InfGetMultiSzField (InfStruct, 1);
  2049. if (!type || !sections) {
  2050. LOG ((LOG_WARNING, (PCSTR) MSG_BAD_INF_LINE, Section));
  2051. InfLogContext (LOG_WARNING, InfHandle, InfStruct);
  2052. continue;
  2053. }
  2054. result = pParseOneInstruction (InfHandle, type, sections, InfStruct, Application);
  2055. } while (result && InfFindNextLine (InfStruct));
  2056. }
  2057. InfCleanUpInfStruct (InfStruct);
  2058. GbFree (&multiSz);
  2059. return result;
  2060. }
  2061. BOOL
  2062. ParseInfInstructions (
  2063. IN HINF InfHandle,
  2064. IN PCTSTR Application, OPTIONAL
  2065. IN PCTSTR Section
  2066. )
  2067. {
  2068. PCTSTR osSpecificSection;
  2069. BOOL b;
  2070. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  2071. PTSTR instrSection;
  2072. b = pParseInfInstructionsWorker (&is, InfHandle, Application, Section);
  2073. if (b) {
  2074. osSpecificSection = GetMostSpecificSection (&is, InfHandle, Section);
  2075. if (osSpecificSection) {
  2076. b = pParseInfInstructionsWorker (&is, InfHandle, Application, osSpecificSection);
  2077. FreeText (osSpecificSection);
  2078. }
  2079. }
  2080. InfCleanUpInfStruct (&is);
  2081. return b;
  2082. }
  2083. BOOL
  2084. pParseInf (
  2085. IN HINF InfHandle,
  2086. IN BOOL PreParse
  2087. )
  2088. {
  2089. BOOL result = TRUE;
  2090. if (InfHandle == INVALID_HANDLE_VALUE) {
  2091. return FALSE;
  2092. }
  2093. //
  2094. // Process the application sections
  2095. //
  2096. if (!ParseApplications (PLATFORM_SOURCE, InfHandle, TEXT("Applications"), PreParse, MASTERGROUP_APP)) {
  2097. LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_APP_PARSE_FAILURE));
  2098. IsmSetCancel();
  2099. return FALSE;
  2100. }
  2101. //
  2102. // Process system settings
  2103. //
  2104. if (!ParseApplications (PLATFORM_SOURCE, InfHandle, TEXT("System Settings"), PreParse, MASTERGROUP_SYSTEM)) {
  2105. LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_SYSTEM_PARSE_FAILURE));
  2106. IsmSetCancel();
  2107. return FALSE;
  2108. }
  2109. //
  2110. // Process user settings
  2111. //
  2112. if (!ParseApplications (PLATFORM_SOURCE, InfHandle, TEXT("User Settings"), PreParse, MASTERGROUP_USER)) {
  2113. LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_USER_PARSE_FAILURE));
  2114. IsmSetCancel();
  2115. return FALSE;
  2116. }
  2117. //
  2118. // Process files and folders settings
  2119. //
  2120. if (!ProcessFilesAndFolders (InfHandle, TEXT("Files and Folders"), PreParse)) {
  2121. LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_FNF_PARSE_FAILURE));
  2122. IsmSetCancel();
  2123. return FALSE;
  2124. }
  2125. //
  2126. // Process the administrator script sections
  2127. //
  2128. if (!ParseApplications (PLATFORM_SOURCE, InfHandle, TEXT("Administrator Scripts"), PreParse, MASTERGROUP_SCRIPT)) {
  2129. LOG ((LOG_FATAL_ERROR, (PCSTR) MSG_SCRIPT_PARSE_FAILURE));
  2130. IsmSetCancel();
  2131. return FALSE;
  2132. }
  2133. return TRUE;
  2134. }
  2135. BOOL
  2136. pAddFileSpec (
  2137. IN PCTSTR Node, OPTIONAL
  2138. IN PCTSTR Leaf, OPTIONAL
  2139. IN BOOL IncludeSubDirs,
  2140. IN BOOL LeafIsPattern,
  2141. IN ACTIONGROUP ActionGroup,
  2142. IN DWORD ActionFlags,
  2143. IN BOOL DefaultPriority,
  2144. IN BOOL SrcPriority
  2145. )
  2146. {
  2147. MIG_OBJECTSTRINGHANDLE srcHandle = NULL;
  2148. MIG_OBJECTSTRINGHANDLE srcBaseHandle = NULL;
  2149. BOOL result = FALSE;
  2150. ACTION_STRUCT actionStruct;
  2151. __try {
  2152. //
  2153. // Build object string
  2154. //
  2155. MYASSERT (Node || Leaf);
  2156. srcHandle = IsmCreateSimpleObjectPattern (Node, IncludeSubDirs, Leaf, LeafIsPattern);
  2157. if (!srcHandle) {
  2158. __leave;
  2159. }
  2160. if (Node) {
  2161. srcBaseHandle = IsmCreateObjectHandle (Node, NULL);
  2162. }
  2163. //
  2164. // Add this rule
  2165. //
  2166. ZeroMemory (&actionStruct, sizeof (ACTION_STRUCT));
  2167. actionStruct.ObjectBase = srcBaseHandle;
  2168. if (!AddRule (
  2169. g_FileType,
  2170. actionStruct.ObjectBase,
  2171. srcHandle,
  2172. ActionGroup,
  2173. ActionFlags,
  2174. &actionStruct
  2175. )) {
  2176. __leave;
  2177. }
  2178. if (!DefaultPriority) {
  2179. AddRuleEx (
  2180. g_FileType,
  2181. actionStruct.ObjectBase,
  2182. srcHandle,
  2183. ACTIONGROUP_SPECIFICPRIORITY,
  2184. SrcPriority?ACTION_PRIORITYSRC:ACTION_PRIORITYDEST,
  2185. NULL,
  2186. RULEGROUP_PRIORITY
  2187. );
  2188. IsmHookEnumeration (
  2189. g_RegType,
  2190. srcHandle,
  2191. ObjectPriority,
  2192. 0,
  2193. NULL
  2194. );
  2195. }
  2196. //
  2197. // Queue enumeration for include patterns
  2198. //
  2199. if (ActionGroup == ACTIONGROUP_INCLUDE) {
  2200. if (IsmIsObjectHandleLeafOnly (srcHandle)) {
  2201. DEBUGMSG ((
  2202. DBG_SCRIPT,
  2203. "File node %s leaf %s triggered enumeration of entire file system",
  2204. Node,
  2205. Leaf
  2206. ));
  2207. QueueAllFiles();
  2208. IsmHookEnumeration (
  2209. g_FileType,
  2210. srcHandle,
  2211. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  2212. 0,
  2213. NULL
  2214. );
  2215. } else {
  2216. IsmQueueEnumeration (
  2217. g_FileType,
  2218. srcHandle,
  2219. g_VcmMode ? GatherVirtualComputer : PrepareActions,
  2220. 0,
  2221. NULL
  2222. );
  2223. }
  2224. }
  2225. result = TRUE;
  2226. }
  2227. __finally {
  2228. IsmDestroyObjectHandle (srcHandle);
  2229. INVALID_POINTER (srcHandle);
  2230. IsmDestroyObjectHandle (srcBaseHandle);
  2231. INVALID_POINTER (srcBaseHandle);
  2232. }
  2233. return result;
  2234. }
  2235. BOOL
  2236. pParseFilesAndFolders (
  2237. IN UINT Group,
  2238. IN ACTIONGROUP ActionGroup,
  2239. IN DWORD ActionFlags,
  2240. IN BOOL HasNode,
  2241. IN BOOL HasLeaf,
  2242. IN BOOL HasPriority
  2243. )
  2244. {
  2245. MIG_COMPONENT_ENUM e;
  2246. BOOL result = FALSE;
  2247. PCTSTR node;
  2248. PCTSTR leaf;
  2249. PTSTR copyOfData = NULL;
  2250. PTSTR p;
  2251. BOOL defaultPriority = TRUE;
  2252. BOOL srcPriority = FALSE;
  2253. __try {
  2254. //
  2255. // Enumerate all the components
  2256. //
  2257. if (IsmEnumFirstComponent (&e, COMPONENTENUM_ENABLED|COMPONENTENUM_ALIASES, Group)) {
  2258. do {
  2259. //
  2260. // Parse string into node/leaf format
  2261. //
  2262. if (e.MasterGroup != MASTERGROUP_FILES_AND_FOLDERS) {
  2263. continue;
  2264. }
  2265. copyOfData = DuplicateText (e.LocalizedAlias);
  2266. node = copyOfData;
  2267. leaf = NULL;
  2268. if (HasNode && HasLeaf) {
  2269. p = (PTSTR) FindLastWack (copyOfData);
  2270. if (p) {
  2271. leaf = _tcsinc (p);
  2272. *p = 0;
  2273. }
  2274. } else if (!HasNode) {
  2275. node = NULL;
  2276. leaf = JoinText (TEXT("*."), copyOfData);
  2277. }
  2278. //
  2279. // Add rule
  2280. //
  2281. if (!pAddFileSpec (
  2282. node,
  2283. leaf,
  2284. (HasNode && (!HasLeaf)),
  2285. (HasNode && (!HasLeaf)) || (!HasNode),
  2286. ActionGroup,
  2287. ActionFlags,
  2288. defaultPriority,
  2289. srcPriority
  2290. )) {
  2291. IsmAbortComponentEnum (&e);
  2292. __leave;
  2293. }
  2294. if (!HasNode) {
  2295. FreeText (leaf);
  2296. }
  2297. FreeText (copyOfData);
  2298. copyOfData = NULL;
  2299. } while (IsmEnumNextComponent (&e));
  2300. }
  2301. result = TRUE;
  2302. }
  2303. __finally {
  2304. FreeText (copyOfData);
  2305. if (!result) {
  2306. IsmAbortComponentEnum (&e);
  2307. }
  2308. }
  2309. return result;
  2310. }
  2311. BOOL
  2312. pSelectFilesAndFolders (
  2313. VOID
  2314. )
  2315. {
  2316. if (!pParseFilesAndFolders (
  2317. COMPONENT_EXTENSION,
  2318. ACTIONGROUP_INCLUDE,
  2319. ACTION_PERSIST,
  2320. FALSE,
  2321. TRUE,
  2322. TRUE
  2323. )) {
  2324. return FALSE;
  2325. }
  2326. if (!pParseFilesAndFolders (
  2327. COMPONENT_FOLDER,
  2328. ACTIONGROUP_INCLUDE,
  2329. ACTION_PERSIST,
  2330. TRUE,
  2331. FALSE,
  2332. TRUE
  2333. )) {
  2334. return FALSE;
  2335. }
  2336. if (!pParseFilesAndFolders (
  2337. COMPONENT_FILE,
  2338. ACTIONGROUP_INCLUDE,
  2339. ACTION_PERSIST,
  2340. TRUE,
  2341. TRUE,
  2342. TRUE
  2343. )) {
  2344. return FALSE;
  2345. }
  2346. return TRUE;
  2347. }
  2348. BOOL
  2349. pParseAllInfs (
  2350. IN BOOL PreParse
  2351. )
  2352. {
  2353. PTSTR multiSz = NULL;
  2354. MULTISZ_ENUM e;
  2355. UINT sizeNeeded;
  2356. HINF infHandle = INVALID_HANDLE_VALUE;
  2357. ENVENTRY_TYPE dataType;
  2358. BOOL result = FALSE;
  2359. if (IsmGetEnvironmentValue (
  2360. IsmGetRealPlatform (),
  2361. NULL,
  2362. S_GLOBAL_INF_HANDLE,
  2363. (PBYTE)(&infHandle),
  2364. sizeof (HINF),
  2365. &sizeNeeded,
  2366. &dataType
  2367. ) &&
  2368. (sizeNeeded == sizeof (HINF)) &&
  2369. (dataType == ENVENTRY_BINARY)
  2370. ) {
  2371. if (pParseInf (infHandle, PreParse)) {
  2372. result = TRUE;
  2373. }
  2374. InfNameHandle (infHandle, NULL, FALSE);
  2375. } else {
  2376. if (!IsmGetEnvironmentValue (IsmGetRealPlatform (), NULL, S_INF_FILE_MULTISZ, NULL, 0, &sizeNeeded, NULL)) {
  2377. return TRUE; // no INF files specified
  2378. }
  2379. __try {
  2380. multiSz = AllocText (sizeNeeded);
  2381. if (!multiSz) {
  2382. __leave;
  2383. }
  2384. if (!IsmGetEnvironmentValue (IsmGetRealPlatform (), NULL, S_INF_FILE_MULTISZ, (PBYTE) multiSz, sizeNeeded, NULL, NULL)) {
  2385. __leave;
  2386. }
  2387. if (EnumFirstMultiSz (&e, multiSz)) {
  2388. do {
  2389. infHandle = InfOpenInfFile (e.CurrentString);
  2390. if (infHandle != INVALID_HANDLE_VALUE) {
  2391. if (!pParseInf (infHandle, PreParse)) {
  2392. InfCloseInfFile (infHandle);
  2393. infHandle = INVALID_HANDLE_VALUE;
  2394. __leave;
  2395. }
  2396. } else {
  2397. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_INF, e.CurrentString));
  2398. }
  2399. InfCloseInfFile (infHandle);
  2400. infHandle = INVALID_HANDLE_VALUE;
  2401. } while (EnumNextMultiSz (&e));
  2402. }
  2403. result = TRUE;
  2404. }
  2405. __finally {
  2406. if (multiSz) {
  2407. FreeText (multiSz);
  2408. multiSz = NULL;
  2409. }
  2410. }
  2411. }
  2412. return result;
  2413. }