windows-nt/Source/XPSP1/NT/sdktools/mc/mcout.c
2020-09-26 16:20:57 +08:00

467 lines
15 KiB
C

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
mcout.c
Abstract:
This file contains the output functions of the Win32 Message Compiler (MC)
Author:
Steve Wood (stevewo) 22-Aug-1991
Revision History:
--*/
#include "mc.h"
PMESSAGE_BLOCK MessageBlocks = NULL;
int NumberOfBlocks = 0;
BOOL
McBlockMessages( void )
{
PMESSAGE_BLOCK p, *pp;
PMESSAGE_INFO MessageInfo;
pp = &MessageBlocks;
p = NULL;
MessageInfo = Messages;
while (MessageInfo) {
if (p) {
if (p->HighId+1 == MessageInfo->Id) {
p->HighId += 1;
}
else {
pp = &p->Next;
}
}
if (!*pp) {
NumberOfBlocks += 1;
p = malloc( sizeof( *p ) );
if (!p) {
McInputErrorA( "Out of memory reading messages", TRUE, NULL );
return FALSE;
}
p->Next = NULL;
p->LowId = MessageInfo->Id;
p->HighId = MessageInfo->Id;
p->LowInfo = MessageInfo;
*pp = p;
}
MessageInfo = MessageInfo->Next;
}
return( TRUE );
}
BOOL
McWriteBinaryFilesA( void )
{
PNAME_INFO LanguageName, *pp;
PLANGUAGE_INFO LanguageInfo;
PMESSAGE_INFO MessageInfo;
PMESSAGE_BLOCK BlockInfo;
char *FileName;
ULONG cb, cbNeeded;
ULONG MessageOffset;
MESSAGE_RESOURCE_ENTRY MessageEntry;
MESSAGE_RESOURCE_BLOCK MessageBlock;
MESSAGE_RESOURCE_DATA MessageData;
ULONG Zeroes = 0;
ULONG NumberOfMessages;
LPBYTE lpBuf;
ULONG Size = 256;
FileName = BinaryMessageFileName;
FileName += strlen( FileName );
lpBuf = malloc( Size );
if (!lpBuf) {
McInputErrorA( "Out of memory writing to output file - %s", TRUE, BinaryMessageFileName );
return( FALSE );
}
pp = &LanguageNames;
while (LanguageName = *pp) {
pp = &LanguageName->Next;
if (!LanguageName->Used) {
continue;
}
WideCharToMultiByte( CP_OEMCP, 0, LanguageName->Value, -1, FileName,
sizeof( BinaryMessageFileName ) - strlen( FileName ), NULL, NULL );
strcat( FileName, ".bin" );
if (!(BinaryMessageFile = fopen( BinaryMessageFileName, "wb" ))) {
McInputErrorA( "unable to open output file - %s", TRUE, BinaryMessageFileName );
return( FALSE );
}
if (VerboseOutput) {
fprintf( stderr, "Writing %s\n", BinaryMessageFileName );
}
fprintf( RcInclFile, "LANGUAGE 0x%x,0x%x\r\n",
PRIMARYLANGID( LanguageName->Id ),
SUBLANGID( LanguageName->Id )
);
if (fUniqueBinName) {
fprintf(RcInclFile, "1 11 %s_%s\r\n", FNameMsgFileName, FileName);
} else {
fprintf( RcInclFile, "1 11 %s\r\n", FileName );
}
NumberOfMessages = 0L;
MessageData.NumberOfBlocks = NumberOfBlocks;
MessageOffset = fwrite( &MessageData,
1,
(size_t)FIELD_OFFSET( MESSAGE_RESOURCE_DATA,
Blocks[ 0 ]
),
BinaryMessageFile
);
MessageOffset += NumberOfBlocks * sizeof( MessageBlock );
BlockInfo = MessageBlocks;
while (BlockInfo) {
MessageBlock.LowId = BlockInfo->LowId;
MessageBlock.HighId = BlockInfo->HighId;
MessageBlock.OffsetToEntries = MessageOffset;
fwrite( &MessageBlock, 1, sizeof( MessageBlock ), BinaryMessageFile );
BlockInfo->InfoLength = 0;
MessageInfo = BlockInfo->LowInfo;
while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
LanguageInfo = MessageInfo->MessageText;
while (LanguageInfo) {
if (LanguageInfo->Id == LanguageName->Id) {
break;
}
else {
LanguageInfo = LanguageInfo->Next;
}
}
if (LanguageInfo != NULL) {
cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
WideCharToMultiByte( LanguageName->CodePage,
0,
LanguageInfo->Text,
LanguageInfo->Length,
NULL, 0, NULL, NULL ) + 1;
cb = (cb + 3) & ~3;
BlockInfo->InfoLength += cb;
}
else {
fprintf( stderr,
"MC: No %ws language text for %ws\n",
LanguageName->Name,
MessageInfo->SymbolicName
);
fclose( BinaryMessageFile );
return( FALSE );
}
MessageInfo = MessageInfo->Next;
}
if (VerboseOutput) {
fprintf( stderr, " [%08lx .. %08lx] - %lu bytes\n",
BlockInfo->LowId,
BlockInfo->HighId,
BlockInfo->InfoLength
);
}
MessageOffset += BlockInfo->InfoLength;
BlockInfo = BlockInfo->Next;
}
BlockInfo = MessageBlocks;
while (BlockInfo) {
MessageInfo = BlockInfo->LowInfo;
while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
LanguageInfo = MessageInfo->MessageText;
while (LanguageInfo) {
if (LanguageInfo->Id == LanguageName->Id) {
break;
}
else {
LanguageInfo = LanguageInfo->Next;
}
}
if (LanguageInfo != NULL) {
cbNeeded = WideCharToMultiByte( LanguageName->CodePage,
0,
LanguageInfo->Text,
LanguageInfo->Length,
NULL, 0, NULL, NULL );
cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
cbNeeded + 1;
cb = (cb + 3) & ~3;
MessageEntry.Length = (USHORT)cb;
MessageEntry.Flags = 0;
cb = fwrite( &MessageEntry,
1,
(size_t)FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY,
Text[ 0 ]
),
BinaryMessageFile
);
if (Size < cbNeeded ) {
lpBuf = realloc( lpBuf, cbNeeded );
if (!lpBuf) {
McInputErrorA( "Out of memory writing to output file - %s",
TRUE, BinaryMessageFileName );
return( FALSE );
}
Size = cbNeeded;
}
WideCharToMultiByte( LanguageName->CodePage,
0,
LanguageInfo->Text,
LanguageInfo->Length,
lpBuf, cbNeeded, NULL, NULL );
cb += fwrite( lpBuf,
1,
(size_t)cbNeeded,
BinaryMessageFile
);
NumberOfMessages++;
cb = MessageEntry.Length - cb;
if (cb) {
fwrite( &Zeroes,
1,
(size_t)cb,
BinaryMessageFile
);
}
}
MessageInfo = MessageInfo->Next;
}
BlockInfo = BlockInfo->Next;
}
if (VerboseOutput) {
fprintf( stderr, " Total of %lu messages, %lu bytes\n",
NumberOfMessages,
ftell( BinaryMessageFile )
);
}
fclose( BinaryMessageFile );
McClearArchiveBit( BinaryMessageFileName );
}
free( lpBuf );
return( TRUE );
}
BOOL
McWriteBinaryFilesW( void )
{
PNAME_INFO LanguageName, *pp;
PLANGUAGE_INFO LanguageInfo;
PMESSAGE_INFO MessageInfo;
PMESSAGE_BLOCK BlockInfo;
char *FileName;
ULONG cb;
ULONG MessageOffset;
MESSAGE_RESOURCE_ENTRY MessageEntry;
MESSAGE_RESOURCE_BLOCK MessageBlock;
MESSAGE_RESOURCE_DATA MessageData;
ULONG Zeroes = 0;
ULONG NumberOfMessages;
FileName = BinaryMessageFileName;
FileName += strlen( FileName );
pp = &LanguageNames;
while (LanguageName = *pp) {
pp = &LanguageName->Next;
if (!LanguageName->Used) {
continue;
}
WideCharToMultiByte( CP_OEMCP, 0, LanguageName->Value, -1,
FileName, sizeof( BinaryMessageFileName ), NULL, NULL);
strcat( FileName, ".bin" );
if (!(BinaryMessageFile = fopen( BinaryMessageFileName, "wb" ))) {
McInputErrorA( "unable to open output file - %s", TRUE, BinaryMessageFileName );
return( FALSE );
}
if (VerboseOutput) {
fprintf( stderr, "Writing %s\n", BinaryMessageFileName );
}
fprintf( RcInclFile, "LANGUAGE 0x%x,0x%x\r\n",
PRIMARYLANGID( LanguageName->Id ),
SUBLANGID( LanguageName->Id )
);
if (fUniqueBinName) {
fprintf(RcInclFile, "1 11 %s_%s\r\n", FNameMsgFileName, FileName);
} else {
fprintf( RcInclFile, "1 11 %s\r\n", FileName );
}
NumberOfMessages = 0L;
MessageData.NumberOfBlocks = NumberOfBlocks;
MessageOffset = fwrite( &MessageData,
1,
(size_t)FIELD_OFFSET( MESSAGE_RESOURCE_DATA,
Blocks[ 0 ]
),
BinaryMessageFile
);
MessageOffset += NumberOfBlocks * sizeof( MessageBlock );
BlockInfo = MessageBlocks;
while (BlockInfo) {
MessageBlock.LowId = BlockInfo->LowId;
MessageBlock.HighId = BlockInfo->HighId;
MessageBlock.OffsetToEntries = MessageOffset;
fwrite( &MessageBlock, 1, sizeof( MessageBlock ), BinaryMessageFile );
BlockInfo->InfoLength = 0;
MessageInfo = BlockInfo->LowInfo;
while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
LanguageInfo = MessageInfo->MessageText;
while (LanguageInfo) {
if (LanguageInfo->Id == LanguageName->Id) {
break;
}
else {
LanguageInfo = LanguageInfo->Next;
}
}
if (LanguageInfo != NULL) {
cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
( LanguageInfo->Length + 1 );
cb = (cb + 3) & ~3;
BlockInfo->InfoLength += cb;
}
else {
fprintf( stderr,
"MC: No %ws language text for %ws\n",
LanguageName->Name,
MessageInfo->SymbolicName
);
fclose( BinaryMessageFile );
_unlink( BinaryMessageFileName );
return( FALSE );
}
MessageInfo = MessageInfo->Next;
}
if (VerboseOutput) {
fprintf( stderr, " [%08lx .. %08lx] - %lu bytes\n",
BlockInfo->LowId,
BlockInfo->HighId,
BlockInfo->InfoLength
);
}
MessageOffset += BlockInfo->InfoLength;
BlockInfo = BlockInfo->Next;
}
BlockInfo = MessageBlocks;
while (BlockInfo) {
MessageInfo = BlockInfo->LowInfo;
while (MessageInfo != NULL && MessageInfo->Id <= BlockInfo->HighId) {
LanguageInfo = MessageInfo->MessageText;
while (LanguageInfo) {
if (LanguageInfo->Id == LanguageName->Id) {
break;
}
else {
LanguageInfo = LanguageInfo->Next;
}
}
if (LanguageInfo != NULL) {
cb = FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY, Text[ 0 ] ) +
( LanguageInfo->Length + 1 ) ;
cb = (cb + 3) & ~3;
MessageEntry.Length = (USHORT)cb;
MessageEntry.Flags = MESSAGE_RESOURCE_UNICODE;
cb = fwrite( &MessageEntry,
1,
(size_t)FIELD_OFFSET( MESSAGE_RESOURCE_ENTRY,
Text[ 0 ]
),
BinaryMessageFile
);
cb += fwrite( LanguageInfo->Text,
1,
(size_t)( LanguageInfo->Length ),
BinaryMessageFile
);
NumberOfMessages++;
cb = MessageEntry.Length - cb;
if (cb) {
fwrite( &Zeroes,
1,
(size_t)cb,
BinaryMessageFile
);
}
}
MessageInfo = MessageInfo->Next;
}
BlockInfo = BlockInfo->Next;
}
if (VerboseOutput) {
fprintf( stderr, " Total of %lu messages, %lu bytes\n",
NumberOfMessages,
ftell( BinaryMessageFile )
);
}
fclose( BinaryMessageFile );
McClearArchiveBit( BinaryMessageFileName );
}
return( TRUE );
}