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.

580 lines
15 KiB

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