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.

468 lines
16 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. mcout.c
  5. Abstract:
  6. This file contains the output functions of the Win32 Message Compiler (MC)
  7. Author:
  8. Steve Wood (stevewo) 22-Aug-1991
  9. Revision History:
  10. --*/
  11. #include "mc.h"
  12. PMESSAGE_BLOCK MessageBlocks = NULL;
  13. int NumberOfBlocks = 0;
  14. BOOL
  15. McBlockMessages( void )
  16. {
  17. PMESSAGE_BLOCK p, *pp;
  18. PMESSAGE_INFO MessageInfo;
  19. pp = &MessageBlocks;
  20. p = NULL;
  21. MessageInfo = Messages;
  22. while (MessageInfo) {
  23. if (p) {
  24. if (p->HighId+1 == MessageInfo->Id) {
  25. p->HighId += 1;
  26. }
  27. else {
  28. pp = &p->Next;
  29. }
  30. }
  31. if (!*pp) {
  32. NumberOfBlocks += 1;
  33. p = malloc( sizeof( *p ) );
  34. if (!p) {
  35. McInputErrorA( "Out of memory reading messages", TRUE, NULL );
  36. return FALSE;
  37. }
  38. p->Next = NULL;
  39. p->LowId = MessageInfo->Id;
  40. p->HighId = MessageInfo->Id;
  41. p->LowInfo = MessageInfo;
  42. *pp = p;
  43. }
  44. MessageInfo = MessageInfo->Next;
  45. }
  46. return( TRUE );
  47. }
  48. BOOL
  49. McWriteBinaryFilesA( void )
  50. {
  51. PNAME_INFO LanguageName, *pp;
  52. PLANGUAGE_INFO LanguageInfo;
  53. PMESSAGE_INFO MessageInfo;
  54. PMESSAGE_BLOCK BlockInfo;
  55. char *FileName;
  56. ULONG cb, cbNeeded;
  57. ULONG MessageOffset;
  58. MESSAGE_RESOURCE_ENTRY MessageEntry;
  59. MESSAGE_RESOURCE_BLOCK MessageBlock;
  60. MESSAGE_RESOURCE_DATA MessageData;
  61. ULONG Zeroes = 0;
  62. ULONG NumberOfMessages;
  63. LPBYTE lpBuf;
  64. ULONG Size = 256;
  65. FileName = BinaryMessageFileName;
  66. FileName += strlen( FileName );
  67. lpBuf = malloc( Size );
  68. if (!lpBuf) {
  69. McInputErrorA( "Out of memory writing to output file - %s", TRUE, BinaryMessageFileName );
  70. return( FALSE );
  71. }
  72. pp = &LanguageNames;
  73. while (LanguageName = *pp) {
  74. pp = &LanguageName->Next;
  75. if (!LanguageName->Used) {
  76. continue;
  77. }
  78. WideCharToMultiByte( CP_OEMCP, 0, LanguageName->Value, -1, FileName,
  79. sizeof( BinaryMessageFileName ) - strlen( FileName ), NULL, NULL );
  80. strcat( FileName, ".bin" );
  81. if (!(BinaryMessageFile = fopen( BinaryMessageFileName, "wb" ))) {
  82. McInputErrorA( "unable to open output file - %s", TRUE, BinaryMessageFileName );
  83. return( FALSE );
  84. }
  85. if (VerboseOutput) {
  86. fprintf( stderr, "Writing %s\n", BinaryMessageFileName );
  87. }
  88. fprintf( RcInclFile, "LANGUAGE 0x%x,0x%x\r\n",
  89. PRIMARYLANGID( LanguageName->Id ),
  90. SUBLANGID( LanguageName->Id )
  91. );
  92. if (fUniqueBinName) {
  93. fprintf(RcInclFile, "1 11 %s_%s\r\n", FNameMsgFileName, FileName);
  94. } else {
  95. fprintf( RcInclFile, "1 11 %s\r\n", FileName );
  96. }
  97. NumberOfMessages = 0L;
  98. MessageData.NumberOfBlocks = NumberOfBlocks;
  99. MessageOffset = fwrite( &MessageData,
  100. 1,
  101. (size_t)FIELD_OFFSET( MESSAGE_RESOURCE_DATA,
  102. Blocks[ 0 ]
  103. ),
  104. BinaryMessageFile
  105. );
  106. MessageOffset += NumberOfBlocks * sizeof( MessageBlock );
  107. BlockInfo = MessageBlocks;
  108. while (BlockInfo) {
  109. MessageBlock.LowId = BlockInfo->LowId;
  110. MessageBlock.HighId = BlockInfo->HighId;
  111. MessageBlock.OffsetToEntries = MessageOffset;
  112. fwrite( &MessageBlock, 1, sizeof( MessageBlock ), BinaryMessageFile );
  113. BlockInfo->InfoLength = 0;
  114. MessageInfo = BlockInfo->LowInfo;
  115. while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
  116. LanguageInfo = MessageInfo->MessageText;
  117. while (LanguageInfo) {
  118. if (LanguageInfo->Id == LanguageName->Id) {
  119. break;
  120. }
  121. else {
  122. LanguageInfo = LanguageInfo->Next;
  123. }
  124. }
  125. if (LanguageInfo != NULL) {
  126. cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
  127. WideCharToMultiByte( LanguageName->CodePage,
  128. 0,
  129. LanguageInfo->Text,
  130. LanguageInfo->Length,
  131. NULL, 0, NULL, NULL ) + 1;
  132. cb = (cb + 3) & ~3;
  133. BlockInfo->InfoLength += cb;
  134. }
  135. else {
  136. fprintf( stderr,
  137. "MC: No %ws language text for %ws\n",
  138. LanguageName->Name,
  139. MessageInfo->SymbolicName
  140. );
  141. fclose( BinaryMessageFile );
  142. return( FALSE );
  143. }
  144. MessageInfo = MessageInfo->Next;
  145. }
  146. if (VerboseOutput) {
  147. fprintf( stderr, " [%08lx .. %08lx] - %lu bytes\n",
  148. BlockInfo->LowId,
  149. BlockInfo->HighId,
  150. BlockInfo->InfoLength
  151. );
  152. }
  153. MessageOffset += BlockInfo->InfoLength;
  154. BlockInfo = BlockInfo->Next;
  155. }
  156. BlockInfo = MessageBlocks;
  157. while (BlockInfo) {
  158. MessageInfo = BlockInfo->LowInfo;
  159. while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
  160. LanguageInfo = MessageInfo->MessageText;
  161. while (LanguageInfo) {
  162. if (LanguageInfo->Id == LanguageName->Id) {
  163. break;
  164. }
  165. else {
  166. LanguageInfo = LanguageInfo->Next;
  167. }
  168. }
  169. if (LanguageInfo != NULL) {
  170. cbNeeded = WideCharToMultiByte( LanguageName->CodePage,
  171. 0,
  172. LanguageInfo->Text,
  173. LanguageInfo->Length,
  174. NULL, 0, NULL, NULL );
  175. cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
  176. cbNeeded + 1;
  177. cb = (cb + 3) & ~3;
  178. MessageEntry.Length = (USHORT)cb;
  179. MessageEntry.Flags = 0;
  180. cb = fwrite( &MessageEntry,
  181. 1,
  182. (size_t)FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY,
  183. Text[ 0 ]
  184. ),
  185. BinaryMessageFile
  186. );
  187. if (Size < cbNeeded ) {
  188. void *pv = realloc( lpBuf, cbNeeded );
  189. if (!pv) {
  190. McInputErrorA( "Out of memory writing to output file - %s",
  191. TRUE, BinaryMessageFileName );
  192. return( FALSE );
  193. }
  194. lpBuf = pv;
  195. Size = cbNeeded;
  196. }
  197. WideCharToMultiByte( LanguageName->CodePage,
  198. 0,
  199. LanguageInfo->Text,
  200. LanguageInfo->Length,
  201. lpBuf, cbNeeded, NULL, NULL );
  202. cb += fwrite( lpBuf,
  203. 1,
  204. (size_t)cbNeeded,
  205. BinaryMessageFile
  206. );
  207. NumberOfMessages++;
  208. cb = MessageEntry.Length - cb;
  209. if (cb) {
  210. fwrite( &Zeroes,
  211. 1,
  212. (size_t)cb,
  213. BinaryMessageFile
  214. );
  215. }
  216. }
  217. MessageInfo = MessageInfo->Next;
  218. }
  219. BlockInfo = BlockInfo->Next;
  220. }
  221. if (VerboseOutput) {
  222. fprintf( stderr, " Total of %lu messages, %lu bytes\n",
  223. NumberOfMessages,
  224. ftell( BinaryMessageFile )
  225. );
  226. }
  227. fclose( BinaryMessageFile );
  228. McClearArchiveBit( BinaryMessageFileName );
  229. }
  230. free( lpBuf );
  231. return( TRUE );
  232. }
  233. BOOL
  234. McWriteBinaryFilesW( void )
  235. {
  236. PNAME_INFO LanguageName, *pp;
  237. PLANGUAGE_INFO LanguageInfo;
  238. PMESSAGE_INFO MessageInfo;
  239. PMESSAGE_BLOCK BlockInfo;
  240. char *FileName;
  241. ULONG cb;
  242. ULONG MessageOffset;
  243. MESSAGE_RESOURCE_ENTRY MessageEntry;
  244. MESSAGE_RESOURCE_BLOCK MessageBlock;
  245. MESSAGE_RESOURCE_DATA MessageData;
  246. ULONG Zeroes = 0;
  247. ULONG NumberOfMessages;
  248. FileName = BinaryMessageFileName;
  249. FileName += strlen( FileName );
  250. pp = &LanguageNames;
  251. while (LanguageName = *pp) {
  252. pp = &LanguageName->Next;
  253. if (!LanguageName->Used) {
  254. continue;
  255. }
  256. WideCharToMultiByte( CP_OEMCP, 0, LanguageName->Value, -1,
  257. FileName, sizeof( BinaryMessageFileName ), NULL, NULL);
  258. strcat( FileName, ".bin" );
  259. if (!(BinaryMessageFile = fopen( BinaryMessageFileName, "wb" ))) {
  260. McInputErrorA( "unable to open output file - %s", TRUE, BinaryMessageFileName );
  261. return( FALSE );
  262. }
  263. if (VerboseOutput) {
  264. fprintf( stderr, "Writing %s\n", BinaryMessageFileName );
  265. }
  266. fprintf( RcInclFile, "LANGUAGE 0x%x,0x%x\r\n",
  267. PRIMARYLANGID( LanguageName->Id ),
  268. SUBLANGID( LanguageName->Id )
  269. );
  270. if (fUniqueBinName) {
  271. fprintf(RcInclFile, "1 11 %s_%s\r\n", FNameMsgFileName, FileName);
  272. } else {
  273. fprintf( RcInclFile, "1 11 %s\r\n", FileName );
  274. }
  275. NumberOfMessages = 0L;
  276. MessageData.NumberOfBlocks = NumberOfBlocks;
  277. MessageOffset = fwrite( &MessageData,
  278. 1,
  279. (size_t)FIELD_OFFSET( MESSAGE_RESOURCE_DATA,
  280. Blocks[ 0 ]
  281. ),
  282. BinaryMessageFile
  283. );
  284. MessageOffset += NumberOfBlocks * sizeof( MessageBlock );
  285. BlockInfo = MessageBlocks;
  286. while (BlockInfo) {
  287. MessageBlock.LowId = BlockInfo->LowId;
  288. MessageBlock.HighId = BlockInfo->HighId;
  289. MessageBlock.OffsetToEntries = MessageOffset;
  290. fwrite( &MessageBlock, 1, sizeof( MessageBlock ), BinaryMessageFile );
  291. BlockInfo->InfoLength = 0;
  292. MessageInfo = BlockInfo->LowInfo;
  293. while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
  294. LanguageInfo = MessageInfo->MessageText;
  295. while (LanguageInfo) {
  296. if (LanguageInfo->Id == LanguageName->Id) {
  297. break;
  298. }
  299. else {
  300. LanguageInfo = LanguageInfo->Next;
  301. }
  302. }
  303. if (LanguageInfo != NULL) {
  304. cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
  305. ( LanguageInfo->Length + 1 );
  306. cb = (cb + 3) & ~3;
  307. BlockInfo->InfoLength += cb;
  308. }
  309. else {
  310. fprintf( stderr,
  311. "MC: No %ws language text for %ws\n",
  312. LanguageName->Name,
  313. MessageInfo->SymbolicName
  314. );
  315. fclose( BinaryMessageFile );
  316. _unlink( BinaryMessageFileName );
  317. return( FALSE );
  318. }
  319. MessageInfo = MessageInfo->Next;
  320. }
  321. if (VerboseOutput) {
  322. fprintf( stderr, " [%08lx .. %08lx] - %lu bytes\n",
  323. BlockInfo->LowId,
  324. BlockInfo->HighId,
  325. BlockInfo->InfoLength
  326. );
  327. }
  328. MessageOffset += BlockInfo->InfoLength;
  329. BlockInfo = BlockInfo->Next;
  330. }
  331. BlockInfo = MessageBlocks;
  332. while (BlockInfo) {
  333. MessageInfo = BlockInfo->LowInfo;
  334. while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
  335. LanguageInfo = MessageInfo->MessageText;
  336. while (LanguageInfo) {
  337. if (LanguageInfo->Id == LanguageName->Id) {
  338. break;
  339. }
  340. else {
  341. LanguageInfo = LanguageInfo->Next;
  342. }
  343. }
  344. if (LanguageInfo != NULL) {
  345. cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
  346. ( LanguageInfo->Length + 1 ) ;
  347. cb = (cb + 3) & ~3;
  348. MessageEntry.Length = (USHORT)cb;
  349. MessageEntry.Flags = MESSAGE_RESOURCE_UNICODE;
  350. cb = fwrite( &MessageEntry,
  351. 1,
  352. (size_t)FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY,
  353. Text[ 0 ]
  354. ),
  355. BinaryMessageFile
  356. );
  357. cb += fwrite( LanguageInfo->Text,
  358. 1,
  359. (size_t)( LanguageInfo->Length ),
  360. BinaryMessageFile
  361. );
  362. NumberOfMessages++;
  363. cb = MessageEntry.Length - cb;
  364. if (cb) {
  365. fwrite( &Zeroes,
  366. 1,
  367. (size_t)cb,
  368. BinaryMessageFile
  369. );
  370. }
  371. }
  372. MessageInfo = MessageInfo->Next;
  373. }
  374. BlockInfo = BlockInfo->Next;
  375. }
  376. if (VerboseOutput) {
  377. fprintf( stderr, " Total of %lu messages, %lu bytes\n",
  378. NumberOfMessages,
  379. ftell( BinaryMessageFile )
  380. );
  381. }
  382. fclose( BinaryMessageFile );
  383. McClearArchiveBit( BinaryMessageFileName );
  384. }
  385. return( TRUE );
  386. }