From 9692a83f626cf362c2b796a9ea79d80dcf1dc8fe Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 1 Apr 2004 20:45:03 +0000 Subject: [PATCH] resource-string-loading-20040401 Fix TaLocale_Initialize to be thread safe Fix String Resource loading to not generate exceptions which must be caught by try-catch(...) --- src/WINNT/talocale/tal_main.cpp | 174 ++++++++++++++++++-------------- 1 file changed, 99 insertions(+), 75 deletions(-) diff --git a/src/WINNT/talocale/tal_main.cpp b/src/WINNT/talocale/tal_main.cpp index 895174558..ebea1ad3d 100644 --- a/src/WINNT/talocale/tal_main.cpp +++ b/src/WINNT/talocale/tal_main.cpp @@ -10,6 +10,8 @@ extern "C" { #include #include +#include +#include } #include @@ -55,22 +57,38 @@ BOOL IsValidStringTemplate (LPCSTRINGTEMPLATE pTable); void TaLocale_Initialize (void) { - static BOOL fInitialized = FALSE; - if (!fInitialized) - { - fInitialized = TRUE; + static BOOL fInitialized = FALSE; + + if (!fInitialized) { + char mutexName[256]; + sprintf(mutexName, "TaLocale_Initialize pid=%d", getpid()); + HANDLE hMutex = CreateMutex(NULL, TRUE, mutexName); + if ( GetLastError() == ERROR_ALREADY_EXISTS ) { + if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) { + return; + } + } - InitCommonControls(); - InitializeCriticalSection (&l_csModules); - TaLocale_SpecifyModule (GetModuleHandle(NULL)); + if (!fInitialized) + { + InitCommonControls(); + InitializeCriticalSection (&l_csModules); - LCID lcidUser = GetUserDefaultLCID(); - TaLocale_SetLanguage (LANGIDFROMLCID (lcidUser)); + fInitialized = TRUE; + ReleaseMutex(hMutex); + CloseHandle(hMutex); - LANGID LangOverride; - if ((LangOverride = TaLocale_GetLanguageOverride()) != (LANGID)0) - TaLocale_SetLanguage (LangOverride); - } + + TaLocale_SpecifyModule (GetModuleHandle(NULL)); + + LCID lcidUser = GetUserDefaultLCID(); + TaLocale_SetLanguage (LANGIDFROMLCID (lcidUser)); + + LANGID LangOverride; + if ((LangOverride = TaLocale_GetLanguageOverride()) != (LANGID)0) + TaLocale_SetLanguage (LangOverride); + } + } } @@ -609,81 +627,87 @@ LPCDLGTEMPLATE TaLocale_GetDialogResource (int idd, HINSTANCE *phInstFound) LPCSTRINGTEMPLATE TaLocale_GetStringResource (int ids, HINSTANCE *phInstFound) { - // Strings are organized into heaps of String Tables, each table - // holding 16 strings (regardless of their length). The first table's - // first string index is for string #1. When searching for a string, - // the string's table is the index given to FindResource. - // - LPCSTRINGTEMPLATE pst = NULL; - LANGID lang = TaLocale_GetLanguage(); - - int iTable = (ids / 16) + 1; // 1 = first string table - int iIndex = ids - ((iTable-1) * 16); // 0 = first string in the table - - HINSTANCE hInstance; - for (size_t iModule = 0; !pst && TaLocale_EnumModule (iModule, &hInstance); ++iModule) - { - HRSRC hr; - if ((hr = FindResourceEx (hInstance, RT_STRING, MAKEINTRESOURCE( iTable ), lang)) == NULL) - { - // Our translation teams don't usually change the language - // constants within .RC files, so we should look for English - // language translations too. - // - if ((hr = FindResourceEx (hInstance, RT_STRING, MAKEINTRESOURCE( iTable ), MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US))) == NULL) - { - // If we still can't find it, we'll take anything... + // Strings are organized into heaps of String Tables, each table + // holding 16 strings (regardless of their length). The first table's + // first string index is for string #1. When searching for a string, + // the string's table is the index given to FindResource. + // + LPCSTRINGTEMPLATE pst = NULL; + LANGID lang = TaLocale_GetLanguage(); + + int iTable = (ids / 16) + 1; // 1 = first string table + int iIndex = ids - ((iTable-1) * 16); // 0 = first string in the table + + HINSTANCE hInstance; + for (size_t iModule = 0; !pst && TaLocale_EnumModule (iModule, &hInstance); ++iModule) + { + HRSRC hr; + if ((hr = FindResourceEx (hInstance, RT_STRING, MAKEINTRESOURCE( iTable ), lang)) == NULL) + { + // Our translation teams don't usually change the language + // constants within .RC files, so we should look for English + // language translations too. // - if ((hr = FindResource (hInstance, RT_STRING, MAKEINTRESOURCE( iTable ))) == NULL) - continue; + if ((hr = FindResourceEx (hInstance, RT_STRING, MAKEINTRESOURCE( iTable ), MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US))) == NULL) + { + // If we still can't find it, we'll take anything... + // + if ((hr = FindResource (hInstance, RT_STRING, MAKEINTRESOURCE( iTable ))) == NULL) + continue; } - } + } - HGLOBAL hg; - if ((hg = LoadResource (hInstance, hr)) != NULL) - { - const WORD *pTable; - if ((pTable = (WORD*)LockResource (hg)) != NULL) + HGLOBAL hg; + if ((hg = LoadResource (hInstance, hr)) != NULL) + { + const WORD *pTable; + if ((pTable = (WORD*)LockResource (hg)) != NULL) { - try { - // Skip words in the string table until we reach the string - // index we're looking for. - // - for (int iIndexWalk = iIndex; iIndexWalk; --iIndexWalk) - pTable += 1 + ((LPCSTRINGTEMPLATE)pTable)->cchString; - - if (IsValidStringTemplate ((LPCSTRINGTEMPLATE)pTable)) - { - pst = (LPCSTRINGTEMPLATE)pTable; - if (phInstFound) - *phInstFound = hInstance; - } - } - catch(...) - { - // If we walked off the end of the table, then the - // string we want just wasn't there. - } + try { + // Skip words in the string table until we reach the string + // index we're looking for. + // + for (int iIndexWalk = iIndex; iIndexWalk && ((LPCSTRINGTEMPLATE)pTable)->cchString; --iIndexWalk) { + pTable += 1 + ((LPCSTRINGTEMPLATE)pTable)->cchString; + } + + if (IsValidStringTemplate ((LPCSTRINGTEMPLATE)pTable)) + { + pst = (LPCSTRINGTEMPLATE)pTable; + if (phInstFound) + *phInstFound = hInstance; + } else { + UnlockResource(pTable); + FreeResource(hg); + } + } + catch(...) + { + UnlockResource(pTable); + FreeResource(hg); + // If we walked off the end of the table, then the + // string we want just wasn't there. + } } - } - } + } + } - return pst; + return pst; } BOOL IsValidStringTemplate (LPCSTRINGTEMPLATE pTable) { - if (!pTable->cchString) - return FALSE; + if (!pTable->cchString) + return FALSE; - for (size_t ii = 0; ii < pTable->cchString; ++ii) - { - if (!pTable->achString[ii]) - return FALSE; - } + for (size_t ii = 0; ii < pTable->cchString; ++ii) + { + if (!pTable->achString[ii]) + return FALSE; + } - return TRUE; + return TRUE; } -- 2.39.5