Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

200 lines
6.2 KiB

/****************************************************************************
*
* satellite.h
*
* Support for satellite resource DLLs.
*
* Owner: cthrash
*
* Copyright © 1999-2000 Microsoft Corporation All Rights Reserved.
*
*****************************************************************************/
#pragma once
//--- Includes --------------------------------------------------------------
#include <sphelper.h>
//--- Forward and External Declarations -------------------------------------
//--- TypeDef and Enumeration Declarations ----------------------------------
//--- Constants -------------------------------------------------------------
//--- Class, Struct and Union Definitions -----------------------------------
class CSpSatelliteDLL
{
private:
enum LoadState_t
{
LoadState_NotChecked,
LoadState_Loaded,
LoadState_NotFound
};
#pragma pack(push, LANGANDCODEPAGE, 2)
struct LangAndCodePage_t
{
WORD wLanguage;
WORD wCodePage;
};
#pragma pack(pop, LANGANDCODEPAGE)
private:
LoadState_t m_eLoadState;
HINSTANCE m_hinstRes; // cached so FreeLibrary can be called;
public:
CSpSatelliteDLL() { m_eLoadState = LoadState_NotChecked; m_hinstRes = 0; }
~CSpSatelliteDLL() { if (m_hinstRes) { FreeLibrary(m_hinstRes); } }
public:
BOOL Checked() const { return LoadState_NotChecked != m_eLoadState; }
public:
HINSTANCE Load(
HINSTANCE hinstModule, // [in] Instance handle of core DLL
LPCTSTR lpszSatelliteName) // [in] Satellite DLL name
{
HINSTANCE hinstRes = hinstModule;
LANGID langidUI = SpGetUserDefaultUILanguage();
LANGID langidModule = 0;
TCHAR achPath[MAX_PATH];
DWORD cch = GetModuleFileName(hinstModule, achPath, sp_countof(achPath));
if (cch)
{
//
// First check the locale of the module;
// If it's the same as the UI, assume it contains language-appropriate resources
//
DWORD dwHandle;
DWORD dwVerInfoSize = GetFileVersionInfoSize(achPath, &dwHandle);
if (dwVerInfoSize)
{
void * lpBuffer = malloc(dwVerInfoSize);
if (lpBuffer)
{
if (GetFileVersionInfo(achPath, dwHandle, dwVerInfoSize, lpBuffer))
{
LangAndCodePage_t *pLangAndCodePage;
UINT cch;
if (VerQueryValue(lpBuffer, TEXT("\\VarFileInfo\\Translation"), (LPVOID *)&pLangAndCodePage, &cch) && cch)
{
// pay attention only to first entry
langidModule = (LANGID)pLangAndCodePage->wLanguage;
}
}
free(lpBuffer);
}
}
//
// If the languages don't match, look for a resource DLL
//
if (langidUI != langidModule)
{
DWORD cchDir;
HINSTANCE hinst;
// Look for {path}\{lcid}\{dll-name}
while (cch && achPath[--cch] != TEXT('\\'));
hinst = CheckDLL(achPath, achPath + cch + 1, langidUI, lpszSatelliteName);
if (hinst)
{
hinstRes = hinst; // Found!
}
else
{
//
// Couldn't find for specified UI langid; try default/netural sublangs.
//
if (SUBLANGID(langidUI) != SUBLANG_DEFAULT)
{
hinst = CheckDLL(achPath, achPath + cch + 1, MAKELANGID(PRIMARYLANGID(langidUI), SUBLANG_DEFAULT), lpszSatelliteName);
}
if (hinst)
{
hinstRes = hinst; // Found for SUBLANG_DEFAULT!
}
else if (SUBLANGID(langidUI) != SUBLANG_NEUTRAL)
{
hinst = CheckDLL(achPath, achPath + cch + 1, MAKELANGID(PRIMARYLANGID(langidUI), SUBLANG_NEUTRAL), lpszSatelliteName);
if (hinst)
{
hinstRes = hinst; // Found for SUBLANG_NEUTRAL!
}
}
}
}
}
if (hinstModule != hinstRes)
{
m_hinstRes = hinstRes; // Cache it so the dtor can call FreeLibrary
}
return hinstRes;
}
HINSTANCE Detach(void)
{
HINSTANCE hinstRes = m_hinstRes;
m_hinstRes = NULL;
return hinstRes;
}
private:
//
// Check if satellite DLL exist for a particular LANGID
//
HINSTANCE CheckDLL(
TCHAR * achPath, // [in] Complete path of module
TCHAR * pchDir, // [in] Path to directory of module (including backslash)
LANGID langid, // [in] Language of Satellite DLL
LPCTSTR lpszSatelliteName) // [in] Satellite DLL name
{
TCHAR * pchSubDir;
size_t cch;
// TODO: Verify that the versions are in sync with core DLL?
_itot(langid, pchDir, 10);
pchSubDir = pchDir + _tcslen(pchDir);
*pchSubDir++ = TEXT('\\');
_tcscpy(pchSubDir, lpszSatelliteName);
return LoadLibrary(achPath);
}
};
//--- Function Declarations -------------------------------------------------
//--- Inline Function Definitions -------------------------------------------