Problem in Reading Registry Data ...
Hi,
I am facing some problems in reading unicode data stored in the Registry.
The problem is as follows:
I have a registry entry which is something like this:
Location : Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts
Value : Helvetica-Narrow (OpenType)
Data : Helvetica-ΝrěÅ¡ow.otf" [Observe some unicode characters in the string]
I am using RegQueryValueEx() API to read the Data for this Key. But this API replaces the unicode characters in the Data string with some other values ["ΝrěÅ¡ow.otf" is replaced by "?REÅ*OW.OTF"]. This is breaking my logic.
I tried using RegQueryValueExW() version of this API but that also does not help me as it tells me to provide unicode "Value" but I want unicode "Data" back from the registry.
RegQueryValueExW (
IN HKEY hKey,
IN LPCWSTR lpValueName, <-- This can be unicode.
IN LPDWORD lpReserved,
OUT LPDWORD lpType,
IN OUT LPBYTE lpData, <-- But I need unicode data back in this parameter.
IN OUT LPDWORD lpcbData
);
Can someone tell how to read unicode data stored in registry?
An immediate help will be really appreciated?
Santosh
Re: Problem in Reading Regsitry Value ...
Can't you use the ANSI function (RegQueryValueA) and then use MultiByteToWideChar() with the resulting string?
Re: Problem in Reading Regsitry Value ...
Hi Phil,
Actually both "RegQueryValueExA" and "RegQueryValueExW" returns the data in "IN OUT LPBYTE lpData" which cannot contain unicode characters. So even MultiByteToWideChar() won't help in this case.
Btw I already tried all these permutations.
Santosh
Re: Problem in Reading Regsitry Value ...
Where have you seen the "bad characters"? In the Watch window? Go to "Tools/Options" dialog, "Format" tab, select "Watch Window", then a font which displays your characters as expected, if available.
Re: Problem in Reading Regsitry Value ...
The return value is just a ptr to a BYTE buffer, so it can easily contain anything. To tell RegQueryValueEx to just grab X bytes, use the REG_BINARY flag and tell it the length is number of WCHARs in string * 2 + 2 (for null term).
FYI, The RegQueryValueExW function is designed to be used ONLY on UNICODE systems (preprocessor defs redirect to either A or W based on system flag), and just means params like the "subkey" will be passed as wide strings. The return value will be ANSI because your system is flagged as being ANSI.
Good luck.
sulu
Re: Problem in Reading Regsitry Value ...
Hi Sulu,
I am not able to get proper value using that Byte pointer you mentioned.
Here is the code snippet:
int32 err = RegQueryValueEx(key, (char *)buffer, NULL, &type,buffer, &datasize);
Output:
--------------------
Debug value Before call :
buffer 0x0012c830 "Helvetica-Narrow (OpenType)" unsigned char*
Debug value After call:
buffer 0x0012c830 "Helvetica-?rešow.otf" unsigned char *
You can see that the byte value is not proper.
Can you help??
Santosh
Re: Problem in Reading Regsitry Value ...
Quote:
Originally Posted by mistersulu
The return value is just a ptr to a BYTE buffer, so it can easily contain anything.
Right.
Quote:
Originally Posted by mistersulu
To tell RegQueryValueEx to just grab X bytes, use the REG_BINARY flag and tell it the length is number of WCHARs in string * 2 + 2 (for null term).
- lpType is a pointer to an [output] variable that receives a code indicating the type of data stored in the specified value. No matter the input value.
- No need to calculate the necessary buffer size. You can do it, but what about you have no idea about it? One alternative is to call RegQueryValueEx first with NULL in lpData. The returned lpcbData will contain the necessary size. See the second Q/A of THIS FAQ.
- To OP. Have you tried my first advice? And also after RegQueryValueEx call cast the returned buffer value to LPCWSTR.
Re: Problem in Reading Regsitry Value ...
ovidiucucu:
Good point, you don't need to pass the size or type to Query, just Set :) I always forget.
Santosh:
From what I can see, it looks like your "string" that you're getting from the RegQueryValueEx() is neither a unicode or ansi string, but a weird hybrid. Is your system UNICODE? If it isn't then those chars will not be legal for loading the font's filename anyway, right? If it is, then RegQueryValueEx (no 'A' or 'W' :)) should return the proper string--if you're system settings support the particular character set. As my system is straight ANSI, this is just a theory. I'm kinda out of my league... sorry.
sulu
1 Attachment(s)
Re: Problem in Reading Regsitry Value ...
Hi Sulu,
My System is unicode compliant:
OS: Windows XP with service pack 2
Hardware Configuration: Pentium 4 2.8 GHz
I installed a font with file name containing characters other than roman encoding. And when I tried to figure out the actual filename from registry for this Open type font, Registry fails to give me the actual filename as I have mentioned in my original query.
When I search the font in Registry using regedit I can see the correct "Value name" and "Data" for the font I installed but using the RegQueryValueEx() I am not getting the same and due to that my logic of getting the actual file name of the font is failing.
Since if Regedit can show me the correct file name I expected the API also to return me the correct value but it failed.
Attached a snapshot of what I see in Regedit Window and the problematic Font too. Just Change the .txt file extension to .otf as ".otf" files are not supported in CodeGuru.
Santosh
Re: Problem in Reading Regsitry Value ...
Dear Santosh,
Again. Are you sure that in output window you have the proper font set?
Please, just let me know.
I feel ignored here. ;)
Re: Problem in Reading Regsitry Value ...
Hi Ovidiu,
First of all excuse me for not acknowledging your suggestions though i have been reading them carefully. Regarding changing the font of Debug window, will that matter that much?
I can find out that since its API is not giving me the correct string (which is my filename of the problem font), I am not able to copy it to some other location. Hence I am sure that its not the Debug window problem. Btw I have tried that too also even then my string is not proper in Debug window.
Do you want to suggest something else?
Santosh
1 Attachment(s)
Re: Problem in Reading Regsitry Value ...
Well, I just have presume that. Take a look in attached picture which shows the string you have posted using different fonts.
Re: Problem in Reading Regsitry Value ...
Sounds like posting the problem portion of your code is the best option. I was gonna suggest just opening the file, but it sounds like you'ved tried that.
BTW, ovidiu's theories still seem like the most plausible reason for your problem.
We're gonna figure this one out... I'm curious :) Can you post the code when you get a chance. Thanks Santosh.
sulu
1 Attachment(s)
Re: Problem in Reading Regsitry Value ...
Hi Sulu,
I am still struggling with this issue. Code is included for your reference:
=============================================
int main(int argc, char* argv[])
{
bool found = FALSE;
unsigned char buffer[512] = "" ;
HKEY key;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",
0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS ||
RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\Fonts",
0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
{
unsigned char *suffix = (unsigned char *)" (OpenType)";
DWORD type = REG_SZ;
strcpy((char *)buffer, "Helvetica-Narrow");
strcat((char *)buffer, (const char *)suffix);
DWORD datasize = sizeof(buffer);
// I have tried using RegQueryValueExW() values also but that
// too does not serve the purpose
long err = RegQueryValueEx(key, (char *)buffer, NULL, &type,
buffer, &datasize);
found = (err == ERROR_SUCCESS);
if (found)
{
// Some usage of the file name that I got
// CopyFontToWorkingDir(buffer) ;
}
RegCloseKey(key);
}
return 0;
}
=============================================
One more thing to add:
WinZip was also not allowing me to zip these fonts. It was giving me the exception. Image included.
Santosh Thankachan
Re: Problem in Reading Regsitry Value ...
Hi All,
My problem is still not resolved.
Can any Guru step in and lend me a helping hand :)
Santosh