bug and "hotfix" in atlperf.inl
Hello,
Some weeks ago, I posted here a strange bug I had with ATL Performance
Counters in Windows x64. I discovered that the error had another cause, but
it is still an ATL 8 bug.
The previous post:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1137253&SiteID=1
I understand that certainly my input in the previous post was not enough so
that someone could help me with a moderate effort. Fortunately, these days I
finally got some time to deeply investigate the problem and for debugging.
Actually, I detected the bug and made a small hotfix that solved my problem
and I would like to share it here, although I'm sure that MS developers will
be able to find an even better solution.
Later, I found that someone had already detected this error in VS 2003
years, but unfortunately he did not find the [Microsoft "BUGZILLA" to correct
this in Studio 2005] as you can read in his post in another forum at
http://www.eggheadcafe.com/forumarchives/vcatl/Sep2005/post23538044.asp
My problem is really the same, I have a Windows 2003 Server x64 in English
but with Portuguese BRASIL Regional Settings and Language.
The problem is that ATL tries to write the key in
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\016"
but, this key does not exists in the machine, thus the ATL registration
decides to just ignore it, making an incomplete registration and does not
return an error.
Bellow is my "hotfix" in atlperf.inl, calling GetSystemDefaultUILanguage()
to get the original Windows language and returning an error in case of
failure; because returning S_FALSE just ignores the failure and drive people
crazy (:
inline HRESULT CPerfMon::RegisterStrings(
LANGID language /* = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) */,
HINSTANCE hResInstance /* = _AtlBaseModule.GetResourceInstance() */
) throw()
{
_ATLTRY
{
CString str;
DWORD dwErr;
HRESULT hr;
CRegKey rkLang;
CRegKey rkApp;
LANGID wPrimaryLanguage = (LANGID) PRIMARYLANGID(language);
if (language == MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL))
{
//First try current thread locale
language = LANGIDFROMLCID(GetThreadLocale());
wPrimaryLanguage = (LANGID) PRIMARYLANGID(language);
}
str.Format(c_szAtlPerfPerfLibLangKey, wPrimaryLanguage);
dwErr = rkLang.Open(HKEY_LOCAL_MACHINE, str);
if (dwErr == ERROR_FILE_NOT_FOUND)
{
// failed using current thread, so try default system lcid
language = GetSystemDefaultLangID();
wPrimaryLanguage = (LANGID) PRIMARYLANGID(language);
str.Format(c_szAtlPerfPerfLibLangKey, wPrimaryLanguage);
dwErr = rkLang.Open(HKEY_LOCAL_MACHINE, str);
}
/* start of hotfix **************************/
if (dwErr == ERROR_FILE_NOT_FOUND)
{
// failed using default system, so try the original operating system language
language = GetSystemDefaultUILanguage();
wPrimaryLanguage = (LANGID) PRIMARYLANGID(language);
str.Format(c_szAtlPerfPerfLibLangKey, wPrimaryLanguage);
dwErr = rkLang.Open(HKEY_LOCAL_MACHINE, str);
}
/* return an HRESULT error */
if (dwErr == ERROR_FILE_NOT_FOUND)
// return S_FALSE; // the language isn't installed on the system
return E_ABORT;
// S_FALSE only hides the registration error and drives people crazy (:
// an specific error code would be even nicer
/* end of hotfix **************************/
if (dwErr != ERROR_SUCCESS)
return AtlHresultFromWin32(dwErr);
....
}
I am looking forward to a MS feedback.
Regards,
Djalma