Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

578 lines
15 KiB

  1. /****************************************************************************/
  2. /* */
  3. /* rcx.C - AFX symbol info writer */
  4. /* */
  5. /* Windows 3.5 Resource Compiler */
  6. /* */
  7. /****************************************************************************/
  8. #include "rc.h"
  9. /////////////////////////////////////////////////////////////////////////////
  10. // Symbol information
  11. static PFILE fhFileMap;
  12. static LONG lFileMap;
  13. static PFILE fhResMap;
  14. static LONG lResMap;
  15. static PFILE fhRefMap;
  16. static LONG lRefMap;
  17. static PFILE fhSymList;
  18. static LONG lSymList;
  19. static LONG HdrOffset;
  20. static CHAR szEndOfResource[2] = {'$', '\000'};
  21. static CHAR szSymList[_MAX_PATH];
  22. static CHAR szFileMap[_MAX_PATH];
  23. static CHAR szRefMap[_MAX_PATH];
  24. static CHAR szResMap[_MAX_PATH];
  25. static WCHAR szName[] = L"HWB";
  26. #define OPEN_FLAGS (_O_TRUNC | _O_BINARY | _O_CREAT | _O_RDWR)
  27. #define PROT_FLAGS (S_IWRITE | S_IWRITE)
  28. void
  29. wtoa(
  30. WORD value,
  31. char* string,
  32. int radix
  33. )
  34. {
  35. if (value == (WORD)-1)
  36. _itoa(-1, string, radix);
  37. else
  38. _itoa(value, string, radix);
  39. }
  40. int
  41. ConvertAndWrite(
  42. PFILE fp,
  43. PWCHAR pwch
  44. )
  45. {
  46. int n;
  47. char szMultiByte[_MAX_PATH]; // assumes _MAX_PATH >= MAX_SYMBOL
  48. n = wcslen(pwch) + 1;
  49. n = WideCharToMultiByte(uiCodePage, 0,
  50. pwch, n,
  51. szMultiByte, MAX_PATH,
  52. NULL, NULL);
  53. return MyWrite(fp, (PVOID)szMultiByte, n);
  54. }
  55. VOID
  56. WriteResHdr (
  57. FILE *fh,
  58. LONG size,
  59. WORD id
  60. )
  61. {
  62. LONG val;
  63. /* add data size and header size */
  64. MyWrite(fh, (PVOID)&size, sizeof(ULONG)); // will backpatch
  65. MyWrite(fh, (PVOID)&HdrOffset, sizeof(ULONG));
  66. /* add type and name */
  67. MyWrite(fh, (PVOID)szName, sizeof(szName));
  68. val = 0xFFFF;
  69. MyWrite(fh, (PVOID)&val, sizeof(WORD));
  70. MyWrite(fh, (PVOID)&id, sizeof(WORD));
  71. MyAlign(fh);
  72. /* add data struct version, flags, language, resource data version
  73. /* and characteristics */
  74. val = 0;
  75. MyWrite(fh, (PVOID)&val, sizeof(ULONG));
  76. val = 0x0030;
  77. MyWrite(fh, (PVOID)&val, sizeof(WORD));
  78. MyWrite(fh, (PVOID)&language, sizeof(WORD));
  79. val = 2;
  80. MyWrite(fh, (PVOID)&val, sizeof(ULONG));
  81. MyWrite(fh, (PVOID)&characteristics, sizeof(ULONG));
  82. }
  83. BOOL
  84. InitSymbolInfo(
  85. void
  86. )
  87. {
  88. PCHAR szTmp;
  89. if (!fAFXSymbols)
  90. return(TRUE);
  91. if ((szTmp = _tempnam(NULL, "RCX1")) != NULL) {
  92. strcpy(szSymList, szTmp);
  93. free(szTmp);
  94. } else {
  95. strcpy(szSymList, tmpnam(NULL));
  96. }
  97. if ((szTmp = _tempnam(NULL, "RCX2")) != NULL) {
  98. strcpy(szFileMap, szTmp);
  99. free(szTmp);
  100. } else {
  101. strcpy(szFileMap, tmpnam(NULL));
  102. }
  103. if ((szTmp = _tempnam(NULL, "RCX3")) != NULL) {
  104. strcpy(szRefMap, szTmp);
  105. free(szTmp);
  106. } else {
  107. strcpy(szRefMap, tmpnam(NULL));
  108. }
  109. if ((szTmp = _tempnam(NULL, "RCX4")) != NULL) {
  110. strcpy(szResMap, szTmp);
  111. free(szTmp);
  112. } else {
  113. strcpy(szResMap, tmpnam(NULL));
  114. }
  115. if (!(fhFileMap = fopen(szFileMap, "w+b")) ||
  116. !(fhSymList = fopen(szSymList, "w+b")) ||
  117. !(fhRefMap = fopen(szRefMap, "w+b")) ||
  118. !(fhResMap = fopen(szResMap, "w+b")))
  119. return FALSE;
  120. /* calculate header size */
  121. HdrOffset = sizeof(szName);
  122. HdrOffset += 2 * sizeof(WORD);
  123. if (HdrOffset % 4)
  124. HdrOffset += sizeof(WORD); // could only be off by 2
  125. HdrOffset += sizeof(RESADDITIONAL);
  126. WriteResHdr(fhSymList, lSymList, 200);
  127. WriteResHdr(fhFileMap, lFileMap, 201);
  128. WriteResHdr(fhRefMap, lRefMap, 202);
  129. WriteResHdr(fhResMap, lResMap, 2);
  130. return TRUE;
  131. }
  132. BOOL
  133. TermSymbolInfo(
  134. PFILE fhResFile
  135. )
  136. {
  137. long lStart;
  138. PTYPEINFO pType;
  139. RESINFO r;
  140. if (!fAFXSymbols)
  141. return(TRUE);
  142. if (fhResFile == NULL_FILE)
  143. goto termCloseOnly;
  144. WriteSymbolDef(L"", L"", L"", 0, (char)0);
  145. MySeek(fhSymList, 0L, SEEK_SET);
  146. MyWrite(fhSymList, (PVOID)&lSymList, sizeof(lSymList));
  147. MySeek(fhFileMap, 0L, SEEK_SET);
  148. MyWrite(fhFileMap, (PVOID)&lFileMap, sizeof(lFileMap));
  149. WriteResInfo(NULL, NULL, FALSE);
  150. MySeek(fhRefMap, 0L, SEEK_SET);
  151. MyWrite(fhRefMap, (PVOID)&lRefMap, sizeof(lRefMap));
  152. // now append these to .res
  153. pType = AddResType(L"HWB", 0);
  154. r.flags = 0x0030;
  155. r.name = NULL;
  156. r.next = NULL;
  157. r.language = language;
  158. r.version = version;
  159. r.characteristics = characteristics;
  160. MySeek(fhSymList, 0L, SEEK_SET);
  161. MyAlign(fhResFile);
  162. r.BinOffset = MySeek(fhResFile, 0L, SEEK_END) + HdrOffset;
  163. r.size = lSymList;
  164. r.nameord = 200;
  165. WriteResInfo(&r, pType, TRUE);
  166. MyCopyAll(fhSymList, fhResFile);
  167. MySeek(fhFileMap, 0L, SEEK_SET);
  168. MyAlign(fhResFile);
  169. r.BinOffset = MySeek(fhResFile, 0L, SEEK_END) + HdrOffset;
  170. r.size = lFileMap;
  171. r.nameord = 201;
  172. WriteResInfo(&r, pType, TRUE);
  173. MyCopyAll(fhFileMap, fhResFile);
  174. MySeek(fhRefMap, 0L, SEEK_SET);
  175. MyAlign(fhResFile);
  176. r.BinOffset = MySeek(fhResFile, 0L, SEEK_END) + HdrOffset;
  177. r.size = lRefMap;
  178. r.nameord = 202;
  179. WriteResInfo(&r, pType, TRUE);
  180. MyCopyAll(fhRefMap, fhResFile);
  181. MyAlign(fhResFile);
  182. lStart = MySeek(fhResFile, 0L, SEEK_CUR);
  183. MySeek(fhResMap, 0L, SEEK_SET);
  184. MyWrite(fhResMap, (PVOID)&lResMap, sizeof(lResMap));
  185. MySeek(fhResMap, 0L, SEEK_SET);
  186. MyCopyAll(fhResMap, fhResFile);
  187. // patch the HWB:1 resource with HWB:2's starting point
  188. MySeek(fhResFile, lOffIndex, SEEK_SET);
  189. MyWrite(fhResFile, (PVOID)&lStart, sizeof(lStart));
  190. MySeek(fhResFile, 0L, SEEK_END);
  191. termCloseOnly:;
  192. if (fhFileMap) {
  193. fclose(fhFileMap);
  194. remove(szFileMap);
  195. }
  196. if (fhRefMap) {
  197. fclose(fhRefMap);
  198. remove(szRefMap);
  199. }
  200. if (fhSymList) {
  201. fclose(fhSymList);
  202. remove(szSymList);
  203. }
  204. if (fhResMap) {
  205. fclose(fhResMap);
  206. remove(szResMap);
  207. }
  208. return TRUE;
  209. }
  210. void
  211. WriteSymbolUse(
  212. PSYMINFO pSym
  213. )
  214. {
  215. if (!fAFXSymbols)
  216. return;
  217. if (pSym == NULL) {
  218. WORD nID = (WORD)-1;
  219. lRefMap += MyWrite(fhRefMap, (PVOID)&szEndOfResource, sizeof(szEndOfResource));
  220. lRefMap += MyWrite(fhRefMap, (PVOID)&nID, sizeof(nID));
  221. } else {
  222. lRefMap += ConvertAndWrite(fhRefMap, pSym->name);
  223. lRefMap += MyWrite(fhRefMap, (PVOID)&pSym->nID, sizeof(pSym->nID));
  224. }
  225. }
  226. void
  227. WriteSymbolDef(
  228. PWCHAR name,
  229. PWCHAR value,
  230. PWCHAR file,
  231. WORD line,
  232. char flags
  233. )
  234. {
  235. if (!fAFXSymbols)
  236. return;
  237. if (name[0] == L'$' && value[0] != L'\0') {
  238. RESINFO res;
  239. TYPEINFO typ;
  240. res.nameord = (USHORT) -1;
  241. res.language = language;
  242. typ.typeord = (USHORT) -1;
  243. WriteFileInfo(&res, &typ, value);
  244. return;
  245. }
  246. lSymList += ConvertAndWrite(fhSymList, name);
  247. lSymList += ConvertAndWrite(fhSymList, value);
  248. lSymList += MyWrite(fhSymList, (PVOID)&line, sizeof(line));
  249. lSymList += MyWrite(fhSymList, (PVOID)&flags, sizeof(flags));
  250. }
  251. void
  252. WriteFileInfo(
  253. PRESINFO pRes,
  254. PTYPEINFO pType,
  255. PWCHAR szFileName
  256. )
  257. {
  258. WORD n1 = 0xFFFF;
  259. if (!fAFXSymbols)
  260. return;
  261. if (pType->typeord == 0) {
  262. lFileMap += MyWrite(fhFileMap, (PVOID)pType->type,
  263. (wcslen(pType->type) + 1) * sizeof(WCHAR));
  264. } else {
  265. WORD n2 = pType->typeord;
  266. if (n2 == (WORD)RT_MENUEX)
  267. n2 = (WORD)RT_MENU;
  268. else if (n2 == (WORD)RT_DIALOGEX)
  269. n2 = (WORD)RT_DIALOG;
  270. lFileMap += MyWrite(fhFileMap, (PVOID)&n1, sizeof(WORD));
  271. lFileMap += MyWrite(fhFileMap, (PVOID)&n2, sizeof(WORD));
  272. }
  273. if (pRes->nameord == 0) {
  274. lFileMap += MyWrite(fhFileMap, (PVOID)pRes->name,
  275. (wcslen(pRes->name) + 1) * sizeof(WCHAR));
  276. } else {
  277. lFileMap += MyWrite(fhFileMap, (PVOID)&n1, sizeof(WORD));
  278. lFileMap += MyWrite(fhFileMap, (PVOID)&pRes->nameord, sizeof(WORD));
  279. }
  280. lFileMap += MyWrite(fhFileMap, (PVOID)&pRes->language, sizeof(WORD));
  281. lFileMap += MyWrite(fhFileMap, (PVOID)szFileName,
  282. (wcslen(szFileName) + 1) * sizeof(WCHAR));
  283. }
  284. void
  285. WriteResInfo(
  286. PRESINFO pRes,
  287. PTYPEINFO pType,
  288. BOOL bWriteMapEntry
  289. )
  290. {
  291. if (!fAFXSymbols)
  292. return;
  293. if (pRes == NULL) {
  294. WORD nID = (WORD)-1;
  295. //assert(bWriteMapEntry == FALSE);
  296. lRefMap += MyWrite(fhRefMap, (PVOID)&szEndOfResource, sizeof(szEndOfResource));
  297. lRefMap += MyWrite(fhRefMap, (PVOID)&nID, sizeof(nID));
  298. return;
  299. }
  300. if (bWriteMapEntry) {
  301. WORD n1 = 0xFFFF;
  302. ULONG t0 = 0;
  303. /* add data size and data offset */
  304. lResMap += MyWrite(fhResMap, (PVOID)&pRes->size, sizeof(ULONG));
  305. lResMap += MyWrite(fhResMap, (PVOID)&pRes->BinOffset, sizeof(ULONG));
  306. /* Is this an ordinal type? */
  307. if (pType->typeord) {
  308. WORD n2 = pType->typeord;
  309. if (n2 == (WORD)RT_MENUEX)
  310. n2 = (WORD)RT_MENU;
  311. else if (n2 == (WORD)RT_DIALOGEX)
  312. n2 = (WORD)RT_DIALOG;
  313. lResMap += MyWrite(fhResMap, (PVOID)&n1, sizeof(WORD));
  314. lResMap += MyWrite(fhResMap, (PVOID)&n2, sizeof(WORD));
  315. } else {
  316. lResMap += MyWrite(fhResMap, (PVOID)pType->type,
  317. (wcslen(pType->type) + 1) * sizeof(WCHAR));
  318. }
  319. if (pRes->nameord) {
  320. lResMap += MyWrite(fhResMap, (PVOID)&n1, sizeof(WORD));
  321. lResMap += MyWrite(fhResMap, (PVOID)&pRes->nameord, sizeof(WORD));
  322. } else {
  323. lResMap += MyWrite(fhResMap, (PVOID)pRes->name,
  324. (wcslen(pRes->name) + 1) * sizeof(WCHAR));
  325. }
  326. lResMap += MyAlign(fhResMap);
  327. /* add data struct version, flags, language, resource data version
  328. /* and characteristics */
  329. lResMap += MyWrite(fhResMap, (PVOID)&t0, sizeof(ULONG));
  330. lResMap += MyWrite(fhResMap, (PVOID)&pRes->flags, sizeof(WORD));
  331. lResMap += MyWrite(fhResMap, (PVOID)&pRes->language, sizeof(WORD));
  332. lResMap += MyWrite(fhResMap, (PVOID)&pRes->version, sizeof(ULONG));
  333. lResMap += MyWrite(fhResMap, (PVOID)&pRes->characteristics, sizeof(ULONG));
  334. return;
  335. }
  336. if (pType->typeord == 0) {
  337. lRefMap += ConvertAndWrite(fhRefMap, pType->type);
  338. } else {
  339. char szID[33];
  340. WORD n2 = pType->typeord;
  341. if (n2 == (WORD)RT_MENUEX)
  342. n2 = (WORD)RT_MENU;
  343. else if (n2 == (WORD)RT_DIALOGEX)
  344. n2 = (WORD)RT_DIALOG;
  345. wtoa(n2, szID, 10);
  346. lRefMap += MyWrite(fhRefMap, (PVOID)szID, strlen(szID)+1);
  347. }
  348. if (pRes->nameord == 0) {
  349. lRefMap += ConvertAndWrite(fhRefMap, pRes->name);
  350. } else {
  351. char szID[33];
  352. wtoa(pRes->nameord, szID, 10);
  353. lRefMap += MyWrite(fhRefMap, (PVOID)szID, strlen(szID)+1);
  354. }
  355. lRefMap += ConvertAndWrite(fhRefMap, pRes->sym.name);
  356. lRefMap += ConvertAndWrite(fhRefMap, pRes->sym.file);
  357. lRefMap += MyWrite(fhRefMap,(PVOID)&pRes->sym.line,sizeof(pRes->sym.line));
  358. }
  359. /*---------------------------------------------------------------------------*/
  360. /* */
  361. /* GetSymbolDef() - get a symbol def record and write out info */
  362. /* */
  363. /*---------------------------------------------------------------------------*/
  364. void
  365. GetSymbolDef(
  366. int fReportError,
  367. WCHAR curChar
  368. )
  369. {
  370. SYMINFO sym;
  371. WCHAR szDefn[_MAX_PATH];
  372. WCHAR szLine[16];
  373. PWCHAR p;
  374. CHAR flags = 0;
  375. WCHAR currentChar = curChar;
  376. if (!fAFXSymbols)
  377. return;
  378. currentChar = LitChar(); // get past SYMDEFSTART
  379. /* read the symbol name */
  380. p = sym.name;
  381. while ((*p++ = currentChar) != SYMDELIMIT)
  382. currentChar = LitChar();
  383. *--p = L'\0';
  384. if (p - sym.name > MAX_SYMBOL) {
  385. ParseError1(2247);
  386. return;
  387. }
  388. currentChar = LitChar(); /* read past the delimiter */
  389. p = szDefn;
  390. while ((*p++ = currentChar) != SYMDELIMIT)
  391. currentChar = LitChar();
  392. *--p = L'\0';
  393. currentChar = LitChar(); /* read past the delimiter */
  394. sym.file[0] = L'\0';
  395. p = szLine;
  396. while ((*p++ = currentChar) != SYMDELIMIT)
  397. currentChar = LitChar();
  398. *--p = L'\0';
  399. sym.line = (WORD)wcsatoi(szLine);
  400. currentChar = LitChar(); /* read past the delimiter */
  401. flags = (CHAR)currentChar;
  402. flags &= 0x7f; // clear the hi bit
  403. currentChar = LitChar(); /* read past the delimiter */
  404. /* leave positioned at last character (LitChar will bump) */
  405. if (currentChar != SYMDELIMIT) {
  406. ParseError1(2248);
  407. }
  408. WriteSymbolDef(sym.name, szDefn, sym.file, sym.line, flags);
  409. }
  410. /*---------------------------------------------------------------------------*/
  411. /* */
  412. /* GetSymbol() - read a symbol and put id in the token if there */
  413. /* */
  414. /*---------------------------------------------------------------------------*/
  415. void
  416. GetSymbol(
  417. int fReportError,
  418. WCHAR curChar
  419. )
  420. {
  421. WCHAR currentChar = curChar;
  422. token.sym.name[0] = L'\0';
  423. token.sym.file[0] = L'\0';
  424. token.sym.line = 0;
  425. if (!fAFXSymbols)
  426. return;
  427. /* skip whitespace */
  428. while (iswhite(currentChar))
  429. currentChar = LitChar();
  430. if (currentChar == SYMUSESTART) {
  431. WCHAR * p;
  432. int i = 0;
  433. WCHAR szLine[16];
  434. currentChar = LitChar(); // get past SYMUSESTART
  435. if (currentChar != L'\"') {
  436. ParseError1(2249);
  437. return;
  438. }
  439. currentChar = LitChar(); // get past the first \"
  440. /* read the symbol name */
  441. p = token.sym.name;
  442. while ((*p++ = currentChar) != SYMDELIMIT)
  443. currentChar = LitChar();
  444. *--p = L'\0';
  445. if (p - token.sym.name > MAX_SYMBOL) {
  446. ParseError1(2247);
  447. return;
  448. }
  449. currentChar = LitChar(); /* read past the delimiter */
  450. p = token.sym.file;
  451. while ((*p++ = currentChar) != SYMDELIMIT)
  452. currentChar = LitChar();
  453. *--p = L'\0';
  454. currentChar = LitChar(); /* read past the delimiter */
  455. p = szLine;
  456. while ((*p++ = currentChar) != L'\"')
  457. currentChar = LitChar();
  458. *--p = L'\0';
  459. token.sym.line = (WORD)wcsatoi(szLine);
  460. if (currentChar != L'\"') {
  461. ParseError1(2249);
  462. return;
  463. }
  464. currentChar = LitChar(); // get past SYMDELIMIT
  465. /* skip whitespace */
  466. while (iswhite(currentChar))
  467. currentChar = LitChar();
  468. }
  469. }