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