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.

2569 lines
78 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /**************************************************************************/
  4. /***** Common Library Component - Parse Table Handling Routines 2 *********/
  5. /**************************************************************************/
  6. extern BOOL APIENTRY FGetCmo(INT Line, UINT *pcFields, CMO * pcmo);
  7. extern HWND hWndShell;
  8. extern UINT iFieldCur;
  9. extern BOOL fFullScreen;
  10. extern BOOL
  11. FWaitForEventOrFailure(
  12. IN LPSTR InfVar,
  13. IN LPSTR Event,
  14. IN DWORD Timeout
  15. );
  16. extern
  17. BOOL
  18. APIENTRY
  19. FFlushInfParsedInfo(
  20. SZ szInfName
  21. );
  22. VOID TermRestoreDiskLogging();
  23. BOOL APIENTRY FParseBmpShow ( INT Line, UINT * pcFields ) ;
  24. BOOL APIENTRY FParseBmpHide ( INT Line, UINT * pcFields ) ;
  25. // PSEFL pseflHead = (PSEFL)NULL;
  26. /*
  27. ** Array of String Code Pairs for initializing Flow Statement Handling
  28. */
  29. SCP rgscpFlow[] = {
  30. { "SET", spcSet },
  31. { "SET-SUBSYM", spcSetSubsym },
  32. { "SET-SUBST", spcSetSubst },
  33. { "SET-ADD", spcSetAdd },
  34. { "SET-SUB", spcSetSub },
  35. { "SET-MUL", spcSetMul },
  36. { "SET-DIV", spcSetDiv },
  37. { "SET-OR", spcSetOr },
  38. { "SET-HEXTODEC", spcSetHexToDec },
  39. { "SET-DECTOHEX", spcSetDecToHex },
  40. { "IFSTR", spcIfStr },
  41. { "==", spcEQ },
  42. { "!=", spcNE },
  43. { "ELSE", spcElse },
  44. { "ENDIF", spcEndIf },
  45. { "GOTO", spcGoTo },
  46. { "ELSE-IFSTR", spcElseIfStr },
  47. { "IFINT", spcIfInt },
  48. { "<", spcLT },
  49. { "<=", spcLE },
  50. { "=<", spcLE },
  51. { ">", spcGT },
  52. { ">=", spcGE },
  53. { "=>", spcGE },
  54. { "ELSE-IFINT", spcElseIfInt },
  55. { "IFSTR(I)", spcIfStrI },
  56. { "ELSE-IFSTR(I)", spcElseIfStrI },
  57. { "IFCONTAINS", spcIfContains },
  58. { "IFCONTAINS(I)", spcIfContainsI },
  59. { "IN", spcIn },
  60. { "NOT-IN", spcNotIn },
  61. { "ELSE-IFCONTAINS", spcElseIfContains },
  62. { "ELSE-IFCONTAINS(I)", spcElseIfContainsI },
  63. { "FORLISTDO", spcForListDo },
  64. { "ENDFORLISTDO", spcEndForListDo },
  65. { "DEBUG-MSG", spcDebugMsg },
  66. { "STARTWAIT", spcHourglass },
  67. { "ENDWAIT", spcArrow },
  68. { "SETHELPFILE", spcSetHelpFile },
  69. { "CREATEREGKEY", spcCreateRegKey },
  70. { "OPENREGKEY", spcOpenRegKey },
  71. { "FLUSHREGKEY", spcFlushRegKey },
  72. { "CLOSEREGKEY", spcCloseRegKey },
  73. { "DELETEREGKEY", spcDeleteRegKey },
  74. { "DELETEREGTREE", spcDeleteRegTree },
  75. { "ENUMREGKEY", spcEnumRegKey },
  76. { "SETREGVALUE", spcSetRegValue },
  77. { "GETREGVALUE", spcGetRegValue },
  78. { "DELETEREGVALUE", spcDeleteRegValue },
  79. { "ENUMREGVALUE", spcEnumRegValue },
  80. { "GETDRIVEINPATH", spcGetDriveInPath },
  81. { "GETDIRINPATH", spcGetDirInPath },
  82. { "LOADLIBRARY", spcLoadLibrary },
  83. { "FREELIBRARY", spcFreeLibrary },
  84. { "LIBRARYPROCEDURE", spcLibraryProcedure },
  85. { "RUNPROGRAM", spcRunExternalProgram },
  86. { "INVOKEAPPLET", spcInvokeApplet },
  87. { "STARTDETACHEDPROCESS", spcStartDetachedProcess },
  88. { "DEBUG-OUTPUT", spcDebugOutput },
  89. { "SPLIT-STRING", spcSplitString },
  90. { "QUERYLISTSIZE", spcQueryListSize },
  91. { "ADDFILETODELETELIST", spcAddFileToDeleteList },
  92. { "INITRESTOREDISKLOG", spcInitRestoreDiskLog },
  93. { "WAITONEVENT", spcWaitOnEvent },
  94. { "SIGNALEVENT", spcSignalEvent },
  95. { "SLEEP", spcSleep },
  96. { "FLUSHINF", spcFlushInf },
  97. { "BMPSHOW", spcBmpShow },
  98. { "BMPHIDE", spcBmpHide },
  99. { "TERMRESTOREDISKLOG", spcTermRestoreDiskLog },
  100. { NULL, spcUnknown }
  101. };
  102. /*
  103. ** String Parsing Table for handling Flow Statements
  104. */
  105. PSPT psptFlow = (PSPT)NULL;
  106. /*
  107. ** Purpose:
  108. ** Evaluates an expression and determines whether it is valid, and if
  109. ** so, if it is true or false. Used by FHandleFlowStatements().
  110. ** Arguments:
  111. ** hwndParent: window handle to be used in MessageBoxes.
  112. ** ecm: Comparison Mode (eg ecmIfStr, ecmIfInt)
  113. ** szArg1: Non-NULL string for left argument.
  114. ** szArg2: Non-NULL string for right argument.
  115. ** szOper: Non-NULL string for operator (eg '==', '>=', etc).
  116. ** Notes:
  117. ** Requires that psptFlow was initialized with a successful call to
  118. ** FInitFlowPspt().
  119. ** Returns:
  120. ** ercError if comparison is not valid (eg operator and ecm don't
  121. ** correspond).
  122. ** ercTrue if expression evaluates to fTrue.
  123. ** ercFalse if expression evaluates to fFalse.
  124. **
  125. **************************************************************************/
  126. ERC APIENTRY ErcEvaluateCompare(HWND hwndParent,
  127. ECM ecm,
  128. SZ szArg1,
  129. SZ szArg2,
  130. SZ szOper)
  131. {
  132. SPC spc;
  133. PreCondFlowInit(ecmError);
  134. ChkArg(ecm == ecmIfStr ||
  135. ecm == ecmIfStrI ||
  136. ecm == ecmIfInt ||
  137. ecm == ecmIfContains ||
  138. ecm == ecmIfContainsI, 1, ecmError);
  139. ChkArg(szArg1 != (SZ)NULL, 2, ecmError);
  140. ChkArg(szArg2 != (SZ)NULL, 3, ecmError);
  141. ChkArg(szOper != (SZ)NULL &&
  142. *szOper != '\0', 4, ecmError);
  143. EvalAssert((spc = SpcParseString(psptFlow, szOper)) != spcError);
  144. switch (ecm)
  145. {
  146. case ecmIfStrI:
  147. EvalAssert(SzStrUpper(szArg1) == szArg1);
  148. EvalAssert(SzStrUpper(szArg2) == szArg2);
  149. case ecmIfStr:
  150. /* BLOCK */
  151. {
  152. CRC crc = CrcStringCompare(szArg1, szArg2);
  153. switch (spc)
  154. {
  155. case spcEQ:
  156. return ((crc == crcEqual) ? ercTrue : ercFalse);
  157. case spcNE:
  158. return ((crc != crcEqual) ? ercTrue : ercFalse);
  159. }
  160. }
  161. break;
  162. case ecmIfInt:
  163. /* BLOCK */
  164. {
  165. LONG arg1 = atol(szArg1);
  166. LONG arg2 = atol(szArg2);
  167. switch (spc)
  168. {
  169. case spcEQ:
  170. return ((arg1 == arg2) ? ercTrue : ercFalse);
  171. case spcNE:
  172. return ((arg1 != arg2) ? ercTrue : ercFalse);
  173. case spcLT:
  174. return ((arg1 < arg2) ? ercTrue : ercFalse);
  175. case spcLE:
  176. return ((arg1 <= arg2) ? ercTrue : ercFalse);
  177. case spcGT:
  178. return ((arg1 > arg2) ? ercTrue : ercFalse);
  179. case spcGE:
  180. return ((arg1 >= arg2) ? ercTrue : ercFalse);
  181. }
  182. }
  183. break;
  184. case ecmIfContainsI:
  185. EvalAssert(SzStrUpper(szArg1) == szArg1);
  186. EvalAssert(SzStrUpper(szArg2) == szArg2);
  187. case ecmIfContains:
  188. switch (spc)
  189. {
  190. case spcIn:
  191. case spcNotIn:
  192. /* BLOCK */
  193. {
  194. RGSZ rgsz;
  195. PSZ psz;
  196. while ((rgsz = RgszFromSzListValue(szArg2)) == (RGSZ)NULL)
  197. if (!FHandleOOM(hwndParent))
  198. return(ercError);
  199. if ((psz = rgsz) != (RGSZ)NULL)
  200. {
  201. while (*psz != (SZ)NULL)
  202. {
  203. if (CrcStringCompare(szArg1, *psz) == crcEqual)
  204. {
  205. EvalAssert(FFreeRgsz(rgsz));
  206. return((spc == spcIn) ? ercTrue : ercFalse);
  207. }
  208. psz++;
  209. }
  210. EvalAssert(FFreeRgsz(rgsz));
  211. return((spc == spcIn) ? ercFalse : ercTrue);
  212. }
  213. }
  214. }
  215. break;
  216. }
  217. return(ercError);
  218. }
  219. /*
  220. ** Purpose:
  221. ** Skips Script statements until an ENDIF statement is reached.
  222. ** Arguments:
  223. ** hwndParent: window handle to be used in MessageBoxes.
  224. ** Notes:
  225. ** Requires that psptFlow was initialized with a successful call to
  226. ** FInitFlowPspt().
  227. ** Returns:
  228. ** fTrue if successful.
  229. ** fFalse if an ENDIF was not found before running out of Script
  230. ** statements in the current INF section.
  231. **
  232. **************************************************************************/
  233. BOOL APIENTRY FSkipToEnd(INT *Line,HWND hwndParent)
  234. {
  235. UINT cEndsToSkip = 1;
  236. UINT cFields;
  237. SZ szCmd;
  238. SPC spc;
  239. PreCondFlowInit(fFalse);
  240. do {
  241. do {
  242. if ((*Line = FindNextLineFromInf(*Line)) == -1)
  243. return(fTrue); /* REVIEW */
  244. } while ((cFields = CFieldsInInfLine(*Line)) == 0);
  245. while ((szCmd = SzGetNthFieldFromInfLine(*Line,1)) == (SZ)NULL)
  246. if (!FHandleOOM(hwndParent))
  247. return(fFalse);
  248. EvalAssert((spc = SpcParseString(psptFlow, szCmd)) != spcError);
  249. SFree(szCmd);
  250. if (spc >= spcIfFirst &&
  251. spc <= spcIfLast)
  252. cEndsToSkip++;
  253. } while (spc != spcEndIf ||
  254. cEndsToSkip-- != 1);
  255. return(fTrue); /* REVIEW */
  256. return((BOOL)(cFields == 1));
  257. }
  258. /*
  259. ** Purpose:
  260. ** Skips to the next ELSE or ENDIF statement, and if it is an ELSE-IF,
  261. ** evaluates it and possibly skips to the next ELSE statement.
  262. ** Arguments:
  263. ** hwndParent: window handle to be used in MessageBoxes.
  264. ** Notes:
  265. ** Requires that psptFlow was initialized with a successful call to
  266. ** FInitFlowPspt().
  267. ** Returns:
  268. ** fTrue if successful.
  269. ** fFalse if an ENDIF or ELSEIF was not found before running out of Script
  270. ** statements in the current INF section.
  271. **
  272. **************************************************************************/
  273. BOOL APIENTRY FSkipToElse(INT *Line,HWND hwndParent)
  274. {
  275. UINT cEndsToSkip = 0;
  276. UINT cFields;
  277. SPC spc;
  278. PreCondFlowInit(fFalse);
  279. do {
  280. ECM ecm;
  281. ERC erc;
  282. RGSZ rgsz;
  283. SZ sz;
  284. if ((*Line = FindNextLineFromInf(*Line)) == -1)
  285. return(fTrue);
  286. while((sz = SzGetNthFieldFromInfLine(*Line,1)) == NULL) {
  287. if(!FHandleOOM(hwndParent)) {
  288. return(FALSE);
  289. }
  290. }
  291. EvalAssert((spc = SpcParseString(psptFlow, sz)) != spcError);
  292. if ((spc >= spcIfFirst) && (spc <= spcIfLast)) {
  293. cEndsToSkip++;
  294. }
  295. if (cEndsToSkip > 0) {
  296. SFree(sz);
  297. continue;
  298. }
  299. if (spc == spcElseIfStr) {
  300. ecm = ecmIfStr;
  301. } else if (spc == spcElseIfInt) {
  302. ecm = ecmIfInt;
  303. } else if (spc == spcElseIfStrI) {
  304. ecm = ecmIfStrI;
  305. } else if (spc == spcElseIfContains) {
  306. ecm = ecmIfContains;
  307. } else if (spc == spcElseIfContainsI) {
  308. ecm = ecmIfContainsI;
  309. } else {
  310. SFree(sz);
  311. continue;
  312. }
  313. cFields = CFieldsInInfLine(*Line);
  314. if (cFields != 4) {
  315. SFree(sz);
  316. continue; /* REVIEW */
  317. return(fFalse);
  318. }
  319. SFree(sz);
  320. while((rgsz = RgszFromInfScriptLine(*Line,cFields)) == NULL) {
  321. if(!FHandleOOM(hwndParent)) {
  322. return(FALSE);
  323. }
  324. }
  325. if (spc == spcIfStrI || spc == spcIfContainsI) {
  326. EvalAssert(SzStrUpper(rgsz[1]) == rgsz[1]);
  327. EvalAssert(SzStrUpper(rgsz[3]) == rgsz[3]);
  328. }
  329. if ((erc = ErcEvaluateCompare(hwndParent, ecm, rgsz[1], rgsz[3],
  330. rgsz[2])) == ercError)
  331. {
  332. EvalAssert(FFreeRgsz(rgsz));
  333. continue; /* REVIEW */
  334. return(fFalse);
  335. }
  336. EvalAssert(FFreeRgsz(rgsz));
  337. if (erc == ercTrue)
  338. return(fTrue);
  339. } while ((spc != spcEndIf || cEndsToSkip-- > 0) && (spc != spcElse || cEndsToSkip > 0));
  340. return(fTrue); /* REVIEW */
  341. return((BOOL)(cFields == 1));
  342. }
  343. /*
  344. ** Purpose:
  345. ** Allocates a new empty SEFL struct.
  346. ** Arguments:
  347. ** none
  348. ** Returns:
  349. ** non-Null PSEFL if successful; NULL otherwise.
  350. **
  351. **************************************************************************/
  352. PSEFL APIENTRY PseflAlloc(VOID)
  353. {
  354. PSEFL psefl;
  355. if ((psefl = (PSEFL)SAlloc((CB)sizeof(SEFL))) != (PSEFL)NULL)
  356. {
  357. psefl->rgszList = (RGSZ)NULL;
  358. psefl->szDollarSav = (SZ)NULL;
  359. psefl->szPoundSav = (SZ)NULL;
  360. }
  361. return(psefl);
  362. }
  363. /*
  364. ** Purpose:
  365. ** Frees an SEFL struct and any non-Null fields.
  366. ** Arguments:
  367. ** psefl: non-Null SEFL to free.
  368. ** Returns:
  369. ** fTrue if successful; fFalse otherwise.
  370. **
  371. **************************************************************************/
  372. BOOL APIENTRY FFreePsefl(psefl)
  373. PSEFL psefl;
  374. {
  375. ChkArg(psefl != (PSEFL)NULL, 1, fFalse);
  376. if(psefl->rgszList) {
  377. FFreeRgsz(psefl->rgszList);
  378. }
  379. if(psefl->szDollarSav) {
  380. SFree(psefl->szDollarSav);
  381. }
  382. if(psefl->szPoundSav) {
  383. SFree(psefl->szPoundSav);
  384. }
  385. SFree(psefl);
  386. return(fTrue);
  387. }
  388. /*
  389. ** Purpose:
  390. ** Skips Script statements until an ENDFORLISTDO statement is reached.
  391. ** Arguments:
  392. ** hwndParent: window handle to be used in MessageBoxes.
  393. ** Notes:
  394. ** Requires that psptFlow was initialized with a successful call to
  395. ** FInitFlowPspt().
  396. ** Returns:
  397. ** fTrue if successful.
  398. ** fFalse if an ENDFORLISTDO was not found before running out of Script
  399. ** statements in the current INF section.
  400. **
  401. **************************************************************************/
  402. BOOL APIENTRY FSkipToEndOfLoop(INT *Line,HWND hwndParent)
  403. {
  404. UINT cEndOfLoopsToSkip = 1;
  405. UINT cFields;
  406. SZ szCmd;
  407. SPC spc;
  408. PreCondFlowInit(fFalse);
  409. do {
  410. do {
  411. if ((*Line = FindNextLineFromInf(*Line)) == -1)
  412. return(fTrue); /* REVIEW */
  413. } while ((cFields = CFieldsInInfLine(*Line)) == 0);
  414. while ((szCmd = SzGetNthFieldFromInfLine(*Line,1)) == (SZ)NULL)
  415. if (!FHandleOOM(hwndParent))
  416. return(fFalse);
  417. EvalAssert((spc = SpcParseString(psptFlow, szCmd)) != spcError);
  418. SFree(szCmd);
  419. if (spc == spcForListDo)
  420. cEndOfLoopsToSkip++;
  421. } while (spc != spcEndForListDo ||
  422. cEndOfLoopsToSkip-- != 1);
  423. return(fTrue); /* REVIEW */
  424. return((BOOL)(cFields == 1));
  425. }
  426. /*
  427. ** Purpose:
  428. ** Handles a ForListDo statement by setting up the appropriate structs
  429. ** and setting $($) and $(#).
  430. ** Arguments:
  431. ** hwndParent: window handle to be used in MessageBoxes.
  432. ** szList: non-Null list to handle in For Loop.
  433. ** Notes:
  434. ** Requires that psptFlow was initialized with a successful call to
  435. ** FInitFlowPspt().
  436. ** Requires that statements within the loop do not jump out of the loop
  437. ** (eg no GoTo to outside the loop or If/EndIf block that straddles a loop
  438. ** boundary).
  439. ** Returns:
  440. ** fTrue if successful; fFalse otherwise.
  441. **
  442. **************************************************************************/
  443. BOOL APIENTRY FInitForLoop(INT *Line,HWND hwndParent,SZ szList)
  444. {
  445. PSEFL psefl;
  446. RGSZ rgsz;
  447. SZ sz;
  448. ChkArg(szList != (SZ)NULL, 1, fFalse);
  449. PreCondFlowInit(fFalse);
  450. while ((rgsz = RgszFromSzListValue(szList)) == (RGSZ)NULL)
  451. if (!FHandleOOM(hwndParent))
  452. return(fFalse);
  453. if (*rgsz == (SZ)NULL)
  454. {
  455. EvalAssert(FFreeRgsz(rgsz));
  456. return(FSkipToEndOfLoop(Line,hwndParent));
  457. }
  458. while ((psefl = PseflAlloc()) == (PSEFL)NULL)
  459. if (!FHandleOOM(hwndParent))
  460. {
  461. EvalAssert(FFreeRgsz(rgsz));
  462. return(fFalse);
  463. }
  464. psefl->rgszList = rgsz;
  465. psefl->iItemCur = 1;
  466. psefl->iStartLine = *Line;
  467. if ((sz = SzFindSymbolValueInSymTab("$")) != (SZ)NULL)
  468. while ((psefl->szDollarSav = SzDupl(sz)) == (SZ)NULL)
  469. if (!FHandleOOM(hwndParent))
  470. {
  471. EvalAssert(FFreePsefl(psefl));
  472. return(fFalse);
  473. }
  474. if ((sz = SzFindSymbolValueInSymTab("#")) != (SZ)NULL)
  475. while ((psefl->szPoundSav = SzDupl(sz)) == (SZ)NULL)
  476. if (!FHandleOOM(hwndParent))
  477. {
  478. EvalAssert(FFreePsefl(psefl));
  479. return(fFalse);
  480. }
  481. while (!FAddSymbolValueToSymTab("#", "1"))
  482. if (!FHandleOOM(hwndParent))
  483. {
  484. EvalAssert(FFreePsefl(psefl));
  485. return(fFalse);
  486. }
  487. while (!FAddSymbolValueToSymTab("$", rgsz[0]))
  488. if (!FHandleOOM(hwndParent))
  489. {
  490. EvalAssert(FFreePsefl(psefl));
  491. return(fFalse);
  492. }
  493. psefl->pseflNext = pLocalContext()->pseflHead;
  494. pLocalContext()->pseflHead = psefl;
  495. return(fTrue);
  496. }
  497. /*
  498. ** Purpose:
  499. ** Handles an EndForListDo statement by resetting $($) and $(#) and
  500. ** jumping back to the top of the loop (if appropriate).
  501. ** Arguments:
  502. ** hwndParent: window handle to be used in MessageBoxes.
  503. ** Notes:
  504. ** Requires that a ForListDo statement was previously successfully handled.
  505. ** Returns:
  506. ** fTrue if successful; fFalse otherwise.
  507. **
  508. **************************************************************************/
  509. BOOL APIENTRY FContinueForLoop(INT *Line,HWND hwndParent)
  510. {
  511. PSEFL psefl = pLocalContext()->pseflHead;
  512. PCHP rgchp = (PCHP)NULL;
  513. PreCondition(psefl != (PSEFL)NULL, fFalse);
  514. if (*(psefl->rgszList + psefl->iItemCur) == (SZ)NULL)
  515. {
  516. pLocalContext()->pseflHead = psefl->pseflNext;
  517. if (psefl->szDollarSav == (SZ)NULL)
  518. EvalAssert(FRemoveSymbolFromSymTab("$"));
  519. else
  520. while (!FAddSymbolValueToSymTab("$", psefl->szDollarSav))
  521. if (!FHandleOOM(hwndParent))
  522. return(fFalse);
  523. if (psefl->szPoundSav == (SZ)NULL)
  524. EvalAssert(FRemoveSymbolFromSymTab("#"));
  525. else
  526. while (!FAddSymbolValueToSymTab("#", psefl->szPoundSav))
  527. if (!FHandleOOM(hwndParent))
  528. return(fFalse);
  529. EvalAssert(FFreePsefl(psefl));
  530. return(fTrue);
  531. }
  532. while (!FAddSymbolValueToSymTab("$", *(psefl->rgszList + psefl->iItemCur)))
  533. if (!FHandleOOM(hwndParent))
  534. return(fFalse);
  535. while ((rgchp = (PCHP)SAlloc((CB)(20 * sizeof(CHP)))) == (PCHP)NULL)
  536. if (!FHandleOOM(hwndParent))
  537. return(fFalse);
  538. EvalAssert(_itoa(++(psefl->iItemCur), rgchp, 10) == rgchp);
  539. while (!FAddSymbolValueToSymTab("#", rgchp))
  540. if (!FHandleOOM(hwndParent))
  541. {
  542. SFree(rgchp);
  543. return(fFalse);
  544. }
  545. SFree(rgchp);
  546. *Line = psefl->iStartLine;
  547. return(fTrue);
  548. }
  549. /*
  550. ** Purpose:
  551. ** Processes a string and replaces symbol references ('$(SYM)').
  552. ** Arguments:
  553. ** hwndParent: window handle to be used in MessageBoxes.
  554. ** sz: non-Null string to process.
  555. ** Returns:
  556. ** non-Null string if successful; Null otherwise.
  557. **
  558. **************************************************************************/
  559. SZ APIENTRY SzProcessSzForSyms(hwndParent, sz)
  560. HWND hwndParent;
  561. SZ sz;
  562. {
  563. SZ szNew, szCur;
  564. ChkArg(sz != (SZ)NULL, 1, (SZ)NULL);
  565. /* REVIEW doesn't check for running off end of buffer */
  566. while ((szNew = (SZ)SAlloc((CB)cbSymbolMax)) == (SZ)NULL)
  567. if (!FHandleOOM(hwndParent))
  568. return((SZ)NULL);
  569. szCur = szNew;
  570. while (*sz != '\0')
  571. {
  572. SZ szNext;
  573. if (*sz == '$' && *(sz + 1) == '(')
  574. {
  575. szNext = sz;
  576. while (*szNext != ')' && *szNext != '\0')
  577. szNext++;
  578. if (*szNext == ')')
  579. {
  580. SZ szValue;
  581. *szNext = '\0';
  582. sz += 2;
  583. if ((szValue = SzFindSymbolValueInSymTab(sz)) != (SZ)NULL)
  584. {
  585. EvalAssert(strcpy(szCur, szValue) == szCur);
  586. while (*szCur != '\0')
  587. szCur = SzNextChar(szCur);
  588. }
  589. *szNext = ')';
  590. sz = szNext + 1;
  591. continue;
  592. }
  593. }
  594. szNext = SzNextChar(sz);
  595. while (sz < szNext)
  596. *szCur++ = *sz++;
  597. }
  598. *szCur = '\0';
  599. Assert(strlen(szNew) < (CB)(cbSymbolMax - 1));
  600. szCur = SRealloc(szNew,strlen(szNew)+1);
  601. Assert(szCur);
  602. return(szCur);
  603. }
  604. /*
  605. ** Purpose:
  606. ** Processes a string and replaces escape sequences (\n \r \t \###
  607. ** where ### is an octal number) with their byte equivalent.
  608. ** Arguments:
  609. ** hwndParent: window handle to be used in MessageBoxes. NULL implies
  610. ** no message box - just fail.
  611. ** sz: non-Null string to process.
  612. ** Returns:
  613. ** non-Null string if successful; Null otherwise.
  614. **
  615. **************************************************************************/
  616. SZ APIENTRY SzProcessSz(hwndParent, sz)
  617. HWND hwndParent;
  618. SZ sz;
  619. {
  620. SZ szNew, szCur;
  621. ChkArg(sz != (SZ)NULL && strlen(sz) < cbSymbolMax, 2, (SZ)NULL);
  622. while ((szNew = (SZ)SAlloc(cbSymbolMax)) == (SZ)NULL)
  623. if (hwndParent == NULL || !FHandleOOM(hwndParent))
  624. return((SZ)NULL);
  625. szCur = szNew;
  626. while (*sz != '\0')
  627. {
  628. if (*sz == '\\')
  629. {
  630. CHP chp1, chp2, chp3;
  631. if ((chp1 = *(++sz)) == '\\')
  632. *szCur++ = '\\';
  633. else if (chp1 == 'n')
  634. *szCur++ = '\n';
  635. else if (chp1 == 'r')
  636. *szCur++ = '\r';
  637. else if (chp1 == 't')
  638. *szCur++ = '\t';
  639. else if (chp1 < '0' || chp1 > '7' ||
  640. (chp2 = *(sz + 1)) < '0' || chp2 > '7')
  641. {
  642. *szCur++ = '\\';
  643. *szCur++ = chp1;
  644. }
  645. else if ((chp3 = *(sz + 2)) < '0' || chp3 > '7' ||
  646. (chp1 == '0' && chp2 == '0' && chp3 == '0'))
  647. {
  648. *szCur++ = '\\';
  649. *szCur++ = chp1;
  650. *szCur++ = chp2;
  651. *szCur++ = chp3;
  652. sz += 2;
  653. }
  654. else
  655. {
  656. *szCur++ = (CHP)(64*(chp1-'0') + 8*(chp2-'0') + chp3-'0');
  657. sz += 2;
  658. }
  659. sz++;
  660. }
  661. else
  662. {
  663. SZ szNext;
  664. szNext = SzNextChar(sz);
  665. while (sz < szNext)
  666. *szCur++ = *sz++;
  667. }
  668. }
  669. *szCur = '\0';
  670. Assert(strlen(szNew) < (CB)cbSymbolMax);
  671. while ((szCur = SzDupl(szNew)) == (SZ)NULL)
  672. if (hwndParent == NULL || !FHandleOOM(hwndParent))
  673. return((SZ)NULL);
  674. SFree(szNew);
  675. return(szCur);
  676. }
  677. /*
  678. ** Purpose:
  679. ** Handles Flow Script statements (IFs, ELSEs, ENDIFs, GOTOs, SETs),
  680. ** returning when an unrecognized statement is encountered.
  681. ** Arguments:
  682. ** CurrentLine: current line #, gets new line # if return value is fTrue
  683. ** hwndParent: window handle to be used in MessageBoxes.
  684. ** szSection: non-NULL, non-empty section label (goto statements).
  685. ** CallerCFields: if non-NULL, will be filled with the number of fields
  686. ** on the line with the unrecognized statement (if
  687. ** returning TRUE)
  688. ** CallerRgsz: if non-NULL, will get a pointer to the rgsz for the line
  689. ** with the unrecognized statement (if returning true).
  690. ** Notes:
  691. ** Requires that psptFlow was initialized with a successful call to
  692. ** FInitFlowPspt(), that an INF file was successfully opened, that
  693. ** the INF Read location is defined and pointing at the beginning of
  694. ** a script line to be interpreted, and that the Symbol Table was
  695. ** successfully initialized.
  696. ** Returns:
  697. ** fTrue if an unrecognized statement is reached.
  698. ** The caller must free rgsz if CallerRgsz was non-NULL.
  699. ** fFalse if the end of the section is reached before an unrecognized
  700. ** statement is reached, or if a Flow statement has an invalid
  701. ** format.
  702. **
  703. **************************************************************************/
  704. BOOL APIENTRY FHandleFlowStatements(INT *CurrentLine,
  705. HWND hwndParent,
  706. SZ szSection,
  707. UINT *CallerCFields,
  708. RGSZ *CallerRgsz)
  709. {
  710. SPC spc;
  711. RGSZ rgsz;
  712. INT Line = *CurrentLine;
  713. CHP rgchNum[20];
  714. PreCondFlowInit(fFalse);
  715. PreCondInfOpen(fFalse);
  716. PreCondSymTabInit(fFalse);
  717. ChkArg(szSection != (SZ)NULL &&
  718. *szSection != '\0' &&
  719. *szSection != '[', 1, fFalse);
  720. while (fTrue)
  721. {
  722. UINT cFields;
  723. ECM ecm;
  724. ERC erc;
  725. SZ sz, sz2 ;
  726. if ((cFields = CFieldsInInfLine(Line)) == 0)
  727. {
  728. rgsz = (RGSZ)NULL;
  729. spc = spcSet;
  730. goto LNextFlowLine;
  731. }
  732. while ((rgsz = RgszFromInfScriptLine(Line,cFields)) == (RGSZ)NULL)
  733. if (!FHandleOOM(hwndParent))
  734. return(fFalse);
  735. switch ((spc = SpcParseString(psptFlow, rgsz[0])))
  736. {
  737. case spcSet:
  738. SdAtNewLine(Line);
  739. if (cFields != 4 ||
  740. *(rgsz[1]) == '\0' ||
  741. CrcStringCompare(rgsz[2], "=") != crcEqual)
  742. goto LFlowParseError;
  743. while (!FAddSymbolValueToSymTab(rgsz[1], rgsz[3]))
  744. if (!FHandleOOM(hwndParent))
  745. goto LFlowParseExitErr;
  746. break;
  747. case spcSetSubsym:
  748. case spcSetSubst:
  749. SdAtNewLine(Line);
  750. if (cFields != 4 ||
  751. *(rgsz[1]) == '\0' ||
  752. CrcStringCompare(rgsz[2], "=") != crcEqual)
  753. goto LFlowParseError;
  754. if ((spc == spcSetSubsym &&
  755. (sz=SzProcessSzForSyms(hwndParent,rgsz[3])) == (SZ)NULL) ||
  756. (spc == spcSetSubst &&
  757. (sz = SzProcessSz(hwndParent, rgsz[3])) == (SZ)NULL))
  758. goto LFlowParseExitErr;
  759. while (!FAddSymbolValueToSymTab(rgsz[1], sz))
  760. if (!FHandleOOM(hwndParent))
  761. {
  762. SFree(sz);
  763. goto LFlowParseExitErr;
  764. }
  765. SFree(sz);
  766. break;
  767. case spcSetAdd:
  768. case spcSetSub:
  769. case spcSetMul:
  770. case spcSetDiv:
  771. case spcSetOr:
  772. SdAtNewLine(Line);
  773. if ( cFields != 5 ||
  774. *(rgsz[1]) == '\0' ||
  775. CrcStringCompare(rgsz[2], "="
  776. ) != crcEqual) {
  777. goto LFlowParseError;
  778. }
  779. switch ( spc ) {
  780. case spcSetAdd:
  781. _ltoa ( atol(rgsz[3]) + atol(rgsz[4]), rgchNum, 10 );
  782. break;
  783. case spcSetSub:
  784. _ltoa ( atol(rgsz[3]) - atol(rgsz[4]), rgchNum, 10 );
  785. break;
  786. case spcSetMul:
  787. _ltoa ( atol(rgsz[3]) * atol(rgsz[4]), rgchNum, 10 );
  788. break;
  789. case spcSetDiv:
  790. _ltoa ( atol(rgsz[3]) / atol(rgsz[4]), rgchNum, 10 );
  791. break;
  792. case spcSetOr:
  793. _ultoa ( (ULONG)atol(rgsz[2]) | (ULONG)atol(rgsz[4]), rgchNum, 10);
  794. break;
  795. default:
  796. break;
  797. }
  798. while (!FAddSymbolValueToSymTab(rgsz[1], rgchNum)) {
  799. if (!FHandleOOM(hwndParent)) {
  800. goto LFlowParseExitErr;
  801. }
  802. }
  803. break;
  804. case spcSetHexToDec:
  805. SdAtNewLine(Line);
  806. if (cFields != 4 ||
  807. *(rgsz[1]) == '\0' ||
  808. CrcStringCompare(rgsz[2], "=") != crcEqual)
  809. goto LFlowParseError;
  810. _ltoa ( strtoul(rgsz[3],(char **)NULL,16), rgchNum, 10 );
  811. while (!FAddSymbolValueToSymTab(rgsz[1], rgchNum))
  812. if (!FHandleOOM(hwndParent))
  813. goto LFlowParseExitErr;
  814. break;
  815. case spcSetDecToHex:
  816. SdAtNewLine(Line);
  817. if (cFields != 4 ||
  818. *(rgsz[1]) == '\0' ||
  819. CrcStringCompare(rgsz[2], "=") != crcEqual)
  820. goto LFlowParseError;
  821. wsprintf(rgchNum,"0x%X",atol(rgsz[3]));
  822. while (!FAddSymbolValueToSymTab(rgsz[1], rgchNum))
  823. if (!FHandleOOM(hwndParent))
  824. goto LFlowParseExitErr;
  825. break;
  826. case spcDebugMsg:
  827. #if DBG
  828. SdAtNewLine(Line);
  829. if (cFields != 2)
  830. goto LFlowParseError;
  831. if ((sz = SzProcessSzForSyms(hwndParent, rgsz[1])) == (SZ)NULL)
  832. goto LFlowParseExitErr;
  833. EvalAssert(LoadString(hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax));
  834. MessageBox(hwndParent, sz, rgchBufTmpShort, MB_OK | MB_TASKMODAL);
  835. SFree(sz);
  836. #endif /* DBG */
  837. break;
  838. case spcIfStrI:
  839. ecm = ecmIfStrI;
  840. goto LHandleIfs;
  841. case spcIfInt:
  842. ecm = ecmIfInt;
  843. goto LHandleIfs;
  844. case spcIfContains:
  845. ecm = ecmIfContains;
  846. goto LHandleIfs;
  847. case spcIfContainsI:
  848. ecm = ecmIfContainsI;
  849. goto LHandleIfs;
  850. case spcIfStr:
  851. ecm = ecmIfStr;
  852. LHandleIfs:
  853. SdAtNewLine(Line);
  854. if (cFields != 4)
  855. goto LFlowParseError;
  856. if (spc == spcIfStrI ||
  857. spc == spcIfContainsI)
  858. {
  859. EvalAssert(SzStrUpper(rgsz[1]) == rgsz[1]);
  860. EvalAssert(SzStrUpper(rgsz[3]) == rgsz[3]);
  861. }
  862. if ((erc = ErcEvaluateCompare(hwndParent, ecm, rgsz[1], rgsz[3],
  863. rgsz[2])) == ercError)
  864. goto LFlowParseError;
  865. if (erc == ercFalse &&
  866. !FSkipToElse(&Line,hwndParent))
  867. goto LFlowParseExitErr;
  868. break;
  869. case spcEndIf:
  870. SdAtNewLine(Line);
  871. if (cFields != 1)
  872. goto LFlowParseError;
  873. break;
  874. case spcElse:
  875. SdAtNewLine(Line);
  876. if (cFields != 1)
  877. goto LFlowParseError;
  878. case spcElseIfStr:
  879. case spcElseIfStrI:
  880. case spcElseIfInt:
  881. case spcElseIfContains:
  882. case spcElseIfContainsI:
  883. SdAtNewLine(Line);
  884. if (spc != spcElse &&
  885. cFields != 4)
  886. goto LFlowParseError;
  887. if (!FSkipToEnd(&Line,hwndParent))
  888. goto LFlowParseExitErr;
  889. break;
  890. case spcGoTo:
  891. SdAtNewLine(Line);
  892. if (cFields != 2 ||
  893. *(rgsz[1]) == '\0' ||
  894. (Line = FindLineFromInfSectionKey(szSection, rgsz[1])) == -1)
  895. goto LFlowParseError;
  896. break;
  897. case spcForListDo:
  898. SdAtNewLine(Line);
  899. if (cFields != 2)
  900. goto LFlowParseError;
  901. if (!FInitForLoop(&Line,hwndParent, rgsz[1]))
  902. goto LFlowParseExitErr;
  903. break;
  904. case spcEndForListDo:
  905. SdAtNewLine(Line);
  906. if (cFields != 1)
  907. goto LFlowParseError;
  908. if (!FContinueForLoop(&Line,hwndParent))
  909. goto LFlowParseExitErr;
  910. break;
  911. case spcHourglass:
  912. SdAtNewLine(Line);
  913. if(cFields != 1) {
  914. goto LFlowParseError;
  915. }
  916. SetCursor(CurrentCursor = LoadCursor(NULL,IDC_WAIT));
  917. break;
  918. case spcArrow:
  919. SdAtNewLine(Line);
  920. if(cFields != 1) {
  921. goto LFlowParseError;
  922. }
  923. SetCursor(CurrentCursor = LoadCursor(NULL,IDC_ARROW));
  924. break;
  925. case spcSetHelpFile:
  926. SdAtNewLine(Line);
  927. //
  928. // Command is SetHelpFile "helpfilename" "locontext" "highcontext" "helpindex-optional"
  929. //
  930. if (cFields < 4) {
  931. goto LFlowParseError;
  932. }
  933. if (cFields == 4) {
  934. if ( !FInitWinHelpFile (
  935. hWndShell,
  936. rgsz[1],
  937. rgsz[2],
  938. rgsz[3],
  939. (SZ)NULL
  940. ) ) {
  941. goto LFlowParseExitErr;
  942. }
  943. }
  944. else {
  945. if ( !FInitWinHelpFile (
  946. hWndShell,
  947. rgsz[1],
  948. rgsz[2],
  949. rgsz[3],
  950. rgsz[4]
  951. ) ) {
  952. goto LFlowParseExitErr;
  953. }
  954. }
  955. break;
  956. case spcGetDriveInPath:
  957. SdAtNewLine(Line);
  958. {
  959. SZ sz;
  960. CHP chp1, chp2, rgchDrive[3];
  961. //
  962. // Command: GetDriveInPath DriveVar, Path
  963. //
  964. if (cFields != 3) {
  965. goto LFlowParseError;
  966. }
  967. sz = rgsz[2];
  968. rgchDrive[0] = '\0';
  969. if ( ((chp1 = *sz++) != '\0') &&
  970. ((chp2 = *sz) == ':') &&
  971. ((chp1 >= 'a' && chp1 <='z') || (chp1 >= 'A' && chp1 <= 'Z'))) {
  972. rgchDrive[0] = chp1;
  973. rgchDrive[1] = chp2;
  974. rgchDrive[2] = '\0';
  975. }
  976. while (!FAddSymbolValueToSymTab(rgsz[1], rgchDrive)) {
  977. if (!FHandleOOM(hwndParent)) {
  978. goto LFlowParseExitErr;
  979. }
  980. }
  981. break;
  982. }
  983. case spcGetDirInPath:
  984. SdAtNewLine(Line);
  985. {
  986. SZ sz, sz1;
  987. SZ szUNDEF = "";
  988. //
  989. // Command: GetDirInPath DirVar, Path
  990. //
  991. if (cFields != 3) {
  992. goto LFlowParseError;
  993. }
  994. sz = rgsz[2];
  995. sz1 = (SZ)strchr(sz, '\\');
  996. if (sz1 == NULL) {
  997. sz1 = szUNDEF;
  998. }
  999. while (!FAddSymbolValueToSymTab(rgsz[1], sz1)) {
  1000. if (!FHandleOOM(hwndParent)) {
  1001. goto LFlowParseExitErr;
  1002. }
  1003. }
  1004. break;
  1005. }
  1006. case spcCreateRegKey:
  1007. case spcOpenRegKey:
  1008. case spcFlushRegKey:
  1009. case spcCloseRegKey:
  1010. case spcDeleteRegKey:
  1011. case spcDeleteRegTree:
  1012. case spcEnumRegKey:
  1013. case spcSetRegValue:
  1014. case spcGetRegValue:
  1015. case spcDeleteRegValue:
  1016. case spcEnumRegValue:
  1017. SdAtNewLine(Line);
  1018. if (!FParseRegistrySection(Line, &cFields, spc)) {
  1019. goto LFlowParseError;
  1020. }
  1021. break;
  1022. case spcLoadLibrary:
  1023. SdAtNewLine(Line);
  1024. if(!FParseLoadLibrary(Line, &cFields)) {
  1025. goto LFlowParseError;
  1026. }
  1027. break;
  1028. case spcFreeLibrary:
  1029. SdAtNewLine(Line);
  1030. if(!FParseFreeLibrary(Line, &cFields)) {
  1031. goto LFlowParseError;
  1032. }
  1033. break;
  1034. case spcLibraryProcedure:
  1035. SdAtNewLine(Line);
  1036. if(!FParseLibraryProcedure(Line, &cFields)) {
  1037. goto LFlowParseError;
  1038. }
  1039. break;
  1040. case spcRunExternalProgram:
  1041. SdAtNewLine(Line);
  1042. if(!FParseRunExternalProgram(Line, &cFields)) {
  1043. goto LFlowParseError;
  1044. }
  1045. break;
  1046. case spcInvokeApplet:
  1047. SdAtNewLine(Line);
  1048. if(!FParseInvokeApplet(Line, &cFields)) {
  1049. goto LFlowParseError;
  1050. }
  1051. break;
  1052. case spcStartDetachedProcess:
  1053. SdAtNewLine(Line);
  1054. if(!FParseStartDetachedProcess(Line, &cFields)) {
  1055. goto LFlowParseError;
  1056. }
  1057. break;
  1058. case spcWaitOnEvent:
  1059. SdAtNewLine(Line);
  1060. if(!FParseWaitOnEvent(Line, &cFields)) {
  1061. goto LFlowParseError;
  1062. }
  1063. break;
  1064. case spcSignalEvent:
  1065. SdAtNewLine(Line);
  1066. if(!FParseSignalEvent(Line, &cFields)) {
  1067. goto LFlowParseError;
  1068. }
  1069. break;
  1070. case spcSleep:
  1071. SdAtNewLine(Line);
  1072. if(!FParseSleep(Line, &cFields)) {
  1073. goto LFlowParseError;
  1074. }
  1075. break;
  1076. case spcFlushInf:
  1077. SdAtNewLine(Line);
  1078. if(!FParseFlushInf(Line, &cFields)) {
  1079. goto LFlowParseError;
  1080. }
  1081. break;
  1082. case spcBmpShow:
  1083. SdAtNewLine(Line);
  1084. if(!FParseBmpShow(Line, &cFields)) {
  1085. goto LFlowParseError;
  1086. }
  1087. break ;
  1088. case spcBmpHide:
  1089. SdAtNewLine(Line);
  1090. if(!FParseBmpHide(Line, &cFields)) {
  1091. goto LFlowParseError;
  1092. }
  1093. break ;
  1094. case spcDebugOutput:
  1095. #if DEVL
  1096. SdAtNewLine(Line);
  1097. if (cFields != 2)
  1098. goto LFlowParseError;
  1099. if ((sz = SzProcessSzForSyms(hwndParent, rgsz[1])) == (SZ)NULL)
  1100. goto LFlowParseExitErr;
  1101. if ( (sz2 = SzFindSymbolValueInSymTab("!G:DebugOutputControl"))
  1102. && atol(sz2) == 0 )
  1103. break;
  1104. OutputDebugString( "SETUP:" );
  1105. OutputDebugString( sz ) ;
  1106. OutputDebugString( "\n" );
  1107. SFree(sz);
  1108. #endif
  1109. break;
  1110. case spcQueryListSize:
  1111. SdAtNewLine(Line);
  1112. {
  1113. INT ListSize = 0;
  1114. CHP rgchListSize[10];
  1115. if( cFields != 3 )
  1116. {
  1117. goto LFlowParseError;
  1118. }
  1119. else
  1120. {
  1121. RGSZ rgszList = NULL;
  1122. if ((rgszList = RgszFromSzListValue( rgsz[2] )) != NULL )
  1123. {
  1124. for(ListSize=0;rgszList[ListSize]; ListSize++)
  1125. {
  1126. ;
  1127. }
  1128. }
  1129. }
  1130. while (!FAddSymbolValueToSymTab(rgsz[1], _itoa(ListSize, rgchListSize, 10))) {
  1131. if (!FHandleOOM(hwndParent)) {
  1132. goto LFlowParseExitErr;
  1133. }
  1134. }
  1135. }
  1136. break;
  1137. case spcAddFileToDeleteList:
  1138. SdAtNewLine(Line);
  1139. if(!FParseAddFileToDeleteList(Line, &cFields)) {
  1140. goto LFlowParseError;
  1141. }
  1142. break;
  1143. case spcInitRestoreDiskLog:
  1144. SdAtNewLine(Line);
  1145. if( cFields != 1 ) {
  1146. goto LFlowParseError;
  1147. }
  1148. InitRestoreDiskLogging(TRUE);
  1149. break;
  1150. case spcTermRestoreDiskLog:
  1151. SdAtNewLine(Line);
  1152. if( cFields != 1 ) {
  1153. goto LFlowParseError;
  1154. }
  1155. TermRestoreDiskLogging();
  1156. break;
  1157. case spcSplitString:
  1158. SdAtNewLine(Line);
  1159. if( cFields != 4 )
  1160. {
  1161. goto LFlowParseError;
  1162. }
  1163. else
  1164. {
  1165. CHP rgchSplitString[2000];
  1166. SZ szSource;
  1167. SZ szSource2;
  1168. SZ szSep;
  1169. SZ szSep2;
  1170. SZ szSplitString;
  1171. INT i;
  1172. BOOL fAddComma;
  1173. BOOL fFind;
  1174. BOOL fFirst;
  1175. szSplitString = rgchSplitString;
  1176. if ((( szSource = SzProcessSzForSyms( hwndParent, rgsz[1] )) == (SZ)NULL) ||
  1177. (( szSep = SzProcessSzForSyms( hwndParent, rgsz[2] )) == (SZ)NULL ))
  1178. {
  1179. goto LFlowParseExitErr;
  1180. }
  1181. fAddComma = FALSE;
  1182. fFirst = TRUE;
  1183. *szSplitString++='{';
  1184. szSource2 = szSource;
  1185. while( *szSource2 != '\0' )
  1186. {
  1187. if ( fAddComma )
  1188. {
  1189. *szSplitString++=',';
  1190. fAddComma = FALSE;
  1191. }
  1192. if ( fFirst )
  1193. {
  1194. *szSplitString++='"';
  1195. }
  1196. szSep2 = szSep;
  1197. fFind = FALSE;
  1198. for ( i = 0; i < (INT)strlen( szSep ); i ++ )
  1199. {
  1200. if ( FSingleByteCharSz( szSep2 ) == FSingleByteCharSz( szSource2 ))
  1201. {
  1202. if ( FSingleByteCharSz( szSep2 ))
  1203. {
  1204. if ( *szSep2 == *szSource2 )
  1205. {
  1206. fFind = TRUE;
  1207. break;
  1208. }
  1209. }
  1210. else
  1211. {
  1212. if (( *szSep2 == *szSource2 ) &&
  1213. ( *(szSep2+1) == *(szSource2+1)))
  1214. {
  1215. fFind = TRUE;
  1216. break;
  1217. }
  1218. }
  1219. }
  1220. szSep2 = SzNextChar(szSep2);
  1221. }
  1222. if (fFind)
  1223. {
  1224. if (!fFirst)
  1225. {
  1226. *szSplitString++ = '"';
  1227. *szSplitString++ = ',';
  1228. *szSplitString++ = '"';
  1229. }
  1230. *szSplitString++ = *szSep2;
  1231. if ( !FSingleByteCharSz( szSep2 ))
  1232. {
  1233. *szSplitString++ = *(szSep2+1);
  1234. }
  1235. *szSplitString++ = '"';
  1236. fAddComma = TRUE;
  1237. fFirst = TRUE;
  1238. }
  1239. else
  1240. {
  1241. *szSplitString++ = *szSource2;
  1242. if ( !FSingleByteCharSz( szSource2 ))
  1243. {
  1244. *szSplitString++ = *(szSource2+1);
  1245. }
  1246. fFirst = FALSE;
  1247. }
  1248. szSource2 = SzNextChar( szSource2 );
  1249. }
  1250. if (!fFirst)
  1251. {
  1252. *szSplitString++='"';
  1253. }
  1254. *szSplitString++='}';
  1255. *szSplitString++='\0';
  1256. while (!FAddSymbolValueToSymTab(rgsz[3], rgchSplitString)) {
  1257. if (!FHandleOOM(hwndParent)) {
  1258. goto LFlowParseExitErr;
  1259. }
  1260. }
  1261. SFree(szSource);
  1262. SFree(szSep);
  1263. }
  1264. break;
  1265. case spcUnknown:
  1266. if(CallerCFields != NULL) {
  1267. *CallerCFields = cFields;
  1268. }
  1269. if(CallerRgsz != NULL) {
  1270. *CallerRgsz = rgsz;
  1271. } else {
  1272. EvalAssert(FFreeRgsz(rgsz));
  1273. }
  1274. *CurrentLine = Line;
  1275. return(fTrue);
  1276. default:
  1277. Assert(fFalse);
  1278. }
  1279. LNextFlowLine:
  1280. if (spc != spcGoTo &&
  1281. ((Line = FindNextLineFromInf(Line)) == -1))
  1282. {
  1283. if (rgsz != (RGSZ)NULL)
  1284. EvalAssert(FFreeRgsz(rgsz));
  1285. EvalAssert(LoadString(hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax));
  1286. EvalAssert(LoadString(hInst, IDS_NEED_EXIT, rgchBufTmpLong, cchpBufTmpLongMax));
  1287. MessageBox(hwndParent, rgchBufTmpLong, rgchBufTmpShort, MB_OK | MB_ICONHAND);
  1288. return(fFalse);
  1289. }
  1290. EvalAssert(rgsz == (RGSZ)NULL ||
  1291. FFreeRgsz(rgsz));
  1292. }
  1293. Assert(fFalse); /* Should never reach here! */
  1294. LFlowParseError:
  1295. /* BLOCK */
  1296. {
  1297. #define cchpBuf (2 * cchpFullPathBuf)
  1298. CHP rgchBuf[cchpBuf];
  1299. EvalAssert(LoadString(hInst, IDS_SHL_CMD_ERROR, rgchBuf, cchpBuf));
  1300. if (rgsz != (RGSZ)NULL ||
  1301. *rgsz != (SZ)NULL)
  1302. {
  1303. USHORT iszCur = 0;
  1304. SZ szCur;
  1305. while ((szCur = rgsz[iszCur++]) != (SZ)NULL)
  1306. {
  1307. if (iszCur == 1)
  1308. EvalAssert(SzStrCat((SZ)rgchBuf, "\n'") == (SZ)rgchBuf);
  1309. else
  1310. EvalAssert(SzStrCat((SZ)rgchBuf, " ") == (SZ)rgchBuf);
  1311. if (strlen(rgchBuf) + strlen(szCur) > (cchpBuf - 7))
  1312. {
  1313. Assert(strlen(rgchBuf) <= (cchpBuf - 5));
  1314. EvalAssert(SzStrCat((SZ)rgchBuf, "...") == (SZ)rgchBuf);
  1315. break;
  1316. }
  1317. else
  1318. EvalAssert(SzStrCat((SZ)rgchBuf, szCur) == (SZ)rgchBuf);
  1319. }
  1320. EvalAssert(SzStrCat((SZ)rgchBuf, "'") == (SZ)rgchBuf);
  1321. }
  1322. EvalAssert(LoadString(hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax));
  1323. MessageBox(hwndParent, rgchBuf, rgchBufTmpShort, MB_OK | MB_ICONHAND);
  1324. }
  1325. LFlowParseExitErr:
  1326. if (rgsz != (RGSZ)NULL)
  1327. EvalAssert(FFreeRgsz(rgsz));
  1328. return(fFalse);
  1329. }
  1330. /*
  1331. ** Purpose:
  1332. ** Initializes the structures needed for parsing/handling Flow Script
  1333. ** statements. Must be called before FHandleFlowStatements().
  1334. ** Arguments:
  1335. ** none
  1336. ** Returns:
  1337. ** fTrue if successful.
  1338. ** fFalse if not successful.
  1339. */
  1340. BOOL APIENTRY FInitFlowPspt(VOID)
  1341. {
  1342. if (psptFlow != (PSPT)NULL)
  1343. return(fFalse);
  1344. return((BOOL)((psptFlow = PsptInitParsingTable(rgscpFlow)) != (PSPT)NULL));
  1345. }
  1346. /*
  1347. ** Purpose:
  1348. ** Destroys the structures needed for parsing/handling Flow Script
  1349. ** statements.
  1350. ** Arguments:
  1351. ** none
  1352. ** Returns:
  1353. ** fTrue if successful.
  1354. ** fFalse if not successful.
  1355. */
  1356. BOOL APIENTRY FDestroyFlowPspt(VOID)
  1357. {
  1358. if (psptFlow == (PSPT)NULL ||
  1359. !FDestroyParsingTable(psptFlow))
  1360. return(fFalse);
  1361. psptFlow = (PSPT)NULL;
  1362. return(fTrue);
  1363. }
  1364. /*
  1365. ** Purpose:
  1366. ** Arguments:
  1367. ** Returns:
  1368. **
  1369. *************************************************************************/
  1370. BOOL APIENTRY FParseRegistrySection(INT Line, UINT *pcFields, SPC spc)
  1371. {
  1372. BOOL fOkay = fFalse;
  1373. SZ szHandle = NULL;
  1374. iFieldCur = 2;
  1375. if ( ( *pcFields >= 1 ) &&
  1376. FGetArgSz( Line, pcFields, &szHandle )
  1377. ) {
  1378. FAddSymbolValueToSymTab( REGLASTERROR, "0" );
  1379. switch (spc) {
  1380. default:
  1381. Assert(fFalse);
  1382. break;
  1383. case spcCreateRegKey:
  1384. fOkay = FParseCreateRegKey( Line, pcFields, szHandle );
  1385. break;
  1386. case spcOpenRegKey:
  1387. fOkay = FParseOpenRegKey( Line, pcFields, szHandle );
  1388. break;
  1389. case spcFlushRegKey:
  1390. fOkay = FParseFlushRegKey( Line, pcFields, szHandle );
  1391. break;
  1392. case spcCloseRegKey:
  1393. fOkay = FParseCloseRegKey( Line, pcFields, szHandle );
  1394. break;
  1395. case spcDeleteRegKey:
  1396. fOkay = FParseDeleteRegKey( Line, pcFields, szHandle );
  1397. break;
  1398. case spcDeleteRegTree:
  1399. fOkay = FParseDeleteRegTree( Line, pcFields, szHandle );
  1400. break;
  1401. case spcEnumRegKey:
  1402. fOkay = FParseEnumRegKey( Line, pcFields, szHandle );
  1403. break;
  1404. case spcSetRegValue:
  1405. fOkay = FParseSetRegValue( Line, pcFields, szHandle );
  1406. break;
  1407. case spcGetRegValue:
  1408. fOkay = FParseGetRegValue( Line, pcFields, szHandle );
  1409. break;
  1410. case spcDeleteRegValue:
  1411. fOkay = FParseDeleteRegValue( Line, pcFields, szHandle );
  1412. break;
  1413. case spcEnumRegValue:
  1414. fOkay = FParseEnumRegValue( Line, pcFields, szHandle );
  1415. break;
  1416. }
  1417. }
  1418. if ( szHandle ) {
  1419. SFree(szHandle);
  1420. }
  1421. return( fOkay );
  1422. }
  1423. /*
  1424. ** Purpose:
  1425. ** Arguments:
  1426. ** Returns:
  1427. **
  1428. *************************************************************************/
  1429. BOOL APIENTRY FParseOpenRegKey(INT Line, UINT *pcFields, SZ szHandle)
  1430. {
  1431. BOOL fOkay = fFalse;
  1432. SZ szMachineName = NULL;
  1433. SZ szKeyName = NULL;
  1434. UINT AccessMask;
  1435. SZ szNewHandle = NULL;
  1436. CMO cmo;
  1437. if ( *pcFields >= 4 ) {
  1438. if ( FGetArgSz( Line, pcFields, &szMachineName ) ) {
  1439. if ( FGetArgSz( Line, pcFields, &szKeyName ) ) {
  1440. if ( FGetArgUINT( Line, pcFields, &AccessMask ) ) {
  1441. if ( FGetArgSz( Line, pcFields, &szNewHandle ) ) {
  1442. if ( FGetCmo( Line, pcFields, &cmo )) {
  1443. fOkay = FOpenRegKey( szHandle,
  1444. szMachineName,
  1445. szKeyName,
  1446. AccessMask,
  1447. szNewHandle,
  1448. cmo );
  1449. }
  1450. }
  1451. SFree(szNewHandle);
  1452. }
  1453. }
  1454. SFree(szKeyName);
  1455. }
  1456. SFree(szMachineName);
  1457. }
  1458. return fOkay;
  1459. }
  1460. /*
  1461. ** Purpose:
  1462. ** Arguments:
  1463. ** Returns:
  1464. **
  1465. *************************************************************************/
  1466. BOOL APIENTRY FParseFlushRegKey(INT Line, UINT *pcFields, SZ szHandle)
  1467. {
  1468. BOOL fOkay = fFalse;
  1469. CMO cmo;
  1470. if ( FGetCmo( Line, pcFields, &cmo )) {
  1471. fOkay = FFlushRegKey( szHandle, cmo );
  1472. }
  1473. return fOkay;
  1474. }
  1475. /*
  1476. ** Purpose:
  1477. ** Arguments:
  1478. ** Returns:
  1479. **
  1480. *************************************************************************/
  1481. BOOL APIENTRY FParseCloseRegKey(INT Line, UINT *pcFields, SZ szHandle)
  1482. {
  1483. BOOL fOkay = fFalse;
  1484. CMO cmo;
  1485. if ( FGetCmo( Line, pcFields, &cmo )) {
  1486. fOkay = FCloseRegKey( szHandle, cmo );
  1487. }
  1488. return fOkay;
  1489. }
  1490. /*
  1491. ** Purpose:
  1492. ** Arguments:
  1493. ** Returns:
  1494. **
  1495. *************************************************************************/
  1496. BOOL APIENTRY FParseDeleteRegKey(INT Line, UINT *pcFields, SZ szHandle)
  1497. {
  1498. BOOL fOkay = fFalse;
  1499. SZ szKeyName = NULL;
  1500. CMO cmo;
  1501. if ( *pcFields >= 1 ) {
  1502. if ( FGetArgSz( Line, pcFields, &szKeyName ) ) {
  1503. if ( FGetCmo( Line, pcFields, &cmo )) {
  1504. fOkay = FDeleteRegKey( szHandle,
  1505. szKeyName,
  1506. cmo );
  1507. }
  1508. }
  1509. SFree(szKeyName);
  1510. }
  1511. return fOkay;
  1512. }
  1513. /*
  1514. ** Purpose:
  1515. ** Arguments:
  1516. ** Returns:
  1517. **
  1518. *************************************************************************/
  1519. BOOL APIENTRY FParseDeleteRegTree(INT Line, UINT *pcFields, SZ szHandle)
  1520. {
  1521. BOOL fOkay = fFalse;
  1522. SZ szKeyName = NULL;
  1523. CMO cmo;
  1524. if ( *pcFields >= 1 ) {
  1525. if ( FGetArgSz( Line, pcFields, &szKeyName ) ) {
  1526. if ( FGetCmo( Line, pcFields, &cmo )) {
  1527. fOkay = FDeleteRegTree( szHandle,
  1528. szKeyName,
  1529. cmo );
  1530. }
  1531. }
  1532. SFree(szKeyName);
  1533. }
  1534. return fOkay;
  1535. }
  1536. /*
  1537. ** Purpose:
  1538. ** Arguments:
  1539. ** Returns:
  1540. **
  1541. *************************************************************************/
  1542. BOOL APIENTRY FParseEnumRegKey(INT Line, UINT *pcFields, SZ szHandle)
  1543. {
  1544. BOOL fOkay = fFalse;
  1545. SZ szInfVar;
  1546. CMO cmo;
  1547. if ( *pcFields >= 1 ) {
  1548. if ( FGetArgSz( Line, pcFields, &szInfVar ) ) {
  1549. if ( FGetCmo( Line, pcFields, &cmo )) {
  1550. fOkay = FEnumRegKey( szHandle,
  1551. szInfVar,
  1552. cmo );
  1553. }
  1554. SFree( szInfVar );
  1555. }
  1556. }
  1557. return fOkay;
  1558. }
  1559. /*
  1560. ** Purpose:
  1561. ** Arguments:
  1562. ** Returns:
  1563. **
  1564. *************************************************************************/
  1565. BOOL APIENTRY FParseSetRegValue(INT Line, UINT *pcFields, SZ szHandle)
  1566. {
  1567. BOOL fOkay = fFalse;
  1568. SZ szValueInfo = NULL;
  1569. SZ szValueName = NULL;
  1570. UINT TitleIndex;
  1571. UINT ValueType;
  1572. SZ szValueData = NULL;
  1573. RGSZ rgszInfo;
  1574. CMO cmo;
  1575. if ( *pcFields >= 1 ) {
  1576. if ( FGetArgSz( Line, pcFields, &szValueInfo )) {
  1577. if ( FListValue( szValueInfo )) {
  1578. if ( rgszInfo = RgszFromSzListValue( szValueInfo )) {
  1579. if ( FGetCmo( Line, pcFields, &cmo )) {
  1580. if ( (rgszInfo[0] != NULL) &&
  1581. (rgszInfo[1] != NULL) &&
  1582. (rgszInfo[2] != NULL) &&
  1583. (rgszInfo[3] != NULL) ) {
  1584. szValueName = rgszInfo[0];
  1585. TitleIndex = atol(rgszInfo[1]);
  1586. ValueType = atol(rgszInfo[2]);
  1587. szValueData = rgszInfo[3];
  1588. fOkay = FSetRegValue( szHandle,
  1589. szValueName,
  1590. TitleIndex,
  1591. ValueType,
  1592. szValueData,
  1593. cmo );
  1594. }
  1595. }
  1596. }
  1597. FFreeRgsz( rgszInfo );
  1598. }
  1599. }
  1600. SFree( szValueInfo );
  1601. }
  1602. return fOkay;
  1603. }
  1604. /*
  1605. ** Purpose:
  1606. ** Arguments:
  1607. ** Returns:
  1608. **
  1609. *************************************************************************/
  1610. BOOL APIENTRY FParseGetRegValue(INT Line, UINT *pcFields, SZ szHandle)
  1611. {
  1612. BOOL fOkay = fFalse;
  1613. SZ szValueName = NULL;
  1614. SZ szInfVar = NULL;
  1615. CMO cmo;
  1616. if ( *pcFields >= 2 ) {
  1617. if ( FGetArgSz( Line, pcFields, &szValueName ) ) {
  1618. if ( FGetArgSz( Line, pcFields, &szInfVar ) ) {
  1619. if ( FGetCmo( Line, pcFields, &cmo )) {
  1620. fOkay = FGetRegValue( szHandle,
  1621. szValueName,
  1622. szInfVar,
  1623. cmo );
  1624. }
  1625. }
  1626. SFree( szInfVar );
  1627. }
  1628. SFree( szValueName );
  1629. }
  1630. return fOkay;
  1631. }
  1632. /*
  1633. ** Purpose:
  1634. ** Arguments:
  1635. ** Returns:
  1636. **
  1637. *************************************************************************/
  1638. BOOL APIENTRY FParseDeleteRegValue(INT Line, UINT *pcFields, SZ szHandle)
  1639. {
  1640. BOOL fOkay = fFalse;
  1641. SZ szValueName = NULL;
  1642. CMO cmo;
  1643. if ( *pcFields >= 1 ) {
  1644. if ( FGetArgSz( Line, pcFields, &szValueName ) ) {
  1645. if ( FGetCmo( Line, pcFields, &cmo )) {
  1646. fOkay = FDeleteRegValue( szHandle,
  1647. szValueName,
  1648. cmo );
  1649. }
  1650. }
  1651. SFree( szValueName );
  1652. }
  1653. return fOkay;
  1654. }
  1655. /*
  1656. ** Purpose:
  1657. ** Arguments:
  1658. ** Returns:
  1659. **
  1660. *************************************************************************/
  1661. BOOL APIENTRY FParseEnumRegValue(INT Line, UINT *pcFields, SZ szHandle)
  1662. {
  1663. BOOL fOkay = fFalse;
  1664. SZ szInfVar;
  1665. CMO cmo;
  1666. if ( *pcFields >= 1 ) {
  1667. if ( FGetArgSz( Line, pcFields, &szInfVar ) ) {
  1668. if ( FGetCmo( Line, pcFields, &cmo )) {
  1669. fOkay = FEnumRegValue( szHandle,
  1670. szInfVar,
  1671. cmo );
  1672. }
  1673. SFree( szInfVar );
  1674. }
  1675. }
  1676. return fOkay;
  1677. }
  1678. /*
  1679. ** Purpose:
  1680. ** Arguments:
  1681. ** Returns:
  1682. **
  1683. *************************************************************************/
  1684. BOOL APIENTRY FParseCreateRegKey(INT Line, UINT *pcFields, SZ szHandle)
  1685. {
  1686. BOOL fOkay = fFalse;
  1687. SZ szKeyInfo;
  1688. SZ szSecurity;
  1689. UINT AccessMask;
  1690. UINT Options;
  1691. SZ szNewHandle;
  1692. SZ szKeyName;
  1693. UINT TitleIndex;
  1694. SZ szClass;
  1695. RGSZ rgszInfo;
  1696. CMO cmo;
  1697. if ( *pcFields >= 5 ) {
  1698. if ( FGetArgSz( Line, pcFields, &szKeyInfo ) ) {
  1699. //
  1700. // Validate the key Info.
  1701. //
  1702. if ( FListValue( szKeyInfo )) {
  1703. if ( rgszInfo = RgszFromSzListValue( szKeyInfo )) {
  1704. if ( (rgszInfo[0] != NULL) &&
  1705. (rgszInfo[1] != NULL) &&
  1706. (rgszInfo[2] != NULL ) ) {
  1707. szKeyName = rgszInfo[0];
  1708. TitleIndex = atol(rgszInfo[1]);
  1709. szClass = rgszInfo[2];
  1710. if ( FGetArgSz( Line, pcFields, &szSecurity ) ) {
  1711. //
  1712. // BugBug At this point we should validate the security Info.
  1713. //
  1714. if ( FGetArgUINT( Line, pcFields, &AccessMask ) ) {
  1715. if ( FGetArgUINT( Line, pcFields, &Options ) ) {
  1716. if ( FGetArgSz( Line, pcFields, &szNewHandle ) ) {
  1717. if ( FGetCmo( Line, pcFields, &cmo )) {
  1718. fOkay = FCreateRegKey( szHandle,
  1719. szKeyName,
  1720. TitleIndex,
  1721. szClass,
  1722. szSecurity,
  1723. AccessMask,
  1724. Options,
  1725. szNewHandle,
  1726. cmo );
  1727. }
  1728. SFree( szNewHandle );
  1729. }
  1730. }
  1731. }
  1732. SFree( szSecurity );
  1733. }
  1734. }
  1735. FFreeRgsz( rgszInfo );
  1736. }
  1737. }
  1738. SFree( szKeyInfo );
  1739. }
  1740. }
  1741. return fOkay;
  1742. }
  1743. /*
  1744. ** Purpose:
  1745. ** Arguments:
  1746. ** Returns:
  1747. **
  1748. *************************************************************************/
  1749. BOOL APIENTRY FParseLoadLibrary(INT Line, UINT *pcFields)
  1750. {
  1751. BOOL fOkay = FALSE;
  1752. SZ szDiskName = NULL,
  1753. szLibName = NULL,
  1754. szHandleVar = NULL;
  1755. iFieldCur = 2;
  1756. if(*pcFields == 4) {
  1757. FGetArgSz(Line,pcFields,&szDiskName); // disk name
  1758. FGetArgSz(Line,pcFields,&szLibName); // library pathname
  1759. FGetArgSz(Line,pcFields,&szHandleVar); // INF var to get lib handle
  1760. if((szLibName != NULL)
  1761. && (szHandleVar != NULL)
  1762. && *szLibName
  1763. && *szHandleVar)
  1764. {
  1765. fOkay = FLoadLibrary(szDiskName,szLibName,szHandleVar);
  1766. }
  1767. if(szDiskName != NULL) {
  1768. SFree(szDiskName);
  1769. }
  1770. if(szLibName != NULL) {
  1771. SFree(szLibName);
  1772. }
  1773. if(szHandleVar != NULL) {
  1774. SFree(szHandleVar);
  1775. }
  1776. }
  1777. return(fOkay);
  1778. }
  1779. /*
  1780. ** Purpose:
  1781. ** Arguments:
  1782. ** Returns:
  1783. **
  1784. *************************************************************************/
  1785. BOOL APIENTRY FParseFreeLibrary(INT Line, UINT *pcFields)
  1786. {
  1787. BOOL fOkay = FALSE;
  1788. SZ szHandle = NULL;
  1789. iFieldCur = 2;
  1790. if(*pcFields == 2) {
  1791. FGetArgSz(Line,pcFields,&szHandle); // lib handle
  1792. if((szHandle != NULL) && *szHandle)
  1793. {
  1794. fOkay = FFreeLibrary(szHandle);
  1795. }
  1796. if(szHandle != NULL) {
  1797. SFree(szHandle);
  1798. }
  1799. }
  1800. return(fOkay);
  1801. }
  1802. /*
  1803. ** Purpose:
  1804. ** Arguments:
  1805. ** Returns:
  1806. **
  1807. *************************************************************************/
  1808. BOOL APIENTRY FParseLibraryProcedure(INT Line,UINT *pcFields)
  1809. {
  1810. BOOL fOkay = fFalse;
  1811. SZ szINFVar = NULL,
  1812. szLibHand = NULL,
  1813. szRoutine = NULL;
  1814. RGSZ rgszArgs = NULL;
  1815. iFieldCur = 2;
  1816. if(*pcFields >= 4) {
  1817. FGetArgSz(Line,pcFields,&szINFVar); // INF var for result
  1818. FGetArgSz(Line,pcFields,&szLibHand); // library handle
  1819. FGetArgSz(Line,pcFields,&szRoutine); // entry point
  1820. rgszArgs = RgszFromInfLineFields(Line,5,(*pcFields) - 4);
  1821. if((szLibHand != NULL)
  1822. && (szRoutine != NULL)
  1823. && (rgszArgs != NULL))
  1824. {
  1825. fOkay = FLibraryProcedure(szINFVar,szLibHand,szRoutine,rgszArgs);
  1826. }
  1827. if(szINFVar != NULL) {
  1828. SFree(szINFVar);
  1829. }
  1830. if(szLibHand != NULL) {
  1831. SFree(szLibHand);
  1832. }
  1833. if(szRoutine != NULL) {
  1834. SFree(szRoutine);
  1835. }
  1836. if(rgszArgs != NULL) {
  1837. FFreeRgsz(rgszArgs);
  1838. }
  1839. }
  1840. return(fOkay);
  1841. }
  1842. /*
  1843. ** Purpose:
  1844. ** Arguments:
  1845. ** Returns:
  1846. **
  1847. *************************************************************************/
  1848. BOOL APIENTRY FParseRunExternalProgram(INT Line,UINT *pcFields)
  1849. {
  1850. BOOL fOkay = fFalse;
  1851. SZ szVar = NULL,
  1852. szDisk = NULL,
  1853. szLibHand = NULL,
  1854. szProgram = NULL;
  1855. RGSZ rgszArgs = NULL;
  1856. iFieldCur = 2;
  1857. if(*pcFields >= 5) {
  1858. FGetArgSz(Line,pcFields,&szVar); // INF variable to stuff
  1859. FGetArgSz(Line,pcFields,&szDisk); // disk name
  1860. FGetArgSz(Line,pcFields,&szLibHand); // mod with string table
  1861. FGetArgSz(Line,pcFields,&szProgram); // name of program
  1862. // To be nice, we will supply argv[0]. To do this we'll
  1863. // take advantage of placement of the program name immediately
  1864. // before the arguments. It ain't perfect (argv[0] doesn't
  1865. // conventionally contain a full path) but it'll do.
  1866. rgszArgs = RgszFromInfLineFields(Line,5,(*pcFields) - 4);
  1867. if((szDisk != NULL) && (szProgram != NULL) && (rgszArgs != NULL)) {
  1868. AssertRet((*szProgram != '\0'),fFalse);
  1869. fOkay = FRunProgram(szVar,szDisk,szLibHand,szProgram,rgszArgs);
  1870. }
  1871. if(szVar != NULL) {
  1872. SFree(szVar);
  1873. }
  1874. if(szDisk != NULL) {
  1875. SFree(szDisk);
  1876. }
  1877. if(szLibHand != NULL) {
  1878. SFree(szLibHand);
  1879. }
  1880. if(szProgram != NULL) {
  1881. SFree(szProgram);
  1882. }
  1883. if(rgszArgs != NULL) {
  1884. FFreeRgsz(rgszArgs);
  1885. }
  1886. }
  1887. return(fOkay);
  1888. }
  1889. /*
  1890. ** Purpose:
  1891. ** Arguments:
  1892. ** Returns:
  1893. **
  1894. *************************************************************************/
  1895. BOOL APIENTRY FParseStartDetachedProcess(INT Line,UINT *pcFields)
  1896. {
  1897. BOOL fOkay = fFalse;
  1898. SZ szVar = NULL,
  1899. szDisk = NULL,
  1900. szLibHand = NULL,
  1901. szProgram = NULL;
  1902. RGSZ rgszArgs = NULL;
  1903. iFieldCur = 2;
  1904. if(*pcFields >= 5) {
  1905. FGetArgSz(Line,pcFields,&szVar); // INF variable to stuff
  1906. FGetArgSz(Line,pcFields,&szDisk); // disk name
  1907. FGetArgSz(Line,pcFields,&szLibHand); // mod with string table
  1908. FGetArgSz(Line,pcFields,&szProgram); // name of program
  1909. // To be nice, we will supply argv[0]. To do this we'll
  1910. // take advantage of placement of the program name immediately
  1911. // before the arguments. It ain't perfect (argv[0] doesn't
  1912. // conventionally contain a full path) but it'll do.
  1913. rgszArgs = RgszFromInfLineFields(Line,5,(*pcFields) - 4);
  1914. if((szDisk != NULL) && (szProgram != NULL) && (rgszArgs != NULL)) {
  1915. AssertRet((*szProgram != '\0'),fFalse);
  1916. fOkay = FStartDetachedProcess(szVar,szDisk,szLibHand,szProgram,rgszArgs);
  1917. }
  1918. if(szVar != NULL) {
  1919. SFree(szVar);
  1920. }
  1921. if(szDisk != NULL) {
  1922. SFree(szDisk);
  1923. }
  1924. if(szLibHand != NULL) {
  1925. SFree(szLibHand);
  1926. }
  1927. if(szProgram != NULL) {
  1928. SFree(szProgram);
  1929. }
  1930. if(rgszArgs != NULL) {
  1931. FFreeRgsz(rgszArgs);
  1932. }
  1933. }
  1934. return(fOkay);
  1935. }
  1936. /*
  1937. ** Purpose:
  1938. ** Arguments:
  1939. ** Returns:
  1940. **
  1941. *************************************************************************/
  1942. BOOL APIENTRY FParseInvokeApplet(INT Line, UINT *pcFields)
  1943. {
  1944. BOOL fOkay = fFalse;
  1945. SZ szLibrary = NULL;
  1946. iFieldCur = 2;
  1947. if(*pcFields >= 2) {
  1948. FGetArgSz(Line,pcFields,&szLibrary); // name of library
  1949. if(szLibrary != NULL) {
  1950. fOkay = FInvokeApplet(szLibrary);
  1951. SFree(szLibrary);
  1952. }
  1953. }
  1954. return(fOkay);
  1955. }
  1956. BOOL APIENTRY FParseAddFileToDeleteList(INT Line, UINT *pcFields)
  1957. {
  1958. BOOL fOkay = fFalse;
  1959. SZ szFile = NULL;
  1960. iFieldCur = 2;
  1961. if(*pcFields >= 2) {
  1962. FGetArgSz(Line,pcFields,&szFile); // filename to add
  1963. if(szFile != NULL) {
  1964. fOkay = AddFileToDeleteList(szFile);
  1965. SFree(szFile);
  1966. }
  1967. }
  1968. return(fOkay);
  1969. }
  1970. #define FAIL_EVENT_MARK '*'
  1971. BOOL APIENTRY FParseWaitOnEvent(INT Line,UINT *pcFields)
  1972. {
  1973. BOOL fOkay = fFalse;
  1974. SZ szInfVar = NULL,
  1975. szEvent = NULL,
  1976. szTimeout = NULL;
  1977. iFieldCur = 2;
  1978. if(*pcFields >= 4) {
  1979. FGetArgSz(Line,pcFields,&szInfVar); // INF variable to stuff
  1980. FGetArgSz(Line,pcFields,&szEvent);
  1981. FGetArgSz(Line,pcFields,&szTimeout);
  1982. //
  1983. // If the first character of the event name string is '*', this is a
  1984. // signal to call the special version of event waiting which allows the
  1985. // signaller to alternatively signal an event named SETUP_FAILED
  1986. // to indicate that the process failed and an error popup has already
  1987. // been presented to the user. In this case, the result variable will
  1988. // contain "EventFailed". If the SETUP_FAILED event cannot be created,
  1989. // the result is "EventNoFailEvent".
  1990. //
  1991. if ( (szInfVar != NULL) && (szEvent != NULL) && (szTimeout != NULL) )
  1992. {
  1993. DWORD dwTimeout = atol( szTimeout ) ;
  1994. if ( szEvent[0] == FAIL_EVENT_MARK )
  1995. {
  1996. fOkay = FWaitForEventOrFailure( szInfVar, szEvent+1, dwTimeout );
  1997. }
  1998. else
  1999. {
  2000. fOkay = FWaitForEvent( szInfVar, szEvent, dwTimeout );
  2001. }
  2002. }
  2003. if(szInfVar != NULL) {
  2004. SFree(szInfVar);
  2005. }
  2006. if(szEvent != NULL) {
  2007. SFree(szEvent);
  2008. }
  2009. if(szTimeout != NULL) {
  2010. SFree(szTimeout);
  2011. }
  2012. }
  2013. return(fOkay);
  2014. }
  2015. BOOL APIENTRY FParseSleep(INT Line,UINT *pcFields)
  2016. {
  2017. SZ szMilliseconds = NULL;
  2018. iFieldCur = 2 ;
  2019. if (*pcFields >= 2) {
  2020. FGetArgSz(Line,pcFields,&szMilliseconds);
  2021. FSleep( atol( szMilliseconds ) ) ;
  2022. }
  2023. return TRUE ;
  2024. }
  2025. BOOL APIENTRY FParseFlushInf(INT Line,UINT *pcFields)
  2026. {
  2027. SZ szInf;
  2028. BOOL fOkay = fFalse;
  2029. iFieldCur = 2 ;
  2030. if (*pcFields >= 2) {
  2031. FGetArgSz(Line,pcFields,&szInf);
  2032. fOkay = FFlushInfParsedInfo( szInf );
  2033. }
  2034. return(fOkay);
  2035. }
  2036. static VOID freeBmps ( VOID )
  2037. {
  2038. INT i ;
  2039. for ( i = 0 ; i < BMP_MAX && hbmAdvertList[i] ; i++ )
  2040. {
  2041. DeleteObject( hbmAdvertList[i] ) ;
  2042. hbmAdvertList[i] = NULL ;
  2043. if ( hWndShell && i == 0 )
  2044. {
  2045. InvalidateRect( hWndShell, NULL, FALSE ) ;
  2046. UpdateWindow( hWndShell ) ;
  2047. }
  2048. }
  2049. }
  2050. //
  2051. // Syntax:
  2052. //
  2053. // BMPSHOW
  2054. // <cycle time in seconds>
  2055. // <relative X position, 0..100>
  2056. // <relative Y position, 0..100>
  2057. // {list of bitmap id numbers}
  2058. //
  2059. BOOL APIENTRY FParseBmpShow ( INT Line, UINT * pcFields )
  2060. {
  2061. SZ sz=NULL;
  2062. INT iId, iCycle, cBmps, i ;
  2063. BOOL fOkay = fFalse;
  2064. RGSZ rgszIds ;
  2065. iFieldCur = 2 ;
  2066. if ( ! fFullScreen )
  2067. {
  2068. fOkay = fTrue ;
  2069. }
  2070. else
  2071. if ( *pcFields >= 4)
  2072. {
  2073. freeBmps() ;
  2074. FGetArgSz( Line, pcFields, & sz );
  2075. iCycle = atoi( sz ) ;
  2076. sz = NULL;
  2077. FGetArgSz( Line, pcFields, & sz );
  2078. cxAdvert = atoi( sz ) ;
  2079. sz = NULL;
  2080. FGetArgSz( Line, pcFields, & sz );
  2081. cyAdvert = atoi( sz ) ;
  2082. sz = NULL;
  2083. FGetArgSz( Line, pcFields, & sz );
  2084. rgszIds = RgszFromSzListValue( sz ) ;
  2085. cBmps = 0 ;
  2086. if ( rgszIds )
  2087. {
  2088. // Load all the bitmaps we can fit and find.
  2089. for ( iId = 0 ; iId < BMP_MAX && rgszIds[iId] ; iId++ )
  2090. {
  2091. hbmAdvertList[cBmps] = LoadBitmap( hInst,
  2092. MAKEINTRESOURCE( atoi( rgszIds[iId] ) ) ) ;
  2093. if ( hbmAdvertList[cBmps] )
  2094. cBmps++ ;
  2095. }
  2096. FFreeRgsz( rgszIds ) ;
  2097. }
  2098. hbmAdvertList[cBmps] = NULL ;
  2099. if ( cBmps )
  2100. {
  2101. fOkay = fTrue ;
  2102. cAdvertCycleSeconds = iCycle ;
  2103. // Activate BMP display: point at last bitmap (end of cycle)
  2104. cAdvertIndex = cBmps - 1 ;
  2105. }
  2106. }
  2107. return(fOkay);
  2108. }
  2109. //
  2110. // Syntax: BMPHIDE
  2111. //
  2112. BOOL APIENTRY FParseBmpHide ( INT Line, UINT * pcFields )
  2113. {
  2114. BOOL fOkay = fTrue ;
  2115. iFieldCur = 2 ;
  2116. if ( fFullScreen )
  2117. {
  2118. // Turn off BMP display
  2119. cAdvertIndex = -1 ;
  2120. freeBmps() ;
  2121. }
  2122. return(fOkay);
  2123. }
  2124. BOOL APIENTRY FParseSignalEvent(INT Line,UINT *pcFields)
  2125. {
  2126. BOOL fOkay = fFalse;
  2127. SZ szInfVar = NULL,
  2128. szEvent = NULL;
  2129. iFieldCur = 2;
  2130. if(*pcFields >= 3) {
  2131. FGetArgSz(Line,pcFields,&szInfVar); // INF variable to stuff
  2132. FGetArgSz(Line,pcFields,&szEvent);
  2133. if((szInfVar != NULL) && (szEvent != NULL)) {
  2134. fOkay = FSignalEvent( szInfVar, szEvent );
  2135. }
  2136. if(szInfVar != NULL) {
  2137. SFree(szInfVar);
  2138. }
  2139. if(szEvent != NULL) {
  2140. SFree(szEvent);
  2141. }
  2142. }
  2143. return(fOkay);
  2144. }