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.

5048 lines
150 KiB

  1. //#include <assert.h>
  2. #include <ctype.h>
  3. #include <malloc.h>
  4. #include <process.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. //#include <string.h>
  8. #include <tchar.h>
  9. #ifdef RLDOS
  10. #include "dosdefs.h"
  11. #else
  12. #include <windows.h>
  13. #include "windefs.h"
  14. #endif
  15. #include "restok.h"
  16. #include "custres.h"
  17. #include "ntmsgtbl.h"
  18. #include "rlmsgtbl.h"
  19. #include "resread.h"
  20. #include "projdata.h"
  21. //B_FormatMessage prototype
  22. #include "showerrs.h"
  23. #define SAME 0 //... Used in string comparisons
  24. #define STRINGFILEINFO (TEXT("StringFileInfo"))
  25. #define VARFILEINFO (TEXT("VarFileInfo"))
  26. #define TRANSLATION (TEXT("Translation"))
  27. #define LANGUAGEINFO (TEXT("Language Info"))
  28. #define STRINGFILEINFOLEN (lstrlen( (TCHAR *)STRINGFILEINFO) + 1)
  29. #define VARFILEINFOLEN (lstrlen( (TCHAR *)VARFILEINFO) + 1)
  30. #define TRANSLATIONLEN (lstrlen( (TCHAR *)TRANSLATION) + 1)
  31. #define LANGSTRINGLEN 8 //... # WCHARs in string denoting language
  32. //... and code page in a Version resource.
  33. #define TRANSDATALEN 2 //... # bytes in a Translation value
  34. #define VERTYPEBINARY 0 //... Version data value is binary
  35. #define VERTYPESTRING 1 //... Version data value is a string
  36. #define VERMEM 2048 //... Fixed size of buffer for new version stamp
  37. //... Decrement WORD at *pw by given amount w
  38. #define DECWORDBY( pw,w) if (pw) { *(pw) = (*(pw) > (w)) ? *(pw) - (w) : 0;}
  39. //... Increment WORD at *pw by given amount w
  40. #define INCWORDBY( pw,w) if (pw) { *(pw) += (w);}
  41. //... How many BYTES in the given string?
  42. #define BYTESINSTRING(s) (lstrlen( (TCHAR *)s) * sizeof( TCHAR))
  43. //... Dialog box controls (from RC.H)
  44. #define BUTTON 0x80
  45. #define EDIT 0x81
  46. #define STATIC 0x82
  47. PVERBLOCK MoveAlongVer( PVERBLOCK, WORD *, WORD *, WORD *);
  48. BOOL FilterRes( WORD, RESHEADER *);
  49. TCHAR *GetVerValue( PVERBLOCK);
  50. void PutNameOrd( FILE *, BOOL, WORD , TCHAR *, DWORD *);
  51. void GetNameOrd( FILE *,
  52. BOOL UNALIGNED*,
  53. WORD UNALIGNED*,
  54. TCHAR *UNALIGNED*,
  55. DWORD *);
  56. void CopyRes( FILE *fpInResFile,
  57. FILE *fpOutResFile,
  58. RESHEADER *pResHeader,
  59. fpos_t *pResSizePos);
  60. BOOL fInThirdPartyEditer = FALSE;//.. Are we in a 3rd-party resource editor?
  61. BOOL fInQuikEd = FALSE; //... Are we in RLQuiked? (see rlquiked.c)
  62. BOOL gfShowClass = FALSE; //... Set TRUE to put dlg box elemnt class
  63. //... in token file
  64. #if defined(DBCS)
  65. BOOL gfExtendedTok = TRUE; //... Set TRUE if -x is choosen
  66. #else
  67. BOOL gfExtendedTok = FALSE; //... Set TRUE if -x is choosen
  68. #endif
  69. #ifdef _DEBUG
  70. extern PMEMLIST pMemList;
  71. #endif
  72. #ifdef RLRES32
  73. #ifndef CAIRO
  74. extern VOID *pResMsgData; // NT-specific Message Table resource
  75. #endif //RLRES32
  76. #endif //CAIRO
  77. extern BOOL gbMaster; //... TRUE if we are working on a Master Project
  78. extern BOOL gfReplace; //... FALSE if appending new language to existing resources
  79. extern BOOL gbShowWarnings; //... Display warnining messages if TRUE
  80. extern UCHAR szDHW[];
  81. extern char * gszTmpPrefix;
  82. MSTRDATA gMstr = //... Data from Master Project file (MPJ)
  83. { //... Fields filled in main (UI)
  84. "",
  85. "",
  86. "",
  87. "",
  88. "",
  89. MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US),
  90. CP_ACP //... System default Windows code page
  91. };
  92. PROJDATA gProj = //... Data from Project file (PRJ)
  93. { //... Fields filled in main (UI)
  94. "",
  95. "",
  96. "",
  97. "",
  98. "",
  99. "",
  100. CP_ACP, //... System default Windows code page
  101. MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US),
  102. FALSE,
  103. FALSE
  104. };
  105. /**
  106. * Function: ReadWinRes
  107. *
  108. * The main resource Read/Writer function to process the resource file to be
  109. * localzied.
  110. *
  111. * ReadWinRes reads the resource header to determine the current resource type,
  112. * then executes the corresponding Get/Put resource functions to extract and
  113. * insert localized information contained in the resource file. ReadWinRes, is
  114. * excuted in two modes, Tokenize, and Generate. During Tokenize mode,
  115. * ReadWinRes writes all the localized information contained in the resouce to
  116. * a token file. During Generate mode, ReadWinRes, replaces all the localized
  117. * information in the input resource file, with the corresponding information
  118. * in the token file to gernerate a localized resource file.
  119. *
  120. * Currently the following resouce types are supported.
  121. *
  122. * Version Stamping.
  123. * Menus.
  124. * Dialogs.
  125. * Accelerators.
  126. * String Tables.
  127. * Version Stamps
  128. * Message Tables (NT)
  129. *
  130. * Arguments:
  131. *
  132. * InResFile, Handle to binary input resource file.
  133. * OutFesFile, Handle to binary output resouce file. Not used during tokenize
  134. * mode.
  135. * TokFile, Handle to text token file.
  136. * BOOL, flag to indicate whether to build output resource file.
  137. * BOOL, flag to indicate whether to build token file.
  138. *
  139. *
  140. * Returns:
  141. * ???
  142. *
  143. * Errors Codes:
  144. * ???
  145. *
  146. * History:
  147. * 10/91 Added Version stamping support. TerryRu
  148. * 11/91, Completed Version stamping support. TerryRu
  149. *
  150. *
  151. **/
  152. int ReadWinRes(
  153. FILE *InResFile,
  154. FILE *OutResFile,
  155. FILE *TokFile,
  156. BOOL fBuildRes,
  157. BOOL fBuildTok,
  158. WORD wFilter)
  159. {
  160. BOOL fDoAccel = TRUE; // set FALSE to not build accelerators
  161. MENUHEADER *pMenuHdr = NULL; // Linked list of Menu info.
  162. static RESHEADER ResHeader; // Structure contain Resource Header info.
  163. VERBLOCK *pVerBlk = NULL; // Memory block containing Version Stamping String File Block,
  164. static VERHEAD VerHdr; // Memory block containing Version Stamping Header info
  165. DIALOGHEADER *pDialogHdr = NULL; // Linked list of Dialog info
  166. STRINGHEADER *pStrHdr = NULL; // Array of String Tables.
  167. ACCELTABLEENTRY *pAccelTable = NULL;// Array of Accelerator Keys
  168. WORD wcTableEntries = 0; // Number of Accelerator tables
  169. fpos_t ResSizePos = 0; // Position of lSize field in the
  170. // Resource Header, used to fixup
  171. // the Header once the size of the
  172. // localized information is determined.
  173. CUSTOM_RESOURCE *pCustomResource = NULL;
  174. LONG lEndOffset = 0L;
  175. //... How large is the res file?
  176. fseek( InResFile, 0L, SEEK_END);
  177. lEndOffset = ftell( InResFile);
  178. rewind( InResFile);
  179. //... process until end of input file
  180. while ( ! feof( InResFile) ) {
  181. LONG lCurrOffset = 0L;
  182. lCurrOffset = (LONG)ftell( InResFile);
  183. if ( (lCurrOffset + (LONG)sizeof( RESHEADER)) >= lEndOffset ) {
  184. return 0;
  185. }
  186. if ( GetResHeader( InResFile, &ResHeader, (DWORD *) NULL) == -1 ) {
  187. return (1);
  188. }
  189. //... Is this the dummy, res32-identifying, res?
  190. if ( ResHeader.lSize == 0L ) { //... Yes, we so simply copy the header if we
  191. //... are building a res file.
  192. if ( fBuildRes ) {
  193. CopyRes( InResFile, OutResFile, &ResHeader, &ResSizePos);
  194. }
  195. #ifdef RLRES32
  196. else {
  197. if ( gbShowWarnings && OutResFile && ftell( OutResFile) != 0L ) {
  198. lstrcpyA( szDHW, "type");
  199. if ( ResHeader.wTypeID == IDFLAG ) {
  200. sprintf( &szDHW[ lstrlenA( szDHW)],
  201. " \"%s\"",
  202. ResHeader.pszType);
  203. } else {
  204. sprintf( &szDHW[ lstrlenA( szDHW)],
  205. " %hu,",
  206. ResHeader.wTypeID);
  207. }
  208. strcat( szDHW, " name");
  209. if ( ResHeader.wNameID == IDFLAG ) {
  210. sprintf( &szDHW[ lstrlenA( szDHW)],
  211. " \"%s\"",
  212. ResHeader.pszName);
  213. } else {
  214. sprintf( &szDHW[ lstrlenA( szDHW)],
  215. " %hu,",
  216. ResHeader.wNameID);
  217. }
  218. sprintf( &szDHW[ lstrlenA( szDHW)],
  219. " pri-lang %#hx sub-lang %#hx",
  220. PRIMARYLANGID( ResHeader.wLanguageId),
  221. SUBLANGID( ResHeader.wLanguageId));
  222. ShowEngineErr( IDS_ZERO_LEN_RES, szDHW, NULL);
  223. }
  224. DWordUpFilePointer( InResFile, MYREAD, ftell( InResFile), NULL);
  225. if (OutResFile != NULL) {
  226. DWordUpFilePointer( OutResFile,
  227. MYWRITE,
  228. ftell(OutResFile),
  229. NULL);
  230. }
  231. }
  232. #endif
  233. ClearResHeader( ResHeader);
  234. continue; //... Ship this dummy header
  235. }
  236. //... Check to see if we want to filter out this
  237. //... resource type.
  238. if ( FilterRes( wFilter, &ResHeader) ) {
  239. //... skip this resource type
  240. SkipBytes( InResFile, (DWORD *)&ResHeader.lSize);
  241. #ifdef RLRES32
  242. DWordUpFilePointer( InResFile, MYREAD, ftell( InResFile), NULL);
  243. #endif
  244. ClearResHeader( ResHeader);
  245. continue;
  246. }
  247. if ( fBuildTok ) {
  248. if ( ResHeader.wLanguageId != (fInThirdPartyEditer
  249. ? gProj.wLanguageID
  250. : gMstr.wLanguageID) ) {
  251. //... Skip this resource (wrong lanugage)
  252. if ( gbShowWarnings ) {
  253. lstrcpyA( szDHW, "type");
  254. if ( ResHeader.wTypeID == IDFLAG ) {
  255. sprintf( &szDHW[ lstrlenA( szDHW)],
  256. " \"%s\"",
  257. ResHeader.pszType);
  258. } else {
  259. sprintf( &szDHW[ lstrlenA( szDHW)],
  260. " %u,",
  261. ResHeader.wTypeID);
  262. }
  263. strcat( szDHW, " name");
  264. if ( ResHeader.wNameID == IDFLAG ) {
  265. sprintf( &szDHW[ lstrlenA( szDHW)],
  266. " \"%s\"",
  267. ResHeader.pszName);
  268. } else {
  269. sprintf( &szDHW[ lstrlenA( szDHW)],
  270. " %u,",
  271. ResHeader.wNameID);
  272. }
  273. sprintf( &szDHW[ lstrlenA( szDHW)],
  274. " pri-lang %#x sub-lang %#x",
  275. PRIMARYLANGID( ResHeader.wLanguageId),
  276. SUBLANGID( ResHeader.wLanguageId));
  277. ShowEngineErr( IDS_SKIP_RES,
  278. LongToPtr(ResHeader.lSize),
  279. szDHW);
  280. }
  281. SkipBytes( InResFile, (DWORD *)&ResHeader.lSize);
  282. #ifdef RLRES32
  283. DWordUpFilePointer( InResFile, MYREAD, ftell(InResFile), NULL);
  284. #endif
  285. ClearResHeader( ResHeader);
  286. continue;
  287. }
  288. } else if ( fBuildRes ) {
  289. if ( gfReplace ) {
  290. if ( ResHeader.wLanguageId == gMstr.wLanguageID ) {
  291. ResHeader.wLanguageId = gProj.wLanguageID;
  292. } else {
  293. //... Copy this resource
  294. CopyRes( InResFile, OutResFile, &ResHeader, &ResSizePos);
  295. ClearResHeader( ResHeader);
  296. continue;
  297. }
  298. } else { //... ! gfReplace
  299. if ( ResHeader.wLanguageId == gMstr.wLanguageID ) {
  300. fpos_t lFilePos = 0L;
  301. DWORD lTmpSize = 0L;
  302. lFilePos = ftell( InResFile); //... Save file position
  303. lTmpSize = ResHeader.lSize; //... and resource size
  304. //... Duplicate this resource
  305. CopyRes( InResFile, OutResFile, &ResHeader, &ResSizePos);
  306. fseek( InResFile, (long)lFilePos, SEEK_SET);
  307. ResHeader.wLanguageId = gProj.wLanguageID;
  308. ResHeader.lSize = lTmpSize;
  309. } else {
  310. //... Simply copy this resource if not target language
  311. if ( ResHeader.wLanguageId == gProj.wLanguageID ) {
  312. SkipBytes( InResFile, (DWORD *)&ResHeader.lSize);
  313. #ifdef RLRES32
  314. DWordUpFilePointer( InResFile, MYREAD, ftell( InResFile), NULL);
  315. #endif
  316. } else {
  317. CopyRes( InResFile, OutResFile, &ResHeader, &ResSizePos);
  318. }
  319. ClearResHeader( ResHeader);
  320. continue;
  321. }
  322. }
  323. }
  324. switch ( ResHeader.wTypeID ) {
  325. case ID_RT_ACCELERATORS:
  326. pAccelTable = GetAccelTable(InResFile,
  327. &wcTableEntries,
  328. (DWORD *)&ResHeader.lSize);
  329. if (fBuildTok) {
  330. TokAccelTable(TokFile,
  331. ResHeader,
  332. pAccelTable,
  333. wcTableEntries);
  334. }
  335. if (fBuildRes) {
  336. PutAccelTable(OutResFile,
  337. TokFile,
  338. ResHeader,
  339. pAccelTable,
  340. wcTableEntries);
  341. }
  342. ClearAccelTable (pAccelTable , wcTableEntries);
  343. break;
  344. case ID_RT_DIALOG:
  345. pDialogHdr = GetDialog(InResFile, (DWORD *)&ResHeader.lSize);
  346. if (fBuildTok == TRUE) {
  347. TokDialog(TokFile, ResHeader, pDialogHdr);
  348. }
  349. if (fBuildRes == TRUE) {
  350. PutDialog(OutResFile, TokFile, ResHeader, pDialogHdr);
  351. }
  352. ClearDialog (pDialogHdr);
  353. break;
  354. case ID_RT_DLGINIT:
  355. {
  356. PDLGINITDATA pDlgInit = GetDlgInit( InResFile, (DWORD *)&ResHeader.lSize);
  357. if ( fBuildTok ) {
  358. TokDlgInit( TokFile, ResHeader, pDlgInit);
  359. }
  360. if ( fBuildRes ) {
  361. PutDlgInit( OutResFile, TokFile, ResHeader, pDlgInit);
  362. }
  363. ClearDlgInitData( pDlgInit);
  364. break;
  365. }
  366. case ID_RT_MENU:
  367. // allocate space for a new header
  368. pMenuHdr = (MENUHEADER *)FALLOC( sizeof( MENUHEADER));
  369. GetResMenu(InResFile, (DWORD *)&ResHeader.lSize, pMenuHdr);
  370. if (fBuildTok == TRUE) {
  371. TokMenu(TokFile, ResHeader, pMenuHdr);
  372. }
  373. if (fBuildRes == TRUE) {
  374. PutMenu(OutResFile, TokFile, ResHeader, pMenuHdr);
  375. }
  376. ClearMenu(pMenuHdr);
  377. break;
  378. case ID_RT_STRING:
  379. pStrHdr = GetString(InResFile, (DWORD *)&ResHeader.lSize);
  380. if (fBuildTok == TRUE) {
  381. TokString(TokFile, ResHeader, pStrHdr);
  382. }
  383. if (fBuildRes == TRUE) {
  384. PutStrHdr(OutResFile, TokFile, ResHeader, pStrHdr);
  385. }
  386. ClearString(pStrHdr);
  387. break;
  388. #ifdef RLRES32
  389. #ifndef CAIRO
  390. // we currently only do Error tables under NT,
  391. // under CAIRO we ignore them
  392. case ID_RT_ERRTABLE: //... NT-specific Message Table resource
  393. pResMsgData = GetResMessage(InResFile, (DWORD *)&ResHeader.lSize);
  394. if (! pResMsgData) {
  395. QuitT( IDS_ENGERR_13, (LPTSTR)IDS_MSGRESTBL, NULL);
  396. }
  397. if (fBuildTok == TRUE) {
  398. TokResMessage(TokFile, ResHeader, pResMsgData);
  399. }
  400. if (fBuildRes == TRUE) {
  401. PutResMessage(OutResFile, TokFile, ResHeader, pResMsgData);
  402. }
  403. ClearResMsg( &pResMsgData);
  404. break;
  405. #endif
  406. #endif
  407. #ifndef CAIRO
  408. case ID_RT_VERSION:
  409. {
  410. WORD wRead = 0;
  411. wRead = GetResVer(InResFile,
  412. (DWORD *)&ResHeader.lSize,
  413. &VerHdr,
  414. &pVerBlk);
  415. #ifdef RLRES32
  416. if (wRead == (WORD)-1)
  417. #else
  418. if (wRead == FALSE)
  419. #endif
  420. {
  421. QuitT( IDS_ENGERR_14, (LPTSTR)IDS_VERBLOCK, NULL);
  422. }
  423. // Building Tok file ?
  424. // but only tokenize it if it contains a Version Block
  425. if ( pVerBlk && fBuildTok == TRUE ) {
  426. #ifdef RLRES32
  427. TokResVer( TokFile, ResHeader, pVerBlk, wRead);
  428. #else
  429. TokResVer( TokFile, ResHeader, pVerBlk);
  430. #endif
  431. }
  432. // Building Res file ?
  433. if ( fBuildRes == TRUE ) {
  434. PutResVer( OutResFile, TokFile, ResHeader,&VerHdr, pVerBlk);
  435. }
  436. RLFREE( pVerBlk);
  437. }
  438. break;
  439. #else
  440. case ID_RT_VERSION:
  441. #endif
  442. case ID_RT_CURSOR:
  443. case ID_RT_BITMAP:
  444. case ID_RT_ICON:
  445. case ID_RT_FONTDIR:
  446. case ID_RT_FONT:
  447. case ID_RT_RCDATA:
  448. #ifndef RLRES32
  449. case ID_RT_ERRTABLE: //... NT-specific Message Table resourc
  450. #endif
  451. case ID_RT_GROUP_CURSOR:
  452. case ID_RT_GROUP_ICON:
  453. case ID_RT_NAMETABLE:
  454. default:
  455. if (GetCustomResource(InResFile,
  456. (DWORD *)&ResHeader.lSize,
  457. &pCustomResource,
  458. ResHeader)) {
  459. // Non localized resource type, skip or copy it
  460. if (fBuildTok == TRUE) {
  461. if ( gbShowWarnings
  462. && ( ResHeader.wTypeID == ID_RT_RCDATA
  463. || ResHeader.wTypeID > 16) ) {
  464. static CHAR szType[256];
  465. static CHAR szName[256];
  466. if ( ResHeader.bTypeFlag == IDFLAG )
  467. sprintf( szType, "%u", ResHeader.wTypeID);
  468. else {
  469. _WCSTOMBS( &szType[1], ResHeader.pszType, sizeof( szType), (UINT)-1);
  470. szType[0] = '\"';
  471. szType[ lstrlenA( szType)] = '\"';
  472. }
  473. if ( ResHeader.bNameFlag == IDFLAG )
  474. sprintf( szName, "%u", ResHeader.wNameID);
  475. else {
  476. _WCSTOMBS( &szName[1], ResHeader.pszName, sizeof( szName), (UINT)-1);
  477. szName[0] = '\"';
  478. szName[ lstrlenA( szName)] = '\"';
  479. }
  480. ShowEngineErr( IDS_UNK_CUST_RES, (void *)szType, (void *)szName);
  481. }
  482. SkipBytes(InResFile, (DWORD *)&ResHeader.lSize);
  483. } else if ( fBuildRes ) {
  484. CopyRes( InResFile, OutResFile, &ResHeader, &ResSizePos);
  485. }
  486. } else {
  487. if (fBuildTok == TRUE) {
  488. TokCustomResource(TokFile, ResHeader, &pCustomResource);
  489. }
  490. if (fBuildRes == TRUE) {
  491. PutCustomResource(OutResFile,
  492. TokFile,
  493. ResHeader,
  494. &pCustomResource);
  495. }
  496. ClearCustomResource(&pCustomResource);
  497. }
  498. #ifdef RLRES32
  499. DWordUpFilePointer(InResFile, MYREAD, ftell(InResFile), NULL);
  500. if (OutResFile != NULL) {
  501. DWordUpFilePointer(OutResFile,
  502. MYWRITE,
  503. ftell(OutResFile),
  504. NULL);
  505. }
  506. #endif
  507. break;
  508. } //... END SWITCH
  509. #ifndef RLRES32
  510. // skip any extra bytes (Win 3.1 exes have
  511. // alot of extra stuff!).
  512. // No extra stuff in res extracted from NT exes
  513. SkipBytes(InResFile, (DWORD *)&ResHeader.lSize);
  514. #endif
  515. ClearResHeader(ResHeader);
  516. #ifdef RLRES32
  517. DWordUpFilePointer(InResFile, MYREAD, ftell(InResFile), NULL);
  518. if (OutResFile != NULL) {
  519. DWordUpFilePointer(OutResFile, MYWRITE, ftell(OutResFile), NULL);
  520. }
  521. #endif
  522. } // END while ( ! feof( InResFile)
  523. return 0;
  524. }
  525. /**
  526. *
  527. *
  528. * Function:ClearAccelTable
  529. * Removes the accelerator table array from memory.
  530. *
  531. * Arguments:
  532. * pAccelTable, pointer to arary of accelerators
  533. * wctablesEntries, number of accelerators in arrary
  534. *
  535. * Returns:
  536. * NA.
  537. *
  538. * Errors Codes:
  539. * NA.
  540. *
  541. * History:
  542. * 7/91, Implemented Terryru
  543. *
  544. *
  545. **/
  546. void ClearAccelTable(ACCELTABLEENTRY *pAccelTable, WORD wcTableEntries)
  547. {
  548. RLFREE( pAccelTable);
  549. }
  550. /**
  551. *
  552. *
  553. * Function: ClearDialog
  554. * Remove Dialog defintions from memory.
  555. *
  556. * Arguments:
  557. * pDilaogHdr, Linked list of dialog information.
  558. *
  559. * Returns:
  560. * NA.
  561. *
  562. * Errors Codes:
  563. * NA.
  564. *
  565. * History:
  566. * 7/91, Implemented TerryRu
  567. *
  568. *
  569. **/
  570. void ClearDialog (DIALOGHEADER * pDialogHdr)
  571. {
  572. BYTE i;
  573. for (i = 0; i < (BYTE) pDialogHdr->wNumberOfItems; i ++) {
  574. if (pDialogHdr->pCntlData[i].pszClass) {
  575. RLFREE( pDialogHdr->pCntlData[i].pszClass);
  576. }
  577. if ( pDialogHdr->pCntlData[i].pExtraStuff ) {
  578. RLFREE( pDialogHdr->pCntlData[i].pExtraStuff );
  579. }
  580. RLFREE( pDialogHdr->pCntlData[i].pszDlgText);
  581. }
  582. // now RLFREE fields in dialog header
  583. RLFREE( pDialogHdr->pszDlgClass);
  584. RLFREE( pDialogHdr->pszFontName);
  585. RLFREE( pDialogHdr->pszDlgMenu);
  586. RLFREE( pDialogHdr->pszCaption);
  587. RLFREE( pDialogHdr->pCntlData);
  588. // and finally clear header
  589. RLFREE( pDialogHdr);
  590. }
  591. /**
  592. *
  593. *
  594. * Function: ClearMenu
  595. * Removes Menu defintions from memory.
  596. *
  597. * Arguments:
  598. * pMenuHdr, linked list of Menu info
  599. *
  600. * Returns:
  601. * NA.
  602. *
  603. * Errors Codes:
  604. * NA.
  605. *
  606. * History:
  607. * 7/91, Implemented. TerryRu
  608. *
  609. *
  610. **/
  611. void ClearMenu(MENUHEADER *pMenuHdr)
  612. {
  613. MENUITEM *pMenuItem;
  614. MENUITEM *pMenuHead;
  615. pMenuItem = pMenuHead = pMenuHdr->pMenuItem;
  616. // remove all the menu items from the list
  617. while (pMenuItem) {
  618. pMenuItem = pMenuHead->pNextItem;
  619. RLFREE( pMenuHead->szItemText);
  620. RLFREE( pMenuHead);
  621. pMenuHead = pMenuItem;
  622. }
  623. // now remove the menuheader
  624. if (pMenuHdr->pExtraStuff)
  625. RLFREE( pMenuHdr->pExtraStuff );
  626. RLFREE( pMenuHdr);
  627. }
  628. /**
  629. *
  630. *
  631. * Function: ClearResHeader
  632. * Remove resheader name, and type fields from memory.
  633. *
  634. * Arguments:
  635. * ResHdr, structure containing resheader info.
  636. *
  637. * Returns:
  638. * NA.
  639. *
  640. * Errors Codes:
  641. * NA.
  642. *
  643. * History:
  644. * 7/91, Implemented TerryRu.
  645. *
  646. *
  647. **/
  648. void ClearResHeader(RESHEADER ResHdr)
  649. {
  650. RLFREE( ResHdr.pszType);
  651. RLFREE( ResHdr.pszName);
  652. }
  653. /**
  654. *
  655. *
  656. * Function: ClearString
  657. * Removes the StringTable Defintions from memory.
  658. *
  659. * Arguments:
  660. * pStrHdr, pointer to array of 16 string tables.
  661. *
  662. * Returns:
  663. * NA.
  664. *
  665. * Errors Codes:
  666. * NA.
  667. *
  668. * History:
  669. * 7/91, Implemented. TerryRu
  670. *
  671. *
  672. **/
  673. void ClearString( STRINGHEADER *pStrHdr)
  674. {
  675. BYTE i;
  676. for (i = 0; i < 16; i++) {
  677. RLFREE( pStrHdr->pszStrings[i]);
  678. }
  679. RLFREE( pStrHdr);
  680. }
  681. /**
  682. *
  683. *
  684. * Function: quit
  685. * quit, Error Handling routine used to display error code and terminate program
  686. *
  687. * Arguments:
  688. * error, number of error.
  689. * pszError, descriptive error message.
  690. *
  691. * Returns:
  692. * NA.
  693. *
  694. * Errors Codes:
  695. *
  696. *
  697. * History:
  698. * 7/91, Implemented TerryRu
  699. * 10/91, Hacked to work under windows TerryRu
  700. * ??? Need to add better win/dos support
  701. *
  702. **/
  703. void QuitA( int error, LPSTR pszArg1, LPSTR pszArg2)
  704. {
  705. char szErrStr1[2048] = "*?*";
  706. char szErrStr2[2048] = "*?*";
  707. char *psz1 = pszArg1;
  708. char *psz2 = pszArg2;
  709. //... clean up after error and exit,
  710. //... returning error code
  711. _fcloseall();
  712. if ( pszArg1 != NULL && pszArg1 <= (LPSTR)0x0000ffff ) {
  713. B_FormatMessage( (FORMAT_MESSAGE_MAX_WIDTH_MASK & 78)
  714. | FORMAT_MESSAGE_IGNORE_INSERTS
  715. | FORMAT_MESSAGE_FROM_HMODULE,
  716. NULL,
  717. (DWORD)(DWORD_PTR)pszArg1,
  718. szErrStr1,
  719. sizeof( szErrStr1),
  720. NULL);
  721. psz1 = szErrStr1;
  722. }
  723. if ( pszArg2 != NULL && pszArg2 < (LPSTR)0x0000ffff ) {
  724. B_FormatMessage( (FORMAT_MESSAGE_MAX_WIDTH_MASK & 78)
  725. | FORMAT_MESSAGE_IGNORE_INSERTS
  726. | FORMAT_MESSAGE_FROM_HMODULE,
  727. NULL,
  728. (DWORD)(DWORD_PTR)pszArg2,
  729. szErrStr2,
  730. sizeof( szErrStr2),
  731. NULL);
  732. psz2 = szErrStr2;
  733. }
  734. ShowEngineErr( error, psz1, psz2);
  735. FreeLangList();
  736. #ifdef _DEBUG
  737. FreeMemList( NULL);
  738. #endif // _DEBUG
  739. DoExit( (error == 4) ? 0 : error);
  740. }
  741. #ifdef UNICODE
  742. /* Handles errors, in UNICODE environments*/
  743. LPSTR MakeMBMsgW(
  744. LPWSTR pszArg, //... Msg ID# or msg text
  745. LPSTR szBuf, //... Buffer for converted msg
  746. USHORT usBufLen) //... #bytes in szBuf
  747. {
  748. char *pszRet = NULL;
  749. if ( pszArg ) {
  750. if ( pszArg >= (LPTSTR)0x0400 ) {
  751. _WCSTOMBS( szBuf,
  752. (WCHAR *)pszArg,
  753. usBufLen,
  754. lstrlen( pszArg ) + 1 );
  755. } else {
  756. B_FormatMessage( (FORMAT_MESSAGE_MAX_WIDTH_MASK & 78)
  757. | FORMAT_MESSAGE_IGNORE_INSERTS
  758. | FORMAT_MESSAGE_FROM_HMODULE,
  759. NULL,
  760. (DWORD)(DWORD_PTR)pszArg,
  761. szBuf,
  762. usBufLen,
  763. NULL);
  764. }
  765. pszRet = szBuf;
  766. }
  767. return ( pszRet);
  768. }
  769. //...............................................................
  770. void QuitW( int error, LPWSTR pszArg1, LPWSTR pszArg2)
  771. {
  772. char szErrStr1[2048] = "*?*";
  773. char szErrStr2[2048] = "*?*";
  774. QuitA( error,
  775. MakeMBMsgW( pszArg1, szErrStr1, sizeof( szErrStr1)),
  776. MakeMBMsgW( pszArg2, szErrStr2, sizeof( szErrStr2)));
  777. }
  778. #endif
  779. /**
  780. *
  781. *
  782. * Function: GetAccelTable,
  783. * Reads the Accelerator key defintions from the resource file
  784. *
  785. * Arguments:
  786. * InResFile, Handle to Resource file.
  787. * pwcTableEntries, pointer to an array of accelerator key defintions.
  788. * plSize, address of size of Resource.
  789. *
  790. * Returns:
  791. * pwcTableEntries containing all the key defintions.
  792. *
  793. * Errors Codes:
  794. *
  795. * History:
  796. * 8/91 Implemented TerryRu
  797. * 4/92 Added RLRES32 support TerryRu
  798. *
  799. *
  800. *
  801. **/
  802. ACCELTABLEENTRY * GetAccelTable(FILE *InResFile,
  803. WORD *pwcTableEntries,
  804. DWORD *plSize)
  805. {
  806. ACCELTABLEENTRY *pAccelTable;
  807. BOOL quit = FALSE;
  808. // need to use sizeof operator in memory
  809. // allocation because of structure packing.
  810. *pwcTableEntries = (WORD) 0;
  811. pAccelTable = (ACCELTABLEENTRY *) FALLOC( ((WORD)*plSize * sizeof( WORD)));
  812. while (*plSize && !quit) {
  813. #ifdef RLRES32
  814. pAccelTable[ *pwcTableEntries].fFlags = (WORD) GetWord( InResFile,
  815. plSize);
  816. #else
  817. pAccelTable[ *pwcTableEntries].fFlags = (BYTE) GetByte( InResFile,
  818. plSize);
  819. #endif
  820. pAccelTable[*pwcTableEntries].wAscii = GetWord (InResFile, plSize);
  821. pAccelTable[*pwcTableEntries].wID = GetWord (InResFile, plSize);
  822. #ifdef RLRES32
  823. pAccelTable[ *pwcTableEntries].wPadding = GetWord( InResFile, plSize);
  824. #endif
  825. if ( pAccelTable[ *pwcTableEntries].fFlags & HIBITVALUE ) {
  826. quit = TRUE;
  827. }
  828. ++*pwcTableEntries;
  829. }
  830. if ( (long)*plSize <= 0 ) {
  831. *plSize = 0;
  832. }
  833. return pAccelTable;
  834. }
  835. /**
  836. *
  837. *
  838. * Function: GetDialog,
  839. * Reads the dialog defintions from the res file, and places the info
  840. * into a linked list.
  841. *
  842. *
  843. * Arguments:
  844. * InResFile, Handle to input resource handle, posistioned to begining
  845. * of dialog defintion.
  846. * plSize, pointer to size in bytes of the dialog information.
  847. *
  848. * Returns:
  849. * pointer to DIALOGHEADER type containing the dialog information,
  850. *
  851. *
  852. * Errors Codes:
  853. * None ???
  854. *
  855. * History:
  856. * 12/91, Cleaned up comments. TerryRu
  857. * 04/92, Added RLRES32 support. TerryRu
  858. *
  859. *
  860. **/
  861. DIALOGHEADER *GetDialog( FILE *InResFile, DWORD * plSize)
  862. {
  863. DIALOGHEADER *pDialogHdr;
  864. TCHAR *UNALIGNED*ptr;
  865. WORD i;
  866. LONG lStartingOffset;
  867. static TCHAR szBuf[ 255];
  868. LONG lExtra;
  869. WORD j;
  870. lStartingOffset = ftell(InResFile);
  871. pDialogHdr = (DIALOGHEADER *)FALLOC( sizeof( DIALOGHEADER));
  872. // lstyle
  873. pDialogHdr->lStyle = GetdWord(InResFile, plSize);
  874. #ifdef RLRES32
  875. pDialogHdr->fDialogEx = (HIWORD(pDialogHdr->lStyle)==0xffff);
  876. if (pDialogHdr->fDialogEx) {
  877. pDialogHdr->wDlgVer = LOWORD(pDialogHdr->lStyle);
  878. pDialogHdr->wSignature = HIWORD(pDialogHdr->lStyle);
  879. pDialogHdr->dwHelpID = GetdWord(InResFile, plSize);
  880. pDialogHdr->lExtendedStyle = GetdWord(InResFile, plSize);
  881. pDialogHdr->lStyle = GetdWord(InResFile, plSize);
  882. } else {
  883. pDialogHdr->lExtendedStyle = GetdWord(InResFile, plSize);
  884. }
  885. pDialogHdr->wNumberOfItems = GetWord(InResFile, plSize);
  886. #else
  887. pDialogHdr->wNumberOfItems = (BYTE) GetByte(InResFile, plSize);
  888. #endif
  889. // allocate space to hold wNumberOfItems of pointers
  890. // to Control Data structures
  891. pDialogHdr->pCntlData = (CONTROLDATA *)
  892. FALLOC( pDialogHdr->wNumberOfItems * sizeof( CONTROLDATA));
  893. // read x, y, cx, cy dialog cordinates
  894. pDialogHdr->x = GetWord(InResFile, plSize);
  895. pDialogHdr->y = GetWord(InResFile, plSize);
  896. pDialogHdr->cx = GetWord(InResFile, plSize);
  897. pDialogHdr->cy = GetWord(InResFile, plSize);
  898. //... Dialog Menu Name
  899. GetNameOrd( InResFile,
  900. (BOOL UNALIGNED *)&pDialogHdr->bMenuFlag, // 9/11/91 (PW)
  901. (WORD UNALIGNED *)&pDialogHdr->wDlgMenuID,
  902. (TCHAR *UNALIGNED*)&pDialogHdr->pszDlgMenu,
  903. plSize);
  904. //... Dialog Class Name
  905. GetNameOrd( InResFile,
  906. (BOOL UNALIGNED *)&pDialogHdr->bClassFlag, // 9/11/91 (PW)
  907. (WORD UNALIGNED *)&pDialogHdr->wDlgClassID,
  908. (TCHAR *UNALIGNED*)&pDialogHdr->pszDlgClass,
  909. plSize);
  910. // Dialog caption name
  911. GetName( InResFile, szBuf, plSize);
  912. ptr = (TCHAR *UNALIGNED*)&pDialogHdr->pszCaption;
  913. AllocateName( *ptr, szBuf);
  914. lstrcpy( (TCHAR *)*ptr, (TCHAR *)szBuf);
  915. // does dialog define a font.
  916. if ( pDialogHdr->lStyle & DS_SETFONT ) {
  917. // extract this info.
  918. pDialogHdr->wPointSize = GetWord( InResFile, plSize);
  919. if (pDialogHdr->fDialogEx) {
  920. pDialogHdr->wWeight = GetWord( InResFile, plSize);
  921. pDialogHdr->wItalic = GetWord( InResFile, plSize);
  922. }
  923. GetName( InResFile, szBuf, plSize);
  924. ptr = (TCHAR *UNALIGNED*)&pDialogHdr->pszFontName;
  925. AllocateName(*ptr, szBuf);
  926. lstrcpy( (TCHAR *)*ptr, (TCHAR *)szBuf);
  927. } else {
  928. pDialogHdr->pszFontName = (TCHAR*)FALLOC( 0);
  929. }
  930. #ifdef RLRES32
  931. DWordUpFilePointer( InResFile, MYREAD, ftell(InResFile), plSize);
  932. #endif
  933. //... read each dialog control
  934. for (i = 0; i < pDialogHdr->wNumberOfItems ; i++) {
  935. #ifdef RLRES32
  936. if (pDialogHdr->fDialogEx) {
  937. pDialogHdr->pCntlData[i].dwHelpID = GetdWord(InResFile, plSize);
  938. pDialogHdr->pCntlData[i].lExtendedStyle = GetdWord(InResFile, plSize);
  939. pDialogHdr->pCntlData[i].lStyle = GetdWord(InResFile, plSize);
  940. } else {
  941. pDialogHdr->pCntlData[i].lStyle = GetdWord(InResFile, plSize);
  942. pDialogHdr->pCntlData[i].lExtendedStyle = GetdWord(InResFile, plSize);
  943. }
  944. #endif // RLRES32
  945. pDialogHdr->pCntlData[i].x = GetWord(InResFile, plSize);
  946. pDialogHdr->pCntlData[i].y = GetWord(InResFile, plSize);
  947. pDialogHdr->pCntlData[i].cx = GetWord(InResFile, plSize);
  948. pDialogHdr->pCntlData[i].cy = GetWord(InResFile, plSize);
  949. // wId
  950. if (pDialogHdr->fDialogEx)
  951. pDialogHdr->pCntlData[i].dwID = GetdWord (InResFile, plSize);
  952. else
  953. pDialogHdr->pCntlData[i].dwID = (DWORD)GetWord (InResFile, plSize);
  954. #ifdef RLRES16
  955. // lStyle
  956. pDialogHdr->pCntlData[i].lStyle = GetdWord(InResFile, plSize);
  957. pDialogHdr->pCntlData[i].bClass = (BYTE) GetByte(InResFile, plSize);
  958. // does dialog have a class?
  959. if (!(pDialogHdr->pCntlData[i].bClass & 0x80)) {
  960. GetName(InResFile, szBuf, plSize);
  961. ptr = &pDialogHdr->pCntlData[i].pszClass;
  962. AllocateName(*ptr, szBuf);
  963. lstrcpy ((TCHAR *)*ptr, (TCHAR *)szBuf);
  964. } else {
  965. pDialogHdr->pCntlData[i].pszClass = NULL;
  966. }
  967. #else
  968. GetNameOrd (InResFile,
  969. (BOOL UNALIGNED *)&pDialogHdr->pCntlData[i].bClass_Flag, // 9/11/91 (PW)
  970. (WORD UNALIGNED *)&pDialogHdr->pCntlData[i].bClass,
  971. (TCHAR *UNALIGNED*)&pDialogHdr->pCntlData[i].pszClass,
  972. plSize);
  973. #endif
  974. GetNameOrd (InResFile,
  975. (BOOL UNALIGNED *)&pDialogHdr->pCntlData[i].bID_Flag, // 9/11/91 (PW)
  976. (WORD UNALIGNED *)&pDialogHdr->pCntlData[i].wDlgTextID,
  977. (TCHAR *UNALIGNED*)&pDialogHdr->pCntlData[i].pszDlgText,
  978. plSize);
  979. #ifdef RLRES16
  980. pDialogHdr->pCntlData[i].unDefined = (BYTE) GetByte(InResFile, plSize);
  981. #else
  982. pDialogHdr->pCntlData[i].wExtraStuff = (WORD) GetWord(InResFile, plSize);
  983. if (pDialogHdr->fDialogEx && pDialogHdr->pCntlData[i].wExtraStuff) {
  984. lExtra = pDialogHdr->pCntlData[i].wExtraStuff;
  985. j = 0;
  986. pDialogHdr->pCntlData[i].pExtraStuff = (BYTE *)FALLOC( pDialogHdr->pCntlData[i].wExtraStuff );
  987. while ( lExtra-- )
  988. pDialogHdr->pCntlData[i].pExtraStuff[j++] = GetByte( InResFile, plSize );
  989. } else
  990. pDialogHdr->pCntlData[i].pExtraStuff = NULL;
  991. #endif // RLRES16
  992. #ifdef RLRES32
  993. DWordUpFilePointer( InResFile, MYREAD, ftell(InResFile), plSize);
  994. #endif // RLRES32
  995. }
  996. // watch for overflow of plsize
  997. if ((long) *plSize <= 0) {
  998. *plSize = 0;
  999. }
  1000. return (pDialogHdr);
  1001. }
  1002. /**
  1003. *
  1004. *
  1005. * Function: GetResMenu,
  1006. * Reads the Menu defintions from the resrouce file, and insert the info
  1007. * into a linked list..
  1008. *
  1009. * Arguments:
  1010. * InResFile, Input res handle, positioned at being of Menu Definition.
  1011. * lSize, pointer to size of Menu Defintion.
  1012. * pMenuHeader, pointer to structure to contain menu info.
  1013. *
  1014. * Returns:
  1015. * pMenuHeader containing linkd list of Menu info.
  1016. *
  1017. * Errors Codes:
  1018. * None.
  1019. *
  1020. * History:
  1021. * 7/91, implemented Terryru
  1022. * 12/91, cleaned up comments Terryru
  1023. * 4/92, Added PDK2 support Terryru
  1024. * 4/92, Added RLRES32 support Terryru
  1025. *
  1026. **/
  1027. void GetResMenu(FILE *InResFile, DWORD *lSize , MENUHEADER *pMenuHeader)
  1028. {
  1029. static TCHAR szItemText[255];
  1030. BOOL fStart = TRUE;
  1031. BOOL fQuit = FALSE;
  1032. LONG lExtra = 0;
  1033. WORD i = 0;
  1034. WORD wPopItems = 0, wMenuID = 0;
  1035. MENUITEM * pcMenuItem;
  1036. TCHAR *UNALIGNED*ptr;
  1037. WORD wNestingLevel = 0;
  1038. WORD wFlags;
  1039. LONG lStartingOffset; // used to dword align file
  1040. lStartingOffset = ftell(InResFile);
  1041. pMenuHeader->wVersion = GetWord(InResFile, lSize);
  1042. pMenuHeader->cbHeaderSize = GetWord(InResFile, lSize);
  1043. pMenuHeader->fMenuEx = (pMenuHeader->wVersion == 1);
  1044. if (pMenuHeader->fMenuEx && pMenuHeader->cbHeaderSize) {
  1045. lExtra = pMenuHeader->cbHeaderSize;
  1046. pMenuHeader->pExtraStuff = (BYTE *)FALLOC( pMenuHeader->cbHeaderSize );
  1047. while ( lExtra-- )
  1048. pMenuHeader->pExtraStuff[i++] = GetByte( InResFile, lSize);
  1049. } else
  1050. pMenuHeader->pExtraStuff = NULL;
  1051. // add all the items to the list
  1052. while ( (((signed long) *lSize) >= 0) && !fQuit) {
  1053. if (fStart) {
  1054. // start the menu item list
  1055. pcMenuItem = pMenuHeader->pMenuItem =
  1056. (MENUITEM *)FALLOC( sizeof( MENUITEM));
  1057. pcMenuItem->pNextItem = NULL;
  1058. fStart = FALSE;
  1059. } else {
  1060. // add space to the menu list
  1061. // allocate space for next Item
  1062. pcMenuItem->pNextItem = (MENUITEM *)FALLOC (sizeof( MENUITEM));
  1063. pcMenuItem = pcMenuItem->pNextItem;
  1064. pcMenuItem->pNextItem = NULL;
  1065. }
  1066. if (pMenuHeader->fMenuEx) {
  1067. pcMenuItem->dwType = GetdWord( InResFile, lSize);
  1068. pcMenuItem->dwState = GetdWord( InResFile, lSize);
  1069. pcMenuItem->dwMenuID = GetdWord( InResFile, lSize);
  1070. pcMenuItem->fItemFlags = wFlags = GetWord(InResFile,lSize); // read type of menu item
  1071. if ( (wFlags & MFR_POPUP) ) {
  1072. wFlags &= ~MFR_POPUP; // Normalize the menu
  1073. wFlags |= MF_POPUP;
  1074. }
  1075. //pcMenuItem->fItemFlags = wFlags;
  1076. } else {
  1077. wFlags = GetWord(InResFile,lSize); // read type of menu item
  1078. pcMenuItem->fItemFlags = wFlags;
  1079. // is it a popup?
  1080. if ( ! (pcMenuItem->fItemFlags & POPUP) ) {
  1081. pcMenuItem->dwMenuID = (DWORD)GetWord( InResFile, lSize);
  1082. }
  1083. }
  1084. GetName( InResFile, szItemText, lSize);
  1085. ptr = (TCHAR *UNALIGNED*)&pcMenuItem->szItemText;
  1086. * ptr = (TCHAR *)FALLOC( MEMSIZE( lstrlen( szItemText) + 1));
  1087. lstrcpy( (TCHAR *)*ptr, (TCHAR *)szItemText);
  1088. if (pMenuHeader->fMenuEx) {
  1089. DWordUpFilePointer( InResFile, MYREAD, ftell(InResFile), lSize);
  1090. if ( (wFlags & POPUP) ) {
  1091. pcMenuItem->dwHelpID = GetdWord( InResFile, lSize);
  1092. }
  1093. }
  1094. if (wFlags & POPUP) {
  1095. ++wNestingLevel;
  1096. }
  1097. if (wFlags & ENDMENU) {
  1098. if (wNestingLevel) {
  1099. --wNestingLevel;
  1100. } else {
  1101. fQuit = TRUE;
  1102. }
  1103. }
  1104. }
  1105. #ifdef RLRES32
  1106. WordUpFilePointer( InResFile,
  1107. MYREAD,
  1108. lStartingOffset,
  1109. ftell( InResFile), lSize);
  1110. #endif
  1111. }
  1112. int MyEOF(FILE *fPtr)
  1113. {
  1114. #ifdef RLRES32
  1115. LONG lCurOffset;
  1116. LONG lEndOffset;
  1117. lCurOffset = ftell(fPtr);
  1118. lEndOffset = fseek(fPtr, SEEK_END, 0);
  1119. // reset file pointer
  1120. fseek( fPtr, lCurOffset, SEEK_SET);
  1121. return ((lEndOffset - lCurOffset) < sizeof (DWORD));
  1122. #else
  1123. return ( feof(fPtr));
  1124. #endif
  1125. }
  1126. void WordUpFilePointer(FILE *fPtr,
  1127. BOOL bMode,
  1128. LONG lStartingOffset,
  1129. LONG lCurrentOffset ,
  1130. LONG *plPos)
  1131. {
  1132. LONG lDelta;
  1133. LONG lOffset;
  1134. char buffer[]="\0\0\0\0\0\0\0\0";
  1135. lDelta = lCurrentOffset - lStartingOffset ;
  1136. lOffset = WORDUPOFFSET( lDelta);
  1137. if ( bMode == MYREAD ) {
  1138. fseek( fPtr, lOffset , SEEK_CUR);
  1139. *plPos -= lOffset;
  1140. } else {
  1141. fwrite( buffer, 1, (size_t) lOffset, fPtr);
  1142. *plPos += lOffset;
  1143. }
  1144. }
  1145. void DWordUpFilePointer(
  1146. FILE *fPtr,
  1147. BOOL bMode,
  1148. LONG lCurrentOffset,
  1149. DWORD *plPos) //... New file position
  1150. {
  1151. LONG lOffset;
  1152. lOffset = DWORDUPOFFSET( lCurrentOffset);
  1153. if ( bMode == MYREAD ) {
  1154. fseek( fPtr, lOffset, SEEK_CUR);
  1155. if ( plPos != NULL ) {
  1156. *plPos -= lOffset;
  1157. }
  1158. } else {
  1159. char buffer[]="\0\0\0\0\0\0\0";
  1160. fwrite( buffer, 1, (size_t)lOffset, fPtr);
  1161. if ( plPos != NULL ) {
  1162. *plPos += lOffset;
  1163. }
  1164. }
  1165. }
  1166. //
  1167. // Function: FilterRes, Public
  1168. //
  1169. // Synopsis: Determine whether the resource type is to be filtered
  1170. // The non filtered resource are OR together, thus several
  1171. // resource types can pass through the filter. Zero indicates
  1172. // no resources are to be filterd, 0xFFFF indicates to not filter
  1173. // custom resource.
  1174. //
  1175. //
  1176. // Arguments: [wFilter] Indicates the resources which we are to pass thru.
  1177. // [pRes] Ptr to Resource header struct
  1178. //
  1179. //
  1180. // Effects:
  1181. //
  1182. // Returns: TRUE Skip the current resource
  1183. // FALSE Use the current resource
  1184. //
  1185. // Modifies:
  1186. //
  1187. // History:
  1188. // 18-Oct-92 Created TerryRu
  1189. //
  1190. //
  1191. // Notes:
  1192. //
  1193. BOOL FilterRes( WORD wFilter, RESHEADER *pRes)
  1194. {
  1195. WORD wCurRes;
  1196. wCurRes = pRes->wTypeID;
  1197. if ( wFilter == 0 ) {
  1198. return ( FALSE);
  1199. }
  1200. if ( wCurRes == 0 ) {
  1201. return ( FALSE);
  1202. }
  1203. // check for special case for custom resources
  1204. if ( wFilter == (WORD)0xFFFF ) {
  1205. if ( wCurRes > 16) {
  1206. return ( FALSE);
  1207. } else {
  1208. return ( TRUE);
  1209. }
  1210. }
  1211. return ( ! (wFilter == wCurRes));
  1212. }
  1213. /**
  1214. *
  1215. *
  1216. * Function: GetResVer
  1217. *
  1218. * Extracts the version stamping information that
  1219. * requires loclization from the resource file. The resource
  1220. * information is containd is a USER defined resource
  1221. * (ID = 16, Type = 1).
  1222. *
  1223. * The resource block format:
  1224. * WORD wTotLen
  1225. * WORD wValLen
  1226. * BYTE szKey
  1227. * BYTE szVal
  1228. *
  1229. * All information in the version stampling is contained in
  1230. * repeating patters of this block type. All Key, and Value
  1231. * fields are padded to start on DWORD boundaries. The
  1232. * padding necessary to allign the blocks is not included in
  1233. * the wTotLen field, but the padding to allign the fields inside
  1234. * the block is.
  1235. *
  1236. * The following information in the Resource block needs to be
  1237. * tokenized:
  1238. *
  1239. *
  1240. * Key Field in StringFileInfo Block
  1241. * Value Fields in StringFileInfo String Blocks.
  1242. * Code Page and Language ID Fields of VarFileInfo
  1243. * Standard Var Blocks.
  1244. *
  1245. * By defintion, any value string contained in the String requires
  1246. * in be localized. It is assumed that there will be two
  1247. * StringFileInfo Blocks in each international resource. The first
  1248. * one, is to remain in English, while the second Block, is to be
  1249. * localized in the language specified by the StingFileInfo Key Field.
  1250. * The VarFileInfo Code Page and Language ID Fields localized to
  1251. * indicate which StringFileInfo block the file supports.
  1252. *
  1253. *
  1254. * Arguments:
  1255. * FILE *InResFile
  1256. * File to extracte version stamping from
  1257. *
  1258. * DWORD *lSize
  1259. * Size of version stamping information
  1260. *
  1261. * VERHEADER *pVerHeader
  1262. * pointer to structure to contain parsed version info.
  1263. *
  1264. * Returns:
  1265. *
  1266. * pVerHead Buffer contain version stamping resource
  1267. * pVerBlock starting location of children blocks
  1268. *
  1269. * Errors Codes:
  1270. * TRUE, Read of Resource sucessfull.
  1271. * FALSE, Read of Resource failed.
  1272. *
  1273. * History:
  1274. *
  1275. * 11/91. Created TerryRu.
  1276. * 10/92. Added Support for NULL Version Blocks TerryRu
  1277. * 10/92. Added RLRES32 version DaveWi
  1278. **/
  1279. #ifdef RLRES32
  1280. WORD GetResVer(
  1281. FILE *InResFile,
  1282. DWORD *plSize,
  1283. VERHEAD *pVerHead,
  1284. VERBLOCK **pVerBuf)
  1285. {
  1286. WORD wVerHeadSize;
  1287. WORD wcRead;
  1288. *pVerBuf = NULL;
  1289. //... Read the fixed info that will not change
  1290. wVerHeadSize = (WORD)(3 * sizeof(WORD)
  1291. + MEMSIZE( lstrlen( TEXT( "VS_VERSION_INFO")) + 1)
  1292. + sizeof( VS_FIXEDFILEINFO));
  1293. wVerHeadSize = DWORDUP(wVerHeadSize);
  1294. if ( ResReadBytes( InResFile,
  1295. (CHAR *)pVerHead,
  1296. (size_t)wVerHeadSize,
  1297. plSize) == FALSE ) {
  1298. return ( (WORD)-1);
  1299. }
  1300. //... check for the special case where
  1301. //... there is no version block.
  1302. if ( wVerHeadSize >= pVerHead->wTotLen) {
  1303. return ( 0);
  1304. }
  1305. //... Version header information read okay
  1306. //... so make a buffer for the rest of the res.
  1307. *pVerBuf = (VERBLOCK *)FALLOC( DWORDUP( pVerHead->wTotLen) - wVerHeadSize);
  1308. //... Now Read Value Information
  1309. wcRead = DWORDUP( pVerHead->wTotLen) - wVerHeadSize;
  1310. return ( ResReadBytes( InResFile,
  1311. (CHAR *)*pVerBuf,
  1312. (size_t)wcRead,
  1313. plSize) == FALSE ? (WORD)-1 : wcRead);
  1314. }
  1315. #else //... RLRES32
  1316. BOOL GetResVer(
  1317. FILE *InResFile,
  1318. DWORD *plSize,
  1319. VERHEAD *pVerHead,
  1320. VERBLOCK **pVerBuf)
  1321. {
  1322. size_t wcRead = sizeof( VERHEAD);
  1323. if ( ResReadBytes( InResFile, (CHAR *) pVerHead, wcRead, plSize) == FALSE ) {
  1324. return ( FALSE);
  1325. }
  1326. // check for the special case where there is no version block
  1327. if ( (size_t)pVerHead->wTotLen == wcRead ) {
  1328. *pVerBuf = NULL;
  1329. return ( TRUE);
  1330. }
  1331. // Version header information read okay.
  1332. *pVerBuf = (VERBLOCK *)FALLOC( DWORDUP( pVerHead->wTotLen) - wcRead);
  1333. // Now Read Value Information
  1334. return ( ResReadBytes( InResFile,
  1335. (CHAR *) *pVerBuf,
  1336. (size_t)(DWORDUP( pVerHead->wTotLen) - wcRead),
  1337. plSize));
  1338. }
  1339. #endif //... RLRES32
  1340. /**
  1341. *
  1342. *
  1343. * Function: GetNameOrd
  1344. * Function to read either the string name, or ordinal number of a
  1345. * resource ID. If the ID begins with a 0xff, the resource ID
  1346. * is a ordinal number, otherwise the ID is a string.
  1347. *
  1348. *
  1349. * Arguments:
  1350. * InResFile, File handle positioned to location of resource
  1351. * ID information.
  1352. * cFlag, pointer to flag indicating which ID type is used.
  1353. * pwID, pointer of ordinal ID number
  1354. * pszText pointer, to address of ID string.
  1355. *
  1356. * Returns:
  1357. * cFlag to indicate if ID is string or ordinal number.
  1358. * pwID, pszText containing actual ID info.
  1359. *
  1360. * Errors Codes:
  1361. *
  1362. * History:
  1363. *
  1364. * 7/91, Implemented TerryRu
  1365. * 9/91, Inserted cFlag as a indicator for ID or string PeterW
  1366. * 4/92, Added RLRES32 support TerryRu
  1367. **/
  1368. void GetNameOrd(
  1369. FILE *fpInResFile, //... File to retrieve header from
  1370. BOOL UNALIGNED*pbFlag,//... For IDFLAG or 1st byte (WORD in RLRES32) of name/ord
  1371. WORD UNALIGNED*pwID, //... For retrieved resource ID (if not a string)
  1372. TCHAR *UNALIGNED*pszText, // For retrieved resource name if it is a string
  1373. DWORD *plSize) // Keeps count of bytes read (or NULL)
  1374. {
  1375. WORD fFlag;
  1376. //... get type info
  1377. #ifdef RLRES16
  1378. fFlag = GetByte( fpInResFile, plSize);
  1379. #else
  1380. fFlag = GetWord( fpInResFile, plSize);
  1381. #endif
  1382. *pbFlag = fFlag;
  1383. if ( fFlag == IDFLAG ) {
  1384. //... field is a numbered item
  1385. #ifdef RLRES16
  1386. *pwID = GetByte( fpInResFile , plSize);
  1387. #else
  1388. *pwID = GetWord( fpInResFile , plSize);
  1389. #endif
  1390. *pszText = (TCHAR *)FALLOC( 0);
  1391. } else {
  1392. static TCHAR szBuf[ 255];
  1393. //... field is a named item.
  1394. //... put fFlag byte(s) back into stream
  1395. //... because it is part of the name.
  1396. *pwID = IDFLAG;
  1397. #ifdef RLRES16
  1398. UnGetByte( fpInResFile, (BYTE) fFlag, plSize);
  1399. #else
  1400. UnGetWord( fpInResFile, (WORD) fFlag, plSize);
  1401. #endif
  1402. GetName( fpInResFile, szBuf, plSize);
  1403. *pszText = (TCHAR *)FALLOC( MEMSIZE( lstrlen( szBuf) + 1));
  1404. lstrcpy( (TCHAR *)*pszText, (TCHAR *)szBuf);
  1405. }
  1406. }
  1407. /**
  1408. *
  1409. *
  1410. * Function: GetResHeader
  1411. * Reads the Resource Header information, and stores it in a structure.
  1412. *
  1413. * Arguments:
  1414. * InResFile, File handle positioned to location of Resource Header.
  1415. * pResHeader, pointer to Resource Header structure.
  1416. *
  1417. * Returns:
  1418. * pResHeader, containing resource header info.
  1419. * plSize, contining size of remaining resource info.
  1420. *
  1421. * Errors Codes:
  1422. * -1, Read of resource header failed.
  1423. *
  1424. * History:
  1425. * 7/91, Implemented TerryRu
  1426. * 4/92, Added RLRES32 Support Terryru
  1427. *
  1428. *
  1429. **/
  1430. int GetResHeader(
  1431. FILE *InResFile, //... File to get header from
  1432. RESHEADER UNALIGNED*pResHeader, //... buffer for the retrieved header
  1433. DWORD *plSize) //... keeps track of the bytes read from the file
  1434. {
  1435. #ifdef RLRES32
  1436. pResHeader->lSize = GetdWord( InResFile, plSize);
  1437. pResHeader->lHeaderSize = GetdWord( InResFile, plSize);
  1438. #endif
  1439. //... get name ID and type ID
  1440. GetNameOrd( InResFile,
  1441. (BOOL UNALIGNED*)&pResHeader->bTypeFlag,
  1442. (WORD UNALIGNED*)&pResHeader->wTypeID,
  1443. (TCHAR *UNALIGNED*)&pResHeader->pszType,
  1444. plSize);
  1445. GetNameOrd( InResFile,
  1446. (BOOL UNALIGNED*)&pResHeader->bNameFlag,
  1447. (WORD UNALIGNED*)&pResHeader->wNameID,
  1448. (TCHAR *UNALIGNED*)&pResHeader->pszName,
  1449. plSize);
  1450. #ifdef RLRES32
  1451. DWordUpFilePointer( InResFile, MYREAD, ftell( InResFile), plSize);
  1452. pResHeader->lDataVersion = GetdWord( InResFile, plSize);
  1453. #endif
  1454. pResHeader->wMemoryFlags = GetWord( InResFile, plSize);
  1455. #ifdef RLRES32
  1456. pResHeader->wLanguageId = GetWord( InResFile, plSize);
  1457. pResHeader->lVersion = GetdWord( InResFile, plSize);
  1458. pResHeader->lCharacteristics = GetdWord( InResFile, plSize);
  1459. #else // RLRES32
  1460. pResHeader->lSize = (DWORD)GetdWord( InResFile, plSize);
  1461. #endif // RLRES32
  1462. return ( 0);
  1463. }
  1464. /**
  1465. *
  1466. *
  1467. * Function: isdup
  1468. * Used to determine if the current dialog control id is a duplicate
  1469. * of an earlyier control id. If so, isdup returns a flag indicating the
  1470. * ID is a duplicate.
  1471. *
  1472. * Arguments:
  1473. * wcCurrent, ID of current dialog control.
  1474. * wpIdBuf, array of dialog control ID's processed so far.
  1475. * wcItems, number of ID's in wpIdBuf
  1476. *
  1477. * Returns:
  1478. * TRUE, ID is a duplicate
  1479. * FALSE, ID is not a duplicate
  1480. *
  1481. * Errors Codes:
  1482. * None.
  1483. *
  1484. * History:
  1485. * 7/91, Implemented TerryRu
  1486. *
  1487. *
  1488. **/
  1489. BOOL isdup(WORD wCurrent, WORD *wpIdBuf, WORD wcItems)
  1490. {
  1491. WORD i;
  1492. for (i = 0; i < wcItems; i++) {
  1493. if (wCurrent == wpIdBuf[i]) {
  1494. return TRUE;
  1495. }
  1496. }
  1497. return FALSE;
  1498. }
  1499. /**
  1500. *
  1501. *
  1502. * Function: ParseTokCrd
  1503. * Places dialog coordinates into a buffer.
  1504. *
  1505. * Arguments:
  1506. * pszCrd, buffer to hold dialog control cordinates.
  1507. * pwX, pwY, pwCX, pwCY, dialog control cordiantes.
  1508. *
  1509. * Returns:
  1510. * NA.
  1511. *
  1512. * Errors Codes:
  1513. * NA.
  1514. *
  1515. * History:
  1516. * 7/91, implemented TerryRu
  1517. *
  1518. *
  1519. **/
  1520. void ParseTokCrd(
  1521. TCHAR *pszCrd,
  1522. WORD UNALIGNED * pwX,
  1523. WORD UNALIGNED * pwY,
  1524. WORD UNALIGNED * pwCX,
  1525. WORD UNALIGNED * pwCY)
  1526. {
  1527. #ifdef RLRES32
  1528. int x = 0;
  1529. int y = 0;
  1530. int cx = 0;
  1531. int cy = 0;
  1532. _stscanf( pszCrd, TEXT("%d %d %d %d"), &x, &y, &cx, &cy);
  1533. *pwX = (WORD) x;
  1534. *pwY = (WORD) y;
  1535. *pwCX = (WORD) cx;
  1536. *pwCY = (WORD) cy;
  1537. #else //RLRES32
  1538. sscanf( pszCrd, "%hd %hd %hd %hd", pwX, pwY, pwCX, pwCY);
  1539. #endif //RLRES32
  1540. }
  1541. int GetAlignFromString( TCHAR *pszStr)
  1542. {
  1543. TCHAR *pStyle;
  1544. if ( !(pStyle = _tcschr( pszStr, TEXT('('))) ) {
  1545. return (-1);
  1546. }
  1547. while ( *pStyle ) {
  1548. if ( *pStyle == TEXT('L') ) {
  1549. if ( ! _tcsnicmp( pStyle, TEXT("LEFT"), 4) ) {
  1550. return (0);
  1551. }
  1552. } else if ( *pStyle == TEXT('C') ) {
  1553. if ( ! _tcsnicmp( pStyle, TEXT("CENTER"), 6)) {
  1554. return (1);
  1555. }
  1556. } else if ( *pStyle == TEXT('R') ) {
  1557. if ( ! _tcsnicmp( pStyle, TEXT("RIGHT"), 5) ) {
  1558. return (2);
  1559. }
  1560. }
  1561. pStyle++;
  1562. }
  1563. return ( -1 ); //none
  1564. }
  1565. void ParseTokCrdAndAlign(
  1566. TCHAR *pszCrd,
  1567. CONTROLDATA *pCntrl)
  1568. {
  1569. int align = 0;
  1570. if ( (pCntrl->bClass_Flag == IDFLAG)
  1571. && ((pCntrl->bClass == STATIC)
  1572. || (pCntrl->bClass == EDIT)) ) {
  1573. if ( (align = GetAlignFromString( pszCrd)) >= 0 ) {
  1574. if ( pCntrl->bClass == STATIC ) {
  1575. pCntrl->lStyle &= ~(SS_LEFT|SS_RIGHT|SS_CENTER);
  1576. if ( align == 2 )
  1577. pCntrl->lStyle |= SS_RIGHT;
  1578. else if ( align == 1 )
  1579. pCntrl->lStyle |= SS_CENTER;
  1580. else
  1581. pCntrl->lStyle |= SS_LEFT;
  1582. } else {
  1583. pCntrl->lStyle &= ~(ES_LEFT|ES_RIGHT|ES_CENTER);
  1584. if ( align == 2 )
  1585. pCntrl->lStyle |= ES_RIGHT;
  1586. else if ( align == 1 )
  1587. pCntrl->lStyle |= ES_CENTER;
  1588. else
  1589. pCntrl->lStyle |= ES_LEFT;
  1590. }
  1591. }
  1592. }
  1593. ParseTokCrd( pszCrd,
  1594. (WORD UNALIGNED *)&pCntrl->x,
  1595. (WORD UNALIGNED *)&pCntrl->y,
  1596. (WORD UNALIGNED *)&pCntrl->cx,
  1597. (WORD UNALIGNED *)&pCntrl->cy);
  1598. }
  1599. /**
  1600. *
  1601. *
  1602. * Function: PutResHeader
  1603. * Writes Resource Header information contained in the ResHeader structure
  1604. * to the ouput resfile. Note, the value of the size field, is not yet
  1605. * know, so it is left blank, to be fixed up once the size resource
  1606. * determined.
  1607. *
  1608. * Arguments:
  1609. * OutResFile, File handle to Output Resource File.
  1610. * ResHeader, Structure containing resource header information.
  1611. * pResSizePos, file position buffer
  1612. *
  1613. * Returns:
  1614. * pResSizePos, position at localization of the OutResFile to insert
  1615. * the resource size.
  1616. *
  1617. * Errors Codes:
  1618. * None.
  1619. *
  1620. * History:
  1621. * 7/91, Implemented Terryru
  1622. * 9/91, Added bTypeFlag to handle case where ID is 255. Peterw
  1623. * 4/92, Added RLRES32 support Terryru
  1624. *
  1625. *
  1626. **/
  1627. int PutResHeader(
  1628. FILE *OutResFile, //... File to write to
  1629. RESHEADER ResHeader, //... Header to be written out
  1630. fpos_t *pResSizePos, //... For offset at which to write the adjusted res size
  1631. DWORD *plSize) //... Keeps track of bytes written
  1632. {
  1633. int rc;
  1634. DWORD ltSize = *plSize;
  1635. #ifdef RLRES32
  1636. //... save position to res size
  1637. rc = fgetpos( OutResFile, pResSizePos);
  1638. //... this size is bogus, will fill in later
  1639. //... unless we are called in the mail loop
  1640. PutdWord( OutResFile, ResHeader.lSize, plSize);
  1641. PutdWord( OutResFile, ResHeader.lHeaderSize, plSize);
  1642. #endif // RLRES32
  1643. PutNameOrd( OutResFile,
  1644. ResHeader.bTypeFlag,
  1645. ResHeader.wTypeID,
  1646. ResHeader.pszType,
  1647. plSize);
  1648. PutNameOrd( OutResFile,
  1649. ResHeader.bNameFlag,
  1650. ResHeader.wNameID,
  1651. ResHeader.pszName,
  1652. plSize);
  1653. #ifdef RLRES32
  1654. DWordUpFilePointer( OutResFile, MYWRITE, ftell( OutResFile), plSize);
  1655. PutdWord( OutResFile, ResHeader.lDataVersion, plSize);
  1656. #endif // RLRES32
  1657. PutWord( OutResFile, ResHeader.wMemoryFlags, plSize);
  1658. #ifdef RLRES32
  1659. PutWord( OutResFile, ResHeader.wLanguageId, plSize);
  1660. PutdWord( OutResFile, ResHeader.lVersion, plSize);
  1661. PutdWord( OutResFile, ResHeader.lCharacteristics, plSize);
  1662. #else // RLRES32
  1663. //... save position to res size
  1664. rc = fgetpos( OutResFile, pResSizePos);
  1665. //... this size is bogus, will fill in later
  1666. //... unless we are called in the mail loop
  1667. PutdWord( OutResFile, ltSize, plSize);
  1668. #endif // RLRES32
  1669. /////////////////// ??????? why? *plSize = ltSize;
  1670. return ( rc);
  1671. }
  1672. /**
  1673. *
  1674. *
  1675. * Function: PutDialog
  1676. * PutDialog writes dialog information to the output resource file as
  1677. * it traveres through the linked list of dialog info. If the info
  1678. * is of the type that needs to be localized, the corresponding translated
  1679. * info is read from the token file, and writen to the resource file.
  1680. *
  1681. * Arguments:
  1682. * OutResFile, The file handle of the res file being generated.
  1683. * TokFile, The file handle of the token file containing tokenized dialog info,
  1684. * typically this file has been localized.
  1685. * ResHeader, Structure containg Dialog resource header information.
  1686. * pDialogHdr, Linked list of unlocalized Dialog information.
  1687. *
  1688. * Returns:
  1689. * Translated dialog information written to the Output Resource file.
  1690. *
  1691. * Errors Codes:
  1692. * None,
  1693. *
  1694. * History:
  1695. * 7/91, Implemented. TerryRu
  1696. * 1/93, Now tokenize dlg fontnames TerryRu
  1697. * 01/93 Support for var length token text MHotchin
  1698. *
  1699. **/
  1700. void PutDialog(FILE *OutResFile,
  1701. FILE *TokFile,
  1702. RESHEADER ResHeader,
  1703. DIALOGHEADER *pDialogHdr)
  1704. {
  1705. static TOKEN tok;
  1706. int found = 0;
  1707. WORD wcDup = 0;
  1708. WORD *pwIdBuf;
  1709. static TCHAR pErrBuf[MAXINPUTBUFFER];
  1710. WORD i, j = 0, k = 0;
  1711. fpos_t ResSizePos;
  1712. CONTROLDATA *pCntlData = pDialogHdr->pCntlData;
  1713. DWORD lSize = 0;
  1714. LONG lStartingOffset; // used to dword align file
  1715. WORD y = 0;
  1716. LONG lExtra = 0;
  1717. lStartingOffset = ftell(OutResFile);
  1718. // Prep for find token call
  1719. tok.wType = ResHeader.wTypeID;
  1720. tok.wName = ResHeader.wNameID;
  1721. tok.wID = 0;
  1722. tok.wReserved = ST_TRANSLATED;
  1723. lstrcpy( (TCHAR *)tok.szName, (TCHAR *)ResHeader.pszName);
  1724. tok.szText = (TCHAR *)FALLOC( MEMSIZE( lstrlen( pDialogHdr->pszCaption) + 1));
  1725. lstrcpy( (TCHAR *)tok.szText, (TCHAR *)pDialogHdr->pszCaption);
  1726. // write the Dialog Res Header
  1727. if ( PutResHeader( OutResFile, ResHeader , &ResSizePos, &lSize)) {
  1728. RLFREE( tok.szText);
  1729. QuitT( IDS_ENGERR_06, (LPTSTR)IDS_DLGBOX, NULL);
  1730. }
  1731. // write the dialog header
  1732. lSize = 0L;
  1733. #ifdef RLRES32
  1734. if (pDialogHdr->fDialogEx) {
  1735. PutWord( OutResFile, pDialogHdr->wDlgVer, &lSize);
  1736. PutWord( OutResFile, pDialogHdr->wSignature, &lSize);
  1737. PutdWord( OutResFile, pDialogHdr->dwHelpID, &lSize);
  1738. PutdWord( OutResFile, pDialogHdr->lExtendedStyle, &lSize);
  1739. PutdWord( OutResFile, pDialogHdr->lStyle, &lSize);
  1740. } else {
  1741. PutdWord( OutResFile, pDialogHdr->lStyle, &lSize);
  1742. PutdWord( OutResFile, pDialogHdr->lExtendedStyle, &lSize);
  1743. }
  1744. PutWord( OutResFile, pDialogHdr->wNumberOfItems, &lSize);
  1745. #else // RLRES32
  1746. PutdWord( OutResFile, pDialogHdr->lStyle, &lSize);
  1747. PutByte( OutResFile, (BYTE)pDialogHdr->wNumberOfItems, &lSize);
  1748. #endif // RLRES32
  1749. // check to see if caption was localized
  1750. // but don't put it in the res file yet
  1751. // order of token is caption, cordinates,
  1752. // while in res its cordinates, caption
  1753. tok.wFlag = ISCAP;
  1754. if ( ! FindToken( TokFile, &tok, ST_TRANSLATED) ) {
  1755. // can not find token, terminate
  1756. ParseTokToBuf( pErrBuf, &tok);
  1757. RLFREE( tok.szText);
  1758. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  1759. }
  1760. tok.wReserved = ST_TRANSLATED;
  1761. // token found, continue
  1762. RLFREE( pDialogHdr->pszCaption);
  1763. pDialogHdr->pszCaption =
  1764. (TCHAR *)FALLOC( MEMSIZE( lstrlen( tok.szText) + 1));
  1765. TextToBin( pDialogHdr->pszCaption,
  1766. tok.szText,
  1767. lstrlen( tok.szText));
  1768. RLFREE( tok.szText);
  1769. // Now get the cordinates of the token
  1770. tok.wFlag = (ISCAP) | (ISCOR);
  1771. if ( ! FindToken( TokFile, &tok, ST_TRANSLATED) ) {
  1772. // token not found, terminate
  1773. ParseTokToBuf(pErrBuf, &tok);
  1774. RLFREE( tok.szText);
  1775. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  1776. }
  1777. tok.wReserved = ST_TRANSLATED;
  1778. // token found continue
  1779. ParseTokCrd( tok.szText,
  1780. (WORD UNALIGNED *)&pDialogHdr->x,
  1781. (WORD UNALIGNED *)&pDialogHdr->y,
  1782. (WORD UNALIGNED *)&pDialogHdr->cx,
  1783. (WORD UNALIGNED *)&pDialogHdr->cy);
  1784. RLFREE( tok.szText);
  1785. // put cordindates in new res file
  1786. PutWord(OutResFile, pDialogHdr->x , &lSize);
  1787. PutWord(OutResFile, pDialogHdr->y , &lSize);
  1788. PutWord(OutResFile, pDialogHdr->cx , &lSize);
  1789. PutWord(OutResFile, pDialogHdr->cy , &lSize);
  1790. PutNameOrd(OutResFile,
  1791. pDialogHdr->bMenuFlag, // 9/11/91 (PW)
  1792. pDialogHdr->wDlgMenuID,
  1793. pDialogHdr->pszDlgMenu,
  1794. &lSize);
  1795. PutNameOrd( OutResFile,
  1796. pDialogHdr->bClassFlag, // 9/11/91 (PW)
  1797. pDialogHdr->wDlgClassID,
  1798. pDialogHdr->pszDlgClass,
  1799. &lSize);
  1800. PutString(OutResFile, pDialogHdr->pszCaption, &lSize);
  1801. if ( pDialogHdr->lStyle & DS_SETFONT ) {
  1802. if (gfExtendedTok) {
  1803. static CHAR szTmpBuf[30];
  1804. // find dialog font size
  1805. tok.wFlag = ISDLGFONTSIZE;
  1806. tok.wReserved = ST_TRANSLATED;
  1807. if ( ! FindToken( TokFile, &tok, ST_TRANSLATED) ) {
  1808. // token not found, terminate
  1809. ParseTokToBuf(pErrBuf, &tok);
  1810. RLFREE( tok.szText);
  1811. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  1812. }
  1813. #ifdef RLRES32
  1814. _WCSTOMBS( szTmpBuf,
  1815. tok.szText,
  1816. sizeof( szTmpBuf),
  1817. lstrlen( tok.szText) + 1);
  1818. PutWord (OutResFile, (WORD) atoi(szTmpBuf), &lSize);
  1819. if (pDialogHdr->fDialogEx) {
  1820. PutWord( OutResFile, pDialogHdr->wWeight , &lSize);
  1821. PutWord( OutResFile, pDialogHdr->wItalic , &lSize);
  1822. }
  1823. #else // RLRES32
  1824. PutWord( OutResFile, (WORD) atoi( tok.szText), &lSize);
  1825. #endif // RLRES32
  1826. RLFREE( tok.szText);
  1827. // find dialog font name
  1828. tok.wFlag = ISDLGFONTNAME;
  1829. tok.wReserved = ST_TRANSLATED;
  1830. if ( ! FindToken( TokFile, &tok, ST_TRANSLATED) ) {
  1831. // token not found, terminate
  1832. ParseTokToBuf(pErrBuf, &tok);
  1833. RLFREE( tok.szText);
  1834. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  1835. }
  1836. PutString( OutResFile, tok.szText, &lSize);
  1837. RLFREE( tok.szText);
  1838. } else {
  1839. PutWord( OutResFile, pDialogHdr->wPointSize , &lSize);
  1840. if (pDialogHdr->fDialogEx) {
  1841. PutWord( OutResFile, pDialogHdr->wWeight , &lSize);
  1842. PutWord( OutResFile, pDialogHdr->wItalic , &lSize);
  1843. }
  1844. PutString( OutResFile, pDialogHdr->pszFontName, &lSize);
  1845. }
  1846. }
  1847. #ifdef RLRES32
  1848. DWordUpFilePointer( OutResFile, MYWRITE, ftell(OutResFile), &lSize);
  1849. #endif // RLRES32
  1850. //... That was the end of the DialogBoxHeader
  1851. //... Now we start with the ControlData's
  1852. pwIdBuf = (WORD *)FALLOC( (DWORD)pDialogHdr->wNumberOfItems
  1853. * sizeof( WORD));
  1854. tok.wReserved = ST_TRANSLATED;
  1855. // now place each of the dialog controls in the new res file
  1856. for (i = 0; i < pDialogHdr->wNumberOfItems; i ++) {
  1857. if (isdup ((WORD)pDialogHdr->pCntlData[i].dwID, pwIdBuf, (WORD)j)) {
  1858. tok.wID = (USHORT)wcDup++;
  1859. tok.wFlag = ISDUP;
  1860. } else {
  1861. // wid is unique so store in buffer for dup check
  1862. pwIdBuf[j++] = (USHORT)pDialogHdr->pCntlData[i].dwID;
  1863. tok.wID = (USHORT)pDialogHdr->pCntlData[i].dwID;
  1864. tok.wFlag = 0;
  1865. }
  1866. if (pDialogHdr->pCntlData[i].pszDlgText[0]) {
  1867. tok.szText = NULL;
  1868. if (!FindToken(TokFile, &tok, ST_TRANSLATED)) {
  1869. // can not find the token, terminate program
  1870. ParseTokToBuf(pErrBuf, &tok);
  1871. RLFREE( tok.szText);
  1872. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  1873. }
  1874. tok.wReserved = ST_TRANSLATED;
  1875. // token found, continue
  1876. RLFREE( pDialogHdr->pCntlData[i].pszDlgText);
  1877. pDialogHdr->pCntlData[i].pszDlgText =
  1878. (TCHAR *)FALLOC( MEMSIZE( lstrlen( tok.szText) + 1));
  1879. if ( pDialogHdr->pCntlData[i].pszDlgText ) {
  1880. TextToBin(pDialogHdr->pCntlData[i].pszDlgText,
  1881. (TCHAR *)tok.szText,
  1882. lstrlen((TCHAR *)tok.szText) + 1);
  1883. }
  1884. RLFREE( tok.szText);
  1885. }
  1886. tok.wFlag |= ISCOR;
  1887. if ( ! FindToken( TokFile, &tok, ST_TRANSLATED) ) {
  1888. ParseTokToBuf( pErrBuf, &tok);
  1889. RLFREE( tok.szText);
  1890. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  1891. }
  1892. tok.wReserved = ST_TRANSLATED;
  1893. ParseTokCrdAndAlign( tok.szText, &pDialogHdr->pCntlData[i] );
  1894. RLFREE( tok.szText);
  1895. #ifdef RLRES32
  1896. if (pDialogHdr->fDialogEx) {
  1897. PutdWord( OutResFile, pDialogHdr->pCntlData[i].dwHelpID, &lSize);
  1898. PutdWord( OutResFile, pDialogHdr->pCntlData[i].lExtendedStyle, &lSize);
  1899. PutdWord( OutResFile, pDialogHdr->pCntlData[i].lStyle, &lSize);
  1900. } else {
  1901. PutdWord( OutResFile, pDialogHdr->pCntlData[i].lStyle, &lSize);
  1902. PutdWord( OutResFile, pDialogHdr->pCntlData[i].lExtendedStyle, &lSize);
  1903. }
  1904. #endif // RLRES32
  1905. // now put control info into res file
  1906. PutWord (OutResFile, pDialogHdr->pCntlData[i].x , &lSize);
  1907. PutWord (OutResFile, pDialogHdr->pCntlData[i].y , &lSize);
  1908. PutWord (OutResFile, pDialogHdr->pCntlData[i].cx , &lSize);
  1909. PutWord (OutResFile, pDialogHdr->pCntlData[i].cy , &lSize);
  1910. if (pDialogHdr->fDialogEx)
  1911. PutdWord (OutResFile, pDialogHdr->pCntlData[i].dwID , &lSize);
  1912. else
  1913. PutWord (OutResFile, (WORD)pDialogHdr->pCntlData[i].dwID , &lSize);
  1914. #ifdef RLRES16
  1915. // lStyle
  1916. PutdWord (OutResFile, pDialogHdr->pCntlData[i].lStyle , &lSize);
  1917. PutByte(OutResFile, (BYTE) pDialogHdr->pCntlData[i].bClass, &lSize);
  1918. if (! (pDialogHdr->pCntlData[i].bClass & 0x80)) {
  1919. PutString (OutResFile, pDialogHdr->pCntlData[i].pszClass , &lSize);
  1920. }
  1921. #else // RLRES16
  1922. PutNameOrd(OutResFile,
  1923. pDialogHdr->pCntlData[i].bClass_Flag, // 9/11/91 (PW)
  1924. pDialogHdr->pCntlData[i].bClass,
  1925. pDialogHdr->pCntlData[i].pszClass,
  1926. &lSize);
  1927. #endif // RLRES16
  1928. PutNameOrd(OutResFile,
  1929. pDialogHdr->pCntlData[i].bID_Flag, // 9/11/91 (PW)
  1930. pDialogHdr->pCntlData[i].wDlgTextID,
  1931. pDialogHdr->pCntlData[i].pszDlgText,
  1932. &lSize);
  1933. #ifdef RLRES16
  1934. PutByte(OutResFile, (BYTE) pDialogHdr->pCntlData[i].unDefined, &lSize);
  1935. #else
  1936. PutWord(OutResFile, (WORD)pDialogHdr->pCntlData[i].wExtraStuff, &lSize);
  1937. if (pDialogHdr->fDialogEx && pDialogHdr->pCntlData[i].wExtraStuff) {
  1938. lExtra = pDialogHdr->pCntlData[i].wExtraStuff;
  1939. y = 0;
  1940. while ( lExtra-- )
  1941. PutByte (OutResFile, pDialogHdr->pCntlData[i].pExtraStuff[y++] , &lSize);
  1942. }
  1943. if ( i < pDialogHdr->wNumberOfItems - 1 ) {
  1944. DWordUpFilePointer( OutResFile, MYWRITE, ftell(OutResFile), &lSize);
  1945. }
  1946. #endif // RLRES16
  1947. }
  1948. RLFREE( pwIdBuf );
  1949. if (!UpdateResSize (OutResFile, &ResSizePos , lSize)) {
  1950. QuitT( IDS_ENGERR_07, (LPTSTR)IDS_DLGBOX, NULL);
  1951. }
  1952. DWordUpFilePointer( OutResFile, MYWRITE, ftell( OutResFile), NULL);
  1953. }
  1954. /**
  1955. *
  1956. *
  1957. * Function: PutMenu
  1958. * Traveres through the linked list of Menu information and writes the info to the
  1959. * output resource file. If the infortion is the type that requires localization,
  1960. * the translated info is read from the token file and writen to the resource.
  1961. * call PutMenuItem to do the actual write of the menu info to the resource.
  1962. *
  1963. * Arguments:
  1964. * OutResFile, File handle of output resource file.
  1965. * TokFile, File handle of token file.
  1966. * ResHeader, Sturcture contain Menu Resource header information.
  1967. * pMenuHdr, Linked list of menu info.
  1968. *
  1969. * Returns:
  1970. * Translated Menu Info written to output resource file.
  1971. *
  1972. * Errors Codes:
  1973. * None.
  1974. *
  1975. * History:
  1976. * 7/91, Implemented. TerryRu.
  1977. * 01/93 Changes to allow var length token text. MHotchin
  1978. *
  1979. **/
  1980. void PutMenu(FILE *OutResFile,
  1981. FILE *TokFile,
  1982. RESHEADER ResHeader,
  1983. MENUHEADER *pMenuHdr)
  1984. {
  1985. DWORD lSize = 0;
  1986. static TOKEN tok;
  1987. static WORD wcPopUp = 0;
  1988. fpos_t ResSizePos;
  1989. MENUITEM *pMenuItem = pMenuHdr->pMenuItem;
  1990. static TCHAR pErrBuf[ MAXINPUTBUFFER];
  1991. LONG lExtra = 0;
  1992. WORD i = 0;
  1993. // write the Menu Res header
  1994. if ( PutResHeader (OutResFile, ResHeader , &ResSizePos, &lSize)) {
  1995. QuitT( IDS_ENGERR_06, (LPTSTR)IDS_MENU, NULL);
  1996. }
  1997. lSize = 0;
  1998. // write the Menu header
  1999. PutWord (OutResFile, pMenuHdr->wVersion, &lSize);
  2000. PutWord (OutResFile, pMenuHdr->cbHeaderSize , &lSize);
  2001. if (pMenuHdr->fMenuEx && pMenuHdr->cbHeaderSize) {
  2002. lExtra = pMenuHdr->cbHeaderSize;
  2003. while ( lExtra-- )
  2004. PutByte (OutResFile, pMenuHdr->pExtraStuff[i++] , &lSize);
  2005. }
  2006. // prep for findtoken call
  2007. tok.wType = ResHeader.wTypeID;
  2008. tok.wName = ResHeader.wNameID;
  2009. tok.wReserved = ST_TRANSLATED;
  2010. // for all menu items,
  2011. // find translated token if item was tokenized
  2012. // write out that menu item, using new translation if available.
  2013. while (pMenuItem) {
  2014. // if Menu Item is a seperator skip it
  2015. if ( *pMenuItem->szItemText ) {
  2016. // check for the popup menu items
  2017. if ((pMenuItem->fItemFlags & MFR_POPUP) && pMenuHdr->fMenuEx) {
  2018. tok.wID = (pMenuItem->dwMenuID == 0 ||
  2019. pMenuItem->dwMenuID == 0x0000ffff) ?
  2020. (USHORT)pMenuItem->dwMenuID : 0x8000 + wcPopUp++;
  2021. tok.wFlag = ISPOPUP;
  2022. } else if (pMenuItem->fItemFlags & POPUP) {
  2023. tok.wID = wcPopUp++;
  2024. tok.wFlag = ISPOPUP;
  2025. } else {
  2026. tok.wID = (USHORT)pMenuItem->dwMenuID;
  2027. tok.wFlag = 0;
  2028. }
  2029. lstrcpy((TCHAR *)tok.szName, (TCHAR *)ResHeader.pszName);
  2030. tok.szText = NULL;
  2031. if ( ! FindToken( TokFile, &tok,ST_TRANSLATED) ) {
  2032. // can not find token, terminate
  2033. ParseTokToBuf(pErrBuf, &tok);
  2034. RLFREE( tok.szText);
  2035. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  2036. }
  2037. tok.wReserved = ST_TRANSLATED;
  2038. // token found, continue
  2039. RLFREE( pMenuItem->szItemText);
  2040. pMenuItem->szItemText=
  2041. (TCHAR *)FALLOC( MEMSIZE( lstrlen( tok.szText) + 1));
  2042. TextToBin(pMenuItem->szItemText,
  2043. (TCHAR *)tok.szText,
  2044. lstrlen((TCHAR *)tok.szText)+1);
  2045. RLFREE( tok.szText);
  2046. }
  2047. PutMenuItem (OutResFile, pMenuItem , &lSize, pMenuHdr->fMenuEx);
  2048. pMenuItem = pMenuItem->pNextItem;
  2049. }
  2050. if (!UpdateResSize (OutResFile, &ResSizePos , lSize)) {
  2051. QuitT( IDS_ENGERR_07, (LPTSTR)IDS_MENU, NULL);
  2052. }
  2053. }
  2054. /**
  2055. *
  2056. *
  2057. * Function: PutMenuItem
  2058. * Called by PutMenu to write a menu item info to the ouput resoruce file.
  2059. *
  2060. *
  2061. * Arguments:
  2062. * OutResFile, File handle of output resfile, positioned at location to
  2063. * write menu item info.
  2064. * pMenuItem, pointer to struture containing menu item info.
  2065. * plSize, pointer of variable to count the number of bytes written to
  2066. * the resource file. Used later to fixup the resource field in the
  2067. * header.
  2068. *
  2069. *
  2070. *
  2071. * Returns:
  2072. * OutReFile, containing translated menu item info, and plSize containing
  2073. * number of bytes written to resource file.
  2074. *
  2075. * Errors Codes:
  2076. * None.
  2077. *
  2078. * History:
  2079. * 7//91, Implemented TerryRu
  2080. *
  2081. *
  2082. **/
  2083. void PutMenuItem(FILE * OutResFile, MENUITEM * pMenuItem, DWORD * plSize, BOOL fMenuEx)
  2084. {
  2085. if (fMenuEx) {
  2086. PutdWord( OutResFile, pMenuItem->dwType, plSize);
  2087. PutdWord( OutResFile, pMenuItem->dwState, plSize);
  2088. PutdWord( OutResFile, pMenuItem->dwMenuID, plSize);
  2089. PutWord( OutResFile, pMenuItem->fItemFlags, plSize);
  2090. } else {
  2091. PutWord( OutResFile, pMenuItem->fItemFlags, plSize);
  2092. if ( ! (pMenuItem->fItemFlags & POPUP) ) {
  2093. PutWord( OutResFile, (WORD)pMenuItem->dwMenuID, plSize);
  2094. }
  2095. }
  2096. PutString( OutResFile, pMenuItem->szItemText, plSize);
  2097. if (fMenuEx) {
  2098. DWordUpFilePointer( OutResFile, MYWRITE, ftell(OutResFile), plSize);
  2099. if (pMenuItem->fItemFlags & MFR_POPUP) {
  2100. PutdWord( OutResFile, pMenuItem->dwHelpID, plSize);
  2101. }
  2102. }
  2103. }
  2104. /**
  2105. *
  2106. *
  2107. * Function: PutNameOrd
  2108. * Writes either the string or ordinal ID of the resource class or type.
  2109. *
  2110. *
  2111. * Arguments:
  2112. * OutResFile, File handle of resource file being generated.
  2113. * bFlag, Flag indicating whether ID is a string or ordinal.
  2114. * pszText, string ID, if used.
  2115. * wId, Ordinal ID if used.
  2116. * pLsize, pointer to DWORD counter var.
  2117. *
  2118. * Returns:
  2119. * OutResFile, containing ID info, and plSize containing the number of
  2120. * bytes written to the file.
  2121. *
  2122. * Errors Codes:
  2123. * None.
  2124. *
  2125. * History:
  2126. * 7/91, Implemented. TerryRu.
  2127. *
  2128. *
  2129. **/
  2130. void PutNameOrd(
  2131. FILE *fpOutResFile,
  2132. BOOL bFlag,
  2133. WORD wID,
  2134. TCHAR *pszText,
  2135. DWORD *plSize)
  2136. {
  2137. if ( bFlag == IDFLAG ) {
  2138. #ifdef RLRES16
  2139. PutByte( fpOutResFile, (BYTE)IDFLAG, plSize);
  2140. #else
  2141. PutWord( fpOutResFile, (WORD)IDFLAG, plSize);
  2142. #endif
  2143. PutWord( fpOutResFile, wID, plSize);
  2144. } else {
  2145. PutString( fpOutResFile, pszText, plSize);
  2146. }
  2147. }
  2148. /**
  2149. *
  2150. *
  2151. * Function: MyAtow,
  2152. * Special Ascii to WORD function that works on 4 digit, hex strings.
  2153. *
  2154. *
  2155. * Arguments:
  2156. * pszNum, 4 digit hex string to convert to binary.
  2157. *
  2158. *
  2159. * Returns:
  2160. * Binary value of pszNumString
  2161. *
  2162. * Errors Codes:
  2163. * None.
  2164. *
  2165. * History:
  2166. * 12//91, Implemented. TerryRu.
  2167. *
  2168. *
  2169. **/
  2170. WORD MyAtoX(
  2171. CHAR *pszNum, //... array of bytes to scan
  2172. int nLen) //... # oc bytes in pszNum to scan
  2173. {
  2174. WORD wNum = 0;
  2175. WORD i;
  2176. WORD nPower = 1;
  2177. if ( nLen > 4 ) {
  2178. QuitT( IDS_ENGERR_16, (LPTSTR)IDS_CHARSTOX, NULL);
  2179. }
  2180. for ( i = 0; i < nLen; i++, nPower *= 16 ) {
  2181. if ( isdigit( pszNum[ i]) ) {
  2182. wNum += nPower * (pszNum[i] - '0');
  2183. } else {
  2184. wNum += nPower * (toupper( pszNum[i]) - 'A' + 10);
  2185. }
  2186. }
  2187. return ( wNum);
  2188. }
  2189. WORD MyAtoW( CHAR *pszNum)
  2190. {
  2191. return ( MyAtoX( pszNum, 4));
  2192. }
  2193. /**
  2194. *
  2195. *
  2196. * Function: PutResVer.
  2197. * Writes the Version stamping info to the Resourc file. Unlike most
  2198. * put functions, PutResVer writes all the localized version stamping info
  2199. * into a memory block, then writes the complete version stamping info to
  2200. * the resource file. This was done because of large number of size
  2201. * fixups needed for the version stamping info.
  2202. *
  2203. *
  2204. * Arguments:
  2205. * OutResFile, file pointer of resource file being generated.
  2206. * TokeFile, file pointer of input token file containing localized info.
  2207. * ResHeader, Structure containing Resource Header info of the
  2208. * version stamping block.
  2209. * pVerHdr, address of Version Header. Note this is different the ResHdr.
  2210. * pVerBlk, address of Version stamping info, which is contained in
  2211. * a series of StringFile, and VarFile info blocks. The number of
  2212. * such blocks is determined by the size fields.
  2213. *
  2214. * Returns:
  2215. * OutResFile, containing localized version stamping info.
  2216. *
  2217. * Errors Codes:
  2218. * None.
  2219. *
  2220. * History:
  2221. * 11/91, Implemented. TerryRu.
  2222. * 12/91, Various fixes to work with different padding. TerryRu.
  2223. * 01/92, Size of Version block updated PeterW.
  2224. * 10/92, Now handles NULL Version Blocks TerryRu.
  2225. * 10/92, Added RLRES32 version DaveWi
  2226. * 01/93, Added var length token text support. MHotchin
  2227. **/
  2228. #ifdef RLRES32
  2229. int PutResVer(
  2230. FILE *fpOutResFile,
  2231. FILE *fpTokFile,
  2232. RESHEADER ResHeader,
  2233. VERHEAD *pVerHdr,
  2234. VERBLOCK *pVerBlk)
  2235. {
  2236. TOKEN Tok;
  2237. BOOL fInStringInfo = FALSE; //... TRUE if reading StringFileInfo
  2238. WORD wTokNum = 0; //... Put into Tok.wID field
  2239. WORD wTokContinueNum = 0; //... Put into Tok.wFlag field
  2240. WORD wDataLen = 0; //... Length of old resource data
  2241. WORD wVerHeadSize; //... Sizeof of the VERHEAD struct
  2242. fpos_t lResSizePos;
  2243. DWORD lSize = 0L;
  2244. int nWritten = 0;
  2245. int nNewVerBlockSize = 0;
  2246. PVERBLOCK pNewVerStamp = NULL;
  2247. PVERBLOCK pNewBlk = NULL;
  2248. wVerHeadSize = (WORD)(3 * sizeof(WORD)
  2249. + MEMSIZE( lstrlen( TEXT( "VS_FIXEDFILEINFO")) + 1)
  2250. + sizeof( VS_FIXEDFILEINFO));
  2251. wVerHeadSize = DWORDUP(wVerHeadSize);
  2252. //... write the Version resouce header
  2253. if ( PutResHeader(fpOutResFile, ResHeader, &lResSizePos, &lSize) ) {
  2254. QuitT( IDS_ENGERR_06, (LPTSTR)IDS_VERSTAMP, NULL);
  2255. }
  2256. lSize = 0L;
  2257. if ( pVerBlk == NULL ) {
  2258. //... We have no version block to write
  2259. //... just write the version header and return
  2260. nWritten = fwrite((void *)pVerHdr,
  2261. sizeof(char),
  2262. wVerHeadSize,
  2263. fpOutResFile);
  2264. if (! UpdateResSize(fpOutResFile, &lResSizePos, (DWORD)nWritten)) {
  2265. QuitT( IDS_ENGERR_07, (LPTSTR)IDS_VERSTAMP, NULL);
  2266. }
  2267. return (1);
  2268. }
  2269. wDataLen = pVerHdr->wTotLen;
  2270. if ( wDataLen == 0 || wDataLen == (WORD)-1 ) {
  2271. return (-1); //... No resource data
  2272. }
  2273. //... Allocate buffer to hold New Version
  2274. //... Stamping Block (make ne buffer large to
  2275. //... account for expansion of strings during
  2276. //... localization).
  2277. pNewVerStamp = (PVERBLOCK)FALLOC( (nNewVerBlockSize = wDataLen * 4));
  2278. //... Fill new memory block with zeros
  2279. memset((void *)pNewVerStamp, 0, nNewVerBlockSize);
  2280. //... Copy version header into buffer
  2281. memcpy((void *)pNewVerStamp, (void *)pVerHdr, wVerHeadSize);
  2282. pNewVerStamp->wLength = wVerHeadSize;
  2283. //... Move to start of new version info block
  2284. pNewBlk = (PVERBLOCK)((PBYTE)pNewVerStamp + wVerHeadSize);
  2285. wDataLen -= wVerHeadSize;
  2286. //... Fill in static part of TOKEN struct
  2287. Tok.wType = ResHeader.wTypeID;
  2288. Tok.wName = IDFLAG;
  2289. Tok.szName[0] = TEXT('\0');
  2290. Tok.szType[0] = TEXT('\0');
  2291. Tok.wReserved = ST_TRANSLATED;
  2292. //... Get a token for each string found in res
  2293. while (wDataLen > 0) {
  2294. WORD wRC;
  2295. //... Start of a StringFileInfo block?
  2296. #ifdef UNICODE
  2297. wRC = (WORD)CompareStringW( MAKELCID( MAKELANGID( LANG_ENGLISH,
  2298. SUBLANG_ENGLISH_US),
  2299. SORT_DEFAULT),
  2300. 0,
  2301. pVerBlk->szKey,
  2302. min( wDataLen, (WORD)STRINGFILEINFOLEN),
  2303. STRINGFILEINFO,
  2304. min( wDataLen, (WORD)STRINGFILEINFOLEN));
  2305. if ( wRC == 2 )
  2306. #else
  2307. wRC = strncmp( pVerBlk->szKey,
  2308. STRINGFILEINFO,
  2309. min( wDataLen, (WORD)STRINGFILEINFOLEN));
  2310. if ( wRC == SAME )
  2311. #endif
  2312. {
  2313. WORD wStringInfoLen = 0; //... # of bytes in StringFileInfo
  2314. WORD wLen = 0;
  2315. PVERBLOCK pNewStringInfoBlk; //... Start of this StringFileInfo blk
  2316. pNewStringInfoBlk = pNewBlk;
  2317. pNewStringInfoBlk->wLength = 0; //... Gets fixed up later
  2318. pNewStringInfoBlk->wValueLength = 0;
  2319. pNewStringInfoBlk->wType = pVerBlk->wType;
  2320. lstrcpy( (TCHAR *)pNewStringInfoBlk->szKey, (TCHAR *)pVerBlk->szKey);
  2321. //... Get # of bytes in this StringFileInfo
  2322. //... (Length of value is always 0 here)
  2323. wStringInfoLen = pVerBlk->wLength;
  2324. //... Move to start of first StringTable blk.
  2325. wLen = (WORD)(DWORDUP(sizeof(VERBLOCK)
  2326. - sizeof(TCHAR)
  2327. + MEMSIZE( STRINGFILEINFOLEN)));
  2328. pVerBlk = (PVERBLOCK)((PBYTE)pVerBlk + wLen);
  2329. pNewBlk = (PVERBLOCK)((PBYTE)pNewStringInfoBlk + wLen);
  2330. DECWORDBY(&wDataLen, wLen);
  2331. DECWORDBY(&wStringInfoLen, wLen);
  2332. INCWORDBY(&pNewVerStamp->wLength, wLen);
  2333. INCWORDBY(&pNewStringInfoBlk->wLength, wLen);
  2334. while (wStringInfoLen > 0) {
  2335. WORD wStringTableLen = 0;
  2336. PVERBLOCK pNewStringTblBlk = NULL;
  2337. //... Get # of bytes in this StringTable
  2338. //... (Length of value is always 0 here)
  2339. wStringTableLen = pVerBlk->wLength;
  2340. //... Copy StringFileInfo key into Token name
  2341. Tok.wID = wTokNum++;
  2342. Tok.wFlag = wTokContinueNum = 0;
  2343. lstrcpy((TCHAR *)Tok.szName, (TCHAR *)LANGUAGEINFO);
  2344. Tok.szText = NULL;
  2345. //... Find token for this
  2346. if ( ! FindToken( fpTokFile, &Tok, ST_TRANSLATED) ) {
  2347. //... token not found, flag error and exit.
  2348. ParseTokToBuf( (TCHAR *)szDHW, &Tok);
  2349. RLFREE( pNewVerStamp);
  2350. RLFREE( Tok.szText);
  2351. QuitT( IDS_ENGERR_05, (TCHAR *)szDHW, NULL);
  2352. }
  2353. Tok.wReserved = ST_TRANSLATED;
  2354. //... Copy lang string into buffer
  2355. pNewStringTblBlk = pNewBlk;
  2356. pNewStringTblBlk->wLength = 0; //... fixed up later
  2357. pNewStringTblBlk->wValueLength = 0;
  2358. pNewStringTblBlk->wType = pVerBlk->wType;
  2359. CopyMemory( pNewStringTblBlk->szKey,
  2360. Tok.szText,
  2361. MEMSIZE( LANGSTRINGLEN));
  2362. RLFREE( Tok.szText);
  2363. //... Move to start of first String.
  2364. wLen = DWORDUP( sizeof(VERBLOCK)
  2365. - sizeof(TCHAR)
  2366. + MEMSIZE( LANGSTRINGLEN));
  2367. pVerBlk = (PVERBLOCK)((PBYTE)pVerBlk + wLen);
  2368. pNewBlk = (PVERBLOCK)((PBYTE)pNewBlk + wLen);
  2369. DECWORDBY(&wDataLen, wLen);
  2370. DECWORDBY(&wStringInfoLen, wLen);
  2371. DECWORDBY(&wStringTableLen, wLen);
  2372. INCWORDBY(&pNewVerStamp->wLength, wLen);
  2373. INCWORDBY(&pNewStringInfoBlk->wLength, wLen);
  2374. INCWORDBY(&pNewStringTblBlk->wLength, wLen);
  2375. while ( wStringTableLen > 0 ) {
  2376. //... Is value a string?
  2377. if (pVerBlk->wType == VERTYPESTRING) {
  2378. wTokContinueNum = 0;
  2379. Tok.wID = wTokNum++;
  2380. Tok.wReserved = ST_TRANSLATED;
  2381. lstrcpy( (TCHAR *)pNewBlk->szKey,
  2382. (TCHAR *)pVerBlk->szKey);
  2383. pNewBlk->wLength =
  2384. DWORDUP(sizeof(VERBLOCK) +
  2385. MEMSIZE(lstrlen((TCHAR *)pNewBlk->szKey)));
  2386. Tok.wFlag = wTokContinueNum++;
  2387. lstrcpy( (TCHAR *)Tok.szName, (TCHAR *)pVerBlk->szKey);
  2388. //... Find token for this
  2389. if ( ! FindToken( fpTokFile, &Tok, ST_TRANSLATED) ) {
  2390. //... token not found, flag error and exit.
  2391. ParseTokToBuf( (TCHAR *)szDHW, &Tok);
  2392. RLFREE( pNewVerStamp);
  2393. QuitT( IDS_ENGERR_05, (TCHAR *)szDHW, NULL);
  2394. }
  2395. Tok.wReserved = ST_TRANSLATED;
  2396. pNewBlk->wValueLength = (WORD)TextToBinW(
  2397. (TCHAR *)((PCHAR)pNewBlk + pNewBlk->wLength),
  2398. Tok.szText,
  2399. 2048);
  2400. pNewBlk->wType = VERTYPESTRING;
  2401. pNewBlk->wLength += MEMSIZE( pNewBlk->wValueLength);
  2402. INCWORDBY(&pNewVerStamp->wLength,
  2403. DWORDUP(pNewBlk->wLength));
  2404. INCWORDBY(&pNewStringInfoBlk->wLength,
  2405. DWORDUP(pNewBlk->wLength));
  2406. INCWORDBY(&pNewStringTblBlk->wLength,
  2407. DWORDUP(pNewBlk->wLength));
  2408. pNewBlk = MoveAlongVer(pNewBlk, NULL, NULL, NULL);
  2409. RLFREE( Tok.szText);
  2410. }
  2411. //... Move to start of next String.
  2412. pVerBlk = MoveAlongVer(pVerBlk,
  2413. &wDataLen,
  2414. &wStringInfoLen,
  2415. &wStringTableLen);
  2416. } //... END while wStringTableLen
  2417. } //... END while wStringInfoLen
  2418. } else {
  2419. if (_tcsncmp((TCHAR *)pVerBlk->szKey,
  2420. (TCHAR *)VARFILEINFO,
  2421. min(wDataLen, (WORD)VARFILEINFOLEN)) == SAME) {
  2422. WORD wVarInfoLen = 0; //... # of bytes in VarFileInfo
  2423. WORD wNewVarInfoLen = 0; //... # of bytes in new VarFileInfo
  2424. WORD wLen = 0;
  2425. PVERBLOCK pNewVarStart = NULL; //... Start of VarInfo block
  2426. wVarInfoLen = pVerBlk->wLength;
  2427. pNewVarStart = pNewBlk;
  2428. //... Get # of bytes in this VarFileInfo
  2429. //... (Length of value is always 0 here)
  2430. wLen = (WORD)(DWORDUP(sizeof(VERBLOCK)
  2431. - sizeof(TCHAR)
  2432. + MEMSIZE( VARFILEINFOLEN)));
  2433. //... Copy non-localized header
  2434. //... pNewVarStart->wLength field fixed up later
  2435. memcpy((void *)pNewVarStart, (void *)pVerBlk, wLen);
  2436. pNewVarStart->wLength = wLen;
  2437. //... Move to start of first Var.
  2438. pVerBlk = (PVERBLOCK)((PBYTE)pVerBlk + wLen);
  2439. pNewBlk = (PVERBLOCK)((PBYTE)pNewBlk + wLen);
  2440. DECWORDBY(&wDataLen, wLen);
  2441. DECWORDBY(&wVarInfoLen, wLen);
  2442. INCWORDBY(&pNewVerStamp->wLength, wLen);
  2443. while (wDataLen > 0 && wVarInfoLen > 0) {
  2444. if (_tcsncmp((TCHAR *)pVerBlk->szKey,
  2445. (TCHAR *)TRANSLATION,
  2446. min(wDataLen, (WORD)TRANSLATIONLEN)) == SAME) {
  2447. WORD wTransLen = 0;
  2448. PBYTE pValue = NULL;
  2449. wTokContinueNum = 0;
  2450. //... Copy VarFileInfo key into Token
  2451. Tok.wID = wTokNum;
  2452. Tok.wFlag = wTokContinueNum++;
  2453. Tok.szText = NULL;
  2454. lstrcpy((TCHAR *)Tok.szName, (TCHAR *)TRANSLATION);
  2455. Tok.wReserved = ST_TRANSLATED;
  2456. pNewBlk->wLength =
  2457. DWORDUP(sizeof(VERBLOCK) +
  2458. MEMSIZE(lstrlen((TCHAR *)TRANSLATION)));
  2459. INCWORDBY(&pNewVerStamp->wLength, pNewBlk->wLength);
  2460. INCWORDBY(&pNewVarStart->wLength, pNewBlk->wLength);
  2461. pNewBlk->wValueLength = 0; //... fixed up later
  2462. pNewBlk->wType = VERTYPEBINARY;
  2463. lstrcpy( (TCHAR *)pNewBlk->szKey, (TCHAR *)TRANSLATION);
  2464. lstrcpy((TCHAR *)Tok.szName, (TCHAR *)TRANSLATION);
  2465. //... Find token for this
  2466. if ( ! FindToken( fpTokFile, &Tok, ST_TRANSLATED) ) {
  2467. //... token not found, flag error and exit.
  2468. ParseTokToBuf((TCHAR *)szDHW, &Tok);
  2469. RLFREE( pNewVerStamp);
  2470. RLFREE( Tok.szText);
  2471. QuitT( IDS_ENGERR_05, (TCHAR *)szDHW, NULL);
  2472. } else {
  2473. PCHAR pszLangIDs = NULL;
  2474. PCHAR pszLangStart = NULL;
  2475. WORD wLangIDCount = 0;
  2476. size_t nChars;
  2477. //... Get # chars in input string (token text)
  2478. wTransLen = (WORD)lstrlen( Tok.szText);
  2479. pszLangIDs = (PCHAR)FALLOC( MEMSIZE( wTransLen + 1));
  2480. nChars = _WCSTOMBS( pszLangIDs,
  2481. Tok.szText,
  2482. MEMSIZE( wTransLen + 1),
  2483. wTransLen + 1);
  2484. RLFREE( Tok.szText);
  2485. if ( ! nChars ) {
  2486. RLFREE( pNewVerStamp);
  2487. RLFREE( pszLangIDs);
  2488. QuitT( IDS_ENGERR_14,
  2489. (LPTSTR)IDS_INVVERCHAR,
  2490. NULL);
  2491. }
  2492. //... Where to put these bytes?
  2493. pValue = (PBYTE)GetVerValue( pNewBlk);
  2494. //... Get each lang ID in the token
  2495. for ( wLangIDCount = 0, pszLangStart = pszLangIDs;
  2496. wTransLen >= 2 * TRANSDATALEN;
  2497. ++wLangIDCount ) {
  2498. USHORT uByte1 = 0;
  2499. USHORT uByte2 = 0;
  2500. WORD wIndex = 0;
  2501. if ( sscanf( pszLangStart,
  2502. "%2hx%2hx",
  2503. &uByte2,
  2504. &uByte1) != 2 ) {
  2505. QuitA( IDS_ENGERR_16,
  2506. (LPSTR)IDS_ENGERR_21,
  2507. pszLangStart);
  2508. }
  2509. wIndex = wLangIDCount * TRANSDATALEN;
  2510. pValue[ wIndex] = (BYTE)uByte1;
  2511. pValue[ wIndex + 1] = (BYTE)uByte2;
  2512. INCWORDBY(&pNewVerStamp->wLength, TRANSDATALEN);
  2513. INCWORDBY(&pNewVarStart->wLength, TRANSDATALEN);
  2514. INCWORDBY(&pNewBlk->wLength, TRANSDATALEN);
  2515. INCWORDBY(&pNewBlk->wValueLength, TRANSDATALEN);
  2516. //... Set up to get next lang ID in token
  2517. wTransLen -= 2 * TRANSDATALEN;
  2518. pszLangStart += 2 * TRANSDATALEN;
  2519. while ( wTransLen > 2 * TRANSDATALEN
  2520. && *pszLangStart != '\0'
  2521. && isspace( *pszLangStart) ) {
  2522. wTransLen--;
  2523. pszLangStart++;
  2524. }
  2525. } //... END for ( wLangIDCount = 0 ...
  2526. RLFREE( pszLangIDs);
  2527. }
  2528. Tok.wReserved = ST_TRANSLATED;
  2529. } //... END if (_tcsncmp((TCHAR *)pVerBlk->szKey))
  2530. //... Move to start of next Var info block.
  2531. pVerBlk = MoveAlongVer(pVerBlk,
  2532. &wDataLen,
  2533. &wVarInfoLen,
  2534. NULL);
  2535. pNewBlk = MoveAlongVer(pNewBlk, NULL, NULL, NULL);
  2536. } //... END while (wDataLen > 0 && wVarInfoLen)
  2537. } else {
  2538. RLFREE( pNewVerStamp);
  2539. QuitT( IDS_ENGERR_14, (LPTSTR)IDS_INVVERBLK, NULL);
  2540. }
  2541. }
  2542. } //... END while (wDataLen)
  2543. //... write new version stamping information
  2544. //... to the resource file
  2545. nWritten = fwrite((void *)pNewVerStamp,
  2546. sizeof(char),
  2547. (WORD)lSize + pNewVerStamp->wLength,
  2548. fpOutResFile);
  2549. if ( ! UpdateResSize( fpOutResFile,
  2550. &lResSizePos,
  2551. lSize + pNewVerStamp->wLength) ) {
  2552. RLFREE( pNewVerStamp);
  2553. QuitT( IDS_ENGERR_07, (LPTSTR)IDS_VERSTAMP, NULL);
  2554. }
  2555. RLFREE( pNewVerStamp);
  2556. return (0);
  2557. }
  2558. #else //... #ifdef RLRES32
  2559. int PutResVer(
  2560. FILE *OutResFile,
  2561. FILE *TokFile,
  2562. RESHEADER ResHeader,
  2563. VERHEAD *pVerHdr,
  2564. VERBLOCK *pVerBlk)
  2565. {
  2566. TCHAR *pszBuf;
  2567. fpos_t ResSizePos;
  2568. WORD wcLang = 0,
  2569. wcBlock = 0;
  2570. TOKEN tok;
  2571. VERBLOCK *pCurBlk;
  2572. VERBLOCK *pNewBlk,
  2573. *pNewBlkStart;
  2574. TCHAR *pszStr,
  2575. pErrBuf[ 128];
  2576. WORD *pwVal;
  2577. DWORD lTotBlkSize,
  2578. lSize = 0;
  2579. int wTotLen,
  2580. wcCurBlkLen,
  2581. wcTransBlkLen,
  2582. wcRead;
  2583. WORD *pStrBlkSizeLoc,
  2584. wStrBlkSize = 0;
  2585. int wcBlkLen;
  2586. // write the Version resouce header
  2587. if ( PutResHeader( OutResFile, ResHeader, &ResSizePos, &lSize) ) {
  2588. QuitT( IDS_ENGERR_06, MAKEINTRESOURCE( IDS_VERSTAMP), NULL);
  2589. }
  2590. lSize = 0L;
  2591. if ( pVerBlk == NULL ) {
  2592. //... We have no version block to write
  2593. //... just write the version header and return
  2594. wcRead = fwrite( (void *)pVerHdr,
  2595. sizeof( char),
  2596. sizeof( VERHEAD),
  2597. OutResFile);
  2598. if ( ! UpdateResSize( OutResFile, &ResSizePos, (DWORD)wcRead) ) {
  2599. QuitT( IDS_ENGERR_07, MAKEINTRESOURCE( IDS_VERSTAMP), NULL);
  2600. }
  2601. return ( 1);
  2602. }
  2603. wTotLen = pVerBlk->nTotLen;
  2604. // Allocate buffer to hold New Version Stamping Block
  2605. pNewBlk = (VERBLOCK *)FALLOC( VERMEM));
  2606. // Set new memory block to NULLS
  2607. memset( (void *)pNewBlk, 0, VERMEM);
  2608. // save start of new version info block
  2609. pNewBlkStart = pNewBlk;
  2610. wcTransBlkLen = sizeof(VERHEAD);
  2611. lSize += wcTransBlkLen;
  2612. // Insert version header info into new version info bluffer
  2613. memcpy((void *)pNewBlk, (void *)pVerHdr, wcTransBlkLen);
  2614. // Position pNewBlk point at location to insert next piece of version info
  2615. pNewBlk = (VERBLOCK *) ((char *) pNewBlk + wcTransBlkLen);
  2616. // File in static part of TOKEN struct
  2617. tok.wType = ResHeader.wTypeID;
  2618. tok.wName = IDFLAG;
  2619. tok.wReserved = ST_TRANSLATED;
  2620. wTotLen = pVerBlk->nTotLen;
  2621. pCurBlk = pVerBlk;
  2622. tok.wID = wcLang++;
  2623. pszStr = pCurBlk->szKey;
  2624. wcCurBlkLen = 4 + DWORDUP(lstrlen((TCHAR *)pszStr) + 1);
  2625. wTotLen -= wcCurBlkLen;
  2626. // Insert StringFileInfo Header into new version info buffer
  2627. // this info is not localized
  2628. memcpy((void *)pNewBlk, (void *)pCurBlk, wcCurBlkLen);
  2629. pszStr=pNewBlk->szKey;
  2630. // reposition pointers
  2631. pCurBlk = (VERBLOCK *) ((char *) pCurBlk + wcCurBlkLen);
  2632. pNewBlk = (VERBLOCK *) ((char *) pNewBlk + wcCurBlkLen);
  2633. lSize += wcCurBlkLen;
  2634. // Read All the StringTableBlocks
  2635. while (wTotLen > 8) {
  2636. // For String tables blocks we localizes the key field
  2637. tok.wFlag = ISKEY;
  2638. wcBlkLen = pCurBlk->nTotLen;
  2639. lstrcpy((TCHAR *)tok.szName, TEXT("Language Info"));
  2640. tok.wID = wcBlock;
  2641. tok.szText = NULL;
  2642. if ((pszStr = FindTokenText (TokFile,&tok,ST_TRANSLATED)) == NULL) {
  2643. // token not found, flag error and exit.
  2644. ParseTokToBuf(pErrBuf, &tok);
  2645. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  2646. }
  2647. RLFREE(tok.szText);
  2648. tok.szText = NULL;
  2649. tok.wReserved = ST_TRANSLATED;
  2650. // Do not know length of the translated StringTable block
  2651. // so set the nValLen to zero , and save location
  2652. // of string file block size field, to be fixed up latter.
  2653. pNewBlk->nValLen = 0;
  2654. pStrBlkSizeLoc = (WORD *) &pNewBlk->nTotLen;
  2655. // copy the translated key into that location
  2656. TextToBin(pNewBlk->szKey,pszStr,VERMEM-2*sizeof(int));
  2657. RLFREE( pszStr);
  2658. // Update localized string block count
  2659. wStrBlkSize = (WORD) DWORDUP (4 + lstrlen((TCHAR *)pNewBlk->szKey) + 1);
  2660. // get the length of the current block, note the
  2661. // translated length does not change.
  2662. wcCurBlkLen = 4 + pVerBlk->nValLen + DWORDUP(lstrlen((TCHAR *)pCurBlk->szKey) + 1);
  2663. lSize += wStrBlkSize;
  2664. // Update counter vars
  2665. wTotLen -= DWORDUP(wcBlkLen);
  2666. wcBlkLen -= wcCurBlkLen;
  2667. // repostion pointers
  2668. pCurBlk = (VERBLOCK *) ((char *)pCurBlk + DWORDUP(wcCurBlkLen));
  2669. pNewBlk = (VERBLOCK *) ((char *)pNewBlk + DWORDUP(wcCurBlkLen)) ;
  2670. // Read the String Blocks
  2671. // For String Blocks we localize the value fields.
  2672. tok.wFlag = ISVAL;
  2673. while (wcBlkLen > 0) {
  2674. // for string blocks we translate the value fields.
  2675. pszStr = pCurBlk->szKey;
  2676. lstrcpy((TCHAR *)tok.szName, (TCHAR *)pszStr);
  2677. tok.szText = NULL;
  2678. if ((pszStr= FindTokenText(TokFile,&tok,ST_TRANSLATED)) == NULL) {
  2679. //token not found, flag error and exit.
  2680. ParseTokToBuf(pErrBuf, &tok);
  2681. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  2682. }
  2683. RLFREE(tok.szText);
  2684. tok.szText = NULL;
  2685. tok.wReserved = ST_TRANSLATED;
  2686. lstrcpy((TCHAR *)pNewBlk->szKey, (TCHAR *)pCurBlk->szKey);
  2687. // position pointer to location to insert translated token text into pCurBlk
  2688. pszBuf = (TCHAR*) pNewBlk + 4 +
  2689. DWORDUP(lstrlen((TCHAR *)pNewBlk->szKey) + 1);
  2690. // now insert the token text
  2691. TextToBin(pszBuf,
  2692. pszStr ,
  2693. VERMEM - (4+DWORDUP(lstrlen((TCHAR *)pNewBlk->szKey)+1)));
  2694. RLFREE( pszStr);
  2695. // fix up counter fields in pNewBlk
  2696. pNewBlk->nValLen = lstrlen((TCHAR *)pszBuf) + 1;
  2697. pNewBlk->nTotLen = 4 + pNewBlk->nValLen +
  2698. DWORDUP(lstrlen((TCHAR *)pNewBlk->szKey) + 1);
  2699. wcBlkLen -= DWORDUP(pCurBlk->nTotLen);
  2700. lSize += DWORDUP(pNewBlk->nTotLen);
  2701. wStrBlkSize += DWORDUP(pNewBlk->nTotLen);
  2702. pCurBlk = (VERBLOCK *) ((char *) pCurBlk + DWORDUP(pCurBlk->nTotLen));
  2703. pNewBlk = (VERBLOCK *) ((char *) pNewBlk + DWORDUP(pNewBlk->nTotLen));
  2704. } // while
  2705. wcBlock ++;
  2706. *pStrBlkSizeLoc = wStrBlkSize ;
  2707. }
  2708. // this stuff is not translated so just copy it straight over
  2709. // Skip past Head of VarInfoBlock
  2710. pszStr = pCurBlk->szKey;
  2711. wTotLen = pCurBlk->nTotLen;
  2712. wcCurBlkLen = 4 + DWORDUP(pVerBlk->nValLen) +
  2713. DWORDUP(lstrlen((TCHAR *)pszStr) + 1);
  2714. wTotLen -= wcCurBlkLen;
  2715. // Insert Head of Var Info Into new block buffer
  2716. memcpy((void *)pNewBlk, (void *)pCurBlk, wcCurBlkLen);
  2717. pCurBlk = (VERBLOCK *) ((char *) pCurBlk + wcCurBlkLen);
  2718. pNewBlk = (VERBLOCK *) ((char *) pNewBlk + wcCurBlkLen);
  2719. lTotBlkSize = lSize; // Save the size value for the total Version blk (PW)
  2720. lSize += wcCurBlkLen;
  2721. wcLang = 0;
  2722. // Read the Var Info Blocks
  2723. // For Var Info Blocks we localize the Translation Value field.
  2724. tok.wFlag = ISVAL;
  2725. while (wTotLen > 0) {
  2726. pszStr = pCurBlk->szKey;
  2727. lstrcpy((TCHAR *)tok.szName, TEXT("Translation"));
  2728. tok.wID = wcLang;
  2729. tok.szText = NULL;
  2730. // Read Language ID
  2731. if ((pszStr = FindTokenText(TokFile, &tok,ST_TRANSLATED)) == NULL) {
  2732. //token not found, flag error and exit.
  2733. ParseTokToBuf(pErrBuf, &tok);
  2734. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  2735. }
  2736. RLFREE(tok.szText);
  2737. tok.szText = NULL;
  2738. tok.wReserved = ST_TRANSLATED;
  2739. // Found ascii translation string,
  2740. // convert it to binary and insert into pCurBlk
  2741. pwVal = (WORD *)((char *)pCurBlk +
  2742. DWORDUP(4 + lstrlen((TCHAR *)pCurBlk->szKey) + 1));
  2743. *pwVal = MyAtoW((CHAR *)pszStr);
  2744. pwVal++;
  2745. *pwVal = MyAtoW((CHAR *)&pszStr[4]);
  2746. wcLang ++;
  2747. wTotLen -= DWORDUP(pCurBlk->nTotLen );
  2748. memcpy((void *)pNewBlk, (void *)pCurBlk, pCurBlk->nTotLen);
  2749. lSize += pCurBlk->nTotLen;
  2750. // reposition pointers
  2751. pCurBlk = (VERBLOCK *) ((char *) pCurBlk + DWORDUP(pCurBlk->nTotLen) + 4);
  2752. pNewBlk = (VERBLOCK *) ((char *) pNewBlk + DWORDUP(pNewBlk->nTotLen) + 4);
  2753. RLFREE( pszStr);
  2754. }
  2755. // Now fixup VerHeader Size. header not localized so
  2756. // we do not need to update the value size.
  2757. pVerHdr = (VERHEAD *) pNewBlkStart;
  2758. pVerHdr->wTotLen = (WORD) lSize;
  2759. // Update first size value of Version block (PW)
  2760. wcTransBlkLen = sizeof (VERHEAD);
  2761. pNewBlk = (VERBLOCK *) ((char *) pNewBlkStart + wcTransBlkLen);
  2762. pNewBlk->nTotLen = (WORD) (lTotBlkSize - wcTransBlkLen);
  2763. // write new version stamping information to the resource file
  2764. wcRead = fwrite( (void *)pNewBlkStart,
  2765. sizeof(char),
  2766. (size_t)lSize,
  2767. OutResFile);
  2768. if (!UpdateResSize (OutResFile, &ResSizePos, lSize)) {
  2769. QuitT( IDS_ENGERR_07, MAKEINTRESOURCE( IDS_VERSTAMP), NULL);
  2770. }
  2771. RLFREE( pNewBlkStart);
  2772. }
  2773. #endif //... RLRES32
  2774. /**
  2775. *
  2776. *
  2777. * Function: PutStrHdr.
  2778. * Writes the string block info to the resource file.
  2779. *
  2780. *
  2781. * Arguments:
  2782. * OutResFile, pointer to resource file being generated.
  2783. * TokFile, pointer to token file containing localized string blocks.
  2784. * ResHeader, structure containing Resource Header info for the string block.
  2785. * pStrHder, Array of strings defined in the string block.
  2786. *
  2787. *
  2788. * Returns:
  2789. * OutResFile, containing localized string blocks.
  2790. *
  2791. * Errors Codes:
  2792. * None.
  2793. *
  2794. *
  2795. * History:
  2796. * 7/91. Implemented. TerryRu.
  2797. * 01/93 Added support for var length token text strings. MHotchin
  2798. *
  2799. **/
  2800. void PutStrHdr( FILE * OutResFile,
  2801. FILE * TokFile,
  2802. RESHEADER ResHeader,
  2803. STRINGHEADER *pStrHdr)
  2804. {
  2805. static TOKEN tok;
  2806. WORD i, j, k;
  2807. static TCHAR pErrBuf[MAXINPUTBUFFER];
  2808. fpos_t ResSizePos;
  2809. DWORD lSize = 0;
  2810. // write the Menu Res header
  2811. if ( PutResHeader (OutResFile, ResHeader , &ResSizePos, &lSize)) {
  2812. QuitT( IDS_ENGERR_06, (LPTSTR)IDS_MENU, NULL);
  2813. }
  2814. lSize = 0L;
  2815. for (i = 0; i < 16; i++) {
  2816. tok.wType = ResHeader.wTypeID;
  2817. tok.wName = ResHeader.wNameID;
  2818. tok.wID = i;
  2819. tok.wFlag = 0;
  2820. tok.wReserved = ST_TRANSLATED;
  2821. tok.szText = NULL;
  2822. tok.szName[0] = 0;
  2823. lstrcpy((TCHAR *)tok.szName, (TCHAR *)ResHeader.pszName);
  2824. if ( ! FindToken(TokFile, &tok, ST_TRANSLATED) ) {
  2825. // can not find token, terminate
  2826. ParseTokToBuf( pErrBuf, &tok);
  2827. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  2828. }
  2829. tok.wReserved = ST_TRANSLATED;
  2830. // token text found continue
  2831. {
  2832. static TCHAR szTmp[4160];
  2833. int cChars = 0; //... # chars in token text, including nul
  2834. cChars = lstrlen( tok.szText) + 1;
  2835. j = TextToBin( szTmp, tok.szText, cChars) - 1;
  2836. RLFREE( tok.szText);
  2837. #ifdef RLRES16
  2838. PutByte( OutResFile, (BYTE) j, &lSize);
  2839. #else
  2840. PutWord( OutResFile, j, &lSize);
  2841. #endif
  2842. for (k = 0; k < j; k++) {
  2843. #ifdef RLRES16
  2844. PutByte( OutResFile, szTmp[k], &lSize);
  2845. #else
  2846. PutWord( OutResFile, szTmp[k], &lSize);
  2847. #endif
  2848. }
  2849. }
  2850. }
  2851. if (!UpdateResSize (OutResFile, &ResSizePos , lSize)) {
  2852. QuitT( IDS_ENGERR_07, (LPTSTR)IDS_MENU, NULL);
  2853. }
  2854. }
  2855. /**
  2856. *
  2857. *
  2858. * Function: GetString.
  2859. * Read a block of 16 strings from string block in the resource file.
  2860. *
  2861. * Arguments:
  2862. * InResFile, file pointer to location of string block in the
  2863. * resource file.
  2864. * lSize, dummy var not used.
  2865. *
  2866. * Returns:
  2867. * pStrHdr containing 16 strings.
  2868. *
  2869. *
  2870. * Errors Codes:
  2871. * None.
  2872. *
  2873. * History:
  2874. * 7/91. Implemented. TerryRu.
  2875. *
  2876. *
  2877. **/
  2878. STRINGHEADER *GetString( FILE *InResFile, DWORD *lSize)
  2879. {
  2880. WORD wCharsLeft = 0; // Count of remaining characters in the string
  2881. WORD i = 0, j = 0; // Indexes into current block of 16 strings
  2882. STRINGHEADER *pStrHdr;
  2883. pStrHdr = (STRINGHEADER *)FALLOC( sizeof( STRINGHEADER));
  2884. for (j = 0; j < 16; j ++) {
  2885. #ifdef RLRES16
  2886. wCharsLeft = pStrHdr->sChars[j] = (WORD)GetByte( InResFile, lSize);
  2887. #else
  2888. wCharsLeft = pStrHdr->wChars[j] = GetWord( InResFile, lSize);
  2889. #endif
  2890. pStrHdr->pszStrings[j] = (TCHAR *)FALLOC( MEMSIZE( wCharsLeft + 1));
  2891. while ( wCharsLeft-- ) {
  2892. #ifdef RLRES32
  2893. pStrHdr->pszStrings[j][i] = GetWord( InResFile, lSize);
  2894. #else //RLRES32
  2895. pStrHdr->pszStrings[j][i] = GetByte( InResFile, lSize);
  2896. #endif //RLRES32
  2897. ++i;
  2898. }
  2899. pStrHdr->pszStrings[j][i] = TEXT('\0');
  2900. i = 0;
  2901. }
  2902. return (pStrHdr);
  2903. }
  2904. /**
  2905. *
  2906. *
  2907. * Function: ReadInRes.
  2908. * Reads a block of info from the input resource file, and
  2909. *. then writes the same info to the ouput resource file.
  2910. *
  2911. *
  2912. * Arguments:
  2913. * InFile, handle of input file.
  2914. * OutFile, handle of ouput file.
  2915. * lSize, number of bytes to Copy.
  2916. *
  2917. *
  2918. * Returns:
  2919. *
  2920. *
  2921. * Errors Codes:
  2922. * 8, read error.
  2923. * 9, write error.
  2924. *
  2925. * History:
  2926. * 7/91, Implemented. TerryRu.
  2927. * 11/91, Bug fix to copy more then 64k blocks. PeterW.
  2928. * 4/92, Bug fix to copy blocks in smaller chunks to save memory. SteveBl
  2929. *
  2930. **/
  2931. #define CHUNK_SIZE 5120
  2932. void ReadInRes( FILE *InFile, FILE *ResFile, DWORD *plSize )
  2933. {
  2934. if ( *plSize > 0L ) {
  2935. PBYTE pBuf;
  2936. size_t cNum;
  2937. size_t cAmount;
  2938. pBuf = (PBYTE)FALLOC( CHUNK_SIZE);
  2939. do {
  2940. cAmount = (*plSize > (DWORD)CHUNK_SIZE ? CHUNK_SIZE : *plSize);
  2941. cNum = fread( (void *)pBuf, sizeof( BYTE), cAmount, InFile);
  2942. if ( cNum != cAmount ) {
  2943. QuitT( IDS_ENGERR_09, (LPTSTR)IDS_READ, NULL);
  2944. }
  2945. cNum = fwrite( (void *)pBuf, sizeof( BYTE), cAmount, ResFile);
  2946. if ( cNum != cAmount) {
  2947. QuitT( IDS_ENGERR_09, (LPTSTR)IDS_WRITE, NULL);
  2948. }
  2949. *plSize -= cAmount;
  2950. } while ( *plSize);
  2951. RLFREE( pBuf);
  2952. }
  2953. }
  2954. /**
  2955. *
  2956. *
  2957. * Function: TokAccelTable
  2958. * Reads array of accelerator keys, and writes info to be localized
  2959. * to the token file.
  2960. *
  2961. *
  2962. * Arguments:
  2963. * TokeFile, file pointer of token file.
  2964. * ResHeader, Resource Header for Accelerator resource. This info
  2965. * is need to generate token id.
  2966. * pAccelTable, array of accelerator keys.
  2967. * wcTableEntries, number of key definition in Accelerator table
  2968. *
  2969. *
  2970. * Returns:
  2971. * Accelerator info to be localized writen to token file.
  2972. *
  2973. * Errors Codes:
  2974. * None.
  2975. *
  2976. * History:
  2977. * 7/91, Implemented. TerryRu.
  2978. * 01/93 Added support for var length token text strings. MHotchin
  2979. *
  2980. **/
  2981. void TokAccelTable (FILE *TokFile ,
  2982. RESHEADER ResHeader,
  2983. ACCELTABLEENTRY * pAccelTable,
  2984. WORD wcTableEntries)
  2985. {
  2986. TOKEN tok;
  2987. WORD i, l;
  2988. char szBuf[10];
  2989. tok.wType = ResHeader.wTypeID;
  2990. tok.wName = ResHeader.wNameID;
  2991. tok.wFlag = 0;
  2992. tok.wReserved = (gbMaster ? ST_NEW : ST_NEW | ST_TRANSLATED);
  2993. lstrcpy( tok.szName, ResHeader.pszName);
  2994. for (i = 0; i < wcTableEntries ; i ++) {
  2995. tok.wFlag = (WORD) pAccelTable[i].fFlags;
  2996. tok.wID = i;
  2997. // The order of wID and wAscii is reverse to the
  2998. // oder in the accelerator structure and the .rc file
  2999. sprintf( szBuf, "%hu %hu", pAccelTable[i].wID, pAccelTable[i].wAscii);
  3000. l = lstrlenA( szBuf) + 1;
  3001. tok.szText = (TCHAR *)FALLOC( MEMSIZE( l));
  3002. #ifdef RLRES32
  3003. _MBSTOWCS( (TCHAR *)tok.szText, szBuf, l, l);
  3004. #else
  3005. lstrcpyA(tok.szText, szBuf);
  3006. #endif
  3007. PutToken(TokFile, &tok);
  3008. RLFREE( tok.szText);
  3009. }
  3010. }
  3011. /**
  3012. *
  3013. *
  3014. * Function: TokDialog.
  3015. * Travers through linked list of the Dialog defintion, and writes any info
  3016. * which requires localization to the token file.
  3017. *
  3018. *
  3019. * Arguments:
  3020. * TokFile, file pointer of token file.
  3021. * ResHeader, Resource header info of dialog resource. This info is needed
  3022. * to generate the token id.
  3023. * pDialogHdr, linked list of dialog info. Each dialog control is a node
  3024. * in the linked list.
  3025. *
  3026. *
  3027. * Returns:
  3028. * The info requiring localization written to the tok file.
  3029. *
  3030. * Errors Codes:
  3031. * None.
  3032. *
  3033. * History:
  3034. * 7/91. Implemented. TerryRu.
  3035. * 7/91. Now tokenize all control cordiantes, so they are
  3036. * maintained during updates. TerryRu.
  3037. * 8/91. Supported signed coordinates. TerryRu.
  3038. * 1/93. Now tokenize dlg font names. TerryRu
  3039. * 01/93 Add support for var length token text MHotchin
  3040. **/
  3041. void TokDialog( FILE * TokFile, RESHEADER ResHeader, DIALOGHEADER *pDialogHdr)
  3042. {
  3043. WORD wcDup = 0;
  3044. WORD *pwIdBuf;
  3045. WORD i, j = 0, k = 0, l = 0;
  3046. static CHAR szTmpBuf[256];
  3047. static TCHAR szBuf[256];
  3048. static TOKEN tok;
  3049. *szTmpBuf = '\0';
  3050. *szBuf = TEXT('\0');
  3051. // tok the dialog caption
  3052. tok.wType = ResHeader.wTypeID;
  3053. tok.wName = ResHeader.wNameID;
  3054. tok.wID = 0;
  3055. tok.wFlag = ISCAP;
  3056. tok.wReserved = (gbMaster ? ST_NEW : ST_NEW | ST_TRANSLATED);
  3057. lstrcpy ((TCHAR *)tok.szName , (TCHAR *)ResHeader.pszName);
  3058. tok.szText = BinToText( pDialogHdr->pszCaption,
  3059. lstrlen( pDialogHdr->pszCaption));
  3060. PutToken(TokFile, &tok);
  3061. RLFREE( tok.szText);
  3062. // tok the dialog cordinates
  3063. // bug fix, cordinates can be signed.
  3064. tok.wFlag = (ISCAP) | (ISCOR);
  3065. #ifdef RLRES32
  3066. sprintf( szTmpBuf, "%4hd %4hd %4hd %4hd",
  3067. pDialogHdr->x,
  3068. pDialogHdr->y,
  3069. pDialogHdr->cx,
  3070. pDialogHdr->cy);
  3071. if ( gfShowClass ) {
  3072. sprintf( &szTmpBuf[ strlen( szTmpBuf)], " : TDB");
  3073. }
  3074. _MBSTOWCS( szBuf,
  3075. szTmpBuf,
  3076. WCHARSIN( sizeof( szBuf)),
  3077. ACHARSIN( lstrlenA( szTmpBuf ) + 1 ));
  3078. #else
  3079. sprintf( szBuf, "%4hd %4hd %4hd %4hd",
  3080. pDialogHdr->x,
  3081. pDialogHdr->y,
  3082. pDialogHdr->cx,
  3083. pDialogHdr->cy);
  3084. #endif
  3085. tok.szText = BinToText( szBuf, lstrlen( szBuf));
  3086. PutToken(TokFile, &tok);
  3087. RLFREE( tok.szText);
  3088. if (gfExtendedTok) {
  3089. // toknize dialog fontname, and size
  3090. if ( pDialogHdr->lStyle & DS_SETFONT ) {
  3091. tok.wFlag = ISDLGFONTSIZE;
  3092. sprintf(szTmpBuf, "%hu", pDialogHdr->wPointSize);
  3093. l = lstrlenA( szTmpBuf) + 1;
  3094. tok.szText = (TCHAR *)FALLOC( MEMSIZE( l));
  3095. #ifdef RLRES32
  3096. _MBSTOWCS( (TCHAR*) tok.szText, szTmpBuf, l, l);
  3097. #else
  3098. strcpy(tok.szText, szTmpBuf);
  3099. #endif
  3100. PutToken(TokFile, &tok);
  3101. RLFREE( tok.szText);
  3102. tok.wFlag = ISDLGFONTNAME;
  3103. tok.szText = (TCHAR *)FALLOC( MEMSIZE( lstrlen( pDialogHdr->pszFontName) + 1));
  3104. lstrcpy( tok.szText, pDialogHdr->pszFontName);
  3105. PutToken( TokFile, &tok);
  3106. RLFREE( tok.szText);
  3107. tok.szText = NULL;
  3108. }
  3109. }
  3110. // allocate buffer for for duplicate check
  3111. pwIdBuf = (WORD *) FALLOC((DWORD) pDialogHdr->wNumberOfItems * sizeof(WORD));
  3112. for (i = 0; i < (WORD) pDialogHdr->wNumberOfItems; i ++) {
  3113. if (isdup ((WORD)pDialogHdr->pCntlData[i].dwID, pwIdBuf, (WORD)j)) {
  3114. tok.wID = (USHORT)wcDup++;
  3115. tok.wFlag = ISDUP;
  3116. } else {
  3117. // wid is unique so store in buffer for dup check
  3118. pwIdBuf[j++] = (USHORT)pDialogHdr->pCntlData[i].dwID;
  3119. tok.wID = (USHORT)pDialogHdr->pCntlData[i].dwID;
  3120. tok.wFlag = 0;
  3121. }
  3122. if (pDialogHdr->pCntlData[i].pszDlgText[0]) {
  3123. tok.szText = BinToText( pDialogHdr->pCntlData[i].pszDlgText,
  3124. lstrlen( (TCHAR *)pDialogHdr->pCntlData[i].pszDlgText));
  3125. PutToken(TokFile, &tok);
  3126. RLFREE( tok.szText);
  3127. }
  3128. // now do the dialog corrdinates,
  3129. // bug fix, cordinates can be signed.
  3130. #ifdef RLRES32
  3131. sprintf( szTmpBuf,
  3132. "%4hd %4hd %4hd %4hd",
  3133. pDialogHdr->pCntlData[i].x,
  3134. pDialogHdr->pCntlData[i].y,
  3135. pDialogHdr->pCntlData[i].cx,
  3136. pDialogHdr->pCntlData[i].cy);
  3137. _MBSTOWCS( szBuf,
  3138. szTmpBuf,
  3139. WCHARSIN( sizeof ( szBuf)),
  3140. ACHARSIN( lstrlenA( szTmpBuf ) + 1));
  3141. if (gfExtendedTok)
  3142. if ( (pDialogHdr->pCntlData[i].bClass_Flag == IDFLAG)
  3143. && ((pDialogHdr->pCntlData[i].bClass == STATIC)
  3144. || (pDialogHdr->pCntlData[i].bClass == EDIT) ) ) {
  3145. TCHAR *pszCtrl[3] =
  3146. {
  3147. TEXT("LEFT"),
  3148. TEXT("CENTER"),
  3149. TEXT("RIGHT")
  3150. };
  3151. TCHAR *pszAlign = NULL;
  3152. DWORD dwStyle = pDialogHdr->pCntlData[i].lStyle;
  3153. if ( pDialogHdr->pCntlData[i].bClass == STATIC ) {
  3154. // STATIC class alignment values are constants
  3155. // not flags, so we handle them differently
  3156. // than we do for the EDIT class below.
  3157. dwStyle &= (SS_LEFT|SS_CENTER|SS_RIGHT);
  3158. if ( dwStyle == SS_RIGHT ) {
  3159. pszAlign = pszCtrl[2];
  3160. } else if ( dwStyle == SS_CENTER ) {
  3161. pszAlign = pszCtrl[1];
  3162. } else if ( dwStyle == SS_LEFT ) {
  3163. pszAlign = pszCtrl[0];
  3164. }
  3165. } else { // Dealing with an EDIT class
  3166. if ( dwStyle & ES_RIGHT ) {
  3167. pszAlign = pszCtrl[2];
  3168. } else if ( dwStyle & ES_CENTER ) {
  3169. pszAlign = pszCtrl[1];
  3170. } else if ( dwStyle & ES_LEFT ) {
  3171. pszAlign = pszCtrl[0];
  3172. }
  3173. }
  3174. if ( pszAlign ) {
  3175. _stprintf( &szBuf[ _tcslen( szBuf)], TEXT(" ( %s ) "), pszAlign);
  3176. }
  3177. }
  3178. if ( gfShowClass ) {
  3179. if ( pDialogHdr->pCntlData[i].bClass_Flag == IDFLAG ) {
  3180. TCHAR *pszCtrl = TEXT("???"); //... DLG box control class
  3181. switch ( pDialogHdr->pCntlData[i].bClass ) {
  3182. case BUTTON:
  3183. {
  3184. WORD wTmp;
  3185. wTmp = (WORD)(pDialogHdr->pCntlData[i].lStyle & 0xffL);
  3186. switch ( wTmp ) {
  3187. case BS_PUSHBUTTON:
  3188. case BS_DEFPUSHBUTTON:
  3189. pszCtrl = TEXT("BUT");
  3190. break;
  3191. case BS_CHECKBOX:
  3192. case BS_AUTOCHECKBOX:
  3193. case BS_3STATE:
  3194. case BS_AUTO3STATE:
  3195. pszCtrl = TEXT("CHX");
  3196. break;
  3197. case BS_RADIOBUTTON:
  3198. case BS_AUTORADIOBUTTON:
  3199. pszCtrl = TEXT("OPT");
  3200. break;
  3201. case BS_GROUPBOX:
  3202. case BS_USERBUTTON:
  3203. case BS_OWNERDRAW:
  3204. case BS_LEFTTEXT:
  3205. default:
  3206. pszCtrl = TEXT("DIA");
  3207. break;
  3208. } //... END switch( wTmp )
  3209. break;
  3210. }
  3211. case STATIC:
  3212. #ifdef DBCS
  3213. //Special hack
  3214. //I will remove this code later.
  3215. //This code is for fix code between 1.84 and 1.85(STATIC alignment problem)
  3216. {
  3217. WORD wTmp;
  3218. wTmp = (WORD)(pDialogHdr->pCntlData[i].lStyle & (SS_LEFT|SS_CENTER|SS_RIGHT));
  3219. if ( (wTmp==SS_CENTER)
  3220. || (wTmp==SS_LEFT) || (wTmp==SS_RIGHT) ) {
  3221. pszCtrl = TEXT("TXB");
  3222. } else {
  3223. pszCtrl = TEXT("ICO");
  3224. }
  3225. break;
  3226. }
  3227. #else // not DBCS
  3228. pszCtrl = TEXT("TXB");
  3229. break;
  3230. #endif // DBCS
  3231. default:
  3232. pszCtrl = TEXT("DIA");
  3233. break;
  3234. } //... END switch ( pDialogHdr->pCntlData[i].bClass )
  3235. wsprintf( &szBuf[ lstrlen( szBuf)], TEXT(" : %s"), pszCtrl);
  3236. } else {
  3237. wsprintf( &szBuf[ lstrlen( szBuf)],
  3238. TEXT(" : \"%s\""),
  3239. pDialogHdr->pCntlData[i].pszClass);
  3240. }
  3241. }
  3242. #else
  3243. sprintf(szBuf, "%4hd %4hd %4hd %4hd",
  3244. pDialogHdr->pCntlData[i].x,
  3245. pDialogHdr->pCntlData[i].y,
  3246. pDialogHdr->pCntlData[i].cx,
  3247. pDialogHdr->pCntlData[i].cy);
  3248. #endif
  3249. tok.wFlag |= ISCOR;
  3250. tok.szText = BinToText( szBuf, lstrlen( (TCHAR *)szBuf));
  3251. PutToken(TokFile, &tok);
  3252. RLFREE( tok.szText);
  3253. tok.szText = NULL;
  3254. }
  3255. RLFREE( pwIdBuf);
  3256. pwIdBuf = NULL;
  3257. }
  3258. /**
  3259. *
  3260. *
  3261. * Function: TokMenu,
  3262. * Travers the linked list of the Menu definition, and writes any info
  3263. * requiring localization to the token file.
  3264. *
  3265. *
  3266. * Arguments:
  3267. * TokFile, file pointer of token file.
  3268. * ResHeader, Resource header of Menu info. Need to generate token ids.
  3269. * pMenuHdr, Header of the menu used to access the linked list of token info.
  3270. *
  3271. * Returns:
  3272. * TokenFile contain all info requiring localization.
  3273. *
  3274. * Errors Codes:
  3275. * None.
  3276. *
  3277. * History:
  3278. * 7/91, Implemented. TerryRu.
  3279. * 01/93 Added support for var length token text strings. MHotchin
  3280. *
  3281. **/
  3282. void TokMenu(FILE *TokFile , RESHEADER ResHeader, MENUHEADER *pMenuHdr)
  3283. {
  3284. TOKEN tok;
  3285. static WORD wcPopUp = 0;
  3286. MENUITEM *pMenuItem;
  3287. pMenuItem = pMenuHdr->pMenuItem;
  3288. tok.wReserved = (gbMaster? ST_NEW : ST_NEW | ST_TRANSLATED);
  3289. while (pMenuItem) {
  3290. // if Menu Item is a seperator skip it
  3291. if (*pMenuItem->szItemText) {
  3292. tok.wType = ResHeader.wTypeID;
  3293. tok.wName = ResHeader.wNameID;
  3294. // check for the popup menu items
  3295. if ((pMenuItem->fItemFlags & MFR_POPUP) && pMenuHdr->fMenuEx) {
  3296. tok.wID = (pMenuItem->dwMenuID == 0 ||
  3297. pMenuItem->dwMenuID == 0x0000ffff) ?
  3298. (USHORT)pMenuItem->dwMenuID : 0x8000 + wcPopUp++;
  3299. tok.wFlag = ISPOPUP;
  3300. } else if (pMenuItem->fItemFlags & POPUP) {
  3301. tok.wID = wcPopUp++;
  3302. tok.wFlag = ISPOPUP;
  3303. } else {
  3304. tok.wID = (USHORT)pMenuItem->dwMenuID;
  3305. tok.wFlag = 0;
  3306. }
  3307. lstrcpy ((TCHAR *)tok.szName, (TCHAR *)ResHeader.pszName);
  3308. tok.szText = BinToText( pMenuItem->szItemText,
  3309. lstrlen( (TCHAR *)pMenuItem->szItemText));
  3310. PutToken (TokFile, &tok);
  3311. RLFREE( tok.szText);
  3312. }
  3313. pMenuItem = pMenuItem->pNextItem;
  3314. }
  3315. }
  3316. /**
  3317. *
  3318. *
  3319. * Function: TokString
  3320. * Write the 16 strings contained in the string block.
  3321. *
  3322. *
  3323. * Arguments:
  3324. * TokFile, file pointer of Token File.
  3325. * ResHeader, Resource header info of String block.
  3326. * pStrHdr, Array of 16 strings making up portion of the string table.
  3327. *
  3328. * Returns:
  3329. * Strings written to the Token File.
  3330. *
  3331. * Errors Codes:
  3332. * None.
  3333. *
  3334. * History:
  3335. * 7/91, Implemented. TerryRu.
  3336. * 01/93 Added support for var length token text strings. MHotchin
  3337. *
  3338. **/
  3339. void TokString( FILE * TokFile, RESHEADER ResHeader, STRINGHEADER * pStrHdr)
  3340. {
  3341. // int nLen;
  3342. TOKEN tok;
  3343. BYTE i;
  3344. for ( i = 0; i < 16; i++ ) {
  3345. tok.wType = ResHeader.wTypeID;
  3346. tok.wName = ResHeader.wNameID;
  3347. tok.wID = i;
  3348. tok.wFlag = 0;
  3349. tok.wReserved = (gbMaster ? ST_NEW : ST_NEW | ST_TRANSLATED);
  3350. lstrcpy( (TCHAR *)tok.szName, (TCHAR *)ResHeader.pszName);
  3351. // nLen = lstrlen( (TCHAR *)pStrHdr->pszStrings[i]); //DHW_TOOLONG
  3352. tok.szText = BinToText( (TCHAR *)pStrHdr->pszStrings[i], pStrHdr->wChars[i]);
  3353. PutToken( TokFile, &tok);
  3354. RLFREE( tok.szText);
  3355. }
  3356. }
  3357. #ifdef RLRES32
  3358. //................................................................
  3359. //...
  3360. //... Move to start of value field in version resource blocks
  3361. //... and adjust remaining-data-sizes accordingly.
  3362. PVERBLOCK MoveAlongVer(
  3363. PVERBLOCK pVerData, //... Start of current version block
  3364. WORD *pw1, //... First word to decrement
  3365. WORD *pw2, //... Second word to decrement
  3366. WORD *pw3) //... Third word to decrement
  3367. {
  3368. WORD wLen;
  3369. PBYTE pData = (PBYTE)pVerData;
  3370. wLen = DWORDUP( pVerData->wLength);
  3371. pData += DWORDUP( wLen);
  3372. DECWORDBY( pw1, wLen);
  3373. DECWORDBY( pw2, wLen);
  3374. DECWORDBY( pw3, wLen);
  3375. return ( (PVERBLOCK)pData);
  3376. }
  3377. //....................................................................
  3378. TCHAR *GetVerValue( PVERBLOCK pVerData)
  3379. {
  3380. WORD wLen = sizeof( VERBLOCK);
  3381. //... sizeof(VERBLOCK) already includes
  3382. //... the size of a WCHAR so we do not
  3383. //... need to add 1 to length of the key.
  3384. wLen += (WORD) (BYTESINSTRING( pVerData->szKey));
  3385. wLen = DWORDUP( wLen); //... Possible DWORD padding
  3386. return ( (TCHAR *)((PBYTE)pVerData + wLen));
  3387. }
  3388. //....................................................................
  3389. #endif //... RLRES32
  3390. /**
  3391. *
  3392. *
  3393. * Function: TokResVer
  3394. * Reads through the Version Info blocks, and writes any info requiring
  3395. * localization to the token file.
  3396. *
  3397. *
  3398. * Arguments:
  3399. * TokeFile, file pointer of token file.
  3400. * ResHeader, Resource Header info for version stamping. Need to generate
  3401. * the token IDs.
  3402. *
  3403. * Returns:
  3404. *
  3405. * Errors Codes:
  3406. * 1, info written to token file.
  3407. *
  3408. * History:
  3409. * 11/91. Implemented. TerryRu.
  3410. * 10/92. Added RLRES32 version DaveWi
  3411. * 01/93 Added support for var length token text strings. MHotchin
  3412. *
  3413. **/
  3414. #ifdef RLRES32
  3415. int TokResVer(
  3416. FILE *fpTokFile, //... Output token file
  3417. RESHEADER ResHeader, //... Resource header of version resource
  3418. VERBLOCK *pVerData, //... Data to tokenize
  3419. WORD wDataLen) //... # bytes in pVerData
  3420. {
  3421. TOKEN Tok;
  3422. BOOL fInStringInfo = FALSE; //... TRUE if reading StringFileInfo
  3423. WORD wTokNum = 0; //... Put into Tok.wID field
  3424. WORD wTokContinueNum = 0; //... Put into Tok.wFlag field
  3425. if (wDataLen == 0 || wDataLen == (WORD)-1) {
  3426. return (-1); //... No data to tokenize
  3427. }
  3428. //... Fill in static part of TOKEN struct
  3429. Tok.wType = ResHeader.wTypeID;
  3430. Tok.wName = IDFLAG;
  3431. Tok.szName[0] = TEXT('\0');
  3432. Tok.szType[0] = TEXT('\0');
  3433. Tok.wReserved = (gbMaster? ST_NEW : ST_NEW | ST_TRANSLATED);
  3434. //... Make a token for each string found
  3435. while (wDataLen > 0) {
  3436. WORD wRC;
  3437. //... Start of a StringFileInfo block?
  3438. wRC =(WORD)_tcsncmp((TCHAR *)pVerData->szKey,
  3439. (TCHAR *)STRINGFILEINFO,
  3440. min(wDataLen, (WORD)STRINGFILEINFOLEN));
  3441. if (wRC == SAME) {
  3442. WORD wStringInfoLen = 0; //... # of bytes in StringFileInfo
  3443. WORD wLen = 0;
  3444. //... Get # of bytes in this StringFileInfo
  3445. //... (Length of value is always 0 here)
  3446. wStringInfoLen = pVerData->wLength;
  3447. //... Move to start of first StringTable blk.
  3448. wLen = (WORD)(DWORDUP(sizeof(VERBLOCK)
  3449. - sizeof(WCHAR)
  3450. + MEMSIZE( STRINGFILEINFOLEN)));
  3451. pVerData = (PVERBLOCK)((PBYTE)pVerData + wLen);
  3452. DECWORDBY(&wDataLen, wLen);
  3453. DECWORDBY(&wStringInfoLen, wLen);
  3454. while (wStringInfoLen > 0) {
  3455. WORD wStringTableLen = 0;
  3456. //... Get # of bytes in this StringTable
  3457. //... (Length of value is always 0 here)
  3458. wStringTableLen = pVerData->wLength;
  3459. //... Copy Language BLOCK Info key
  3460. //... into Token name
  3461. lstrcpy((TCHAR *)Tok.szName, (TCHAR *)LANGUAGEINFO);
  3462. //... Copy lang string into token
  3463. Tok.szText = (TCHAR *) FALLOC(MEMSIZE(LANGSTRINGLEN+1));
  3464. CopyMemory( Tok.szText,
  3465. pVerData->szKey,
  3466. LANGSTRINGLEN * sizeof ( TCHAR));
  3467. Tok.szText[ LANGSTRINGLEN] = TEXT('\0');
  3468. Tok.wID = wTokNum++;
  3469. Tok.wFlag = 0;
  3470. PutToken(fpTokFile, &Tok);
  3471. RLFREE( Tok.szText);
  3472. //... Move to start of first String.
  3473. wLen = DWORDUP(sizeof(VERBLOCK)
  3474. - sizeof(WCHAR)
  3475. + MEMSIZE( LANGSTRINGLEN));
  3476. pVerData = (PVERBLOCK)((PBYTE)pVerData + wLen);
  3477. DECWORDBY(&wDataLen, wLen);
  3478. DECWORDBY(&wStringInfoLen, wLen);
  3479. DECWORDBY(&wStringTableLen, wLen);
  3480. while (wStringTableLen > 0) {
  3481. //... Is value a string?
  3482. if (pVerData->wType == VERTYPESTRING) {
  3483. Tok.wID = wTokNum++;
  3484. lstrcpy( (TCHAR *)Tok.szName, (TCHAR *)pVerData->szKey);
  3485. Tok.szText = BinToText( GetVerValue( pVerData),
  3486. lstrlen( GetVerValue( pVerData)));
  3487. PutToken(fpTokFile, &Tok);
  3488. RLFREE( Tok.szText);
  3489. }
  3490. //... Move to start of next String.
  3491. pVerData = MoveAlongVer(pVerData,
  3492. &wDataLen,
  3493. &wStringInfoLen,
  3494. &wStringTableLen);
  3495. } //... END while (wStringTableLen)
  3496. } //... END while (wStringInfoLen)
  3497. } else {
  3498. if (_tcsncmp((TCHAR *)pVerData->szKey,
  3499. (TCHAR *)VARFILEINFO,
  3500. min(wDataLen, (WORD)VARFILEINFOLEN)) == SAME) {
  3501. WORD wVarInfoLen = 0; //... # of bytes in VarFileInfo
  3502. WORD wLen = 0;
  3503. //... Get # of bytes in this VarFileInfo
  3504. //... (Length of value is always 0 here)
  3505. wVarInfoLen = pVerData->wLength;
  3506. //... Move to start of first Var.
  3507. wLen = (WORD)(DWORDUP(sizeof(VERBLOCK)
  3508. - sizeof(WCHAR)
  3509. + MEMSIZE( VARFILEINFOLEN)));
  3510. pVerData = (PVERBLOCK)((PBYTE)pVerData + wLen);
  3511. DECWORDBY(&wDataLen, wLen);
  3512. DECWORDBY(&wVarInfoLen, wLen);
  3513. while (wVarInfoLen > 0) {
  3514. if (_tcsncmp(pVerData->szKey,
  3515. TRANSLATION,
  3516. min( wDataLen, (WORD)TRANSLATIONLEN)) == SAME) {
  3517. PBYTE pValue = NULL;
  3518. WORD wTransLen = 0;
  3519. USHORT uByte1 = 0;
  3520. USHORT uByte2 = 0;
  3521. UINT uLen = 0;
  3522. wTokContinueNum = 0;
  3523. //... How many bytes are we to tokenize?
  3524. wTransLen = pVerData->wValueLength;
  3525. //... Where are those bytes?
  3526. pValue = (PBYTE)GetVerValue(pVerData);
  3527. //... Copy VarFileInfo into Token
  3528. lstrcpy((TCHAR *)Tok.szName, (TCHAR *)pVerData->szKey);
  3529. //... Allocate a buffer for a space-separated
  3530. //... list of the lang ID's in this vresion res.
  3531. *szDHW = '\0';
  3532. while ( wTransLen >= TRANSDATALEN ) {
  3533. //... Write translation language id by
  3534. //... reversing byte pairs so the id looks
  3535. //... like the language id string. This will
  3536. //... have to be undone in PutResVer().
  3537. uByte1 = *pValue;
  3538. uByte2 = *(pValue + 1);
  3539. sprintf( &szDHW[ lstrlenA( szDHW)],
  3540. "%02hx%02hx",
  3541. uByte2, //... Reverses byte order to
  3542. uByte1); //... be like transltn str.
  3543. //... Move to next possible translation value
  3544. wTransLen -= TRANSDATALEN;
  3545. if ( wTransLen >= TRANSDATALEN ) {
  3546. pValue += TRANSDATALEN;
  3547. strcat( szDHW, " "); //... white-space sep
  3548. }
  3549. } //... END while ( wTransLen ...
  3550. uLen = lstrlenA( szDHW) + 1;
  3551. Tok.szText = (TCHAR *)FALLOC( MEMSIZE( uLen));
  3552. _MBSTOWCS( (TCHAR *)Tok.szText, szDHW, uLen, (UINT)-1);
  3553. Tok.wID = wTokNum;
  3554. Tok.wFlag = wTokContinueNum++;
  3555. PutToken( fpTokFile, &Tok);
  3556. RLFREE( Tok.szText);
  3557. } //... END if (_tcsncmp( ...
  3558. //... Move to start of next Var info block.
  3559. pVerData = MoveAlongVer(pVerData,
  3560. &wDataLen,
  3561. &wVarInfoLen,
  3562. NULL);
  3563. } //... END while (wVarInfoLen)
  3564. } else {
  3565. QuitT( IDS_ENGERR_14, (LPTSTR)IDS_INVVERBLK, NULL);
  3566. }
  3567. }
  3568. } //... END while (wDataLen)
  3569. return (0);
  3570. }
  3571. #else //... RLRES32
  3572. int TokResVer(FILE * TokFile, RESHEADER ResHeader, VERBLOCK *pVerBlk)
  3573. {
  3574. TCHAR szLangIdBuf[20];
  3575. TCHAR szCodePageIdBuf[20];
  3576. #ifdef RLRES32
  3577. CHAR szTmpBuf[20];
  3578. #endif
  3579. WORD wcLang = 0, wcBlock = 0;
  3580. TOKEN tok;
  3581. VERBLOCK *pCurBlk;
  3582. TCHAR *pszStr;
  3583. DWORD *pdwVal;
  3584. int wTotLen, nHeadLen, wBlkLen;
  3585. // the count fields are int because count may go negative
  3586. // because the last DWORD alignment is not counted in the
  3587. // byte count.
  3588. // Fill in static part of TOKEN struct
  3589. tok.wType = ResHeader.wTypeID;
  3590. tok.wName = IDFLAG;
  3591. tok.wReserved = (gbMaster? ST_NEW : ST_NEW | ST_TRANSLATED);
  3592. wTotLen = DWORDUP(pVerBlk->nTotLen);
  3593. tok.wID = wcBlock;
  3594. pszStr = pVerBlk->szKey;
  3595. nHeadLen = 4 + DWORDUP(pVerBlk->nValLen) + DWORDUP(lstrlen((TCHAR *)pszStr) + 1);
  3596. wTotLen -= nHeadLen;
  3597. pCurBlk = (VERBLOCK *) ((TCHAR *) pVerBlk + nHeadLen);
  3598. while (wTotLen > 0) {
  3599. // For string file tables we localize the key field
  3600. tok.wFlag = ISKEY;
  3601. wBlkLen = DWORDUP(pCurBlk->nTotLen);
  3602. pszStr = pCurBlk->szKey;
  3603. tok.szText = BinToText( pszStr, lstrlen((TCHAR *)pszStr));
  3604. lstrcpy((TCHAR *)tok.szName, TEXT("Language Info"));
  3605. tok.wID = wcBlock;
  3606. PutToken(TokFile, &tok);
  3607. RLFREE(tok.szText);
  3608. // Get offset to next block;
  3609. nHeadLen = 4 +
  3610. DWORDUP(pVerBlk->nValLen) +
  3611. DWORDUP(lstrlen((TCHAR *)pszStr) + 1);
  3612. // Update counter vars
  3613. wTotLen -= wBlkLen;
  3614. wBlkLen -= nHeadLen;
  3615. // set pointer to next ver block
  3616. pCurBlk = (VERBLOCK*) ((TCHAR *) pCurBlk + nHeadLen);
  3617. // For string blocks we localize the value field.
  3618. tok.wFlag = ISVAL;
  3619. // Now output the tokens in String Block
  3620. while (wBlkLen>0) {
  3621. pszStr = pCurBlk->szKey;
  3622. lstrcpy((TCHAR *)tok.szName, (TCHAR *)pszStr);
  3623. pszStr = (TCHAR *) pCurBlk+4+DWORDUP(lstrlen((TCHAR *)pszStr)+1);
  3624. tok.szText = BinToText( pszStr, lstrlen((TCHAR *)pszStr));
  3625. PutToken(TokFile, &tok);
  3626. RLFREE(tok.szText);
  3627. wBlkLen -= DWORDUP(pCurBlk->nTotLen);
  3628. pCurBlk = (VERBLOCK *) ((TCHAR *) pCurBlk + DWORDUP(pCurBlk->nTotLen));
  3629. }
  3630. wcBlock++;
  3631. }
  3632. // Skip past Head of VarInfoBlock
  3633. wTotLen = DWORDUP(pCurBlk->nTotLen);
  3634. pszStr = pCurBlk->szKey;
  3635. nHeadLen = 4 + DWORDUP(pVerBlk->nValLen) + DWORDUP(lstrlen((TCHAR *)pszStr) + 1);
  3636. wTotLen -= nHeadLen;
  3637. pCurBlk = (VERBLOCK *)((TCHAR *) pCurBlk + nHeadLen);
  3638. wcLang = 0;
  3639. // In Var File blocks we localize the value fields.
  3640. tok.wFlag = ISVAL;
  3641. while (wTotLen > 0) {
  3642. TCHAR szTemp[256];
  3643. pszStr = pCurBlk->szKey;
  3644. tok.wID = wcLang;
  3645. lstrcpy((TCHAR *)tok.szName, TEXT("Translation"));
  3646. pdwVal = (DWORD *)((TCHAR *) pCurBlk + 4 + DWORDUP(lstrlen((TCHAR *)pszStr) + 1));
  3647. #ifdef RLRES32
  3648. _itoa(HIWORD(*pdwVal) , szTmpBuf, 16);
  3649. _MBSTOWCS( szLangIdBuf,
  3650. szTmpBuf,
  3651. WCHARSIN( sizeof( szLangIdBuf)),
  3652. ACHARSIN( strlen( szTmpBuf ) + 1));
  3653. #else
  3654. _itoa(HIWORD(*pdwVal) , szLangIdBuf, 16);
  3655. #endif
  3656. #ifdef RLRES32
  3657. _itoa(LOWORD(*pdwVal), szTmpBuf, 16);
  3658. _MBSTOWCS( szCodePageIdBuf,
  3659. szTmpBuf,
  3660. WCHARSIN( sizeof( szCodePageIdBuf)),
  3661. ACHARSIN( strlen( szTmpBuf ) + 1));
  3662. #else
  3663. _itoa(LOWORD(*pdwVal), szCodePageIdBuf, 16);
  3664. #endif
  3665. // Construct Token Text
  3666. // Note leading zeros gets lost in itoa translation
  3667. lstrcpy((TCHAR *)szTemp, TEXT("0"));
  3668. _tcscat((TCHAR *)szTemp, _tcsupr((TCHAR *)szCodePageIdBuf));
  3669. _tcscat((TCHAR *)szTemp, TEXT("0"));
  3670. _tcscat((TCHAR *)szTemp, _tcsupr((TCHAR *)szLangIdBuf));
  3671. tok.szText = BinToText( szTemp, lstrlen((TCHAR *)szTemp));
  3672. PutToken(TokFile, &tok);
  3673. RLFREE(tok.szText);
  3674. wcLang ++;
  3675. wTotLen -= DWORDUP(pCurBlk->nTotLen);
  3676. pCurBlk = (VERBLOCK *) ((BYTE *) pCurBlk + DWORDUP(pCurBlk->nTotLen));
  3677. }
  3678. return (1);
  3679. }
  3680. #endif //... RLRES32
  3681. /**
  3682. *
  3683. *
  3684. * Function: UpdateResSize
  3685. * Preforms the Resource Header size fixup, once the size of
  3686. * the localized resource block is determined.
  3687. *
  3688. *
  3689. * Arguments:
  3690. * OutResFile, File pointer of localized resource file.
  3691. * pResSizePos, file location of size file, of the resoure header.
  3692. * lSize, size of the localized resource.
  3693. *
  3694. * Returns:
  3695. * The size field fixed up to the value specfied in the lsize.
  3696. *
  3697. * Errors Codes:
  3698. * TRUE, fixup sucessfull.
  3699. * Result of fsetpos, and fgetpos call.
  3700. *
  3701. * History:
  3702. *
  3703. *
  3704. **/
  3705. WORD UpdateResSize (FILE * OutResFile, fpos_t *pResSizePos, DWORD lSize)
  3706. {
  3707. WORD rc;
  3708. fpos_t tResSizePos;
  3709. if ((rc = (WORD) fgetpos (OutResFile, &tResSizePos)) != 0) {
  3710. return (rc);
  3711. }
  3712. if ((rc = (WORD) fsetpos (OutResFile, pResSizePos)) != 0) {
  3713. return (rc);
  3714. }
  3715. PutdWord(OutResFile, lSize, NULL);
  3716. if ((rc = (WORD) fsetpos (OutResFile, &tResSizePos)) != 0) {
  3717. return (rc);
  3718. }
  3719. return (TRUE) ;
  3720. }
  3721. /**
  3722. *
  3723. *
  3724. * Function:
  3725. *
  3726. *
  3727. * Arguments:
  3728. *
  3729. * Returns:
  3730. *
  3731. * Errors Codes:
  3732. *
  3733. * History:
  3734. * 01/93 Added support for var length token text strings. MHotchin
  3735. *
  3736. **/
  3737. void PutAccelTable(FILE *OutResFile,
  3738. FILE *TokFile,
  3739. RESHEADER ResHeader,
  3740. ACCELTABLEENTRY *pAccelTable,
  3741. WORD wcAccelEntries)
  3742. {
  3743. fpos_t ResSizePos = 0;
  3744. TOKEN tok;
  3745. WORD wcCount = 0;
  3746. DWORD lSize = 0L;
  3747. TCHAR pErrBuf[MAXINPUTBUFFER];
  3748. #ifdef RLRES32
  3749. CHAR szTmpBuf[30];
  3750. #endif
  3751. TCHAR *cpAscii, *cpID;
  3752. if ( PutResHeader (OutResFile, ResHeader , &ResSizePos, &lSize)) {
  3753. QuitT( IDS_ENGERR_06, (LPTSTR)IDS_ACCELKEY, NULL);
  3754. }
  3755. lSize = 0L;
  3756. // Prep for find token call
  3757. tok.wType = ResHeader.wTypeID;
  3758. tok.wName = ResHeader.wNameID;
  3759. tok.wID = 0;
  3760. tok.wFlag = 0;
  3761. tok.wReserved = ST_TRANSLATED;
  3762. lstrcpy( tok.szName, ResHeader.pszName);
  3763. for (wcCount = 0; wcCount < wcAccelEntries; wcCount++) {
  3764. tok.wID = wcCount;
  3765. tok.wFlag = (WORD) pAccelTable[wcCount].fFlags;
  3766. tok.szText = NULL;
  3767. if (!FindToken(TokFile, &tok, ST_TRANSLATED)) {
  3768. ParseTokToBuf(pErrBuf, &tok);
  3769. QuitT( IDS_ENGERR_05, pErrBuf, NULL);
  3770. }
  3771. tok.wReserved = ST_TRANSLATED;
  3772. cpID = (TCHAR *)tok.szText;
  3773. cpAscii = _tcschr((TCHAR *)tok.szText, TEXT(' '));
  3774. (*cpAscii) = '\0';
  3775. cpAscii++;
  3776. #ifdef RLRES16
  3777. #ifndef PDK2
  3778. PutByte (OutResFile, (BYTE) pAccelTable[wcCount].fFlags, &lSize);
  3779. #else // PDK2
  3780. PutWord (OutResFile, (WORD) pAccelTable[wcCount].fFlags, &lSize);
  3781. #endif // PDK2
  3782. #else // RLRES16
  3783. PutWord (OutResFile, (WORD) pAccelTable[wcCount].fFlags, &lSize);
  3784. #endif // RLRES16
  3785. #ifdef RLRES32
  3786. _WCSTOMBS( szTmpBuf,
  3787. cpAscii,
  3788. ACHARSIN( sizeof( szTmpBuf)),
  3789. lstrlen( cpAscii ) + 1 );
  3790. PutWord (OutResFile, (WORD) atoi(szTmpBuf), &lSize);
  3791. _WCSTOMBS( szTmpBuf,
  3792. cpID,
  3793. ACHARSIN( sizeof( szTmpBuf)),
  3794. lstrlen( cpID ) + 1 );
  3795. PutWord (OutResFile, (WORD) atoi(szTmpBuf), &lSize);
  3796. #else // RLRES32
  3797. PutWord (OutResFile, (WORD) atoi(cpAscii), &lSize);
  3798. PutWord (OutResFile, (WORD) atoi(cpID), &lSize);
  3799. #endif // RLRES32
  3800. #ifdef RLRES32
  3801. PutWord (OutResFile, pAccelTable[wcCount].wPadding, &lSize);
  3802. #endif
  3803. RLFREE( tok.szText);
  3804. } // for
  3805. if (!UpdateResSize (OutResFile, &ResSizePos , lSize)) {
  3806. QuitT( IDS_ENGERR_07, (LPTSTR)IDS_ACCELKEY, NULL);
  3807. }
  3808. } // PutAccelTable
  3809. void CopyRes(
  3810. FILE *fpInResFile,
  3811. FILE *fpOutResFile,
  3812. RESHEADER *pResHeader,
  3813. fpos_t *pResSizePos)
  3814. {
  3815. DWORD dwTmp = 0L;
  3816. PutResHeader( fpOutResFile, *pResHeader, pResSizePos, &dwTmp);
  3817. ReadInRes( fpInResFile, fpOutResFile, (DWORD *)&(pResHeader->lSize));
  3818. #ifdef RLRES32
  3819. DWordUpFilePointer( fpInResFile, MYREAD, ftell( fpInResFile), NULL);
  3820. DWordUpFilePointer( fpOutResFile, MYWRITE, ftell( fpOutResFile), NULL);
  3821. #endif
  3822. }
  3823. /////////////////////////////
  3824. // GetDlgInit
  3825. //
  3826. // VC++ uses a new resource type, DLGINIT (#240) when storing the
  3827. // initial contents of a list box. The data for this resource type
  3828. // is unaligned and containg non-Unicode strings. This function will
  3829. // read the resource data from the resource file pfInRes into a linked
  3830. // list of structures and will return a pointer to the head of that list.
  3831. // The parameter pdwSize contains the size of the resource as read from
  3832. // the resources associated resource header prior to this function
  3833. // being called.
  3834. // NOTE: The first entry in the list is aligned so it is treated
  3835. // slightly differently than are the remaining entries.
  3836. PDLGINITDATA GetDlgInit( FILE * pfInRes, DWORD *pdwSize)
  3837. {
  3838. PDLGINITDATA pList = NULL;
  3839. PDLGINITDATA pListEntry = NULL;
  3840. WORD wTmp = 0;
  3841. while ( *pdwSize > sizeof( DWORD) + 2 * sizeof( WORD) ) {
  3842. if ( pList ) { // allocate the next entry in the list
  3843. pListEntry->pNext = (PDLGINITDATA)FALLOC( sizeof( DLGINITDATA));
  3844. pListEntry = pListEntry->pNext;
  3845. } else { // allocate the head of the list
  3846. pList = (PDLGINITDATA)FALLOC( sizeof( DLGINITDATA));
  3847. pListEntry = pList;
  3848. }
  3849. // save the first two WORD fields of the data
  3850. pListEntry->wControlID = GetWord( pfInRes, pdwSize);
  3851. pListEntry->wMessageNumber = GetWord( pfInRes, pdwSize);
  3852. // get the string's length (incl nul terminator)
  3853. pListEntry->dwStringLen = GetdWord( pfInRes, pdwSize);
  3854. // get the string
  3855. pListEntry->pszString = FALLOC( pListEntry->dwStringLen);
  3856. for ( wTmp = 0; (pListEntry->pszString[ wTmp] = GetByte( pfInRes, pdwSize)); ++wTmp )
  3857. ; // empty loop
  3858. }
  3859. // Skip the trailing zero-value WORD
  3860. SkipBytes( pfInRes, pdwSize);
  3861. #ifdef RLRES32
  3862. DWordUpFilePointer( pfInRes, MYREAD, ftell( pfInRes), NULL);
  3863. #endif
  3864. return ( pList);
  3865. }
  3866. //////////////////////////////
  3867. // TokDlgInit
  3868. //
  3869. // Make tokens in pTokFile out of the data in the pDlgInit linked list.
  3870. void TokDlgInit( FILE *pfTokFile, RESHEADER ResHeader, PDLGINITDATA pDlgInit)
  3871. {
  3872. int nLen = 0;
  3873. WORD wCount = 0;
  3874. static TOKEN Tok;
  3875. #ifdef UNICODE
  3876. static TCHAR szTmpBuf[ 256];
  3877. #else
  3878. PCHAR szTmpBuf = NULL;
  3879. #endif
  3880. ZeroMemory( &Tok, sizeof( Tok));
  3881. Tok.wType = ResHeader.wTypeID;
  3882. Tok.wName = ResHeader.wNameID;
  3883. Tok.wReserved = (gbMaster ? ST_NEW : ST_NEW | ST_TRANSLATED);
  3884. lstrcpy( Tok.szName, ResHeader.pszName);
  3885. while ( pDlgInit ) {
  3886. Tok.wID = wCount++;
  3887. Tok.wFlag = 0;
  3888. #ifdef UNICODE
  3889. nLen = _MBSTOWCS( szTmpBuf,
  3890. pDlgInit->pszString,
  3891. WCHARSIN( sizeof( szTmpBuf)),
  3892. (UINT)-1);
  3893. #else
  3894. nLen = strlen( pDlgInit->pszString);
  3895. szTmpBuf = pDlgInit->pszString;
  3896. #endif
  3897. Tok.szText = BinToTextW( szTmpBuf, nLen);
  3898. PutToken( pfTokFile, &Tok);
  3899. RLFREE( Tok.szText);
  3900. pDlgInit = pDlgInit->pNext;
  3901. }
  3902. }
  3903. ////////////////////////////
  3904. // PutDlgInit
  3905. //
  3906. // Create a new resource in pfOutRes using the data stored in pDlgInit
  3907. // and the token text in the pfTokFile.
  3908. void PutDlgInit( FILE *pOutResFile, FILE *pTokFile, RESHEADER ResHeader, PDLGINITDATA pDlgInit)
  3909. {
  3910. fpos_t ResSizePos = 0;
  3911. TOKEN Tok;
  3912. DWORD lSize = 0L;
  3913. PCHAR pszTmp = NULL;
  3914. if ( PutResHeader( pOutResFile, ResHeader , &ResSizePos, &lSize)) {
  3915. QuitT( IDS_ENGERR_06, TEXT("DLGINIT"), NULL);
  3916. }
  3917. lSize = 0L;
  3918. // Prep for find token call
  3919. Tok.wType = ResHeader.wTypeID;
  3920. Tok.wName = ResHeader.wNameID;
  3921. Tok.wID = 0;
  3922. Tok.wFlag = 0;
  3923. Tok.wReserved = ST_TRANSLATED;
  3924. lstrcpy( Tok.szName, ResHeader.pszName);
  3925. while ( pDlgInit ) {
  3926. Tok.szText = NULL;
  3927. if ( ! FindToken( pTokFile, &Tok, ST_TRANSLATED)) {
  3928. ParseTokToBuf( (LPTSTR)szDHW, &Tok);
  3929. QuitT( IDS_ENGERR_05, (LPTSTR)szDHW, NULL);
  3930. }
  3931. Tok.wReserved = ST_TRANSLATED;
  3932. Tok.wID++;
  3933. // Write out the two unchanged WORD fields
  3934. PutWord( pOutResFile, pDlgInit->wControlID, &lSize);
  3935. PutWord( pOutResFile, pDlgInit->wMessageNumber, &lSize);
  3936. // write the length of the new string (incl nul)
  3937. _WCSTOMBS( szDHW, Tok.szText, DHWSIZE, (UINT)-1);
  3938. PutdWord( pOutResFile, strlen( szDHW) + 1, &lSize);
  3939. // write the new string (incl nul)
  3940. for ( pszTmp = szDHW; *pszTmp; ++pszTmp ) {
  3941. PutByte( pOutResFile, *pszTmp, &lSize);
  3942. }
  3943. PutByte( pOutResFile, '\0', &lSize);
  3944. pDlgInit = pDlgInit->pNext;
  3945. }
  3946. // write the trailing zero-value WORD
  3947. PutWord( pOutResFile, 0, &lSize);
  3948. if ( ! UpdateResSize( pOutResFile, &ResSizePos, lSize) ) {
  3949. QuitT( IDS_ENGERR_07, TEXT("DLGINIT"), NULL);
  3950. }
  3951. #ifdef RLRES32
  3952. DWordUpFilePointer( pOutResFile, MYWRITE, ftell( pOutResFile), NULL);
  3953. #endif
  3954. }
  3955. //////////////////////////////
  3956. // ClearDlgInitData
  3957. //
  3958. // Free the memory allocated for the DlgInitData linked list in GetDlgInit().
  3959. void ClearDlgInitData( PDLGINITDATA pDlgInit)
  3960. {
  3961. while ( pDlgInit ) {
  3962. PDLGINITDATA pTmp = pDlgInit->pNext;
  3963. RLFREE( pDlgInit->pszString);
  3964. RLFREE( pDlgInit);
  3965. pDlgInit = pTmp;
  3966. }
  3967. }