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.

704 lines
16 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /*++
  4. Copyright (c) 1991 Microsoft Corporation
  5. Module Name:
  6. inf_rt2.c
  7. Abstract:
  8. INF file runtime field interpreter.
  9. A given string is interpreted as a tokenized field and an output
  10. buffer containing the result is constructed.
  11. Author:
  12. Ted Miller (tedm) 10-Spetember-1991
  13. --*/
  14. /* Input stuff */
  15. LPBYTE Interpret_Inputp;
  16. #define GETTOKEN() (*Interpret_Inputp++)
  17. #define PEEKTOKEN() (*Interpret_Inputp)
  18. #define UNGETTOKEN(t) (*(--Interpret_Inputp) = t)
  19. #define VERIFY_SIZE(s) \
  20. if ( SpaceLeftInFieldBuffer < (s) ) { \
  21. GrowBuffer(s); \
  22. }
  23. /* end input stuff */
  24. /* Output stuff */
  25. #define MAX_FIELD_LENGTH 4096
  26. PUCHAR InterpretedFieldBuffer;
  27. UINT SpaceLeftInFieldBuffer;
  28. UINT BufferSize;
  29. PUCHAR Interpret_OutputLoc;
  30. /* end output stuff */
  31. SZ Interpret_GetField(VOID);
  32. BOOL DoVariable(VOID);
  33. BOOL DoListFromSectionNthItem(VOID);
  34. BOOL DoFieldAddressor(VOID);
  35. BOOL DoAppendItemToList(VOID);
  36. BOOL DoNthItemFromList(VOID);
  37. BOOL DoLocateItemInList(VOID);
  38. BOOL DoList(VOID);
  39. BOOL DoString(BYTE StringToken);
  40. /* Run time error field */
  41. GRC grcRTLastError = grcOkay;
  42. VOID GrowBuffer(UINT Size);
  43. SZ
  44. APIENTRY
  45. InterpretField(
  46. SZ Field
  47. )
  48. {
  49. SZ ReturnString,
  50. InputSave = Interpret_Inputp;
  51. Interpret_Inputp = Field;
  52. ReturnString = Interpret_GetField();
  53. Interpret_Inputp = InputSave;
  54. return(ReturnString);
  55. }
  56. SZ
  57. Interpret_GetField(
  58. VOID
  59. )
  60. {
  61. LPSTR OldOutputBuffer = InterpretedFieldBuffer;
  62. LPSTR OldInterpretLoc = Interpret_OutputLoc;
  63. UINT OldSpaceLeft = SpaceLeftInFieldBuffer;
  64. LPSTR ReturnString = NULL;
  65. BYTE Token;
  66. if((InterpretedFieldBuffer
  67. = SAlloc(SpaceLeftInFieldBuffer = MAX_FIELD_LENGTH))
  68. == NULL)
  69. {
  70. grcRTLastError = grcOutOfMemory;
  71. return(NULL);
  72. }
  73. BufferSize = MAX_FIELD_LENGTH;
  74. Interpret_OutputLoc = InterpretedFieldBuffer;
  75. VERIFY_SIZE(1);
  76. SpaceLeftInFieldBuffer--; // leave space for terminating NUL
  77. while((Token = GETTOKEN())
  78. && (Token != TOKEN_COMMA)
  79. && (Token != TOKEN_SPACE)
  80. && (Token != TOKEN_RIGHT_PAREN)
  81. && (Token != TOKEN_LIST_END))
  82. {
  83. if(IS_STRING_TOKEN(Token)) {
  84. if(!DoString(Token)) {
  85. SFree(InterpretedFieldBuffer);
  86. goto Cleanup;
  87. }
  88. } else {
  89. switch(Token) {
  90. case TOKEN_VARIABLE:
  91. if(!DoVariable()) {
  92. SFree(InterpretedFieldBuffer);
  93. goto Cleanup;
  94. }
  95. break;
  96. case TOKEN_LIST_FROM_SECTION_NTH_ITEM:
  97. if(!DoListFromSectionNthItem()) {
  98. SFree(InterpretedFieldBuffer);
  99. goto Cleanup;
  100. }
  101. break;
  102. case TOKEN_FIELD_ADDRESSOR:
  103. if(!DoFieldAddressor()) {
  104. SFree(InterpretedFieldBuffer);
  105. goto Cleanup;
  106. }
  107. break;
  108. case TOKEN_APPEND_ITEM_TO_LIST:
  109. if(!DoAppendItemToList()) {
  110. SFree(InterpretedFieldBuffer);
  111. goto Cleanup;
  112. }
  113. break;
  114. case TOKEN_NTH_ITEM_FROM_LIST:
  115. if(!DoNthItemFromList()) {
  116. SFree(InterpretedFieldBuffer);
  117. goto Cleanup;
  118. }
  119. break;
  120. case TOKEN_LOCATE_ITEM_IN_LIST:
  121. if(!DoLocateItemInList()) {
  122. SFree(InterpretedFieldBuffer);
  123. goto Cleanup;
  124. }
  125. break;
  126. case TOKEN_LIST_START:
  127. if(!DoList()) {
  128. SFree(InterpretedFieldBuffer);
  129. goto Cleanup;
  130. }
  131. break;
  132. default:
  133. #if DBG
  134. {
  135. char str[100];
  136. wsprintf(str,"Bogus token: %u",Token);
  137. MessBoxSzSz("Interpret_GetField",str);
  138. }
  139. #endif
  140. break;
  141. } // switch
  142. } // if-else
  143. } // while
  144. /*
  145. The following is because we want the routines DoOperator()
  146. and DoList() (below) to have access to their terminators.
  147. */
  148. if((Token == TOKEN_RIGHT_PAREN) || (Token == TOKEN_LIST_END)) {
  149. UNGETTOKEN(Token);
  150. }
  151. Assert((LONG)SpaceLeftInFieldBuffer >= 0); // space provided for above
  152. *Interpret_OutputLoc = NUL;
  153. ReturnString = SRealloc(InterpretedFieldBuffer,
  154. BufferSize - SpaceLeftInFieldBuffer
  155. );
  156. Assert(ReturnString); // buffer was shrinking;
  157. Cleanup:
  158. Interpret_OutputLoc = OldInterpretLoc;
  159. InterpretedFieldBuffer = OldOutputBuffer;
  160. SpaceLeftInFieldBuffer = OldSpaceLeft;
  161. return(ReturnString);
  162. }
  163. /*
  164. This routine gets the fields of an operator into an rgsz.
  165. */
  166. RGSZ
  167. DoOperator(
  168. UINT FieldCount
  169. )
  170. {
  171. UINT x;
  172. RGSZ rgsz;
  173. Assert(FieldCount);
  174. if((rgsz = (RGSZ)SAlloc((FieldCount+1)*sizeof(SZ))) == NULL) {
  175. grcRTLastError = grcOutOfMemory;
  176. return(NULL);
  177. }
  178. rgsz[FieldCount] = NULL;
  179. for(x=0; x<FieldCount-1; x++) {
  180. if((rgsz[x] = Interpret_GetField()) == NULL) {
  181. FFreeRgsz(rgsz);
  182. return(NULL);
  183. }
  184. if(PEEKTOKEN() == TOKEN_RIGHT_PAREN) {
  185. FFreeRgsz(rgsz);
  186. grcRTLastError = grcNotOkay;
  187. return(NULL);
  188. }
  189. }
  190. if((rgsz[FieldCount-1] = Interpret_GetField()) == NULL) {
  191. FFreeRgsz(rgsz);
  192. return(NULL);
  193. }
  194. Assert(PEEKTOKEN() != NUL);
  195. if(GETTOKEN() != TOKEN_RIGHT_PAREN) { // skips )
  196. FFreeRgsz(rgsz);
  197. grcRTLastError = grcNotOkay;
  198. return(NULL);
  199. }
  200. return(rgsz);
  201. }
  202. BOOL
  203. DoVariable(
  204. VOID
  205. )
  206. {
  207. RGSZ rgsz;
  208. SZ SymbolValue;
  209. UINT x,SymbolValueLength;
  210. BOOL rc = TRUE;
  211. if((rgsz = DoOperator(1)) == NULL) {
  212. return(FALSE);
  213. }
  214. if((SymbolValue = SzFindSymbolValueInSymTab(rgsz[0])) == NULL) {
  215. SymbolValue = "";
  216. }
  217. SymbolValueLength = lstrlen(SymbolValue);
  218. VERIFY_SIZE(SymbolValueLength);
  219. if(SpaceLeftInFieldBuffer >= SymbolValueLength) {
  220. SpaceLeftInFieldBuffer -= SymbolValueLength;
  221. for(x=0; x<SymbolValueLength; x++) {
  222. *Interpret_OutputLoc++ = *SymbolValue++;
  223. }
  224. } else {
  225. grcRTLastError = grcNotOkay;
  226. rc = FALSE;
  227. }
  228. FFreeRgsz(rgsz);
  229. return(rc);
  230. }
  231. BOOL
  232. DoListFromSectionNthItem(
  233. VOID
  234. )
  235. {
  236. RGSZ rgsz,rgszList = NULL;
  237. UINT LineCount,n,x,LineNo;
  238. BOOL rc = FALSE;
  239. SZ List,ListSave;
  240. if((rgsz = DoOperator(2)) == NULL) {
  241. return(FALSE);
  242. }
  243. grcRTLastError = grcNotOkay;
  244. n = atoi(rgsz[1]);
  245. LineCount = CKeysFromInfSection(rgsz[0],TRUE);
  246. if((rgszList = (RGSZ)SAlloc((LineCount+1)*sizeof(SZ))) != NULL) {
  247. LineNo = FindInfSectionLine(rgsz[0]);
  248. for(x=0; x<LineCount; x++) {
  249. LineNo = FindNextLineFromInf(LineNo);
  250. Assert(LineNo != -1);
  251. rgszList[x] = SzGetNthFieldFromInfLine(LineNo,n);
  252. }
  253. rgszList[LineCount] = NULL;
  254. if((List = SzListValueFromRgsz(rgszList)) != NULL) {
  255. ListSave = List;
  256. x = lstrlen(List);
  257. VERIFY_SIZE(x);
  258. if(SpaceLeftInFieldBuffer >= x) {
  259. SpaceLeftInFieldBuffer -= x;
  260. for(n=0; n<x; n++) {
  261. *Interpret_OutputLoc++ = *List++;
  262. }
  263. grcRTLastError = grcOkay;
  264. rc = TRUE;
  265. }
  266. SFree(ListSave);
  267. } else {
  268. grcRTLastError = grcOutOfMemory;
  269. }
  270. } else {
  271. grcRTLastError = grcOutOfMemory;
  272. }
  273. if(rgszList != NULL) {
  274. FFreeRgsz(rgszList);
  275. }
  276. FFreeRgsz(rgsz);
  277. return(rc);
  278. }
  279. BOOL
  280. DoFieldAddressor(
  281. VOID
  282. )
  283. {
  284. RGSZ rgsz;
  285. UINT x,n;
  286. SZ Result,ResultSave;
  287. BOOL rc = FALSE;
  288. if((rgsz = DoOperator(3)) == NULL) {
  289. return(FALSE);
  290. }
  291. grcRTLastError = grcNotOkay;
  292. n = atoi(rgsz[2]);
  293. // rgsz[0] has section, rgsz[1] has key
  294. if((Result = SzGetNthFieldFromInfSectionKey(rgsz[0],rgsz[1],n)) != NULL) {
  295. ResultSave = Result;
  296. n = lstrlen(Result);
  297. VERIFY_SIZE(n);
  298. if(SpaceLeftInFieldBuffer >= n) {
  299. SpaceLeftInFieldBuffer -= n;
  300. for(x=0; x<n; x++) {
  301. *Interpret_OutputLoc++ = *Result++;
  302. }
  303. grcRTLastError = grcOkay;
  304. rc = TRUE;
  305. }
  306. SFree(ResultSave);
  307. }
  308. FFreeRgsz(rgsz);
  309. return(rc);
  310. }
  311. BOOL
  312. DoAppendItemToList(
  313. VOID
  314. )
  315. {
  316. RGSZ rgsz,rgszList1,rgszList2;
  317. UINT RgszSize,x,y;
  318. SZ ListValue,ListTemp;
  319. if((rgsz = DoOperator(2)) == NULL) {
  320. return(FALSE);
  321. }
  322. // rgsz[0] has list, rgsz[1] has item
  323. if((rgszList1 = RgszFromSzListValue(rgsz[0])) == NULL) {
  324. FFreeRgsz(rgsz);
  325. grcRTLastError = grcOutOfMemory;
  326. return(FALSE);
  327. }
  328. for (RgszSize = 0; rgszList1[RgszSize] != NULL; RgszSize++) {
  329. ;
  330. }
  331. if ((rgszList2 = (RGSZ)SRealloc(rgszList1, (RgszSize+2)*sizeof(SZ)
  332. )) == NULL)
  333. {
  334. FFreeRgsz(rgszList1);
  335. FFreeRgsz(rgsz);
  336. grcRTLastError = grcOutOfMemory;
  337. return(FALSE);
  338. }
  339. rgszList2[RgszSize] = SzDupl(rgsz[1]);
  340. rgszList2[RgszSize+1] = NULL;
  341. ListValue = SzListValueFromRgsz(rgszList2);
  342. FFreeRgsz(rgszList2);
  343. if(ListValue == NULL) {
  344. FFreeRgsz(rgsz);
  345. grcRTLastError = grcOutOfMemory;
  346. return(FALSE);
  347. }
  348. x = lstrlen(ListValue);
  349. VERIFY_SIZE(x);
  350. if(x > SpaceLeftInFieldBuffer) {
  351. SFree(ListValue);
  352. FFreeRgsz(rgsz);
  353. grcRTLastError = grcNotOkay;
  354. return(FALSE);
  355. }
  356. ListTemp = ListValue;
  357. for(y=0; y<x; y++) {
  358. *Interpret_OutputLoc++ = *ListTemp++;
  359. }
  360. SpaceLeftInFieldBuffer -= x;
  361. SFree(ListValue);
  362. FFreeRgsz(rgsz);
  363. return(TRUE);
  364. }
  365. BOOL
  366. DoNthItemFromList(
  367. VOID
  368. )
  369. {
  370. RGSZ rgsz,
  371. rgszList = NULL;
  372. UINT n,x,y,ListSize;
  373. PUCHAR Item;
  374. BOOL rc = FALSE;
  375. if((rgsz = DoOperator(2)) == NULL) {
  376. return(FALSE);
  377. }
  378. grcRTLastError = grcNotOkay;
  379. n = atoi(rgsz[1]);
  380. if((rgszList = RgszFromSzListValue(rgsz[0])) != NULL) {
  381. for(ListSize=0; rgszList[ListSize]; ListSize++) {
  382. ;
  383. } // count list items
  384. if(!n || (n > ListSize)) {
  385. Item = "";
  386. } else {
  387. Item = rgszList[n-1];
  388. }
  389. x = lstrlen(Item);
  390. VERIFY_SIZE(x);
  391. if(SpaceLeftInFieldBuffer >= x) {
  392. SpaceLeftInFieldBuffer -= x;
  393. for(y=0; y<x; y++) {
  394. *Interpret_OutputLoc++ = *Item++;
  395. }
  396. grcRTLastError = grcOkay;
  397. rc = TRUE;
  398. }
  399. } else {
  400. grcRTLastError = grcOutOfMemory;
  401. }
  402. if(rgszList != NULL) {
  403. FFreeRgsz(rgszList);
  404. }
  405. FFreeRgsz(rgsz);
  406. return(rc);
  407. }
  408. BOOL
  409. DoLocateItemInList( // 1-based, 0 if not found
  410. VOID
  411. )
  412. {
  413. RGSZ rgsz,rgszList;
  414. UINT Item = 0,
  415. x,y;
  416. BOOL rc = FALSE;
  417. char szItem[25]; // arbitrary length
  418. char *szItemTemp;
  419. if((rgsz = DoOperator(2)) == NULL) {
  420. return(FALSE);
  421. }
  422. grcRTLastError = grcNotOkay;
  423. // rgsz[0] has list, rgsz[1] has item to locate
  424. if((rgszList = RgszFromSzListValue(rgsz[0])) != NULL) {
  425. for(x=0; rgszList[x]; x++) {
  426. if(!lstrcmpi(rgsz[1],rgszList[x])) {
  427. Item = x+1;
  428. break;
  429. }
  430. }
  431. FFreeRgsz(rgszList);
  432. wsprintf(szItem,"%u",Item);
  433. x = lstrlen(szItem);
  434. VERIFY_SIZE(x);
  435. if( x <= SpaceLeftInFieldBuffer) {
  436. SpaceLeftInFieldBuffer -= x;
  437. szItemTemp = szItem;
  438. for(y=0; y<x; y++) {
  439. *Interpret_OutputLoc++ = *szItemTemp++;
  440. }
  441. rc = TRUE;
  442. grcRTLastError = grcOkay;
  443. }
  444. } else {
  445. grcRTLastError = grcOutOfMemory;
  446. }
  447. FFreeRgsz(rgsz);
  448. return(rc);
  449. }
  450. BOOL
  451. DoList(
  452. VOID
  453. )
  454. {
  455. RGSZ rgsz;
  456. LPVOID r;
  457. UINT RgszSize;
  458. UINT ItemCount;
  459. UINT ListLength,x;
  460. SZ List,ListSave;
  461. BOOL rc;
  462. if((rgsz = (RGSZ)SAlloc(10 * sizeof(SZ))) == NULL) {
  463. grcRTLastError = grcOutOfMemory;
  464. return(FALSE);
  465. }
  466. RgszSize = 10;
  467. ItemCount = 1; // reserve space for the NULL entry
  468. while(PEEKTOKEN() != TOKEN_LIST_END) {
  469. if(ItemCount == RgszSize) {
  470. if((r = SRealloc(rgsz,
  471. (RgszSize + 10) * sizeof(SZ)
  472. )
  473. )
  474. == NULL)
  475. {
  476. rgsz[ItemCount-1] = NULL; // for FFreeRgsz
  477. FFreeRgsz(rgsz);
  478. grcRTLastError = grcOutOfMemory;
  479. return(FALSE);
  480. }
  481. RgszSize += 10;
  482. rgsz = r;
  483. }
  484. if((rgsz[ItemCount-1] = Interpret_GetField()) == NULL) {
  485. FFreeRgsz(rgsz);
  486. return(FALSE);
  487. }
  488. ItemCount++;
  489. }
  490. EvalAssert(GETTOKEN() == TOKEN_LIST_END); // skip list end
  491. Assert(ItemCount <= RgszSize);
  492. rgsz[ItemCount-1] = NULL; // space for this reserved above
  493. rgsz = (RGSZ)SRealloc(rgsz,ItemCount * sizeof(SZ));
  494. Assert(rgsz); // it was shrinking
  495. List = SzListValueFromRgsz(rgsz);
  496. FFreeRgsz(rgsz);
  497. if(List == NULL) {
  498. grcRTLastError = grcOutOfMemory;
  499. return(FALSE);
  500. }
  501. ListLength = lstrlen(List);
  502. ListSave = List;
  503. VERIFY_SIZE(ListLength);
  504. if(SpaceLeftInFieldBuffer >= ListLength) {
  505. SpaceLeftInFieldBuffer -= ListLength;
  506. for(x=0; x<ListLength; x++) {
  507. *Interpret_OutputLoc++ = *List++;
  508. }
  509. rc = TRUE;
  510. } else {
  511. grcRTLastError = grcNotOkay;
  512. rc = FALSE;
  513. }
  514. SFree(ListSave);
  515. return(rc);
  516. }
  517. BOOL
  518. DoString(
  519. BYTE StringToken
  520. )
  521. {
  522. USHORT StringLength;
  523. UINT x;
  524. Assert(IS_STRING_TOKEN(StringToken));
  525. if(StringToken < TOKEN_STRING) { // test for short string
  526. StringLength = (USHORT)StringToken - (USHORT)TOKEN_SHORT_STRING;
  527. } else if (StringToken == TOKEN_STRING) { // test for regular string
  528. StringLength = (USHORT)GETTOKEN() + (USHORT)100;
  529. } else { // long string
  530. Assert(StringToken == TOKEN_LONG_STRING);
  531. StringLength = (USHORT)GETTOKEN() << 8;
  532. StringLength |= (USHORT)GETTOKEN();
  533. }
  534. VERIFY_SIZE( StringLength );
  535. if(SpaceLeftInFieldBuffer >= StringLength) {
  536. SpaceLeftInFieldBuffer -= StringLength;
  537. for(x=0; x<StringLength; x++) {
  538. *Interpret_OutputLoc++ = GETTOKEN();
  539. }
  540. } else {
  541. grcRTLastError = grcNotOkay;
  542. return(FALSE);
  543. }
  544. return(TRUE);
  545. }
  546. VOID
  547. GrowBuffer( UINT Size )
  548. {
  549. while ( SpaceLeftInFieldBuffer < Size ) {
  550. //
  551. // Reallocate buffer
  552. //
  553. PUCHAR p;
  554. UINT_PTR Offset = Interpret_OutputLoc - InterpretedFieldBuffer;
  555. p = (PUCHAR)SRealloc( InterpretedFieldBuffer,
  556. BufferSize + MAX_FIELD_LENGTH);
  557. if ( p ) {
  558. InterpretedFieldBuffer = p;
  559. Interpret_OutputLoc = InterpretedFieldBuffer + Offset;
  560. SpaceLeftInFieldBuffer += MAX_FIELD_LENGTH;
  561. BufferSize += MAX_FIELD_LENGTH;
  562. } else {
  563. break;
  564. }
  565. }
  566. }