|
|
#include "private.h"
#ifdef UNIX
/* Convert from little endian to big endian format */ #define CONVERTLONG(a,b,c,d) (((unsigned long )a) + \
((unsigned long )b << 8) + \ ((unsigned long )c << 16) + \ ((unsigned long )d << 24)) #endif /* UNIX */
//
// Globals
//
CMimeDatabaseReg *g_pMimeDatabaseReg = NULL;
//
// Globals
//
PRFC1766INFOA g_pRfc1766Reg = NULL; UINT g_cRfc1766Reg = 0, g_cMaxRfc1766 = 0;
//
// Functions
//
void CMimeDatabaseReg::BuildRfc1766Table(void) { HKEY hKey = NULL; DWORD dwIndex, dwType, cInfo, cbMaxValueLen, cbLCID, cb; TCHAR szLCID[8], sz[MAX_RFC1766_NAME + MAX_LOCALE_NAME + 1];
DebugMsg(DM_TRACE, TEXT("CRfc1766::BuildRfc1766Table called.")); EnterCriticalSection(&g_cs); if (NULL == g_pRfc1766Reg) { if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, REGSTR_KEY_MIME_DATABASE_RFC1766, 0, KEY_READ, &hKey)) { ASSERT(NULL != hKey); if (ERROR_SUCCESS == RegQueryInfoKey(hKey, NULL, NULL, 0, NULL, NULL, NULL, &cInfo, &cbMaxValueLen, NULL, NULL, NULL)) { g_pRfc1766Reg = (PRFC1766INFOA)LocalAlloc(LPTR, sizeof(RFC1766INFOA) * cInfo); if (NULL != g_pRfc1766Reg) { g_cRfc1766Reg = 0; g_cMaxRfc1766 = cInfo; dwIndex = 0; while (g_cRfc1766Reg < g_cMaxRfc1766) { LONG lRet;
cbLCID = ARRAYSIZE(szLCID) - 2; cb = sizeof(sz); lRet = RegEnumValue(hKey, dwIndex++, szLCID + 2, &cbLCID, 0, &dwType, (LPBYTE)sz, &cb); if (ERROR_SUCCESS == lRet) { int iLCID;
szLCID[0] = TEXT('0'); szLCID[1] = TEXT('x'); // StrToInt
if (iLCID = HexToNum(szLCID + 2)) { g_pRfc1766Reg[g_cRfc1766Reg].lcid = (LCID)iLCID; if (REG_SZ == dwType) { TCHAR *psz = sz;
while (*psz) { if (TEXT(';') == *psz) { *psz = TEXT('\0'); break; } psz = CharNext(psz); } lstrcpyn(g_pRfc1766Reg[g_cRfc1766Reg].szRfc1766, sz, MAX_RFC1766_NAME); lstrcpyn(g_pRfc1766Reg[g_cRfc1766Reg].szLocaleName, psz + 1, MAX_LOCALE_NAME); g_cRfc1766Reg++; } } } else if (ERROR_NO_MORE_ITEMS == lRet) break; } } } RegCloseKey(hKey); } } LeaveCriticalSection(&g_cs); }
void CMimeDatabaseReg::FreeRfc1766Table(void) { DebugMsg(DM_TRACE, TEXT("CRfc1766::FreeRfc1766Table called.")); EnterCriticalSection(&g_cs); if (NULL != g_pRfc1766Reg) { LocalFree(g_pRfc1766Reg); g_pRfc1766Reg = NULL; g_cRfc1766Reg = g_cMaxRfc1766 = 0; } LeaveCriticalSection(&g_cs); }
void CMimeDatabaseReg::EnsureRfc1766Table(void) { // Ensure g_pRfc1766 is initialized
if (NULL == g_pRfc1766Reg) BuildRfc1766Table(); }
STDAPI CMimeDatabaseReg::LcidToRfc1766A(LCID Locale, LPSTR pszRfc1766, int iMaxLength) { UINT i; HRESULT hr = E_INVALIDARG;
EnsureRfc1766Table(); if (NULL != pszRfc1766 && 0 < iMaxLength) { for (i = 0; i < g_cRfc1766Reg; i++) { if (g_pRfc1766Reg[i].lcid == Locale) break; } if (i < g_cRfc1766Reg) { lstrcpyn(pszRfc1766, g_pRfc1766Reg[i].szRfc1766, iMaxLength); hr = S_OK; } else { TCHAR sz[MAX_RFC1766_NAME];
if (GetLocaleInfoA(Locale, LOCALE_SABBREVLANGNAME, sz, ARRAYSIZE(sz))) { CharLowerA(sz); if (!lstrcmpA(sz, TEXT("cht"))) lstrcpynA(pszRfc1766, TEXT("zh-cn"), iMaxLength); else if (!lstrcmpA(sz, TEXT("chs"))) lstrcpynA(pszRfc1766, TEXT("zh-tw"), iMaxLength); else if (!lstrcmpA(sz, TEXT("jpn"))) lstrcpynA(pszRfc1766, TEXT("ja"), iMaxLength); else { sz[2] = TEXT('\0'); lstrcpynA(pszRfc1766, sz, iMaxLength); } hr = S_OK; } else hr = E_FAIL; } } return hr; }
STDAPI CMimeDatabaseReg::LcidToRfc1766W(LCID Locale, LPWSTR pwszRfc1766, int nChar) { HRESULT hr = E_INVALIDARG;
if (NULL != pwszRfc1766 && 0 < nChar) { TCHAR sz[MAX_RFC1766_NAME];
hr = LcidToRfc1766A(Locale, (LPSTR)sz, ARRAYSIZE(sz)); if (S_OK == hr) { int i;
for (i = 0; i < nChar - 1; i++) { pwszRfc1766[i] = (WCHAR)sz[i]; if (L'\0' == pwszRfc1766[i]) break; } if (i == nChar - 1) pwszRfc1766[i] = L'\0'; } } return hr; }
STDAPI CMimeDatabaseReg::Rfc1766ToLcidA(PLCID pLocale, LPCSTR pszRfc1766) { UINT i; HRESULT hr = E_INVALIDARG;
EnsureRfc1766Table(); if (NULL != pLocale && NULL != pszRfc1766) { for (i = 0; i < g_cRfc1766Reg; i++) { if (!lstrcmpi(g_pRfc1766Reg[i].szRfc1766, pszRfc1766)) break; } if (i < g_cRfc1766Reg) { *pLocale = g_pRfc1766Reg[i].lcid; hr = S_OK; } else { if (2 < lstrlen(pszRfc1766)) { TCHAR sz[3];
sz[0] = pszRfc1766[0]; sz[1] = pszRfc1766[1]; sz[2] = TEXT('\0'); for (i = 0; i < g_cRfc1766Reg; i++) { if (!lstrcmpi(g_pRfc1766Reg[i].szRfc1766, sz)) break; } if (i < g_cRfc1766Reg) { *pLocale = g_pRfc1766Reg[i].lcid; hr = S_FALSE; } else hr = E_FAIL; } else hr = E_FAIL; } } return hr; }
STDAPI CMimeDatabaseReg::Rfc1766ToLcidW(PLCID pLocale, LPCWSTR pwszRfc1766) { HRESULT hr = E_INVALIDARG;
if (NULL != pLocale && NULL != pwszRfc1766) { int i; TCHAR sz[MAX_RFC1766_NAME];
for (i = 0; i < MAX_RFC1766_NAME - 1; i++) { sz[i] = (TCHAR)pwszRfc1766[i]; if (TEXT('\0') == sz[i]) break; } if (i == MAX_RFC1766_NAME -1) sz[i] = TEXT('\0');
hr = Rfc1766ToLcidA(pLocale, (LPCSTR)sz); } return hr; }
//
// CMimeDatabase implementation
//
CMimeDatabaseReg::CMimeDatabaseReg() { DebugMsg(DM_TRACE, TEXT("constructor of CMimeDatabase 0x%08x"), this); _pCodePage = NULL; _cCodePage = _cMaxCodePage = 0; _pCharset = NULL; _cCharset = _cMaxCharset = 0; _fAllCPCached = FALSE; InitializeCriticalSection(&_cs); }
CMimeDatabaseReg::~CMimeDatabaseReg() { DebugMsg(DM_TRACE, TEXT("destructor of CMimeDatabase 0x%08x"), this); FreeMimeDatabase(); DeleteCriticalSection(&_cs); }
void CMimeDatabaseReg::BuildCodePageMimeDatabase(void) { HKEY hKey = NULL; DWORD cInfo, cbMaxSubKeyLen;
DebugMsg(DM_TRACE, TEXT("CMimeDatabase::BuildCodePageMimeDatabase called.")); // Open CodePage Mime Database Key
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, REGSTR_KEY_MIME_DATABASE_CODEPAGE, 0, KEY_READ, &hKey)) { ASSERT(NULL != hKey); if (ERROR_SUCCESS == RegQueryInfoKey(hKey, NULL, NULL, 0, &cInfo, &cbMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL)) { if (NULL == _pCodePage) { _pCodePage = (PMIMECPINFO)LocalAlloc(LPTR, sizeof(MIMECPINFO) * cInfo); if (NULL != _pCodePage) _cMaxCodePage = cInfo;
} } RegCloseKey(hKey); hKey = NULL; }
}
void CMimeDatabaseReg::BuildCharsetMimeDatabase(void) { HKEY hKey = NULL; DWORD cInfo, cbMaxSubKeyLen;
DebugMsg(DM_TRACE, TEXT("CMimeDatabase::BuildCharsetMimeDatabase called.")); // Open Charset Mime Database Key
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, REGSTR_KEY_MIME_DATABASE_CHARSET, 0, KEY_READ, &hKey)) { ASSERT(NULL != hKey); if (ERROR_SUCCESS == RegQueryInfoKey(hKey, NULL, NULL, 0, &cInfo, &cbMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL)) { if (NULL == _pCharset) { _pCharset = (PMIMECSETINFO)LocalAlloc(LPTR, sizeof(MIMECSETINFO) * cInfo); if (NULL != _pCharset) _cMaxCharset = cInfo; } } RegCloseKey(hKey); hKey = NULL; } }
void CMimeDatabaseReg::FreeMimeDatabase(void) { DebugMsg(DM_TRACE, TEXT("CMimeDatabase::FreeMimeDatabase called.")); EnterCriticalSection(&_cs); if (NULL != _pCodePage) { LocalFree(_pCodePage); _pCodePage = NULL; _cCodePage = _cMaxCodePage = 0; } if (NULL != _pCharset) { LocalFree(_pCharset); _pCharset = NULL; _cCharset = _cMaxCharset = 0; } LeaveCriticalSection(&_cs); FreeRfc1766Table(); }
STDAPI CMimeDatabaseReg::EnumCodePageInfo(void) { HKEY hKey = NULL; DWORD dwIndex = 0; MIMECPINFO CPInfo; TCHAR szCodePage[15]; HRESULT hr = S_OK;
DebugMsg(DM_TRACE, TEXT("CMimeDatabase::EnumCodePageInfo called.")); EnterCriticalSection(&_cs); if (FALSE == _fAllCPCached) { if (NULL == _pCodePage) BuildCodePageMimeDatabase(); if (_pCodePage) { // Open CodePage Mime Database Key
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, REGSTR_KEY_MIME_DATABASE_CODEPAGE, 0, KEY_READ, &hKey)) { ASSERT(NULL != hKey); while (ERROR_SUCCESS == RegEnumKey(hKey, dwIndex++, szCodePage, ARRAYSIZE(szCodePage))) { UINT uiCodePage = MLStrToInt(szCodePage); if (0 <= FindCodePageFromCache(uiCodePage)) continue;
if (TRUE == FindCodePageFromRegistry(uiCodePage, &CPInfo)) { _pCodePage[_cCodePage] = CPInfo; _cCodePage++; } } _fAllCPCached = TRUE; RegCloseKey(hKey); hKey = NULL; } if (0 < _cCodePage) QSortCodePageInfo(0, _cCodePage-1);
// Fill empty font face field base on its FamilyCodePage
for (UINT i = 0; i < _cCodePage; i++) { UINT uiFamily; WCHAR wszFixed[MAX_MIMEFACE_NAME], wszProp[MAX_MIMEFACE_NAME];
uiFamily = 0; wszFixed[0] = wszProp[0] = TEXT('\0');
if (TEXT('\0') == _pCodePage[i].wszFixedWidthFont[0] || TEXT('\0') == _pCodePage[i].wszProportionalFont[0]) { if (uiFamily != _pCodePage[i].uiFamilyCodePage) { for (UINT j = 0; j < _cCodePage; j++) { if (_pCodePage[i].uiFamilyCodePage == _pCodePage[j].uiCodePage) { uiFamily = _pCodePage[j].uiCodePage; MLStrCpyNW(wszFixed, _pCodePage[j].wszFixedWidthFont, MAX_MIMEFACE_NAME); MLStrCpyNW(wszProp, _pCodePage[j].wszProportionalFont, MAX_MIMEFACE_NAME); break; } } } MLStrCpyNW(_pCodePage[i].wszFixedWidthFont, wszFixed, MAX_MIMEFACE_NAME); MLStrCpyNW(_pCodePage[i].wszProportionalFont, wszProp, MAX_MIMEFACE_NAME); } } } else { hr = E_OUTOFMEMORY; } } LeaveCriticalSection(&_cs);
return hr; }
STDAPI CMimeDatabaseReg::GetNumberOfCodePageInfo(UINT *pcCodePage) { EnterCriticalSection(&_cs); if (NULL == _pCodePage) BuildCodePageMimeDatabase(); *pcCodePage = _cMaxCodePage; LeaveCriticalSection(&_cs); return NOERROR; }
STDAPI CMimeDatabaseReg::GetCodePageInfo(UINT uiCodePage, PMIMECPINFO pcpInfo) { int idx; HRESULT hr = E_FAIL;
DebugMsg(DM_TRACE, TEXT("CMimeDatabase::GetCodePageInfo called.")); if (NULL != pcpInfo) { EnterCriticalSection(&_cs); if (NULL == _pCodePage) BuildCodePageMimeDatabase();
if (_pCodePage) { idx = FindCodePageFromCache(uiCodePage); if (0 > idx) { MIMECPINFO CPInfo = {0};
if (TRUE == FindCodePageFromRegistry(uiCodePage, &CPInfo)) { if (CPInfo.uiCodePage != CPInfo.uiFamilyCodePage) { idx = FindCodePageFromCache(CPInfo.uiFamilyCodePage); if (0 > idx) { MIMECPINFO FamilyCPInfo;
if (TRUE == FindCodePageFromRegistry(CPInfo.uiFamilyCodePage, &FamilyCPInfo)) { idx = _cCodePage; _pCodePage[_cCodePage] = FamilyCPInfo; _cCodePage++; } } MLStrCpyNW(CPInfo.wszFixedWidthFont, _pCodePage[idx].wszFixedWidthFont, MAX_MIMEFACE_NAME); MLStrCpyNW(CPInfo.wszProportionalFont, _pCodePage[idx].wszProportionalFont, MAX_MIMEFACE_NAME); } _pCodePage[_cCodePage] = CPInfo; _cCodePage++; QSortCodePageInfo(0, _cCodePage-1); idx = FindCodePageFromCache(uiCodePage); } } if (0 <= idx) { *pcpInfo = _pCodePage[idx]; hr = S_OK; } LeaveCriticalSection(&_cs); } } return hr; }
int CMimeDatabaseReg::FindCodePageFromCache(UINT uiCodePage) { UINT i; int iRet = -1;
for (i = 0; i < _cCodePage; i++) { if (_pCodePage[i].uiCodePage == uiCodePage) { iRet = i; break; } } return iRet; }
BOOL CMimeDatabaseReg::FindCodePageFromRegistry(UINT uiCodePage, PMIMECPINFO pcpInfo) { HKEY hKey; DWORD dw, cb; TCHAR szKey[256], sz[MAX_MIMECP_NAME]; BOOL fRet = FALSE;
wsprintf(szKey, TEXT("%s\\%d"), REGSTR_KEY_MIME_DATABASE_CODEPAGE, uiCodePage); if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hKey)) { TCHAR *psz, *pszComma; CHARSETINFO rCharsetInfo;
pcpInfo->uiCodePage = uiCodePage;
cb = sizeof(dw); if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_FAMILY, 0, NULL, (LPBYTE)&dw, &cb)) pcpInfo->uiFamilyCodePage = (UINT)dw; else pcpInfo->uiFamilyCodePage = pcpInfo->uiCodePage;
cb = sizeof(dw); if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_LEVEL, 0, NULL, (LPBYTE)&dw, &cb)) #ifdef UNIX
{ BYTE* px = (BYTE*)&dw; pcpInfo->dwFlags = CONVERTLONG(px[0], px[1], px[2], px[3]); } #else
pcpInfo->dwFlags = dw; #endif /* UNIX */
else pcpInfo->dwFlags = 0;
cb = sizeof(sz); if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_DESCRIPTION, NULL, NULL, (LPBYTE)sz, &cb)) MultiByteToWideChar(CP_ACP, 0, sz, -1, pcpInfo->wszDescription, ARRAYSIZE(pcpInfo->wszDescription)); else { TCHAR szDef[MAX_MIMECP_NAME];
LoadString(g_hInst, IDS_MIME_LANG_DEFAULT, szDef, ARRAYSIZE(szDef)); wsprintf(sz, szDef, pcpInfo->uiCodePage); MultiByteToWideChar(CP_ACP, 0, sz, -1, pcpInfo->wszDescription, ARRAYSIZE(pcpInfo->wszDescription)); }
cb = sizeof(sz); if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_FIXEDWIDTHFONT, NULL, NULL, (LPBYTE)sz, &cb)) { psz = sz; pszComma = MLStrChr(sz, TEXT(',')); if (NULL != pszComma) // If there are multiple font name
{ if (uiCodePage != g_uACP) psz = pszComma + 1; // Take right side(English) fontname for non-native codepage info
else *pszComma = TEXT('\0'); // Take left side(DBCS) fontname for native codepage info
} if (lstrlen(psz) >= MAX_MIMEFACE_NAME) psz[MAX_MIMEFACE_NAME-1] = TEXT('\0'); MultiByteToWideChar(CP_ACP, 0, psz, -1, pcpInfo->wszFixedWidthFont, ARRAYSIZE(pcpInfo->wszFixedWidthFont)); } else pcpInfo->wszFixedWidthFont[0] = L'\0';
cb = sizeof(sz); if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_PROPORTIONALFONT, NULL, NULL, (LPBYTE)sz, &cb)) { psz = sz; pszComma = MLStrChr(sz, TEXT(',')); if (NULL != pszComma) // If there are multiple font name
{ if (uiCodePage != g_uACP) psz = pszComma + 1; // Take right side(English) fontname for non-native codepage info
else *pszComma = TEXT('\0'); // Take left side(DBCS) fontname for native codepage info
} if (lstrlen(psz) >= MAX_MIMEFACE_NAME) psz[MAX_MIMEFACE_NAME-1] = TEXT('\0'); MultiByteToWideChar(CP_ACP, 0, psz, -1, pcpInfo->wszProportionalFont, ARRAYSIZE(pcpInfo->wszProportionalFont)); } else pcpInfo->wszProportionalFont[0] = L'\0';
cb = sizeof(sz); if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_BODYCHARSET, NULL, NULL, (LPBYTE)sz, &cb)) MultiByteToWideChar(CP_ACP, 0, sz, -1, pcpInfo->wszBodyCharset, ARRAYSIZE(pcpInfo->wszBodyCharset)); else pcpInfo->wszBodyCharset[0] = L'\0';
cb = sizeof(sz); if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_HEADERCHARSET, NULL, NULL, (LPBYTE)sz, &cb)) MultiByteToWideChar(CP_ACP, 0, sz, -1, pcpInfo->wszHeaderCharset, ARRAYSIZE(pcpInfo->wszHeaderCharset)); else MLStrCpyNW(pcpInfo->wszHeaderCharset, pcpInfo->wszBodyCharset, MAX_MIMECSET_NAME);
cb = sizeof(sz); if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_WEBCHARSET, NULL, NULL, (LPBYTE)sz, &cb)) MultiByteToWideChar(CP_ACP, 0, sz, -1, pcpInfo->wszWebCharset, ARRAYSIZE(pcpInfo->wszWebCharset)); else MLStrCpyNW(pcpInfo->wszWebCharset, pcpInfo->wszBodyCharset, MAX_MIMECSET_NAME);
cb = sizeof(sz); if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_PRIVCONVERTER, NULL, NULL, (LPBYTE)sz, &cb)) pcpInfo->dwFlags |= MIMECONTF_PRIVCONVERTER;
if (0 != TranslateCharsetInfo(IntToPtr_(LPDWORD, pcpInfo->uiFamilyCodePage), &rCharsetInfo, TCI_SRCCODEPAGE)) pcpInfo->bGDICharset = (BYTE)rCharsetInfo.ciCharset; else pcpInfo->bGDICharset = DEFAULT_CHARSET;
if (1200 == pcpInfo->uiFamilyCodePage || 50000 == pcpInfo->uiFamilyCodePage || TRUE == _IsValidCodePage(pcpInfo->uiFamilyCodePage)) // 50000 means user defined
{ if (TRUE == CheckFont(pcpInfo->bGDICharset)) { if (pcpInfo->uiCodePage == pcpInfo->uiFamilyCodePage || TRUE == _IsValidCodePage(pcpInfo->uiCodePage)) pcpInfo->dwFlags |= MIMECONTF_VALID|MIMECONTF_VALID; else if (S_OK == IsConvertINetStringAvailable(pcpInfo->uiCodePage, pcpInfo->uiFamilyCodePage)) pcpInfo->dwFlags |= MIMECONTF_VALID|MIMECONTF_VALID; } else { if (pcpInfo->uiCodePage == pcpInfo->uiFamilyCodePage || TRUE == _IsValidCodePage(pcpInfo->uiCodePage)) pcpInfo->dwFlags |= MIMECONTF_VALID_NLS; else if (S_OK == IsConvertINetStringAvailable(pcpInfo->uiCodePage, pcpInfo->uiFamilyCodePage)) pcpInfo->dwFlags |= MIMECONTF_VALID_NLS; }
} RegCloseKey(hKey); fRet = TRUE; } return fRet; }
STDAPI CMimeDatabaseReg::GetCodePageInfoWithIndex(UINT uidx, PMIMECPINFO pcpInfo) { HRESULT hr = NOERROR;
DebugMsg(DM_TRACE, TEXT("CMimeDatabase::GetCodePageInfoWithIndex called.")); EnterCriticalSection(&_cs); if (NULL == _pCodePage) BuildCodePageMimeDatabase(); if (uidx < _cCodePage && _pCodePage) *pcpInfo = _pCodePage[uidx]; else hr = E_FAIL; LeaveCriticalSection(&_cs); return hr; }
STDAPI CMimeDatabaseReg::GetCharsetInfo(BSTR Charset, PMIMECSETINFO pcsetInfo) { int idx; HRESULT hr = E_FAIL;
DebugMsg(DM_TRACE, TEXT("CMimeDatabase::GetCharsetInfo called.")); if (NULL != pcsetInfo) { EnterCriticalSection(&_cs); if (NULL == _pCharset) BuildCharsetMimeDatabase(); if (_pCharset) { idx = FindCharsetFromCache(Charset); if (0 > idx) idx = FindCharsetFromRegistry(Charset, FALSE); if (0 <= idx) { *pcsetInfo = _pCharset[idx]; hr = S_OK; } } LeaveCriticalSection(&_cs); } return hr; }
int CMimeDatabaseReg::FindCharsetFromCache(BSTR Charset) { int iStart, iEnd, iMiddle, iCmpResult, iRet = -1;
iStart = 0; iEnd = _cCharset - 1; while (iStart <= iEnd) { iMiddle = (iStart + iEnd) / 2; iCmpResult = MLStrCmpIW(Charset, _pCharset[iMiddle].wszCharset); if (iCmpResult < 0) iEnd = iMiddle - 1; else if (iCmpResult > 0) iStart = iMiddle + 1; else { iRet = iMiddle; break; } } return iRet; }
int CMimeDatabaseReg::FindCharsetFromRegistry(BSTR Charset, BOOL fFromAlias) { HKEY hKey; TCHAR szKey[256], szCharset[MAX_MIMECSET_NAME]; int iRet = -1;
WideCharToMultiByte(CP_ACP, 0, Charset, -1, szCharset, ARRAYSIZE(szCharset), NULL, NULL); lstrcpy(szKey, REGSTR_KEY_MIME_DATABASE_CHARSET); lstrcat(szKey, TEXT("\\")); lstrcat(szKey, szCharset); if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hKey)) { DWORD cb, dw; TCHAR sz[MAX_MIMECSET_NAME]; WCHAR wsz[MAX_MIMECSET_NAME];
cb = sizeof(sz); if (FALSE == fFromAlias && ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_ALIASTO, NULL, NULL, (LPBYTE)sz, &cb)) { MultiByteToWideChar(CP_ACP, 0, sz, -1, wsz, ARRAYSIZE(wsz)); iRet = FindCharsetFromCache(wsz); if (0 > iRet) iRet = FindCharsetFromRegistry(wsz, TRUE); if (0 <= iRet) { MLStrCpyNW(_pCharset[_cCharset].wszCharset, Charset, MAX_MIMECSET_NAME); _pCharset[_cCharset].uiCodePage = _pCharset[iRet].uiCodePage; _pCharset[_cCharset].uiInternetEncoding = _pCharset[iRet].uiInternetEncoding; _cCharset++; QSortCharsetInfo(0, _cCharset-1); iRet = FindCharsetFromCache(Charset); } } else { MLStrCpyNW(_pCharset[_cCharset].wszCharset, Charset, MAX_MIMECSET_NAME); cb = sizeof(dw); if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_CODEPAGE, 0, NULL, (LPBYTE)&dw, &cb)) { _pCharset[_cCharset].uiCodePage = (UINT)dw; cb = sizeof(dw); if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_INETENCODING, 0, NULL, (LPBYTE)&dw, &cb)) { _pCharset[_cCharset].uiInternetEncoding = (UINT)dw; _cCharset++; QSortCharsetInfo(0, _cCharset-1); iRet = FindCharsetFromCache(Charset); } } } RegCloseKey(hKey); } return iRet; }
BOOL CMimeDatabaseReg::CheckFont(BYTE bGDICharset) { BOOL fRet = FALSE;
DebugMsg(DM_TRACE, TEXT("CMimeDatabase::CheckFont called.")); if (DEFAULT_CHARSET == bGDICharset) fRet = TRUE; else { HDC hDC; LOGFONT lf; HWND hWnd;
hWnd = GetTopWindow(GetDesktopWindow()); hDC = GetDC(hWnd);
if (NULL != hDC) { lf.lfFaceName[0] = TEXT('\0'); lf.lfPitchAndFamily = 0; lf.lfCharSet = bGDICharset; EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)EnumFontFamExProc, (LPARAM)&fRet, 0); } ReleaseDC(hWnd, hDC); } return fRet; }
void CMimeDatabaseReg::QSortCodePageInfo(LONG left, LONG right) { register LONG i, j; WCHAR k[MAX_MIMECP_NAME]; MIMECPINFO t;
DebugMsg(DM_TRACE, TEXT("CMimeDatabase::QSortCodePageInfo called.")); i = left; j = right; MLStrCpyW(k, _pCodePage[(left + right) / 2].wszDescription);
do { while(MLStrCmpIW(_pCodePage[i].wszDescription, k) < 0 && i < right) i++; while (MLStrCmpIW(_pCodePage[j].wszDescription, k) > 0 && j > left) j--;
if (i <= j) { t = _pCodePage[i]; _pCodePage[i] = _pCodePage[j]; _pCodePage[j] = t; i++; j--; }
} while (i <= j);
if (left < j) QSortCodePageInfo(left, j); if (i < right) QSortCodePageInfo(i, right); }
void CMimeDatabaseReg::QSortCharsetInfo(LONG left, LONG right) { register LONG i, j; WCHAR k[MAX_MIMECSET_NAME]; MIMECSETINFO t;
DebugMsg(DM_TRACE, TEXT("CMimeDatabase::QSortCharsetInfo called.")); i = left; j = right; MLStrCpyW(k, _pCharset[(left + right) / 2].wszCharset);
do { while(MLStrCmpIW(_pCharset[i].wszCharset, k) < 0 && i < right) i++; while (MLStrCmpIW(_pCharset[j].wszCharset, k) > 0 && j > left) j--;
if (i <= j) { t = _pCharset[i]; _pCharset[i] = _pCharset[j]; _pCharset[j] = t; i++; j--; }
} while (i <= j);
if (left < j) QSortCharsetInfo(left, j); if (i < right) QSortCharsetInfo(i, right); }
// validates all cps that are in the same
// family of the given codepage
STDAPI CMimeDatabaseReg::ValidateCP(UINT uiCodePage) { UINT i;
if (NULL == _pCodePage) BuildCodePageMimeDatabase(); //
// just look into already cached codepages
//
for (i = 0; i < _cCodePage; i++) { if (_pCodePage[i].uiFamilyCodePage == uiCodePage) _pCodePage[i].dwFlags |= MIMECONTF_VALID|MIMECONTF_VALID_NLS; } return S_OK; // never fail?
}
|