KERNEL: Implement undocumented SetCPGlobal API call

Troy Rollo wine at troy.rollo.name
Wed Mar 30 22:18:27 CST 2005


On Wed, 30 Mar 2005 14:10, Dmitry Timoshkov wrote:
> "Troy Rollo" <wine at troy.rollo.name> wrote:
> > > What app does depend on it?
> >
> > I can't name a specific app that depends on it already (other than
> > Windows login management processes),
>
> I wonder then how did you discover its existence and syntax and how did you
> test its real behaviour?

It became apparent when looking through the documentation for other API calls 
that it must exist. I then checked the exports of KERNEL32.DLL and found it 
there, and traced into it to see what it did. I then checked the return value 
of GetACP() after calling SetCPGlobal(), and for good measure traced into 
GetACP() to see what *it* did.

I have not tested all *A calls to verify that they all then use the new code 
page (although I have looked through the relevant parts of the code of some 
of them), but the fact that the new value is returned by GetACP() means that 
GetACP() would not be conforming to its documented behaviour if they did not 
use the new value. To this degree I have assumed a minimal level of 
competence at Microsoft, and while this is often a precarious assumption I 
don't see the need to assume the consequent in this case. But by all means if 
you want to test all the *A functions on Windows to see what happens, be my 
guest.

> > but:
> >
> > - the call has some fairly obvious uses such that it is not out of the
> > question for an app to use it;
>
> I'd say that an obvious one is SetThreadLocale.

Perhaps not - The ACP value appears to be global to the process rather than 
the thread. The OEMCP (as returned by GetOEMCP) is not.

> > - similar API calls to change the OEM code page are documented;
>
> What are they? Could you list that API calls?

SetConsoleCP and SetConsoleOutputCP change the OEM code page used by the 
console attached to a process. There appears to be no call to change the 
value returned by GetOEMCP (this is set in KERNEL32.DLL's startup code), 
however an application that cares would be able to avoid the need for one by 
calling SetConsoleCP, SetConsoleOutputCP, and SetCPGlobal all with the new 
OEM code page, and avoiding any call to SetFileApisToOEM.

> and this API has enough power to break an app without a notice.

1. Not if the app doesn't use it; and
2. If the app does use it, not unless the app is already broken.

> Do you have an evidence that Windows does it in the same way?

Other than from reading the disassembly and testing the APIs, no. That would 
be the "undocumented" part.

> No. It's better to change the locale of your system to an appropriate one.

That assumes every process is OK working with the same code page. This is not 
necessarily the case with a server application, which may well be serving 
clients in multiple regions in a multi-national environment. I know one major 
bank that has a presence in almost every country in the world that uses three 
central server farms - one in New York, one in Singapore, and I think the 
third was in London. A server process running on one of these systems may 
have to deal with clients using many different code pages, and if the program 
is written in C or C++ using the C or C++ libraries, then changing the ACP 
may turn out to be the only reasonable way to deal with this.

It may not even be the case with a client application: you may have a software 
reseller who supports multiple regions and needs to be able to view data in a 
program that does not use Unicode when that data has come from a client in a 
region with a different code page; you may have somebody in a business whose 
native language is not the same as that of the locality they are in who 
prefers to use most applications in their native language, but needs to use 
some with the local code page to get access to business data.

These are not problems solved by forcing people to make a choice of system 
code page.

Bottom line, it's been exported by at least one Windows KERNEL32.DLL, which it 
seems to me makes it a reasonable candidate for implementation in WINE 
provided we know its behaviour, which we do.



More information about the wine-devel mailing list