Three fixes for localization MessageTable resources
Zhangrong Huang
hzhr at users.sourceforge.net
Sun Jul 18 23:17:14 CDT 2004
Hi,
Currently, kernel32.dll only supports English error messages(file
dlls/kernel/messages/winerr_enu.mc), when I tried to add my own language message resources, I
met some problems.
First, I added my own .mc file, then use wmc to generate .mc.rc file from .mc file, wmc's output
like this:
1 MESSAGETABLE
LANGUAGE 0x9, 0x1
{
....
}
But my .mc file contained multibyte characters, wmc failed with error message:
Internal error (please report) write.c 103: Buffer overflow? code -1.
It's because in file tools/wmc/write.c, when called wine_cp_wcstombs in function dup_u2c, the
output buffer cptr was too less.
Secondly, when wrc compiled the .rc files, it complained:
Error: Duplicate resource name '1'
Since file tools/wrc/wrc.doc doesn't say the grammar of MessageTable resources is
nameID MESSAGETABLE [loadmem]
[LANGUAGE language, sublanguage]
filename
I simplely modified wmc, changed it's output to:
LANGUAGE 0x9, 0x1
1 MESSAGETABLE
{
....
}
This will fix the "Duplicate resource name" problem.
But, maybe the better way is to patch wrc to suports this:
nameID MESSAGETABLE [loadmem]
[LANGUAGE language, sublanguage]
filename
Anyway, add the separating
LANGUAGE 0x9, 0x1
for each .rc file is a good idea, I think.
Then, when all ok, and test program run, the localization messages sometimes looked ugly,
that's because of a bug in file dlls/kernel/format_msg.c:
(return of load_messageA()) != (return of load_messageW()) when strings contain multibyte
characters.
Now, after this fixes it works fine.
I would like to contribute my own language message resources file if I get a program run in
Windows that can automate generate the .mc file. So what you guys think about this?
ChangeLog:
Call WideCharToMultiByte()/wine_cp_wcstombs() to retrieval actual length of buffer before
conversion.
-------------- next part --------------
Index: dlls/kernel/format_msg.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/format_msg.c,v
retrieving revision 1.36
diff -u -r1.36 format_msg.c
--- dlls/kernel/format_msg.c 14 Jun 2004 17:04:35 -0000 1.36
+++ dlls/kernel/format_msg.c 18 Jul 2004 09:41:10 -0000
@@ -127,7 +127,10 @@
{
ret = load_messageW(instance, id, lang, bufferW, buflen);
if (ret > 0)
+ {
+ ret = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, ret, NULL, NULL);
+ }
}
return ret;
-------------- next part --------------
Index: tools/wmc/write.c
===================================================================
RCS file: /home/wine/wine/tools/wmc/write.c,v
retrieving revision 1.8
diff -u -r1.8 write.c
--- tools/wmc/write.c 2 Oct 2003 04:29:30 -0000 1.8
+++ tools/wmc/write.c 18 Jul 2004 09:54:09 -0000
@@ -95,11 +95,13 @@
static char *dup_u2c(int cp, const WCHAR *uc)
{
int len = unistrlen(uc);
- char *cptr = xmalloc(len+1);
+ char *cptr;
const union cptable *cpdef = find_codepage(cp);
if(!cpdef)
internal_error(__FILE__, __LINE__, "Codepage %d not found (vanished?)", cp);
- if((len = wine_cp_wcstombs(cpdef, 0, uc, unistrlen(uc)+1, cptr, len+1, NULL, NULL)) < 0)
+ len = wine_cp_wcstombs(cpdef, 0, uc, unistrlen(uc), NULL, 0, NULL, NULL);
+ cptr = xmalloc(len);
+ if((len = wine_cp_wcstombs(cpdef, 0, uc, unistrlen(uc), cptr, len, NULL, NULL)) < 0)
internal_error(__FILE__, __LINE__, "Buffer overflow? code %d.", len);
return cptr;
}
@@ -377,12 +379,14 @@
}
else
{
- char *tmp = xmalloc(2*len+1);
- char *cc = tmp;
+ char *tmp, *cc;
+ int mlen;
const union cptable *cpdef = find_codepage(codepage);
assert(cpdef != NULL);
- if((i = wine_cp_wcstombs(cpdef, 0, uc, unistrlen(uc)+1, tmp, 2*len+1, NULL, NULL)) < 0)
+ mlen = wine_cp_wcstombs(cpdef, 0, uc, unistrlen(uc), NULL, 0, NULL, NULL);
+ cc = tmp = xmalloc(mlen);
+ if((i = wine_cp_wcstombs(cpdef, 0, uc, unistrlen(uc), tmp, mlen, NULL, NULL)) < 0)
internal_error(__FILE__, __LINE__, "Buffer overflow? code %d.", i);
*cptr++ = ' ';
*cptr++ = '"';
@@ -447,8 +451,8 @@
for(lbp = lanblockhead; lbp; lbp = lbp->next)
{
unsigned offs = 4 * (lbp->nblk * 3 + 1);
- fprintf(fp, "\n1 MESSAGETABLE\n");
fprintf(fp, "LANGUAGE 0x%x, 0x%x\n", lbp->lan & 0x3ff, lbp->lan >> 10);
+ fprintf(fp, "\n1 MESSAGETABLE\n");
fprintf(fp, "{\n");
fprintf(fp, " /* NBlocks */ 0x%08xL,\n", lbp->nblk);
for(i = 0; i < lbp->nblk; i++)
More information about the wine-patches
mailing list