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

3037 lines
85 KiB

  1. /** CustRes.c
  2. *
  3. * Custom resource handler module for TOKRES.
  4. *
  5. * Written by SteveBl
  6. *
  7. * Exported Functions:
  8. * int ParseResourceDescriptionFile(FILE *ResourceDescriptionFile);
  9. *
  10. * int GetCustomResource(FILE *inResFile, DWORD *lsize,
  11. * CUSTOM_RESOURCE *pCustomResource,
  12. * WORD wTypeId);
  13. *
  14. * void TokCustomResource(FILE *TokFile, RESHEADER ResHeader,
  15. * CUSTOM_RESOURCE *pCustomResource);
  16. *
  17. * void PutCustomResource(FILE *OutResFile, FILE *TokFile,
  18. * RESHEADER ResHeader,
  19. * CUSTOM_RESOURCE *pCustomResource);
  20. *
  21. * void ClearCustomResource(CUSTOM_RESOURCE *pCustomResource);
  22. *
  23. * History:
  24. * Initial version written January 21, 1992. -- SteveBl
  25. *
  26. * 01/21/93 - Changes to allow arb length token texts. Also, fix
  27. * some latent bugs. MHotchin
  28. **/
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include <tchar.h>
  33. #ifdef RLDOS
  34. #include "dosdefs.h"
  35. #else
  36. #include <windows.h>
  37. #include "windefs.h"
  38. #endif
  39. #include "custres.h"
  40. #include "restok.h"
  41. #include "resread.h"
  42. extern PROJDATA gProj; //... Fields filled in main (UI)
  43. extern BOOL gbMaster;
  44. extern UCHAR szDHW[];
  45. enum LOCALIZABLE_TYPES // determines data storage, reading, and printing method
  46. {
  47. NOTLOCALIZABLE, // not to be stored
  48. NOTLOCALIZABLESZ, // unlocalizable null terminated string
  49. NOTLOCALIZABLEWSZ, // unlocalizable null terminated Unicode string
  50. LT_INTEGER, // store as a long integer
  51. LT_FLOAT, // store as a double preceision floating point number
  52. LT_CHAR, // store as a single character
  53. LT_STRING, // an array of char
  54. LT_SZ, // a null terminated array of characters
  55. LT_WCHAR, // store as a single Unicode character
  56. LT_WSTRING, // an array of Unicode char
  57. LT_WSZ, // a null terminated array of Unicode characters
  58. LT_UNSIGNED=16 // add with the others
  59. };
  60. typedef struct typesizes
  61. {
  62. CHAR *szType;
  63. enum LOCALIZABLE_TYPES iType;
  64. int iShortSize;
  65. int iLongSize;
  66. } TYPESIZES;
  67. TYPESIZES rgTypeSizes[] =
  68. {
  69. #ifdef RLWIN32
  70. "WCHAR", LT_WCHAR, 2, 2,
  71. "TCHAR", LT_WCHAR, 2, 2,
  72. "INT", LT_INTEGER, 4, 4,
  73. "SIGNED", LT_INTEGER, 4, 4,
  74. "UNSIGNED", LT_INTEGER, 4, 4,
  75. "ENUM", LT_INTEGER, 4, 4,
  76. #else //RLWIN32
  77. "TCHAR", LT_CHAR, 1, 1,
  78. "INT", LT_INTEGER, 2, 4,
  79. "SIGNED", LT_INTEGER, 2, 4,
  80. "UNSIGNED", LT_INTEGER, 2, 4,
  81. "ENUM", LT_INTEGER, 2, 2,
  82. #endif //RLWIN32
  83. "CHAR", LT_CHAR, 1, 1,
  84. "BYTE", LT_INTEGER, 1, 1,
  85. "WORD", LT_INTEGER, 2, 2,
  86. "SHORT", LT_INTEGER, 2, 2,
  87. "FLOAT", LT_FLOAT, 4, 4,
  88. "LONG", LT_INTEGER, 4, 4,
  89. "DOUBLE", LT_FLOAT, 8, 8,
  90. "DWORD", LT_INTEGER, 4, 4
  91. };
  92. typedef struct resourcetypes
  93. {
  94. CHAR *szType;
  95. int iType;
  96. } RESOURCETYPES;
  97. RESOURCETYPES rgResourceTypes[] =
  98. {
  99. "CURSOR", 1,
  100. "BITMAP", 2,
  101. "ICON", 3,
  102. "MENU", 4,
  103. "DIALOG", 5,
  104. "STRING", 6,
  105. "FONTDIR", 7,
  106. "FONT", 8,
  107. "ACCELERATORS", 9,
  108. "RCDATA", 10,
  109. "ERRTABLE", 11,
  110. "GROUP_CURSOR", 12,
  111. "GROUP_ICON", 14,
  112. "NAMETABLE", 15,
  113. "VERSION", 16
  114. };
  115. typedef struct CustResTemplate
  116. {
  117. enum LOCALIZABLE_TYPES iType;
  118. unsigned uSize;
  119. struct CustResTemplate far *pNext;
  120. } CUSTRESTEMPLATE;
  121. typedef struct CustResNode
  122. {
  123. BYTE bTypeFlag; /* Indicat's if ID or string */
  124. BYTE bNameFlag; /* Indicat's if ID or string */
  125. WORD wTypeID;
  126. WORD wNameID;
  127. TCHAR *pszType;
  128. TCHAR *pszName;
  129. CUSTRESTEMPLATE far *pTemplate;
  130. struct CustResNode far *pNext;
  131. } CUSTRESNODE;
  132. typedef CUSTRESTEMPLATE far * FPCUSTRESTEMPLATE;
  133. typedef CUSTRESNODE far * FPCUSTRESNODE;
  134. CUSTRESNODE far *pCustResList = NULL;
  135. #define SYMBOLSIZE 255
  136. int fUseSavedSymbol = FALSE;
  137. int *piLineNumber = NULL;
  138. CHAR szSavedSymbol[ SYMBOLSIZE];
  139. /*
  140. * Function Predefinitions:
  141. */
  142. static int GetResourceType( CHAR sz[]);
  143. static int AddStructureElement( int iType,
  144. int nSize,
  145. FPCUSTRESTEMPLATE *ppCRT,
  146. int fMerge);
  147. #ifdef RLWIN32
  148. static void AddToW( TCHAR *sz, int *c, int lTarget, TCHAR ch);
  149. static TCHAR *CheckBufSizeW(
  150. int *lTarget, //... Length of output buffer
  151. int cOutBufLen, //... Bytes already used in output buffer
  152. int cDelta, //... # characters we want to add to output buffer
  153. TCHAR *szOutBuf); //... ptr to output buffer
  154. #endif
  155. static CHAR *CheckBufSize(
  156. int *lTarget, //... Length of output buffer
  157. int cOutBufLen, //... Bytes already used in output buffer
  158. int cDelta, //... # characters we want to add to output buffer
  159. CHAR *szOutBuf); //... ptr to output buffer
  160. static void AddTo( CHAR *sz, int *c, int lTarget, CHAR ch);
  161. static int UngetSymbol( CHAR sz[]);
  162. static int GetNextSymbol( CHAR sz[], unsigned n, FILE *f);
  163. static int ParseBlock( FILE *f, FPCUSTRESTEMPLATE *ppCRT);
  164. static CUSTRESNODE far * MatchResource( RESHEADER Resheader);
  165. static void far * GetResData( enum LOCALIZABLE_TYPES wType,
  166. unsigned uSize,
  167. FILE *f,
  168. DWORD *lSize);
  169. static int PutResData( void far *pData,
  170. enum LOCALIZABLE_TYPES wType,
  171. unsigned uSize,
  172. FILE *f);
  173. static void far * GetTextData( enum LOCALIZABLE_TYPES wType,
  174. unsigned uSize,
  175. TCHAR sz[]);
  176. static int PutTextData( void far *pData,
  177. enum LOCALIZABLE_TYPES wType,
  178. unsigned uSize,
  179. TCHAR sz[],
  180. int l);
  181. int atoihex( CHAR sz[]);
  182. /** Function: GetResourceType
  183. * Returns the value of the number or resource type in sz.
  184. *
  185. * Arguments:
  186. * sz, string containing either a positive number or a resource type
  187. *
  188. * Returns:
  189. * value in resource
  190. *
  191. * Error Codes:
  192. * -1 if illegal value
  193. *
  194. * History:
  195. * 1/92 - initial implementation -- SteveBl
  196. **/
  197. static int GetResourceType( CHAR sz[])
  198. {
  199. int i;
  200. if (sz[0] >= '0' && sz[0] <= '9')
  201. {
  202. return atoi(sz);
  203. }
  204. for (i = sizeof(rgResourceTypes)/sizeof(RESOURCETYPES);i--;)
  205. {
  206. if ( ! lstrcmpiA( sz, rgResourceTypes[i].szType) )
  207. {
  208. return rgResourceTypes[i].iType;
  209. }
  210. }
  211. return -1;
  212. }
  213. /** Function: AddStructureElement
  214. * Adds an element's type and size to the Template list.
  215. * If this element can be merged with the last element do so.
  216. *
  217. * Arguments:
  218. * iType, how the data is interpreted
  219. * nSize, number of bytes used by the data
  220. * ppCRT, pointer to the next Custom Resource Template pointer
  221. * fMerge, if true then NOTLOCALIZABLE data will be merged.
  222. *
  223. * Returns:
  224. * 0 - if successful
  225. * !0 - if unsuccessful
  226. *
  227. * Error Codes:
  228. * 1 - out of memory
  229. *
  230. * History:
  231. * 1/92 - initial implementation -- SteveBl
  232. **/
  233. static int AddStructureElement(
  234. int iType,
  235. int nSize,
  236. FPCUSTRESTEMPLATE *ppCRT,
  237. int fMerge)
  238. {
  239. if ( fMerge
  240. && ((iType == NOTLOCALIZABLE && (*ppCRT)->iType == NOTLOCALIZABLE)
  241. || (iType == NOTLOCALIZABLESZ && (*ppCRT)->iType == NOTLOCALIZABLESZ)
  242. || (iType == NOTLOCALIZABLEWSZ && (*ppCRT)->iType == NOTLOCALIZABLEWSZ)))
  243. {
  244. // combine this with the last one
  245. (*ppCRT)->uSize+=nSize;
  246. return 0;
  247. }
  248. // can't be combined with previous element
  249. (*ppCRT)->pNext = (CUSTRESTEMPLATE far *)FALLOC( sizeof( CUSTRESTEMPLATE));
  250. (*ppCRT) = (*ppCRT)->pNext;
  251. if (!*ppCRT)
  252. {
  253. return 1;
  254. }
  255. (*ppCRT)->iType = iType;
  256. (*ppCRT)->uSize = nSize;
  257. (*ppCRT)->pNext = NULL;
  258. return 0;
  259. }
  260. /**
  261. * Function: UngetSymbol
  262. * Causes GetNextSymbol to get this symbol next time.
  263. *
  264. * Arguments:
  265. * sz, string buffer for symbol
  266. *
  267. * Returns:
  268. * 0 - if successful
  269. * 1 - if unsuccessful
  270. *
  271. * Error Codes:
  272. * 1 - tried to unget two symbols in a row
  273. *
  274. * History:
  275. * 1/92 - initial implementation -- SteveBl
  276. *
  277. **/
  278. static int UngetSymbol( CHAR sz[])
  279. {
  280. if ( fUseSavedSymbol )
  281. {
  282. return 1; // can only unget one symbol
  283. }
  284. fUseSavedSymbol = 1;
  285. CopyMemory( szSavedSymbol, sz, min( sizeof( szSavedSymbol) - 1, lstrlenA( sz)));
  286. szSavedSymbol[ sizeof( szSavedSymbol) - 1] = '\0';
  287. return( 0);
  288. }
  289. /**
  290. * Function: GetNextSymbol
  291. * Retrieves the next symbol from the file f.
  292. * Whitespace and comments are removed.
  293. * Comments are delimited by either c type comments or
  294. * # (in which case comment extends until end of line)
  295. * If the fUseSavedSymbol flag is set then it gets its symbol
  296. * from szSavedSymbol instead of the file.
  297. *
  298. * Arguments:
  299. * sz - string buffer for next symbol
  300. * n - size of buffer
  301. * f - handle to the input file
  302. *
  303. * Returns:
  304. * 0 if successful with symbol in sz
  305. * 1 if unsuccessful (sz undefined)
  306. *
  307. * Error Codes:
  308. * 1 - eof
  309. *
  310. * History:
  311. * 1/92 - initial implementation -- SteveBl
  312. **/
  313. static int GetNextSymbol( CHAR sz[], unsigned n, FILE *f)
  314. {
  315. unsigned c = 0;
  316. CHAR ch, chLast;
  317. if ( fUseSavedSymbol )
  318. {
  319. CopyMemory( sz, szSavedSymbol, min( (int)n, lstrlenA( szSavedSymbol) + 1));
  320. sz[ n == 0 ? 0 : n - 1] = '\0';
  321. fUseSavedSymbol = FALSE;
  322. return 0;
  323. }
  324. do
  325. {
  326. if (feof(f)) return 1;
  327. ch = (CHAR) getc(f);
  328. if (ch == '\n')
  329. ++*piLineNumber;
  330. }
  331. while ((ch == ' ') ||
  332. (ch == '\n') ||
  333. (ch == '\t') ||
  334. (ch == '\f') ||
  335. (ch == '\r') ||
  336. (ch == (CHAR)-1));
  337. if (ch == '#') // commented rest of line
  338. {
  339. do
  340. {
  341. if (feof(f))
  342. {
  343. return 1;
  344. }
  345. ch = (CHAR) getc(f);
  346. } while (ch != '\n');
  347. ++*piLineNumber;
  348. return GetNextSymbol( sz, n, f);
  349. }
  350. if (ch == '"') // it is a label, parse to the next quote
  351. {
  352. do
  353. {
  354. if (c<n)
  355. {
  356. sz[c++]=ch; // write all but the last quote
  357. }
  358. if (feof(f))
  359. {
  360. return 1;
  361. }
  362. ch = (CHAR)getc(f);
  363. if (ch == '\n')
  364. {
  365. return 1;
  366. }
  367. } while (ch != '"');
  368. if (c<n)
  369. {
  370. sz[ c++] = '\0';
  371. }
  372. else
  373. {
  374. sz[ n == 0 ? 0 : n - 1] = '\0';
  375. }
  376. return 0;
  377. }
  378. if (ch == '/') // possible comment
  379. {
  380. if (feof(f))
  381. {
  382. return 1;
  383. }
  384. ch = (CHAR) getc(f);
  385. if (ch == '/') // commented rest of line
  386. {
  387. do
  388. {
  389. if (feof(f))
  390. {
  391. return 1;
  392. }
  393. ch = (CHAR) getc(f);
  394. } while (ch != '\n');
  395. ++*piLineNumber;
  396. return( GetNextSymbol( sz, n, f));
  397. }
  398. if (ch == '*') // commented until */
  399. {
  400. if (feof(f))
  401. {
  402. return 1;
  403. }
  404. ch = (CHAR) getc(f);
  405. if (ch == '\n')
  406. {
  407. ++*piLineNumber;
  408. }
  409. do
  410. {
  411. chLast = ch;
  412. if (feof(f))
  413. {
  414. return 1;
  415. }
  416. ch = (CHAR) getc(f);
  417. if (ch == '\n')
  418. ++*piLineNumber;
  419. } while (!(chLast == '*' && ch == '/'));
  420. return( GetNextSymbol( sz, n, f));
  421. }
  422. ungetc(ch, f);
  423. }
  424. // finally found the beginning of a symbol
  425. if (ch < '0' || (ch > '9' && ch < '@')
  426. || (ch > 'Z' && ch < 'a') || ch > 'z')
  427. {
  428. if (c<n)
  429. {
  430. sz[c++] = ch;
  431. }
  432. if (c<n)
  433. {
  434. sz[c] = '\0';
  435. }
  436. else
  437. {
  438. sz[ n == 0 ? 0 : n - 1] = 0;
  439. }
  440. return 0;
  441. }
  442. do
  443. {
  444. if (c<n)
  445. {
  446. sz[c++]=ch;
  447. }
  448. if (feof(f))
  449. {
  450. return 0;
  451. }
  452. ch = (CHAR) getc(f);
  453. } while((ch >= '0' && ch <= '9') ||
  454. (ch >= '@' && ch <= 'Z') ||
  455. (ch >= 'a' && ch <= 'z'));
  456. ungetc(ch, f);
  457. if (c<n)
  458. {
  459. sz[c] = '\0';
  460. }
  461. else
  462. {
  463. sz[ n == 0 ? 0 : n - 1] = '\0';
  464. }
  465. return 0;
  466. }
  467. /**
  468. * Function: ParseBlock
  469. * Parses a block of a custom resource description from just after the
  470. * first curly braces { to just after the closing curly braces } .
  471. * It returns the size of the block it just parsed (in bytes).
  472. *
  473. * Arguments:
  474. * f, handle to an open description file
  475. * ppCRT, pointer to a pointer to the next Custom Resource Template node.
  476. *
  477. * Returns:
  478. * Updated pointer to the next Custom Resource Template node.
  479. * Number of bytes in this block.
  480. * (<0 if there was an error)
  481. *
  482. * Error Codes:
  483. * -1 - Syntax error
  484. * -2 - Unexpected end of file
  485. * -3 - out of memory
  486. *
  487. * History:
  488. * 1/92 - initial implementation -- SteveBl
  489. */
  490. static int ParseBlock( FILE *f, FPCUSTRESTEMPLATE * ppCRT)
  491. {
  492. int c = 0; // size of the whole block
  493. int n = 0; // size of the current item
  494. int i; //scratch variable
  495. int fUnsigned;
  496. int fLong;
  497. int iType; // type of the current item
  498. int nElements; // size of the array (if one exists)
  499. CHAR szSymbol[SYMBOLSIZE], sz[SYMBOLSIZE];
  500. CUSTRESTEMPLATE far * pFirst,
  501. // saves the first one so we know where to count
  502. // from in case of an array
  503. far *pTemp, far *pEnd;
  504. int fMerge = 0;
  505. // it's only ok to merge after the first element has been written
  506. while (1)
  507. {
  508. pFirst = *ppCRT;
  509. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  510. {
  511. return -2;
  512. }
  513. if (szSymbol[0] == '}')
  514. {
  515. return c;
  516. }
  517. if ( ! lstrcmpiA( "near", szSymbol) )
  518. { // near * type
  519. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  520. {
  521. return -2;
  522. }
  523. if (szSymbol[0]!='*')
  524. {
  525. return -1;
  526. }
  527. // may want to check for a legal type here
  528. do
  529. {
  530. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  531. {
  532. return -2;
  533. }
  534. } while ((szSymbol[0] != '[') &&
  535. (szSymbol[0] != '}') &&
  536. (szSymbol[0] != ','));
  537. UngetSymbol(szSymbol);
  538. n = 2;
  539. iType = NOTLOCALIZABLE;
  540. if (AddStructureElement(iType, n, ppCRT, fMerge))
  541. {
  542. return -3;
  543. }
  544. }
  545. else
  546. {
  547. if ( ! lstrcmpiA( "far", szSymbol) )
  548. { // far * type
  549. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  550. {
  551. return -2;
  552. }
  553. if (szSymbol[0] != '*')
  554. {
  555. return -1;
  556. }
  557. // may want to check for a legal type here
  558. do
  559. {
  560. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  561. {
  562. return -2;
  563. }
  564. } while ((szSymbol[0] != '[') &&
  565. (szSymbol[0] != '}') &&
  566. (szSymbol[0] != ','));
  567. UngetSymbol(szSymbol);
  568. n = 4;
  569. iType = NOTLOCALIZABLE;
  570. if(AddStructureElement(iType, n, ppCRT, fMerge))
  571. {
  572. return -3;
  573. }
  574. }
  575. else
  576. {
  577. if (szSymbol[0] == '*')
  578. { // * type
  579. // may want to check for a legal type here
  580. do
  581. {
  582. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  583. {
  584. return -2;
  585. }
  586. } while ((szSymbol[0] != '[') &&
  587. (szSymbol[0] != '}') &&
  588. (szSymbol[0] != ','));
  589. UngetSymbol(szSymbol);
  590. n = 2;
  591. iType = NOTLOCALIZABLE;
  592. if(AddStructureElement(iType, n, ppCRT, fMerge))
  593. {
  594. return -3;
  595. }
  596. }
  597. else
  598. {
  599. if (szSymbol[0] == '{')
  600. {
  601. n = ParseBlock(f, ppCRT);
  602. if (n<0)
  603. {
  604. return n;
  605. }
  606. }
  607. else
  608. { //it must be in our list of types
  609. fUnsigned = 0;
  610. fLong = 0;
  611. if ( ! lstrcmpiA( "UNSIGNED", szSymbol) )
  612. { // unsigned
  613. if ( GetNextSymbol( sz, sizeof( sz), f) )
  614. {
  615. return -2;
  616. }
  617. if (sz[0] == '[' || sz[0] == ',')
  618. {
  619. UngetSymbol(sz);
  620. }
  621. else
  622. {
  623. lstrcpyA( szSymbol, sz);
  624. if ( lstrcmpiA( sz, "SHORT")
  625. && lstrcmpiA( sz, "LONG")
  626. && lstrcmpiA( sz, "CHAR")
  627. && lstrcmpiA( sz, "TCHAR")
  628. && lstrcmpiA( sz, "INT") )
  629. {
  630. // must be followed by one of these
  631. return -1;
  632. }
  633. }
  634. fUnsigned = 1;
  635. }
  636. else
  637. {
  638. if ( ! lstrcmpiA( "SIGNED", szSymbol) )
  639. { // signed
  640. if ( GetNextSymbol( sz, sizeof( sz), f) )
  641. {
  642. return -2;
  643. }
  644. if (sz[0] == '[' || sz[0] == ',')
  645. {
  646. UngetSymbol(sz);
  647. }
  648. else
  649. {
  650. lstrcpyA( szSymbol, sz);
  651. if ( lstrcmpiA( sz, "SHORT")
  652. && lstrcmpiA( sz, "LONG")
  653. && lstrcmpiA( sz, "CHAR")
  654. && lstrcmpiA( sz, "TCHAR")
  655. && lstrcmpiA( sz, "INT") )
  656. {
  657. // must be followed by one of these
  658. return -1;
  659. }
  660. }
  661. }
  662. }
  663. if ( ! lstrcmpiA( "SHORT", szSymbol) )
  664. { // short
  665. if ( GetNextSymbol( sz, sizeof( sz), f) )
  666. {
  667. return -2;
  668. }
  669. if (sz[0] == '[' || sz[0] == ',')
  670. {
  671. UngetSymbol(sz);
  672. }
  673. else
  674. {
  675. lstrcpyA( szSymbol, sz);
  676. if ( lstrcmpiA( sz, "INT") )
  677. {
  678. // must be followed by one of these
  679. return -1;
  680. }
  681. }
  682. }
  683. else
  684. {
  685. if ( ! lstrcmpiA( "LONG", szSymbol) )
  686. { // long
  687. if ( GetNextSymbol( sz, sizeof( sz), f) )
  688. {
  689. return -2;
  690. }
  691. if (sz[0] == '[' || sz[0] == ',')
  692. {
  693. UngetSymbol(sz);
  694. }
  695. else
  696. {
  697. lstrcpyA( szSymbol, sz);
  698. if ( lstrcmpiA( sz, "INT")
  699. && lstrcmpiA( sz, "DOUBLE"))
  700. {
  701. // must be followed by one of these
  702. return -1;
  703. }
  704. }
  705. // BUG! - this code allows UNSIGNED LONG DOUBLE
  706. // which is an illegal type in c. But it's not
  707. // a serious bug so I'll leave it.
  708. fLong = 1;
  709. }
  710. }
  711. i = sizeof(rgTypeSizes)/sizeof(TYPESIZES);
  712. do
  713. {
  714. --i;
  715. } while ( lstrcmpiA( szSymbol, rgTypeSizes[i].szType) && i);
  716. if ( lstrcmpiA( szSymbol, rgTypeSizes[i].szType) )
  717. {
  718. return -1; // type not found in the list
  719. }
  720. if (fLong)
  721. {
  722. n = rgTypeSizes[i].iLongSize;
  723. }
  724. else
  725. {
  726. n = rgTypeSizes[i].iShortSize;
  727. }
  728. iType = rgTypeSizes[i].iType;
  729. if (fUnsigned)
  730. {
  731. iType+=LT_UNSIGNED;
  732. }
  733. if ( lstrcmpA( szSymbol, rgTypeSizes[i].szType) )
  734. {
  735. iType = NOTLOCALIZABLE; // type was not in all caps
  736. }
  737. if ( lstrcmpiA( szSymbol, "CHAR") == 0
  738. || lstrcmpiA( szSymbol, "TCHAR") == 0
  739. || lstrcmpiA( szSymbol, "WCHAR") == 0 )
  740. { // check for a string
  741. lstrcpyA( szDHW, szSymbol); // So can be used later
  742. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  743. {
  744. return -2;
  745. }
  746. if (szSymbol[0] == '[') // we have a string
  747. {
  748. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  749. {
  750. return -2;
  751. }
  752. if (szSymbol[0] == ']') // null terminated string
  753. {
  754. n = 0;
  755. if (iType != NOTLOCALIZABLE)
  756. {
  757. if ( lstrcmpiA( szDHW, "CHAR") == 0 )
  758. {
  759. iType += LT_SZ-LT_CHAR;
  760. }
  761. else if ( lstrcmpiA( szDHW,
  762. "WCHAR") == 0 )
  763. {
  764. iType += LT_WSZ-LT_WCHAR;
  765. }
  766. else
  767. {
  768. #ifdef RLRES32
  769. iType += LT_WSZ-LT_WCHAR;
  770. #else
  771. iType += LT_SZ-LT_CHAR;
  772. #endif
  773. }
  774. }
  775. else
  776. {
  777. if ( lstrcmpiA( szDHW, "CHAR") == 0 )
  778. {
  779. iType = NOTLOCALIZABLESZ;
  780. }
  781. else if ( lstrcmpiA( szDHW,
  782. "WCHAR") == 0 )
  783. {
  784. iType = NOTLOCALIZABLEWSZ;
  785. }
  786. else
  787. {
  788. #ifdef RLWIN32
  789. iType = NOTLOCALIZABLEWSZ;
  790. #else
  791. iType = NOTLOCALIZABLESZ;
  792. #endif
  793. }
  794. }
  795. }
  796. else
  797. {
  798. i = atoi(szSymbol);
  799. if (i<1)
  800. {
  801. return -1;
  802. }
  803. n *= i;
  804. if (iType != NOTLOCALIZABLE)
  805. {
  806. if ( lstrcmpiA( szDHW, "CHAR") == 0 )
  807. {
  808. iType += LT_STRING-LT_CHAR;
  809. }
  810. else if ( lstrcmpiA( szDHW,
  811. "WCHAR") == 0 )
  812. {
  813. iType += LT_WSTRING-LT_WCHAR;
  814. }
  815. else
  816. {
  817. #ifdef RLRES32
  818. iType += LT_WSTRING-LT_WCHAR;
  819. #else
  820. iType += LT_STRING-LT_CHAR;
  821. #endif
  822. }
  823. }
  824. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  825. {
  826. return -2;
  827. }
  828. if (szSymbol[0] != ']')
  829. {
  830. return -1;
  831. }
  832. }
  833. }
  834. else
  835. {
  836. UngetSymbol(szSymbol);
  837. }
  838. }
  839. if(AddStructureElement(iType, n, ppCRT, fMerge))
  840. {
  841. return -3;
  842. }
  843. }
  844. }
  845. }
  846. }
  847. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  848. {
  849. return -2;
  850. }
  851. while (szSymbol[0] == '[')
  852. {// we have an array
  853. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  854. {
  855. return -2;
  856. }
  857. if ((szSymbol[0] < '0' || szSymbol[0] > '9') && szSymbol[0] != ']')
  858. {
  859. return -1;
  860. }
  861. nElements = atoi(szSymbol);
  862. if (nElements < 1)
  863. {
  864. return -1;
  865. }
  866. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  867. {
  868. return -2;
  869. }
  870. if (szSymbol[0] != ']')
  871. {
  872. return -1;
  873. }
  874. pEnd = *ppCRT;
  875. if (pEnd != pFirst)
  876. {
  877. for (i=nElements-1;i--;)
  878. {
  879. pTemp = pFirst;
  880. do
  881. {
  882. pTemp = pTemp->pNext;
  883. AddStructureElement(pTemp->iType,
  884. pTemp->uSize,
  885. ppCRT,
  886. 0);
  887. } while (pTemp != pEnd);
  888. }
  889. }
  890. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), f) )
  891. {
  892. return -2;
  893. }
  894. }
  895. c += n;
  896. if (szSymbol[0] == '}')
  897. {
  898. return c;
  899. }
  900. if (szSymbol[0] != ',')
  901. {
  902. return -1;
  903. }
  904. fMerge = 1;
  905. }
  906. }
  907. //+-------------------------------------------------------------------------
  908. //
  909. // Function: LoadCustResDescriptions, Public
  910. //
  911. // Synopsis: Loads the Cusutom Resource Descriptions defined in the RDF
  912. // files, to all the tokenize to parse them.
  913. //
  914. //
  915. // Arguments: [szFileName] The RDF file containing the resource
  916. // descriptions.
  917. //
  918. //
  919. // Effects: The custom resources are loaded into a global list of
  920. // resource descriptions, and used by ReadWinRes to tokenize
  921. // the particular custom resources
  922. //
  923. // Returns: -1 Error Condition
  924. // 1 Resource descrptions loaded
  925. //
  926. //
  927. //
  928. //
  929. // Modifies: [pCustResList] Global list of Custom resource descriptions.
  930. //
  931. // History:
  932. // 16-Oct-92 Created TerryRu
  933. //
  934. //
  935. // Notes: ParseResourceDescriptionFile is the function called to
  936. // actually load the descriptions resources.
  937. //
  938. //--------------------------------------------------------------------------
  939. int LoadCustResDescriptions( CHAR *szRDFs)
  940. {
  941. FILE *fRdf = NULL;
  942. CHAR szCurRDF[MAXFILENAME] = "";
  943. int i1, i2;
  944. if (szRDFs && *szRDFs) //... resource description file name given?
  945. {
  946. i1 = 0;
  947. while (szRDFs[i1] == ' ' && szRDFs[i1] != 0)
  948. {
  949. ++i1;
  950. }
  951. while (szRDFs[i1] != 0)
  952. {
  953. i2 = 0;
  954. while (szRDFs[i1] != ' ' && szRDFs[i1] != 0)
  955. {
  956. szCurRDF[i2++] = szRDFs[i1++];
  957. }
  958. szCurRDF[i2] = 0;
  959. while (szRDFs[i1] == ' ' && szRDFs[i1] != 0)
  960. {
  961. ++i1;
  962. }
  963. if (fRdf = FOPEN( szCurRDF, "rt"))
  964. {
  965. ParseResourceDescriptionFile(fRdf, &i2);
  966. FCLOSE(fRdf);
  967. }
  968. else
  969. {
  970. return(-1);
  971. }
  972. }
  973. }
  974. return(1); //... Success
  975. }
  976. /**
  977. * Function: ParseResourceDescriptionFile
  978. * Parses a resource description block creating a structure definining
  979. * all recognized custom resources.
  980. *
  981. * Arguments:
  982. * ResourceDescriptionFile, handle to an open description file
  983. * (or the beginning of a description block)
  984. * piErrorLine, pointer to an integer that will hold the line number
  985. * an error occured at in the event that a parsing error is
  986. * encountered.
  987. *
  988. * Returns:
  989. * 0 if successful
  990. * !0 if some error was encountered
  991. * *piErrorLine will hold the line number for the error
  992. *
  993. * Error Codes:
  994. * -1 - Syntax error
  995. * -2 - Unexpected end of file
  996. * -3 - out of memory
  997. *
  998. * History:
  999. * 1/92 - initial implementation -- SteveBl
  1000. *
  1001. **/
  1002. int ParseResourceDescriptionFile(
  1003. FILE *pfResourceDescriptionFile,
  1004. int *piErrorLine)
  1005. {
  1006. CUSTRESNODE far * lpCustResNode = NULL;
  1007. CUSTRESTEMPLATE far * pCustResTemplate;
  1008. static CHAR szSymbol[SYMBOLSIZE];
  1009. /*************************************************************************
  1010. TCHAR *szResourceType;
  1011. *************************************************************************/
  1012. int iResourceType;
  1013. int r;
  1014. BOOL fBeginList = TRUE;
  1015. // position lpCustResNode at end of the custom reosource list.
  1016. if ( lpCustResNode == NULL )
  1017. {
  1018. pCustResList = lpCustResNode =
  1019. (CUSTRESNODE far *)FALLOC( sizeof( CUSTRESNODE));
  1020. }
  1021. else
  1022. {
  1023. fBeginList = FALSE;
  1024. lpCustResNode = pCustResList;
  1025. while ( lpCustResNode->pNext )
  1026. {
  1027. lpCustResNode = lpCustResNode->pNext;
  1028. }
  1029. }
  1030. piLineNumber = piErrorLine;
  1031. *piLineNumber = 1;
  1032. if ( GetNextSymbol( szSymbol,
  1033. sizeof( szSymbol),
  1034. pfResourceDescriptionFile) )
  1035. {
  1036. return 0; // file is empty
  1037. }
  1038. while ( lstrcmpiA( szSymbol, "END") )
  1039. {
  1040. if ( szSymbol[0] != '<' )
  1041. {
  1042. return -1; // must begin with a resource number
  1043. }
  1044. if ( fBeginList == FALSE )
  1045. {
  1046. lpCustResNode->pNext =
  1047. (CUSTRESNODE far *)FALLOC( sizeof( CUSTRESNODE));
  1048. lpCustResNode = lpCustResNode->pNext;
  1049. }
  1050. fBeginList = FALSE;
  1051. // intialize nodes fields to Zero defaults.
  1052. memset( lpCustResNode, 0, sizeof( CUSTRESNODE));
  1053. //... Next symbol will be the resource type
  1054. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), pfResourceDescriptionFile) )
  1055. {
  1056. return -2; // need a number
  1057. }
  1058. //... Is type a string or a number?
  1059. if ( szSymbol[0] != '"' )
  1060. { //... number
  1061. iResourceType = GetResourceType( szSymbol);
  1062. if ( iResourceType < 0 )
  1063. {
  1064. return -1;
  1065. }
  1066. lpCustResNode->wTypeID = (WORD)iResourceType;
  1067. lpCustResNode->bTypeFlag = TRUE;
  1068. }
  1069. else //... string
  1070. {
  1071. UINT uChars = lstrlenA( szSymbol+1) + 1;
  1072. lpCustResNode->pszType = (TCHAR *)FALLOC( MEMSIZE( uChars));
  1073. if ( lpCustResNode->pszType == NULL )
  1074. {
  1075. return -3;
  1076. }
  1077. _MBSTOWCS( lpCustResNode->pszType, szSymbol+1, uChars, (UINT)-1);
  1078. lpCustResNode->bTypeFlag = FALSE;
  1079. }
  1080. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), pfResourceDescriptionFile) )
  1081. {
  1082. return -2;
  1083. }
  1084. /*************************************************************************
  1085. //... Is a name provided?
  1086. if (szSymbol[0] != '>' && szSymbol[0] != ',')
  1087. {
  1088. return -1; // must have closing symbol for resource id #
  1089. }
  1090. if (szSymbol[0] == ',')
  1091. { //... Yes, name is provided
  1092. if (iResourceType >= 0)
  1093. {
  1094. lpCustResNode->wNameID = (WORD)iResourceType;
  1095. lpCustResNode->bNameFlag = TRUE;
  1096. }
  1097. else
  1098. {
  1099. lpCustResNode->wTypeID = 0;
  1100. lpCustResNode->wNameID = IDFLAG;
  1101. lpCustResNode->pszType = szResourceType;
  1102. lpCustResNode->bTypeFlag = 0;
  1103. }
  1104. }
  1105. else
  1106. {
  1107. if (iResourceType >= 0)
  1108. {
  1109. lpCustResNode->wNameID = iResourceType;
  1110. }
  1111. else
  1112. {
  1113. lpCustResNode->wNameID = 0;
  1114. lpCustResNode->pszName = szResourceType;
  1115. lpCustResNode->bNameFlag = 0xff;
  1116. }
  1117. if (GetNextSymbol(szSymbol, sizeof( szSymbol), pfResourceDescriptionFile))
  1118. {
  1119. return -2;
  1120. }
  1121. if (szSymbol[0] != '"')
  1122. {
  1123. r = GetResourceType(szSymbol);
  1124. lpCustResNode->wTypeID = (WORD)r;
  1125. }
  1126. else
  1127. {
  1128. lpCustResNode->wTypeID = 0;
  1129. lpCustResNode->bTypeFlag = 0;
  1130. szResourceType = (TCHAR *)FALLOC(
  1131. MEMSIZE( (strlen( szSymbol + 1) + 1)));
  1132. strcpy((PCHAR)szResourceType, szSymbol+1);
  1133. lpCustResNode->pszType = szResourceType;
  1134. }
  1135. if (GetNextSymbol(szSymbol, sizeof( szSymbol), pfResourceDescriptionFile))
  1136. {
  1137. return -2;
  1138. }
  1139. if (szSymbol[0] != '>')
  1140. {
  1141. return -1;
  1142. }
  1143. }
  1144. *************************************************************************/
  1145. // Start the template by creating a single empty node
  1146. // This is necessary for handling recursive arrays.
  1147. // There might be a way around it but this works and it is easy.
  1148. lpCustResNode->pTemplate=
  1149. (FPCUSTRESTEMPLATE)FALLOC( sizeof( CUSTRESTEMPLATE));
  1150. if (!lpCustResNode->pTemplate)
  1151. {
  1152. return -3;
  1153. }
  1154. pCustResTemplate = (lpCustResNode->pTemplate);
  1155. pCustResTemplate->iType = NOTLOCALIZABLE;
  1156. pCustResTemplate->uSize = 0;
  1157. pCustResTemplate->pNext = NULL;
  1158. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), pfResourceDescriptionFile) )
  1159. {
  1160. return -2;
  1161. }
  1162. if (szSymbol[0] != '{')
  1163. {
  1164. return -1; // must have at least one block
  1165. }
  1166. r = ParseBlock( pfResourceDescriptionFile,
  1167. (FPCUSTRESTEMPLATE *)&pCustResTemplate);
  1168. if (r < 0)
  1169. {
  1170. return r;
  1171. }
  1172. // Now remove that initial empty node (not necessary but cleaner)
  1173. pCustResTemplate = lpCustResNode->pTemplate;
  1174. lpCustResNode->pTemplate = pCustResTemplate->pNext;
  1175. RLFREE( pCustResTemplate);
  1176. // the last thing the ParseBlock routine should have read in was a
  1177. // closing brace to close the block. The next thing we read should
  1178. // either be "end", the end of file, or a new resource definition.
  1179. if ( GetNextSymbol( szSymbol, sizeof( szSymbol), pfResourceDescriptionFile) )
  1180. {
  1181. return 0; // reached end of file
  1182. }
  1183. }
  1184. return 0;
  1185. }
  1186. /**
  1187. * Function: GetCustomResource
  1188. * Reads a custom resource from the resource file and returns a pointer
  1189. * to the resource data.
  1190. *
  1191. * Arguments:
  1192. * inResFile, handle to an open resource file
  1193. * lSize, size in bytes of the resource
  1194. * ppCustomResource, address of a pointer to an empty custom resource
  1195. * structure
  1196. * ResHeader, resource header for this resource
  1197. *
  1198. * Returns:
  1199. * if resource has a definition:
  1200. * returns 0 and
  1201. * inResFile containing a linked list of the localizable resource data
  1202. * else
  1203. * returns 1
  1204. *
  1205. * Error Codes:
  1206. * 0 - no error -- resource was retrieved
  1207. * 1 - resource is not an understood custom resource (use another method
  1208. * or ignore the resource)
  1209. * 2 - some error occured parsing the resource
  1210. *
  1211. * History:
  1212. * 1/92 - initial implementation -- SteveBl
  1213. *
  1214. **/
  1215. int GetCustomResource(
  1216. FILE *inResFile,
  1217. DWORD *plSize,
  1218. FPCUSTOM_RESOURCE *ppCustomResource,
  1219. RESHEADER ResHeader)
  1220. {
  1221. CUSTOM_RESOURCE far *lpCustomResource;
  1222. CUSTRESNODE far *pCRN;
  1223. CUSTRESTEMPLATE far *pCRT;
  1224. void far * pData;
  1225. BOOL fBeginList = TRUE;
  1226. if ( ! (pCRN = MatchResource( ResHeader)) )
  1227. {
  1228. return 1; // resource doesn't have a match
  1229. }
  1230. *ppCustomResource = lpCustomResource =
  1231. (CUSTOM_RESOURCE far *)FALLOC( sizeof( CUSTOM_RESOURCE));
  1232. pCRT = pCRN->pTemplate;
  1233. while ( *plSize )
  1234. {
  1235. // allocate new custome resrouce structure
  1236. if ( fBeginList == FALSE )
  1237. {
  1238. lpCustomResource->pNext =
  1239. (CUSTOM_RESOURCE far *)FALLOC( sizeof( CUSTOM_RESOURCE));
  1240. lpCustomResource = lpCustomResource->pNext;
  1241. }
  1242. if ( ! lpCustomResource )
  1243. {
  1244. return 2; // no memory
  1245. }
  1246. pData = GetResData( pCRT->iType, pCRT->uSize, inResFile, plSize);
  1247. if ( ! pData )
  1248. {
  1249. return 2; //GetResData crapped out
  1250. }
  1251. lpCustomResource->pData = pData;
  1252. lpCustomResource->pNext = NULL;
  1253. fBeginList = FALSE;
  1254. pCRT = pCRT->pNext;
  1255. if (!pCRT)
  1256. {
  1257. pCRT = pCRN->pTemplate; //begin next structure
  1258. }
  1259. }
  1260. return 0;
  1261. }
  1262. /**
  1263. * Function: TokCustomResource
  1264. * Writes custom resource information to the token file.
  1265. *
  1266. * Arguments:
  1267. * TokFile, handle to the token file
  1268. * ResHeader, resource header for this resource
  1269. * ppCustomResource, address of a pointer to a filled out
  1270. * custom resource structure
  1271. *
  1272. * Returns:
  1273. * Data written to TokFile
  1274. *
  1275. * Error Codes:
  1276. * none
  1277. *
  1278. * History:
  1279. * 1/92 - initial implementation -- SteveBl
  1280. *
  1281. * 01/93 - Add support for var length Token texts MHotchin
  1282. *
  1283. **/
  1284. void TokCustomResource(
  1285. FILE *TokFile,
  1286. RESHEADER ResHeader,
  1287. FPCUSTOM_RESOURCE *ppCustomResource)
  1288. {
  1289. CUSTRESNODE far *pCRN;
  1290. CUSTRESTEMPLATE far *pCRT;
  1291. CUSTOM_RESOURCE far *lpCustomResource;
  1292. TCHAR sz[ MAXTEXTLEN];
  1293. TOKEN Token;
  1294. WORD wID = 0;
  1295. int l;
  1296. lpCustomResource = *ppCustomResource;
  1297. if (!(pCRN = MatchResource(ResHeader)))
  1298. {
  1299. QuitT( IDS_ENGERR_09, (LPTSTR)IDS_NOCUSTRES, NULL);
  1300. }
  1301. pCRT = pCRN->pTemplate;
  1302. while ( lpCustomResource )
  1303. {
  1304. if ( pCRT->iType != NOTLOCALIZABLE
  1305. && pCRT->iType != NOTLOCALIZABLESZ
  1306. && pCRT->iType != NOTLOCALIZABLEWSZ )
  1307. {
  1308. if ( PutTextData( lpCustomResource->pData,
  1309. pCRT->iType,
  1310. pCRT->uSize,
  1311. sz,
  1312. sizeof( sz)) )
  1313. {
  1314. QuitT( IDS_ENGERR_09, (LPTSTR)IDS_CUSTRES, NULL);
  1315. }
  1316. /* UNCOMMENT THIS WHEN STRING TYPES ARE SUPPORTED IN TOKENS
  1317. **********
  1318. Token.szType[0] = '\0';
  1319. if (!ResHeader.bTypeFlag)
  1320. {
  1321. Token.wType = IDFLAG;
  1322. _tcscpy( Token.szType, ResHeader.pszType);
  1323. }
  1324. else
  1325. **********
  1326. */
  1327. Token.wType = ResHeader.wTypeID;
  1328. Token.wName = ResHeader.wNameID;
  1329. if ( ResHeader.bNameFlag == IDFLAG )
  1330. {
  1331. lstrcpy( Token.szName, ResHeader.pszName);
  1332. }
  1333. else
  1334. {
  1335. Token.szName[0] = '\0';
  1336. }
  1337. Token.wID = wID++;
  1338. Token.wReserved = (gbMaster ? ST_NEW : ST_TRANSLATED);
  1339. Token.wFlag = 0;
  1340. if ( (pCRT->iType == LT_UNSIGNED + LT_STRING)
  1341. || (pCRT->iType == LT_STRING)
  1342. || (pCRT->iType == LT_WSTRING) )
  1343. {
  1344. l = pCRT->uSize;
  1345. while( l > 1 && ! sz[l-1])
  1346. {
  1347. --l; // skip any trailing nulls
  1348. }
  1349. Token.szText = BinToText( sz, l);
  1350. }
  1351. else
  1352. {
  1353. Token.szText = BinToText( sz, lstrlen( sz));
  1354. }
  1355. PutToken( TokFile, &Token);
  1356. RLFREE( Token.szText);
  1357. }
  1358. pCRT = pCRT->pNext;
  1359. if ( ! pCRT )
  1360. {
  1361. pCRT = pCRN->pTemplate; //begin next structure
  1362. }
  1363. lpCustomResource = lpCustomResource->pNext;
  1364. }
  1365. }
  1366. /**
  1367. * Function: PutCustomResource
  1368. * Writes custom resource information to the output resource
  1369. * file. If the information is localizable it is retrieved from the
  1370. * indicated token file.
  1371. *
  1372. * Arguments:
  1373. * OutResFile, handle to the target resource file
  1374. * TokFile, handle to the token file
  1375. * ResHeader, resource header for this resource
  1376. * ppCustomResource, address of a pointer to a filled out
  1377. * custom resource structure
  1378. *
  1379. * Returns:
  1380. * CustomResource written to OutResFile
  1381. *
  1382. * Error Codes:
  1383. * none
  1384. *
  1385. * History:
  1386. * ??/?? Created by ???
  1387. *
  1388. * 01/93 Added support for var length token texts. MHotchin
  1389. *
  1390. **/
  1391. void PutCustomResource(
  1392. FILE *OutResFile,
  1393. FILE *TokFile,
  1394. RESHEADER ResHeader,
  1395. FPCUSTOM_RESOURCE *ppCustomResource)
  1396. {
  1397. CUSTRESNODE far *pCRN = NULL;
  1398. CUSTRESTEMPLATE far *pCRT = NULL;
  1399. CUSTOM_RESOURCE far *lpCustomResource = NULL;
  1400. TCHAR sz[ MAXTEXTLEN] = TEXT("");
  1401. void far *pData = NULL;
  1402. TOKEN Token;
  1403. DWORD lSize = 0;
  1404. fpos_t ResSizePos;
  1405. WORD wID=0;
  1406. unsigned n;
  1407. lpCustomResource = *ppCustomResource;
  1408. if ( ! (pCRN = MatchResource( ResHeader)) )
  1409. {
  1410. QuitT( IDS_ENGERR_09, (LPTSTR)IDS_NOCUSTRES, NULL);
  1411. }
  1412. if ( PutResHeader( OutResFile, ResHeader, &ResSizePos, &lSize) )
  1413. {
  1414. QuitT( IDS_ENGERR_06, (LPTSTR)IDS_CUSTRES, NULL);
  1415. }
  1416. lSize = 0;
  1417. pCRT = pCRN->pTemplate;
  1418. while ( lpCustomResource )
  1419. {
  1420. BOOL fAlloced = FALSE;
  1421. if ( pCRT->iType != NOTLOCALIZABLE
  1422. && pCRT->iType != NOTLOCALIZABLESZ
  1423. && pCRT->iType != NOTLOCALIZABLEWSZ )
  1424. {
  1425. /* UNCOMMENT THIS WHEN STRING TYPES ARE SUPPORTED IN TOKENS
  1426. *
  1427. Token.szwType[0] = '\0';
  1428. if (!ResHeader.bTypeFlag)
  1429. {
  1430. Token.wType = IDFLAG;
  1431. _tcscpy(Token.szwType, ResHeader.pszType);
  1432. }
  1433. else
  1434. *
  1435. */
  1436. Token.wType = ResHeader.wTypeID;
  1437. Token.wName = ResHeader.wNameID;
  1438. if ( ResHeader.bNameFlag == IDFLAG )
  1439. {
  1440. lstrcpy( Token.szName, ResHeader.pszName);
  1441. }
  1442. else
  1443. {
  1444. Token.szName[0] = '\0';
  1445. }
  1446. Token.wID = wID++;
  1447. Token.wFlag = 0;
  1448. Token.wReserved =(gbMaster ? ST_NEW : ST_TRANSLATED);
  1449. Token.szText = NULL;
  1450. if ( ! FindToken( TokFile, &Token, ST_TRANSLATED) )
  1451. {
  1452. QuitT( IDS_ENGERR_06, (LPTSTR)IDS_NOCUSTRES, NULL);
  1453. }
  1454. n = TextToBin( sz, Token.szText, sizeof( sz));
  1455. RLFREE( Token.szText);
  1456. while ( n < pCRT->uSize )
  1457. {
  1458. sz[n++]='\0'; // padd additional space with nulls
  1459. }
  1460. pData = GetTextData( pCRT->iType, pCRT->uSize, sz);
  1461. if ( ! pData)
  1462. {
  1463. QuitT( IDS_ENGERR_09, (LPTSTR)IDS_CUSTRES, NULL);
  1464. }
  1465. fAlloced = TRUE;
  1466. }
  1467. else
  1468. {
  1469. pData = lpCustomResource->pData;
  1470. fAlloced = FALSE;
  1471. }
  1472. lSize += PutResData( pData, pCRT->iType, pCRT->uSize, OutResFile);
  1473. if ( fAlloced )
  1474. {
  1475. RLFREE( pData);
  1476. }
  1477. pCRT = pCRT->pNext;
  1478. if ( ! pCRT )
  1479. {
  1480. pCRT = pCRN->pTemplate; //begin next structure
  1481. }
  1482. lpCustomResource = lpCustomResource->pNext;
  1483. }
  1484. if( ! UpdateResSize( OutResFile, &ResSizePos, lSize) )
  1485. {
  1486. QuitT( IDS_ENGERR_07, (LPTSTR)IDS_CUSTRES, NULL);
  1487. }
  1488. }
  1489. /**
  1490. * Function: ClearCustomResource
  1491. * Frees memory allocated to a custom resource list.
  1492. *
  1493. * Arguments:
  1494. * ppCustomResource, address of a pointer to a filled out
  1495. * custom resource structure
  1496. *
  1497. * Returns:
  1498. * Memory allocatd to pCustomResource is freed.
  1499. *
  1500. * Error Codes:
  1501. * none
  1502. *
  1503. * History:
  1504. * 1/92 -- initial implementation -- SteveBl
  1505. *
  1506. **/
  1507. void ClearCustomResource( FPCUSTOM_RESOURCE *ppCustomResource)
  1508. {
  1509. CUSTOM_RESOURCE far *pCR;
  1510. CUSTOM_RESOURCE far *lpCustomResource;
  1511. lpCustomResource = *ppCustomResource;
  1512. while ( lpCustomResource )
  1513. {
  1514. pCR = lpCustomResource;
  1515. RLFREE( pCR->pData);
  1516. lpCustomResource = pCR->pNext;
  1517. RLFREE( pCR);
  1518. }
  1519. }
  1520. /**
  1521. * Function:
  1522. * Tries to find a custom resource that matches the resource specified
  1523. * in the resource header.
  1524. *
  1525. * Arguments:
  1526. * Resheader, resource header.
  1527. *
  1528. * Returns:
  1529. * pointer to the resource template (or null)
  1530. *
  1531. * Error Codes:
  1532. * null -- resource not found
  1533. *
  1534. * History:
  1535. * 1/92 -- initial implementation -- SteveBl
  1536. *
  1537. **/
  1538. static CUSTRESNODE far * MatchResource( RESHEADER Resheader)
  1539. {
  1540. CUSTRESNODE far *pCR = pCustResList;
  1541. while ( pCR )
  1542. {
  1543. if ( (0==pCR->bTypeFlag) == (0==Resheader.bTypeFlag) )
  1544. {
  1545. if ( ((!pCR->bTypeFlag) && ! _tcscmp( pCR->pszType,
  1546. Resheader.pszType))
  1547. || ((pCR->bTypeFlag) && pCR->wTypeID == Resheader.wTypeID))
  1548. { // TYPES MATCH
  1549. /*************************************************************************
  1550. if (pCR->wNameID == IDFLAG)
  1551. {
  1552. pCRTypeMatch = pCR;
  1553. }
  1554. else
  1555. {
  1556. if ((0==pCR->bNameFlag) == (0==Resheader.bNameFlag))
  1557. {
  1558. if (((!pCR->bNameFlag)
  1559. && ! _tcscmp(pCR->pszName, Resheader.pszName)) ||
  1560. ((pCR->bNameFlag) &&
  1561. pCR->wNameID == Resheader.wNameID))
  1562. { // NAMES MATCH
  1563. *************************************************************************/
  1564. return( pCR); // an exact match
  1565. /*************************************************************************
  1566. }
  1567. }
  1568. }
  1569. *************************************************************************/
  1570. }
  1571. }
  1572. pCR = pCR->pNext;
  1573. }
  1574. return( NULL); // either only the type matched or nothing matched
  1575. }
  1576. /**
  1577. * Function: GetResData
  1578. * Reads data of the specified type and size from a resource file.
  1579. *
  1580. * Arguments:
  1581. * wType, type of this resource (from resource template)
  1582. * uSize, size in bytes of resource (ignored for null terminated strings)
  1583. * f, resource file
  1584. * lSize, pointer to the number of bytes left in the resource
  1585. *
  1586. * Returns:
  1587. * pointer to the data, lSize is updated
  1588. *
  1589. * Error Codes:
  1590. * null pointer on error
  1591. *
  1592. * History:
  1593. * 1/92 -- initial implementation -- SteveBl
  1594. *
  1595. **/
  1596. static void far * GetResData(
  1597. enum LOCALIZABLE_TYPES wType,
  1598. unsigned uSize,
  1599. FILE *f,
  1600. DWORD *lSize)
  1601. {
  1602. BYTE *pData = NULL;
  1603. int i = 0;
  1604. if ( wType % LT_UNSIGNED == LT_SZ
  1605. || wType == NOTLOCALIZABLESZ
  1606. || wType % LT_UNSIGNED == LT_WSZ
  1607. || wType == NOTLOCALIZABLEWSZ )
  1608. { // read in the null terminated string
  1609. TCHAR ch = IDFLAG;
  1610. pData = FALLOC( MEMSIZE(*lSize) );
  1611. while ( *lSize && ch != TEXT('\0') )
  1612. {
  1613. #ifdef RLWIN32
  1614. if ( wType % LT_UNSIGNED == LT_WSZ
  1615. || wType == NOTLOCALIZABLEWSZ )
  1616. {
  1617. ((TCHAR *)pData)[i] = ch = GetWord( f, lSize);
  1618. }
  1619. else
  1620. {
  1621. char chTmp[2];
  1622. chTmp[0] = GetByte( f, lSize);
  1623. if ( IsDBCSLeadByte( chTmp[0]) )
  1624. {
  1625. chTmp[1] = GetByte( f, lSize);
  1626. _MBSTOWCS( &((TCHAR *)pData)[i], chTmp, 1, 2);
  1627. }
  1628. else
  1629. {
  1630. _MBSTOWCS( &((TCHAR *)pData)[i], chTmp, 1, 1);
  1631. }
  1632. ch = ((TCHAR *)pData)[i];
  1633. }
  1634. #else //RLWIN32
  1635. *(pData+i) = ch = GetByte( f, lSize);
  1636. #endif //RLWIN32
  1637. i++;
  1638. } // END while( *lSize ...
  1639. }
  1640. else
  1641. {
  1642. pData = FALLOC( uSize);
  1643. if ( ! pData )
  1644. {
  1645. QuitA( IDS_ENGERR_11, NULL, NULL);
  1646. }
  1647. while (uSize-- && *lSize)
  1648. {
  1649. *(pData+i) = GetByte(f, lSize);
  1650. i++;
  1651. }
  1652. }
  1653. return( pData);
  1654. }
  1655. /**
  1656. * Function: PutResData
  1657. * Writes data of the specified type to a resource file.
  1658. *
  1659. * Arguments:
  1660. * pData, pointer to data
  1661. * wType, type of this resource (from resource template)
  1662. * uSize, size in bytes of resource (ignored for null terminated strings)
  1663. * f, resource file
  1664. *
  1665. * Returns:
  1666. * Number of bytes written.
  1667. *
  1668. * Error Codes:
  1669. * -1 - error
  1670. *
  1671. * History:
  1672. * 1/92 -- initial implementation -- SteveBl
  1673. *
  1674. **/
  1675. static int PutResData(
  1676. void far *pData,
  1677. enum LOCALIZABLE_TYPES wType,
  1678. unsigned uSize,
  1679. FILE *f)
  1680. {
  1681. DWORD dw = 0;
  1682. if ( wType % LT_UNSIGNED == LT_SZ
  1683. || wType == NOTLOCALIZABLESZ
  1684. || wType % LT_UNSIGNED == LT_WSZ
  1685. || wType == NOTLOCALIZABLEWSZ )
  1686. {
  1687. // write the null terminated string
  1688. #ifdef RLWIN32
  1689. TCHAR *pChar = (TCHAR *)pData;
  1690. if ( wType % LT_UNSIGNED == LT_WSZ
  1691. || wType == NOTLOCALIZABLEWSZ )
  1692. {
  1693. while( *pChar )
  1694. {
  1695. PutWord( f, *pChar, &dw);
  1696. pChar++;
  1697. }
  1698. PutWord( f, 0, &dw);
  1699. }
  1700. else
  1701. {
  1702. _WCSTOMBS( szDHW, pChar, DHWSIZE, lstrlen( pChar) + 1);
  1703. while( szDHW[ dw] )
  1704. {
  1705. PutByte( f, szDHW[ dw], &dw);
  1706. }
  1707. PutByte( f, 0, &dw);
  1708. }
  1709. #else //RLWIN32
  1710. while( *((BYTE far *)pData+i) )
  1711. {
  1712. PutByte( f, *((BYTE far *)pData+dw), &dw);
  1713. }
  1714. PutByte( f, 0, &dw);
  1715. #endif //RLWIN32
  1716. }
  1717. else
  1718. {
  1719. while( dw < uSize)
  1720. {
  1721. PutByte( f, *((BYTE far *)pData+dw), &dw);
  1722. }
  1723. }
  1724. return( (int)dw);
  1725. }
  1726. /**
  1727. * Function: GetTextData
  1728. * Reads data of the specified type and size from a string.
  1729. *
  1730. * Arguments:
  1731. * wType, type of this resource (from resource template)
  1732. * uSize, size in bytes of resource (ignored for null terminated strings)
  1733. * sz, source string (always in Unicode if in NT version of tool)
  1734. *
  1735. * Returns:
  1736. * pointer to the data
  1737. *
  1738. * Error Codes:
  1739. * null pointer on error
  1740. *
  1741. * History:
  1742. * 1/92 -- initial implementation -- SteveBl
  1743. *
  1744. **/
  1745. static void far * GetTextData(
  1746. enum LOCALIZABLE_TYPES wType,
  1747. unsigned uSize,
  1748. TCHAR sz[])
  1749. {
  1750. PBYTE pData = NULL;
  1751. int i = 0;
  1752. if ( wType % LT_UNSIGNED == LT_WSZ
  1753. || wType % LT_UNSIGNED == LT_SZ )
  1754. {
  1755. pData = FALLOC( MEMSIZE( MAXTEXTLEN));
  1756. }
  1757. else if ( wType % LT_UNSIGNED == LT_WSTRING
  1758. || wType % LT_UNSIGNED == LT_STRING )
  1759. {
  1760. pData = FALLOC( MEMSIZE( uSize));
  1761. }
  1762. else
  1763. {
  1764. pData = FALLOC( uSize);
  1765. }
  1766. switch (wType)
  1767. {
  1768. case LT_CHAR:
  1769. case LT_UNSIGNED+LT_CHAR:
  1770. *pData = (BYTE) sz[0];
  1771. break;
  1772. case LT_WCHAR:
  1773. case LT_UNSIGNED+LT_WCHAR:
  1774. *((TCHAR *)pData) = sz[0];
  1775. break;
  1776. case LT_INTEGER:
  1777. if ( uSize == 2 )
  1778. {
  1779. sscanf( (PCHAR)sz, "%Fhi", pData);
  1780. }
  1781. else
  1782. {
  1783. sscanf( (PCHAR)sz, "%Fli", pData);
  1784. }
  1785. break;
  1786. case LT_UNSIGNED+LT_INTEGER:
  1787. if ( uSize == 2 )
  1788. {
  1789. sscanf( (PCHAR)sz, "%Fhu", pData);
  1790. }
  1791. else
  1792. {
  1793. sscanf( (PCHAR)sz, "%Flu", pData);
  1794. }
  1795. break;
  1796. case LT_FLOAT:
  1797. case LT_UNSIGNED+LT_FLOAT:
  1798. if ( uSize == 4 )
  1799. {
  1800. sscanf( (PCHAR)sz, "%Ff", pData);
  1801. }
  1802. else
  1803. {
  1804. sscanf( (PCHAR)sz, "%Flf", pData);
  1805. }
  1806. break;
  1807. case LT_STRING:
  1808. case LT_UNSIGNED+LT_STRING:
  1809. case LT_WSTRING:
  1810. case LT_UNSIGNED+LT_WSTRING:
  1811. for ( i = uSize; i--; )
  1812. {
  1813. *((TCHAR far *)pData + i) = sz[i];
  1814. }
  1815. break;
  1816. case LT_SZ:
  1817. case LT_UNSIGNED+LT_SZ:
  1818. case LT_WSZ:
  1819. case LT_UNSIGNED+LT_WSZ:
  1820. #ifdef RLWIN32
  1821. CopyMemory( pData, sz, MEMSIZE( min( lstrlen( sz) + 1, MAXTEXTLEN)));
  1822. #else
  1823. FSTRNCPY( (CHAR far *)pData, sz, MAXTEXTLEN);
  1824. #endif
  1825. break;
  1826. default:
  1827. RLFREE( pData);
  1828. }
  1829. return( pData);
  1830. }
  1831. /**
  1832. * Function: PutTextData
  1833. * Writes data of the specified type to a string.
  1834. *
  1835. * Arguments:
  1836. * pData, pointer to data
  1837. * wType, type of this resource (from resource template)
  1838. * uSize, size in bytes of resource (ignored for null terminated strings)
  1839. * sz, destination string
  1840. * l, length of destination string (in bytes)
  1841. *
  1842. * Returns:
  1843. * 0 - no errors
  1844. *
  1845. * Error Codes:
  1846. * 1 - error
  1847. *
  1848. * History:
  1849. * 1/92 -- initial implementation -- SteveBl
  1850. *
  1851. **/
  1852. static int PutTextData(
  1853. void far *pData,
  1854. enum LOCALIZABLE_TYPES wType,
  1855. unsigned uSize,
  1856. TCHAR sz[],
  1857. int l)
  1858. {
  1859. switch (wType)
  1860. {
  1861. case LT_CHAR:
  1862. case LT_UNSIGNED+LT_CHAR:
  1863. case LT_WCHAR:
  1864. case LT_UNSIGNED+LT_WCHAR:
  1865. CopyMemory( sz, pData, min( uSize, (UINT)l));
  1866. break;
  1867. case LT_INTEGER:
  1868. if ( uSize == 2 )
  1869. {
  1870. wsprintf( sz, TEXT("%Fhi"), pData);
  1871. }
  1872. else
  1873. {
  1874. wsprintf( sz, TEXT("%Fli"), pData);
  1875. }
  1876. break;
  1877. case LT_UNSIGNED+LT_INTEGER:
  1878. if ( uSize == 2 )
  1879. {
  1880. wsprintf( sz, TEXT("%Fhu"), pData);
  1881. }
  1882. else
  1883. {
  1884. wsprintf( sz, TEXT("%Flu"), pData);
  1885. }
  1886. break;
  1887. case LT_FLOAT:
  1888. case LT_UNSIGNED+LT_FLOAT:
  1889. if ( uSize == 4 )
  1890. {
  1891. wsprintf( sz, TEXT("%Ff"), pData);
  1892. }
  1893. else
  1894. {
  1895. wsprintf( sz, TEXT("%Flf"), pData);
  1896. }
  1897. break;
  1898. case LT_STRING:
  1899. case LT_UNSIGNED+LT_STRING:
  1900. case LT_WSTRING:
  1901. case LT_UNSIGNED+LT_WSTRING:
  1902. CopyMemory( sz, pData, uSize);
  1903. break;
  1904. case LT_SZ:
  1905. case LT_UNSIGNED+LT_SZ:
  1906. CopyMemory( sz, pData, MEMSIZE(min( lstrlen( pData) + 1, l)));
  1907. ((LPSTR)sz)[ l - 1] = '\0';
  1908. break;
  1909. case LT_WSZ:
  1910. case LT_UNSIGNED+LT_WSZ:
  1911. CopyMemory( sz, pData, min( MEMSIZE( lstrlen( pData) + 1), WCHARSIN( l)));
  1912. sz[ WCHARSIN( l) - 1] = TEXT('\0');
  1913. break;
  1914. //#ifdef RLWIN32
  1915. // CopyMemory( sz, pData, l > 0 ? l * sizeof( TCHAR) : 0);
  1916. //#else
  1917. // FSTRNCPY( (CHAR far *) sz, (CHAR far *)pData, l);
  1918. //#endif
  1919. break;
  1920. default:
  1921. return( 1);
  1922. }
  1923. return( 0);
  1924. }
  1925. /**
  1926. * Function: AddTo
  1927. * Adds a character to a string at position c.
  1928. * c is then incremented only if it is still less than the maximum
  1929. * length of the target string. This is to prevent runover.
  1930. *
  1931. * Arguments:
  1932. * sz, target string
  1933. * c, pointer to current position value
  1934. * lTarget, maximum length of the target string
  1935. * ch, character to be added to the string
  1936. */
  1937. void AddTo( CHAR *sz, int *c, int lTarget, CHAR ch)
  1938. {
  1939. sz[*c] = ch;
  1940. if (*c < lTarget)
  1941. {
  1942. (*c)++;
  1943. }
  1944. }
  1945. #ifdef RLWIN32
  1946. void AddToW( TCHAR *sz, int *c, int lTarget, TCHAR ch)
  1947. {
  1948. sz[*c] = ch;
  1949. if (*c < lTarget)
  1950. {
  1951. (*c)++;
  1952. }
  1953. }
  1954. /**
  1955. * Function: BinToTextW
  1956. * Converts a binary string to it's c representation
  1957. * (complete with escape sequences). If the target string is NULL,
  1958. * space will be allocated for it.
  1959. *
  1960. * Arguments:
  1961. * rgc, source string
  1962. * lSource, length of source string
  1963. *
  1964. * Returns:
  1965. * nothing
  1966. *
  1967. * Error Codes:
  1968. * none
  1969. *
  1970. * History:
  1971. * 1/92 -- initial implementation -- SteveBl
  1972. *
  1973. * 01/21/93 MHotchin - Made changes to allow this function to allocate
  1974. * the memory for the destination string. If the target string
  1975. * is NULL, then space will be allocated for it. The target
  1976. * string is returned to the caller.
  1977. **/
  1978. UINT _MBSTOWCS( WCHAR wszOut[], CHAR szIn[], UINT cOut, UINT cIn)
  1979. {
  1980. UINT n;
  1981. n = MultiByteToWideChar( gProj.uCodePage,
  1982. MB_PRECOMPOSED,
  1983. szIn,
  1984. cIn,
  1985. wszOut,
  1986. cOut);
  1987. return( n > 0 ? n - 1 : 0);
  1988. }
  1989. UINT _WCSTOMBS( CHAR szOut[], WCHAR wszIn[], UINT cOut, UINT cIn)
  1990. {
  1991. UINT n;
  1992. n = WideCharToMultiByte( gProj.uCodePage,
  1993. 0,
  1994. wszIn,
  1995. cIn,
  1996. szOut,
  1997. cOut,
  1998. NULL,
  1999. NULL);
  2000. return( (cIn > 0 ) ? cIn - 1 : 0);
  2001. }
  2002. WCHAR * BinToTextW(
  2003. TCHAR *szInBuf, //... Input, binary, string
  2004. int lSource) //... Length of szInBuf
  2005. {
  2006. int i;
  2007. int cOutBufLen = 0;
  2008. int lTarget = 0; //... Max length of szOutBuf
  2009. TCHAR *szOutBuf = NULL; //... Output string with escape sequences
  2010. // If the target is NULL, allocate some memory. We set aside
  2011. // 5% more than the source length. MHotchin
  2012. // chngd to 5% or 5 chars if 10% is less than 50 davewi
  2013. lTarget = (lSource == 0) ? 0 : lSource + 1;
  2014. szOutBuf = (TCHAR *)FALLOC( MEMSIZE( lTarget));
  2015. for ( i = 0; i < lSource; i++ )
  2016. {
  2017. switch( szInBuf[i] )
  2018. {
  2019. case TEXT('\a'):
  2020. szOutBuf = CheckBufSizeW( &lTarget, cOutBufLen, 2, szOutBuf);
  2021. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('\\'));
  2022. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('a'));
  2023. break;
  2024. case TEXT('\b'):
  2025. szOutBuf = CheckBufSizeW( &lTarget, cOutBufLen, 2, szOutBuf);
  2026. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('\\'));
  2027. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('b'));
  2028. break;
  2029. case TEXT('\f'):
  2030. szOutBuf = CheckBufSizeW( &lTarget, cOutBufLen, 2, szOutBuf);
  2031. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('\\'));
  2032. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('f'));
  2033. break;
  2034. case TEXT('\n'):
  2035. szOutBuf = CheckBufSizeW( &lTarget, cOutBufLen, 2, szOutBuf);
  2036. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('\\'));
  2037. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('n'));
  2038. break;
  2039. case TEXT('\r'):
  2040. szOutBuf = CheckBufSizeW( &lTarget, cOutBufLen, 2, szOutBuf);
  2041. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('\\'));
  2042. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('r'));
  2043. break;
  2044. case TEXT('\t'):
  2045. szOutBuf = CheckBufSizeW( &lTarget, cOutBufLen, 2, szOutBuf);
  2046. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('\\'));
  2047. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('t'));
  2048. break;
  2049. case TEXT('\v'):
  2050. szOutBuf = CheckBufSizeW( &lTarget, cOutBufLen, 2, szOutBuf);
  2051. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('\\'));
  2052. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('v'));
  2053. break;
  2054. case TEXT('\\'):
  2055. szOutBuf = CheckBufSizeW( &lTarget, cOutBufLen, 2, szOutBuf);
  2056. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('\\'));
  2057. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('\\'));
  2058. break;
  2059. default:
  2060. {
  2061. TCHAR wTmp = szInBuf[i];
  2062. if ( wTmp == 0 )
  2063. {
  2064. szOutBuf = CheckBufSizeW( &lTarget, cOutBufLen, 2, szOutBuf);
  2065. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('\\'));
  2066. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('0'));
  2067. }
  2068. else if ( (wTmp >= 0 && wTmp < 32)
  2069. || wTmp == 0x7f
  2070. || wTmp == 0xa9
  2071. || wTmp == 0xae )
  2072. {
  2073. CHAR szt[5];
  2074. szOutBuf = CheckBufSizeW( &lTarget, cOutBufLen, 4, szOutBuf);
  2075. sprintf( szt, "%#04hx", wTmp);
  2076. AddToW( szOutBuf, &cOutBufLen, lTarget, TEXT('\\'));
  2077. AddToW( szOutBuf, &cOutBufLen, lTarget, (TCHAR)(szt[0]));
  2078. AddToW( szOutBuf, &cOutBufLen, lTarget, (TCHAR)(szt[1]));
  2079. AddToW( szOutBuf, &cOutBufLen, lTarget, (TCHAR)(szt[2]));
  2080. AddToW( szOutBuf, &cOutBufLen, lTarget, (TCHAR)(szt[3]));
  2081. }
  2082. else
  2083. {
  2084. szOutBuf = CheckBufSizeW( &lTarget, cOutBufLen, 1, szOutBuf);
  2085. AddToW( szOutBuf, &cOutBufLen, lTarget, wTmp);
  2086. }
  2087. break;
  2088. }
  2089. }
  2090. }
  2091. szOutBuf[ cOutBufLen] = TEXT('\0');
  2092. return( szOutBuf);
  2093. }
  2094. #endif //RLWIN32
  2095. /** Function: atoihex
  2096. * Converts a string containing hex digits to an integer. String is
  2097. * assumed to contain nothing but legal hex digits. No error checking
  2098. * is performed.
  2099. *
  2100. * Arguments:
  2101. * sz, null terminated string containing hex digits
  2102. *
  2103. * Returns:
  2104. * value of hex digits in sz
  2105. *
  2106. * Error Codes:
  2107. * none
  2108. *
  2109. * History:
  2110. * 1/92 -- initial implementation -- SteveBl
  2111. *
  2112. */
  2113. int atoihex( CHAR sz[])
  2114. {
  2115. int r = 0;
  2116. int i = 0;
  2117. CHAR ch;
  2118. while (sz[i])
  2119. {
  2120. r *= 16;
  2121. ch = (CHAR)toupper(sz[i++]);
  2122. if (ch<='9' && ch>='0')
  2123. {
  2124. r += ch - '0';
  2125. }
  2126. else
  2127. {
  2128. if (ch <= 'F' && ch >= 'A')
  2129. {
  2130. r += ch - 'A' + 10;
  2131. }
  2132. }
  2133. }
  2134. return r;
  2135. }
  2136. #ifdef RLRES32
  2137. /**
  2138. * Function: TextToBinW
  2139. * Converts a string with c escape sequences to a true binary string.
  2140. *
  2141. * Arguments:
  2142. * rgc, target string
  2143. * sz, source string
  2144. * l, maximum length of target string
  2145. *
  2146. * Returns:
  2147. * length of target string
  2148. *
  2149. * Error Codes:
  2150. * none
  2151. *
  2152. * History:
  2153. * 1/92 -- initial implementation -- SteveBl
  2154. * 9/92 -- changed to UNICODE-only version -- davewi
  2155. * 01/21/93 -- Changed to allow arb length strings MHotchin.
  2156. *
  2157. **/
  2158. int TextToBinW(
  2159. WCHAR szOutBuf[], //... Output, binary, string
  2160. WCHAR szInBuf[], //... Input string with escape sequences
  2161. int lTarget) //... Max length of szOutBuf
  2162. {
  2163. int i = 0;
  2164. int c = 0;
  2165. while ( szInBuf[ c] )
  2166. {
  2167. if ( szInBuf[ c] == TEXT('\\') )
  2168. { // escape sequence!
  2169. c++;
  2170. switch ( szInBuf[ c++] )
  2171. {
  2172. case TEXT('a'):
  2173. AddToW( szOutBuf, &i, lTarget, TEXT('\a'));
  2174. break;
  2175. case TEXT('b'):
  2176. AddToW( szOutBuf, &i, lTarget, TEXT('\b'));
  2177. break;
  2178. case TEXT('f'):
  2179. AddToW( szOutBuf, &i, lTarget, TEXT('\f'));
  2180. break;
  2181. case TEXT('n'):
  2182. AddToW( szOutBuf, &i, lTarget, TEXT('\n'));
  2183. break;
  2184. case TEXT('r'):
  2185. AddToW( szOutBuf, &i, lTarget, TEXT('\r'));
  2186. break;
  2187. case TEXT('t'):
  2188. AddToW( szOutBuf, &i, lTarget, TEXT('\t'));
  2189. break;
  2190. case TEXT('v'):
  2191. AddToW( szOutBuf, &i, lTarget, TEXT('\v'));
  2192. break;
  2193. case TEXT('\''):
  2194. AddToW( szOutBuf, &i, lTarget, TEXT('\''));
  2195. break;
  2196. case TEXT('\"'):
  2197. AddToW( szOutBuf, &i, lTarget, TEXT('\"'));
  2198. break;
  2199. case TEXT('\\'):
  2200. AddToW( szOutBuf, &i, lTarget, TEXT('\\'));
  2201. break;
  2202. case TEXT('0'):
  2203. case TEXT('1'):
  2204. case TEXT('2'):
  2205. {
  2206. CHAR szt[4];
  2207. szt[0] = szt[1] = szt[2] = szt[3] = '\0';
  2208. if ( szInBuf[c-1] == TEXT('0')
  2209. && (szInBuf[c] < TEXT('0') || szInBuf[c] > TEXT('9'))
  2210. && szInBuf[c] != TEXT('x') && szInBuf[c] != TEXT('X') )
  2211. {
  2212. // Must be '\0'
  2213. AddToW( szOutBuf, &i, lTarget, (TCHAR)0);
  2214. }
  2215. else if ( szInBuf[c] >= TEXT('0') && szInBuf[c] <= TEXT('9') )
  2216. {
  2217. szt[0] = (CHAR)(szInBuf[c-1]);
  2218. szt[1] = (CHAR)(szInBuf[c++]);
  2219. if ( szInBuf[c] >= TEXT('0') && szInBuf[c] <= TEXT('9'))
  2220. {
  2221. szt[2] = (CHAR)(szInBuf[c++]);
  2222. }
  2223. AddToW( szOutBuf, &i, lTarget, (TCHAR)atoi( szt));
  2224. }
  2225. else if ( szInBuf[c] == TEXT('X')
  2226. || szInBuf[c] == TEXT('x') )
  2227. {
  2228. c++;
  2229. szt[0] = (CHAR)(szInBuf[c++]);
  2230. szt[1] = (CHAR)(szInBuf[c++]);
  2231. AddToW( szOutBuf, &i, lTarget, (TCHAR)atoihex( szt));
  2232. }
  2233. else
  2234. {
  2235. QuitT( IDS_INVESCSEQ, &szInBuf[c-2], NULL);
  2236. }
  2237. break;
  2238. }
  2239. case TEXT('x'):
  2240. case TEXT('X'):
  2241. {
  2242. CHAR szt[4];
  2243. szt[0] = szt[1] = szt[2] = szt[3] = '\0';
  2244. if ( (szInBuf[c] <= TEXT('9') && szInBuf[c] >= TEXT('0'))
  2245. || (szInBuf[c] >= TEXT('A') && szInBuf[c] <= TEXT('F'))
  2246. || (szInBuf[c] >= TEXT('a') && szInBuf[c] <= TEXT('f')) )
  2247. {
  2248. szt[0] = (CHAR)(szInBuf[c++]);
  2249. if ( (szInBuf[c] <= TEXT('9')
  2250. && szInBuf[c] >= TEXT('0'))
  2251. || (szInBuf[c] >= TEXT('A')
  2252. && szInBuf[c] <= TEXT('F'))
  2253. || (szInBuf[c] >= TEXT('a')
  2254. && szInBuf[c] <= TEXT('f')) )
  2255. {
  2256. szt[1] = (CHAR)(szInBuf[c++]);
  2257. if ( (szInBuf[c] <= TEXT('9')
  2258. && szInBuf[c] >= TEXT('0'))
  2259. || (szInBuf[c] >= TEXT('A')
  2260. && szInBuf[c] <= TEXT('F'))
  2261. || (szInBuf[c] >= TEXT('a')
  2262. && szInBuf[c] <= TEXT('f')) )
  2263. {
  2264. szt[2] = (CHAR)(szInBuf[c++]);
  2265. }
  2266. }
  2267. }
  2268. AddToW( szOutBuf, &i, lTarget, (TCHAR)atoihex( szt));
  2269. break;
  2270. }
  2271. default:
  2272. AddToW( szOutBuf, &i, lTarget, szInBuf[c-1]);
  2273. break;
  2274. } //... END switch
  2275. }
  2276. else
  2277. {
  2278. AddToW( szOutBuf, &i, lTarget, szInBuf[c++]);
  2279. }
  2280. } //... END while
  2281. szOutBuf[i++] = TEXT('\0');
  2282. return(i);
  2283. }
  2284. #endif
  2285. void ClearResourceDescriptions( void)
  2286. {
  2287. CUSTRESNODE far *pCR = pCustResList;
  2288. CUSTRESNODE far *pCRNext = NULL;
  2289. CUSTRESTEMPLATE far *pCRT = NULL;
  2290. CUSTRESTEMPLATE far *pCRTNext = NULL;
  2291. CUSTRESTEMPLATE far *pCRTTmp = NULL;
  2292. while ( pCR )
  2293. {
  2294. pCRNext = pCR->pNext;
  2295. if ( pCR->pszType )
  2296. {
  2297. RLFREE(pCR->pszType);
  2298. }
  2299. if ( pCR->pszName )
  2300. {
  2301. RLFREE(pCR->pszName);
  2302. }
  2303. pCRT = pCR->pTemplate;
  2304. while ( pCRT )
  2305. {
  2306. pCRTTmp = pCRT->pNext;
  2307. RLFREE( pCRT);
  2308. pCRT=pCRTTmp;
  2309. }
  2310. RLFREE( pCR);
  2311. pCR = pCRNext;
  2312. }
  2313. pCustResList = NULL;
  2314. }
  2315. // Check to see if we need more room. If we have less that 5 bytes
  2316. // left, grow the target by another 5%. MHotchin
  2317. // chngd to 10% or 10 chars if 10% is less than 10 davewi
  2318. static CHAR *CheckBufSize(
  2319. int *lTarget, //... Length of output buffer
  2320. int cOutBufLen, //... Bytes already used in output buffer
  2321. int cDelta, //... # characters we want to add to output buffer
  2322. CHAR *szOutBuf) //... ptr to output buffer
  2323. {
  2324. //... add 1 to allow for trailing nul
  2325. if ( *lTarget - cOutBufLen < cDelta + 1 )
  2326. {
  2327. *lTarget += cDelta;
  2328. szOutBuf = (CHAR *)FREALLOC( (BYTE *)szOutBuf, *lTarget);
  2329. }
  2330. return( szOutBuf);
  2331. }
  2332. #ifdef RLWIN32
  2333. static TCHAR *CheckBufSizeW(
  2334. int *lTarget, //... Length of output buffer
  2335. int cOutBufLen, //... Bytes already used in output buffer
  2336. int cDelta, //... # characters we want to add to output buffer
  2337. TCHAR *szOutBuf) //... ptr to output buffer
  2338. {
  2339. //... add 1 to allow for trailing nul
  2340. if ( *lTarget - cOutBufLen < (int)(MEMSIZE( cDelta + 1)) )
  2341. {
  2342. *lTarget += MEMSIZE( cDelta);
  2343. szOutBuf = (TCHAR *)FREALLOC( (BYTE *)szOutBuf, MEMSIZE(*lTarget));
  2344. }
  2345. return( szOutBuf);
  2346. }
  2347. #endif //RLWIN32
  2348. /**
  2349. * Function: BinToTextA
  2350. * Converts a binary string to it's c representation
  2351. * (complete with escape sequences)
  2352. *
  2353. * Arguments:
  2354. * rgc, source string
  2355. * lSource, length of source string
  2356. *
  2357. * Returns:
  2358. * nothing
  2359. *
  2360. * Error Codes:
  2361. * none
  2362. *
  2363. * History:
  2364. * 1/92 -- initial implementation -- SteveBl
  2365. * 9/92 -- made this ANSII version-- DaveWi
  2366. * because err msg tables in NT are not UNICODE
  2367. * 01/19/93 -- Removed the string copies. They were not needed, and
  2368. * MHotchin broke anything that had embedded nulls in it.
  2369. * Also added support for allocating memory as needed.
  2370. **/
  2371. PCHAR BinToTextA(
  2372. PCHAR szInBuf, //... Input, binary, string
  2373. int lSource) //... Length of szInBuf
  2374. {
  2375. int i;
  2376. int cOutBufLen = 0;
  2377. int lTarget = 0; //... Max length of szOutBuf
  2378. PCHAR szOutBuf = NULL; //... Output string with escape sequences
  2379. // If the target is NULL, allocate some memory. We set aside
  2380. // 5% more than the source length. MHotchin
  2381. // chngd to 5% or 5 chars if 10% is less than 50 davewi
  2382. lTarget = (lSource == 0) ? 0 : lSource + 1;
  2383. szOutBuf = (PCHAR)FALLOC( lTarget);
  2384. for ( i = 0; i < lSource; i++ )
  2385. {
  2386. switch( szInBuf[i] )
  2387. {
  2388. case '\a':
  2389. szOutBuf = CheckBufSize( &lTarget, cOutBufLen, 2, szOutBuf);
  2390. AddTo(szOutBuf, &cOutBufLen, lTarget, '\\');
  2391. AddTo(szOutBuf, &cOutBufLen, lTarget, 'a');
  2392. break;
  2393. case '\b':
  2394. szOutBuf = CheckBufSize( &lTarget, cOutBufLen, 2, szOutBuf);
  2395. AddTo(szOutBuf, &cOutBufLen, lTarget, '\\');
  2396. AddTo(szOutBuf, &cOutBufLen, lTarget, 'b');
  2397. break;
  2398. case '\f':
  2399. szOutBuf = CheckBufSize( &lTarget, cOutBufLen, 2, szOutBuf);
  2400. AddTo(szOutBuf, &cOutBufLen, lTarget, '\\');
  2401. AddTo(szOutBuf, &cOutBufLen, lTarget, 'f');
  2402. break;
  2403. case '\n':
  2404. szOutBuf = CheckBufSize( &lTarget, cOutBufLen, 2, szOutBuf);
  2405. AddTo(szOutBuf, &cOutBufLen, lTarget, '\\');
  2406. AddTo(szOutBuf, &cOutBufLen, lTarget, 'n');
  2407. break;
  2408. case '\r':
  2409. szOutBuf = CheckBufSize( &lTarget, cOutBufLen, 2, szOutBuf);
  2410. AddTo(szOutBuf, &cOutBufLen, lTarget, '\\');
  2411. AddTo(szOutBuf, &cOutBufLen, lTarget, 'r');
  2412. break;
  2413. case '\t':
  2414. szOutBuf = CheckBufSize( &lTarget, cOutBufLen, 2, szOutBuf);
  2415. AddTo(szOutBuf, &cOutBufLen, lTarget, '\\');
  2416. AddTo(szOutBuf, &cOutBufLen, lTarget, 't');
  2417. break;
  2418. case '\v':
  2419. szOutBuf = CheckBufSize( &lTarget, cOutBufLen, 2, szOutBuf);
  2420. AddTo(szOutBuf, &cOutBufLen, lTarget, '\\');
  2421. AddTo(szOutBuf, &cOutBufLen, lTarget, 'v');
  2422. break;
  2423. case '\\':
  2424. szOutBuf = CheckBufSize( &lTarget, cOutBufLen, 2, szOutBuf);
  2425. AddTo(szOutBuf, &cOutBufLen, lTarget, '\\');
  2426. AddTo(szOutBuf, &cOutBufLen, lTarget, '\\');
  2427. break;
  2428. default:
  2429. {
  2430. unsigned char ucTmp = szInBuf[i];
  2431. if ( (ucTmp >= 0 && ucTmp < 32)
  2432. || ucTmp == 0x7f
  2433. || ucTmp == 0xa9
  2434. || ucTmp == 0xae )
  2435. {
  2436. CHAR szt[5];
  2437. szOutBuf = CheckBufSize( &lTarget, cOutBufLen, 4, szOutBuf);
  2438. sprintf( szt, "%#04hx", (unsigned short)ucTmp);
  2439. AddTo(szOutBuf, &cOutBufLen, lTarget, '\\');
  2440. AddTo(szOutBuf, &cOutBufLen, lTarget, szt[0]);
  2441. AddTo(szOutBuf, &cOutBufLen, lTarget, szt[1]);
  2442. AddTo(szOutBuf, &cOutBufLen, lTarget, szt[2]);
  2443. AddTo(szOutBuf, &cOutBufLen, lTarget, szt[3]);
  2444. }
  2445. else
  2446. {
  2447. szOutBuf = CheckBufSize( &lTarget, cOutBufLen, 1, szOutBuf);
  2448. AddTo(szOutBuf, &cOutBufLen, lTarget, szInBuf[i]);
  2449. }
  2450. break;
  2451. }
  2452. }
  2453. }
  2454. szOutBuf[ cOutBufLen] = '\0';
  2455. return( szOutBuf);
  2456. }
  2457. /**
  2458. * Function: TextToBinA
  2459. * Converts a string with c escape sequences to a true binary string.
  2460. *
  2461. * Arguments:
  2462. * rgc, target string
  2463. * sz, source string
  2464. * l, maximum length of target string
  2465. *
  2466. * Returns:
  2467. * length of target string
  2468. *
  2469. * Error Codes:
  2470. * none
  2471. *
  2472. * History:
  2473. * 1/92 -- initial implementation -- SteveBl
  2474. * 9/92 -- made this ANSII version-- DaveWi
  2475. * because msg resource table strings are not UNICODE
  2476. * 01/21/93 - Removed the string copies - it breaks on embedded NULL's,
  2477. * and they aren't needed anyways. MHotchin
  2478. *
  2479. **/
  2480. int TextToBinA(
  2481. CHAR szOutBuf[], //... Output, binary, string
  2482. CHAR szInBuf[], //... Input string with escape sequences
  2483. int lTarget) //... Max length of szOutBuf
  2484. {
  2485. int i = 0;
  2486. int c = 0;
  2487. while (szInBuf[c])
  2488. {
  2489. if (szInBuf[c] == '\\')
  2490. { // escape sequence!
  2491. c++;
  2492. switch (szInBuf[c++])
  2493. {
  2494. case 'a':
  2495. AddTo(szOutBuf, &i, lTarget, '\a');
  2496. break;
  2497. case 'b':
  2498. AddTo(szOutBuf, &i, lTarget, '\b');
  2499. break;
  2500. case 'f':
  2501. AddTo(szOutBuf, &i, lTarget, '\f');
  2502. break;
  2503. case 'n':
  2504. AddTo(szOutBuf, &i, lTarget, '\n');
  2505. break;
  2506. case 'r':
  2507. AddTo(szOutBuf, &i, lTarget, '\r');
  2508. break;
  2509. case 't':
  2510. AddTo(szOutBuf, &i, lTarget, '\t');
  2511. break;
  2512. case 'v':
  2513. AddTo(szOutBuf, &i, lTarget, '\v');
  2514. break;
  2515. case '\'':
  2516. AddTo(szOutBuf, &i, lTarget, '\'');
  2517. break;
  2518. case '\"':
  2519. AddTo(szOutBuf, &i, lTarget, '\"');
  2520. break;
  2521. case '\\':
  2522. AddTo(szOutBuf, &i, lTarget, '\\');
  2523. break;
  2524. case '0':
  2525. case '1':
  2526. case '2':
  2527. {
  2528. CHAR szt[4];
  2529. szt[0] = szt[1] = szt[2] = szt[3] = '\0';
  2530. if ( szInBuf[c] >= '0' && szInBuf[c] <= '9' )
  2531. {
  2532. szt[0] = szInBuf[c-1];
  2533. szt[1] = szInBuf[c++];
  2534. if ( szInBuf[c] >= '0' && szInBuf[c] <= '9' )
  2535. {
  2536. szt[2] = (CHAR)szInBuf[c++];
  2537. }
  2538. AddTo(szOutBuf, &i, lTarget, (CHAR)atoi( szt));
  2539. }
  2540. else if ( toupper( szInBuf[c]) == 'X' )
  2541. {
  2542. c++;
  2543. szt[0] = szInBuf[c++];
  2544. szt[1] = szInBuf[c++];
  2545. AddTo(szOutBuf, &i, lTarget, (CHAR)atoihex( szt));
  2546. }
  2547. else
  2548. {
  2549. QuitA( IDS_INVESCSEQ, &szInBuf[c-2], NULL);
  2550. }
  2551. break;
  2552. }
  2553. case 'x':
  2554. {
  2555. CHAR szt[4];
  2556. // Changed letters we were comparing to - it used
  2557. // to be lower case. MHotchin
  2558. szt[0] = szt[1] = szt[2] = szt[3] = '\0';
  2559. if ((szInBuf[c] <= '9' && szInBuf[c] >= '0')
  2560. || (toupper(szInBuf[c]) >= 'A'
  2561. && toupper(szInBuf[c]) <= 'F'))
  2562. {
  2563. szt[0] = (CHAR)szInBuf[c++];
  2564. if ((szInBuf[c] <= '9' && szInBuf[c] >= '0')
  2565. || (toupper(szInBuf[c]) >= 'A'
  2566. && toupper(szInBuf[c]) <= 'F'))
  2567. {
  2568. szt[1] = szInBuf[c++];
  2569. if ((szInBuf[c] <= '9' && szInBuf[c] >= '0')
  2570. || (toupper(szInBuf[c]) >= 'A'
  2571. && toupper(szInBuf[c]) <= 'F'))
  2572. {
  2573. szt[2] = szInBuf[c++];
  2574. }
  2575. }
  2576. }
  2577. AddTo(szOutBuf, &i, lTarget, (CHAR)atoihex(szt));
  2578. break;
  2579. }
  2580. default:
  2581. AddTo(szOutBuf, &i, lTarget, szInBuf[c-1]);
  2582. break;
  2583. } //... END switch
  2584. }
  2585. else
  2586. {
  2587. AddTo(szOutBuf, &i, lTarget, (CHAR)szInBuf[c++]);
  2588. }
  2589. } //... END while
  2590. szOutBuf[i++] = '\0';
  2591. return(i);
  2592. }