"Troy Rollo" wine@troy.rollo.name wrote:
SetCPGlobal is the undocumented partner of GetACP - it is used to set the current ANSI code page.
ChangeLog: Implement SetCPGlobal (an undocumented Win32 API)
What app does depend on it?
On Tue, 29 Mar 2005 15:03, Dmitry Timoshkov 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), but:
- the call has some fairly obvious uses such that it is not out of the question for an app to use it; - similar API calls to change the OEM code page are documented; - documented facilities in the API necessarily imply the existence of this API call; and - I am considering using it myself.
While the MultiByteToWideChar API can have its behaviour varied by changing the first parameter from CP_ACP to some global, the *A calls cannot. Thus this API call may be important for a server app not compiled for Unicode (or which uses C libraries without a Unicode interface) which receives, for example, file names from a client application.
In fact I had an enquiry a week or so ago from our London office which involved a problem for which the use of this API call is the only reasonable solution.
Ideally the altered code page setting would be inherited by any child process created by the parent.
"Troy Rollo" wine@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?
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.
- similar API calls to change the OEM code page are documented;
What are they? Could you list that API calls?
- documented facilities in the API necessarily imply the existence of this API
call;
and this API has enough power to break an app without a notice.
and
- I am considering using it myself.
While the MultiByteToWideChar API can have its behaviour varied by changing the first parameter from CP_ACP to some global, the *A calls cannot. Thus this API call may be important for a server app not compiled for Unicode (or which uses C libraries without a Unicode interface) which receives, for example, file names from a client application.
Do you have an evidence that Windows does it in the same way?
In fact I had an enquiry a week or so ago from our London office which involved a problem for which the use of this API call is the only reasonable solution.
Ideally the altered code page setting would be inherited by any child process created by the parent.
No. It's better to change the locale of your system to an appropriate one.
On Wed, 30 Mar 2005 14:10, Dmitry Timoshkov wrote:
"Troy Rollo" wine@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.
On Thu, Mar 31, 2005 at 03:18:27PM +1100, Troy Rollo wrote:
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
The solution in this case is to use Unicode internally, and then add calls to WideCharToMultibyte() (NOTE: the first parameter "can be given the value of any codepage that is installed or available in the system" (Borland 5.0 helpfile)) or a cross-platform library like iconv(3) to your I/O pipelines. I would say that using the Windows OEM code pages is not suggested for new application development.
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.
This situation is an even worse case to try hacking the undocumented Windows internationalization APIs. Remember, for instance, that Win95/98/ME *only* supports one OEM code page for the whole system, in the U.S. and Canada, and that for those systems the wide-character APIs are provided by a redistribuable DLL. If you're writing a text-editor or other general-purpose tool, you ought to be building in some character-set detection heuristics, conversion, etc., anyway. If you're developing you're application's data-file formats from scratch, you ought to define a format (probably using some form of Unicode for character data) and stick to it.
Do you think IE or IIS actually uses this particular call?
On Tue, 5 Apr 2005 05:30, David Lee Lambert wrote:
The solution in this case is to use Unicode internally, and then add calls to WideCharToMultibyte()... This situation is an even worse case to try hacking the undocumented Windows internationalization APIs. Remember, for instance, that Win95/98/ME *only* supports one OEM code page for the whole system...
I was going to write a detailed response to this, but then I thought "to hell with it". You have assumed the presence of particular constraints, and the absence of other particular constraints. To make such assumptions about another arbitrary project you know nothing about is, to say the least, presumptuous. To assume such things hold for every project imaginable is even worse.
To accompany that with statements of the bleeding obvious about the APIs is not helpful.
Do you think IE or IIS actually uses this particular call?
Do you think I care what calls IIS and IE use?