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.

397 lines
12 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. PRESINFO pResString = NULL; /* Used to add a stringtable */
  12. /* at the end of processing if a stringtable */
  13. /* was found. */
  14. static PRCSTRING pSTHeader;
  15. /* Ptr to the start of the parsed STRINGTABLE. */
  16. /*--------------------------------------------------------------------------*/
  17. /* */
  18. /* MyFAlloc() - */
  19. /* */
  20. /*--------------------------------------------------------------------------*/
  21. void *MyFAlloc(size_t cb, const void *pv)
  22. {
  23. void *pvT= MyAlloc(cb);
  24. if (pv != NULL) {
  25. memmove(pvT, pv, cb);
  26. } else {
  27. memset(pvT, 0, cb);
  28. }
  29. return(pvT);
  30. }
  31. /*--------------------------------------------------------------------------*/
  32. /* */
  33. /* GetTable() - */
  34. /* */
  35. /*--------------------------------------------------------------------------*/
  36. PRESINFO
  37. GetTable(
  38. PRESINFO pResTemp
  39. )
  40. {
  41. PRCSTRING pCurrent;
  42. PRCSTRING pTrailer;
  43. CHAR bDone = FALSE;
  44. USHORT nStringID;
  45. PWCHAR p;
  46. PSYMINFO pCurrentSymbol;
  47. DWORD TmpSize;
  48. wchar_t *TmpBuf;
  49. int TmpRow;
  50. PreBeginParse(pResTemp, 2105);
  51. /* Does a string table already exist? */
  52. if (pResString == NULL) {
  53. /* No, start at the beginning - otherwise append. */
  54. pTrailer = (PRCSTRING)NULL;
  55. pSTHeader = (PRCSTRING)NULL;
  56. }
  57. do {
  58. pCurrent = pSTHeader;
  59. bDone = FALSE;
  60. if (token.type != NUMLIT)
  61. ParseError1(2149); //"Expected numeric constant in string table "
  62. nStringID = token.val;
  63. pCurrentSymbol = (SYMINFO*) MyFAlloc(sizeof(token.sym), (char*)&token.sym);
  64. if (!GetFullExpression(&nStringID, GFE_ZEROINIT | GFE_SHORT))
  65. ParseError1(2110); //"Expected numeric constant in v table "
  66. if (token.type == COMMA)
  67. GetToken(TOKEN_NOEXPRESSION);
  68. if (token.type != LSTRLIT)
  69. ParseError1(2150);
  70. tokenbuf[token.val + 1] = 0;
  71. TmpSize = sizeof(WCHAR) * (token.val + 2);
  72. TmpBuf = (wchar_t *) MyFAlloc(TmpSize, tokenbuf);
  73. TmpRow = token.row;
  74. GetToken(TRUE);
  75. // wprintf(L"TmpSize: %d\tTmpBuf: %s\tTmpRow: %d\n", TmpSize, TmpBuf, TmpRow);
  76. while ((token.row == TmpRow) && (token.type == LSTRLIT)) {
  77. size_t NewSize = TmpSize + (sizeof(WCHAR) * (token.val));
  78. wchar_t *NewBuf = (wchar_t *) MyAlloc(NewSize);
  79. memmove(NewBuf, TmpBuf, TmpSize);
  80. memmove((BYTE *) NewBuf + TmpSize-4, tokenbuf, (token.val * sizeof(WCHAR)));
  81. // wprintf(L"NewSize: %d\tNewBuf: %ws\ttoken.row: %d\ttokenbuf: %ws\n", NewSize, NewBuf, token.row, tokenbuf);
  82. MyFree(TmpBuf);
  83. TmpSize = NewSize;
  84. TmpBuf = NewBuf;
  85. GetToken(TRUE);
  86. }
  87. while (!bDone && pCurrent) {
  88. if (pCurrent->language == pResTemp->language) {
  89. if (pCurrent->hibits == (USHORT)(nStringID / BLOCKSIZE)) {
  90. bDone = TRUE;
  91. if (!(pCurrent->rgsz[nStringID % BLOCKSIZE])) {
  92. pCurrent->rgsz[nStringID % BLOCKSIZE] = TmpBuf;
  93. pCurrent->rgsym[nStringID % BLOCKSIZE] = pCurrentSymbol;
  94. }
  95. else {
  96. SET_MSG(2151,
  97. curFile,
  98. TmpRow,
  99. nStringID,
  100. pCurrent->rgsz[nStringID % BLOCKSIZE],
  101. TmpBuf
  102. );
  103. ParseError3(2151);
  104. MyFree(TmpBuf);
  105. }
  106. TmpBuf = NULL; TmpSize = 0;
  107. }
  108. }
  109. pTrailer = pCurrent;
  110. pCurrent = pCurrent->next;
  111. }
  112. if (!bDone) { /* and thus pCurrent == NULL */
  113. pCurrent = (PRCSTRING) MyFAlloc(sizeof(RCSTRING), NULL);
  114. pCurrent->hibits = (short)(nStringID / BLOCKSIZE);
  115. pCurrent->flags = pResTemp->flags;
  116. pCurrent->language = pResTemp->language;
  117. pCurrent->version = pResTemp->version;
  118. pCurrent->characteristics = pResTemp->characteristics;
  119. p = pCurrent->rgsz[nStringID%BLOCKSIZE] = TmpBuf;
  120. TmpBuf = NULL; TmpSize = 0;
  121. pCurrent->rgsym[nStringID%BLOCKSIZE] = pCurrentSymbol;
  122. if (pTrailer)
  123. pTrailer->next = pCurrent;
  124. if (!pSTHeader)
  125. pSTHeader = pCurrent; /* First time only */
  126. }
  127. // GetToken(TRUE);
  128. } while (token.type != END);
  129. pResString = pResTemp;
  130. return pResString;
  131. }
  132. /*--------------------------------------------------------------------------*/
  133. /* */
  134. /* WriteTable() - */
  135. /* */
  136. /*--------------------------------------------------------------------------*/
  137. VOID
  138. WriteTable(
  139. PRESINFO pResOld
  140. )
  141. {
  142. PRCSTRING p;
  143. int i;
  144. PRESINFO pRes;
  145. PTYPEINFO pType;
  146. int n;
  147. PWCHAR s;
  148. UINT nBytesWritten;
  149. SYMINFO symInfo;
  150. /* Start at the start of the proper table. */
  151. p = pSTHeader;
  152. while (p) {
  153. nBytesWritten = 0;
  154. CtlInit();
  155. // 'STR#' resource starts with a count of strings
  156. if (fMacRsrcs)
  157. WriteWord(BLOCKSIZE);
  158. /* Write out the next block. */
  159. for (i = 0; i < BLOCKSIZE; i++) {
  160. n = 0;
  161. s = p->rgsz[i];
  162. if (fMacRsrcs) {
  163. WriteMacString(s, TRUE, TRUE);
  164. continue;
  165. }
  166. if (s) {
  167. while (s[n] || s[n + 1])
  168. n++; // szsz terminated
  169. if (fAppendNull)
  170. n++;
  171. }
  172. nBytesWritten += sizeof(WCHAR) * (n + 1);
  173. WriteWord((WORD)n);
  174. while (n--)
  175. WriteWord(*s++);
  176. }
  177. pRes = (RESINFO * )MyAlloc(sizeof(RESINFO));
  178. pRes->language = p->language;
  179. pRes->version = p->version;
  180. pRes->characteristics = p->characteristics;
  181. pType = AddResType(NULL, RT_STRING);
  182. pRes->size = nBytesWritten;
  183. /* Mark the resource as Moveable and Discardable. */
  184. pRes->flags = p->flags;
  185. /*We're in an origin 1 world here*/
  186. pRes->nameord = (short)(p->hibits + 1);
  187. SaveResFile(pType, pRes);
  188. memset(&symInfo, 0, sizeof(symInfo));
  189. WriteResInfo(pRes, pType, FALSE);
  190. for (i=0; i < BLOCKSIZE; i++) {
  191. WriteSymbolUse(p->rgsym[i] != NULL && p->rgsz[i][0] != '\0' ? p->rgsym[i] : &symInfo);
  192. }
  193. WriteResInfo(NULL, NULL, FALSE);
  194. /* Move on to the next block. */
  195. p = p->next;
  196. }
  197. }
  198. /*--------------------------------------------------------------------------*/
  199. /* */
  200. /* GetAccelerators() _ */
  201. /* */
  202. /*--------------------------------------------------------------------------*/
  203. int
  204. GetAccelerators(
  205. PRESINFO pRes
  206. )
  207. {
  208. int count = 0;
  209. int ntype;
  210. WCHAR c;
  211. int bTypeSpecified;
  212. RCACCEL Accel;
  213. PreBeginParse(pRes, 2106);
  214. do {
  215. if (token.type == END)
  216. continue;
  217. bTypeSpecified = FALSE;
  218. ntype = token.type;
  219. if (token.type == END) {
  220. MarkAccelFlagsByte();
  221. WriteWord(0);
  222. WriteWord(0);
  223. WriteWord(0);
  224. WriteWord(0);
  225. count++;
  226. continue;
  227. }
  228. else if (token.type == NUMLIT)
  229. Accel.ascii = token.val;
  230. else if (token.type == LSTRLIT) {
  231. if (tokenbuf[0] == L'^') {
  232. if (wcslen(tokenbuf) != 2)
  233. ParseError1(2152);
  234. /* GetAccelerators() and support "^^" to put ^ */
  235. if (tokenbuf[1] == L'^')
  236. Accel.ascii = L'^';
  237. else {
  238. if (!iswalpha(c=towupper(tokenbuf[1])))
  239. ParseError1(2154);
  240. Accel.ascii = c - L'A' + 1;
  241. }
  242. }
  243. else if (wcslen(tokenbuf) == 2)
  244. Accel.ascii = (WCHAR)((tokenbuf[0] << 8) + tokenbuf[1]);
  245. else if (wcslen(tokenbuf) == 1)
  246. Accel.ascii = tokenbuf[0];
  247. else
  248. ParseError1(2155);
  249. }
  250. else
  251. ParseError1(2156);
  252. /* Get the trailing comma. */
  253. GetToken(TRUE);
  254. if (token.type != COMMA)
  255. ParseError1(2157);
  256. /* Get the next number. */
  257. GetToken(TRUE);
  258. if (token.type != NUMLIT)
  259. ParseError1(2107);
  260. Accel.id = token.val;
  261. WriteSymbolUse(&token.sym);
  262. if (!GetFullExpression(&Accel.id, GFE_ZEROINIT | GFE_SHORT))
  263. ParseError1(2107); //"Expected numeric command value"
  264. Accel.flags = 0;
  265. if (token.type == COMMA)
  266. do {
  267. GetToken(TRUE);
  268. switch (token.type) {
  269. case TKVIRTKEY:
  270. Accel.flags |= fVIRTKEY;
  271. bTypeSpecified = TRUE;
  272. break;
  273. case TKASCII:
  274. bTypeSpecified = TRUE;
  275. break; /* don't set the flag */
  276. case TKNOINVERT:
  277. Accel.flags |= fNOINVERT;
  278. break;
  279. case TKSHIFT:
  280. Accel.flags |= fSHIFT;
  281. break;
  282. case TKCONTROL:
  283. Accel.flags |= fCONTROL;
  284. break;
  285. case TKALT:
  286. Accel.flags |= fALT;
  287. break;
  288. default:
  289. ParseError1(2159);
  290. }
  291. GetToken(TRUE);
  292. } while (token.type == COMMA);
  293. if (ntype == NUMLIT && !bTypeSpecified)
  294. ParseError1(2163);
  295. if (!(Accel.flags & fVIRTKEY) && (Accel.flags & (fSHIFT | fCONTROL))) {
  296. SET_MSG(4203, curFile, token.row);
  297. SendError(Msg_Text);
  298. }
  299. if (Accel.flags & fVIRTKEY && ntype == LSTRLIT) {
  300. if (!iswalnum(Accel.ascii = (WCHAR)towupper(Accel.ascii))) {
  301. SET_MSG(4204, curFile, token.row);
  302. SendError(Msg_Text);
  303. }
  304. }
  305. MarkAccelFlagsByte();
  306. WriteWord(Accel.flags);
  307. WriteWord(Accel.ascii);
  308. if (fMacRsrcs) {
  309. WriteLong(Accel.id);
  310. } else {
  311. WriteWord(Accel.id);
  312. WriteWord(0);
  313. }
  314. count++;
  315. } while (token.type != END);
  316. PatchAccelEnd();
  317. return(5 * count);
  318. }