提交 1afdd41a 编写于 作者: E Elinor Fung 提交者: Jan Kotas

Remove unused parts of resource loading (#2164)

上级 3ec5b24c
......@@ -567,14 +567,6 @@ void GetResourceCultureCallbacks(
FPGETTHREADUICULTUREID* fpGetThreadUICultureId
);
#if !defined(DACCESS_COMPILE)
// Get the MUI ID, on downlevel platforms where MUI is not supported it
// returns the default system ID.
extern int GetMUILanguageID(LocaleIDValue* pResult);
extern HRESULT GetMUILanguageNames(__inout StringArrayList* pCultureNames);
#endif // !defined(DACCESS_COMPILE)
//*****************************************************************************
// Use this class by privately deriving from noncopyable to disallow copying of
// your class.
......@@ -727,8 +719,6 @@ public:
return m_bUseFallback;
};
static void SetIsMscoree() {s_bIsMscoree = TRUE;}
HRESULT LoadString(ResourceCategory eCategory, UINT iResourceID, __out_ecount (iMax) LPWSTR szBuffer, int iMax , int *pcwchUsed=NULL);
HRESULT LoadString(ResourceCategory eCategory, LocaleID langId, UINT iResourceID, __out_ecount (iMax) LPWSTR szBuffer, int iMax, int *pcwchUsed);
......@@ -742,13 +732,10 @@ public:
FPGETTHREADUICULTUREID* fpGetThreadUICultureId
);
HRESULT LoadMUILibrary(HRESOURCEDLL * pHInst);
// Get the default resource location (mscorrc.dll for desktop, mscorrc.debug.dll for CoreCLR)
static CCompRC* GetDefaultResourceDll();
// Get the generic messages dll (Silverlight only, mscorrc.dll)
static CCompRC* GetFallbackResourceDll();
static void ShutdownDefaultResourceDll();
static void GetDefaultCallbacks(
FPGETTHREADUICULTURENAMES* fpGetThreadUICultureNames,
FPGETTHREADUICULTUREID* fpGetThreadUICultureId)
......@@ -775,25 +762,8 @@ public:
m_FallbackResourceDll.SetResourceCultureCallbacks(
fpGetThreadUICultureNames,
fpGetThreadUICultureId);
}
#ifdef USE_FORMATMESSAGE_WRAPPER
DWORD
PALAPI
static
FormatMessage(
IN DWORD dwFlags,
IN LPCVOID lpSource,
IN DWORD dwMessageId,
IN DWORD dwLanguageId,
OUT LPWSTR lpBuffer,
IN DWORD nSize,
IN va_list *Arguments);
#endif // USE_FORMATMESSAGE_WRAPPER
private:
HRESULT GetLibrary(LocaleID langId, HRESOURCEDLL* phInst);
#ifndef DACCESS_COMPILE
......@@ -839,7 +809,6 @@ private:
FPGETTHREADUICULTURENAMES m_fpGetThreadUICultureNames;
BOOL m_bUseFallback;
static BOOL s_bIsMscoree;
};
HRESULT UtilLoadResourceString(CCompRC::ResourceCategory eCategory, UINT iResouceID, __out_ecount (iMax) LPWSTR szBuffer, int iMax);
......
......@@ -137,11 +137,7 @@
// winbase.h
#define WszGetEnvironmentStrings GetEnvironmentStringsW
#define WszFreeEnvironmentStrings FreeEnvironmentStringsW
#ifndef USE_FORMATMESSAGE_WRAPPER
#define WszFormatMessage FormatMessageW
#else
#define WszFormatMessage CCompRC::FormatMessage
#endif
#define Wszlstrcmp lstrcmpW
#define Wszlstrcmpi lstrcmpiW
#define WszCreateMutex CreateMutexW
......
......@@ -67,7 +67,6 @@ if(CLR_CMAKE_TARGET_WIN32)
appxutil.cpp
dacutil.cpp
dlwrap.cpp
loadrc.cpp
securitywrapper.cpp
securityutil.cpp
stacktrace.cpp
......
......@@ -18,117 +18,9 @@ __attribute__((visibility("default"))) DECLARE_NATIVE_STRING_RESOURCE_TABLE(NATI
#include <stdlib.h>
#ifdef USE_FORMATMESSAGE_WRAPPER
// we implement the wrapper for FormatMessageW.
// Need access to the original
#undef WszFormatMessage
#define WszFormatMessage ::FormatMessageW
#endif
#define MAX_VERSION_STRING 30
// External prototypes.
extern HINSTANCE GetModuleInst();
#ifndef FEATURE_PAL
//*****************************************************************************
// Get the MUI ID, on downlevel platforms where MUI is not supported it
// returns the default system ID.
typedef LANGID (WINAPI *PFNGETUSERDEFAULTUILANGUAGE)(void); // kernel32!GetUserDefaultUILanguage
int GetMUILanguageID(LocaleIDValue* pResult)
{
CONTRACTL
{
GC_NOTRIGGER;
NOTHROW;
#ifdef MODE_PREEMPTIVE
MODE_PREEMPTIVE;
#endif
}
CONTRACTL_END;
_ASSERTE(sizeof(LocaleID)/sizeof(WCHAR) >=LOCALE_NAME_MAX_LENGTH);
return ::GetSystemDefaultLocaleName(*pResult, LOCALE_NAME_MAX_LENGTH);
}
static void BuildMUIDirectory(int langid, __out SString* pResult)
{
CONTRACTL
{
THROWS;
GC_NOTRIGGER;
PRECONDITION(CheckPointer(pResult));
}
CONTRACTL_END;
pResult->Printf(W("MUI\\%04x\\"), langid);
}
void GetMUILanguageName(__out SString* pResult)
{
CONTRACTL
{
THROWS;
GC_NOTRIGGER;
PRECONDITION(CheckPointer(pResult));
}
CONTRACTL_END;
LocaleIDValue langid;
GetMUILanguageID(&langid);
int lcid = ::LocaleNameToLCID(langid,0);
return BuildMUIDirectory(lcid, pResult);
}
void GetMUIParentLanguageName(SString* pResult)
{
WRAPPER_NO_CONTRACT;
int langid = 1033;
BuildMUIDirectory(langid, pResult);
}
#ifndef DACCESS_COMPILE
HRESULT GetMUILanguageNames(__inout StringArrayList* pCultureNames)
{
CONTRACTL
{
NOTHROW;
GC_NOTRIGGER;
PRECONDITION(CheckPointer(pCultureNames));
}
CONTRACTL_END;
HRESULT hr=S_OK;
EX_TRY
{
SString result;
GetMUILanguageName(&result);
if(!result.IsEmpty())
{
pCultureNames->Append(result);
}
GetMUIParentLanguageName(&result);
_ASSERTE(!result.IsEmpty());
pCultureNames->Append(result);
pCultureNames->Append(SString::Empty());
}
EX_CATCH_HRESULT(hr)
return hr;
}
#endif // DACCESS_COMPILE
#endif // !FEATURE_PAL
BOOL CCompRC::s_bIsMscoree = FALSE;
//*****************************************************************************
// Do the mapping from an langId to an hinstance node
//*****************************************************************************
......@@ -807,27 +699,6 @@ HRESULT CCompRC::LoadString(ResourceCategory eCategory, LocaleID langId, UINT iR
}
#ifndef DACCESS_COMPILE
HRESULT CCompRC::LoadMUILibrary(HRESOURCEDLL * pHInst)
{
WRAPPER_NO_CONTRACT;
_ASSERTE(pHInst != NULL);
LocaleID langId;
LocaleIDValue langIdValue;
// Must resolve current thread's langId to a dll.
if(m_fpGetThreadUICultureId) {
int ret = (*m_fpGetThreadUICultureId)(&langIdValue);
// Callback can't return 0, since that indicates empty.
// To indicate empty, callback should return UICULTUREID_DONTCARE
_ASSERTE(ret != 0);
langId=langIdValue;
}
else
langId = UICULTUREID_DONTCARE;
HRESULT hr = GetLibrary(langId, pHInst);
return hr;
}
HRESULT CCompRC::LoadResourceFile(HRESOURCEDLL * pHInst, LPCWSTR lpFileName)
{
......@@ -1004,37 +875,3 @@ HRESULT CCompRC::LoadLibrary(HRESOURCEDLL * pHInst)
return hr;
}
#endif // DACCESS_COMPILE
#ifdef USE_FORMATMESSAGE_WRAPPER
DWORD
PALAPI
CCompRC::FormatMessage(
IN DWORD dwFlags,
IN LPCVOID lpSource,
IN DWORD dwMessageId,
IN DWORD dwLanguageId,
OUT LPWSTR lpBuffer,
IN DWORD nSize,
IN va_list *Arguments)
{
STATIC_CONTRACT_NOTHROW;
StackSString str;
if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
{
dwFlags&=~FORMAT_MESSAGE_FROM_SYSTEM;
dwFlags|=FORMAT_MESSAGE_FROM_STRING;
str.LoadResourceAndReturnHR(NULL,CCompRC::Error,dwMessageId);
lpSource=str.GetUnicode();
}
return WszFormatMessage(dwFlags,
lpSource,
dwMessageId,
dwLanguageId,
lpBuffer,
nSize,
Arguments);
}
#endif // USE_FORMATMESSAGE_WRAPPER
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// LoadRC-impl.cpp : Utility to load a localized file (primarily a DLL)
#include "palclr.h"
#if defined(USE_SSTRING)
// This is the normal path: use SafeString, wrappers, etc...
#include "sstring.h"
#include "safewrap.h"
typedef SString MyString;
typedef SString::CIterator MyStringIterator;
#define EndsWithChar(OBJ, CHAR) (OBJ.EndsWith(CHAR))
#define AppendChar(OBJ, CHAR) (OBJ.Append(CHAR))
#define AppendStr(OBJ, STR) (OBJ.Append(STR))
#define TrimLastChar(OBJ) (OBJ.Truncate(OBJ.End() - 1))
#define GetChars(OBJ) (OBJ.GetUnicode())
#define IsEmptyStr(OBJ) (OBJ.IsEmpty())
#define CharLength(OBJ) (OBJ.GetCount())
#define StrBeginIter(OBJ) (OBJ.Begin())
#define StrEndIter(OBJ) (OBJ.End())
#define FindNext(OBJ, ITER, CHAR) (OBJ.Find(ITER, CHAR))
#define MakeString(DST, OBJ, BEG, END) (DST.Set(OBJ, BEG, END))
#define StrEquals(STR1, STR2) (STR1.Compare(STR2)==0)
#define FindLast(OBJ, ITER, CHAR) (OBJ.FindBack(ITER, CHAR))
void SkipChars(MyString &str, MyStringIterator &i, WCHAR c1, WCHAR c2) { while (str.Skip(i, c1) || str.Skip(i, c2)); }
#elif defined(USE_WSTRING)
// This stuff is used by GacUtil, because it _really_ doesn't want to link with utilcode :-(
#include <string>
#include <algorithm>
typedef std::wstring MyString;
typedef std::wstring::const_iterator MyStringIterator;
#define EndsWithChar(OBJ, CHAR) (*(OBJ.rbegin()) == (CHAR))
#define AppendChar(OBJ, CHAR) (OBJ.push_back(CHAR))
#define AppendStr(OBJ, STR) (OBJ += STR)
#define TrimLastChar(OBJ) (OBJ.resize(OBJ.size() - 1))
#define GetChars(OBJ) (OBJ.c_str())
#define IsEmptyStr(OBJ) (OBJ.empty())
#define CharLength(OBJ) (OBJ.size())
#define StrBeginIter(OBJ) (OBJ.begin())
#define StrEndIter(OBJ) (OBJ.end())
#define FindNext(OBJ, ITER, CHAR) (ITER = std::find<std::wstring::const_iterator>(ITER, OBJ.end(), CHAR))
#define MakeString(DST, OBJ, BEG, END) (DST = MyString(BEG, END))
#define StrEquals(STR1, STR2) ((STR1) == (STR2))
#define ClrGetEnvironmentVariable(var, res) GetEnvVar(L##var, res)
bool FindLast(const MyString &str, MyStringIterator &iter, WCHAR c)
{
size_t pos = str.find_last_of(c);
iter = (pos == std::wstring::npos) ? str.end() : (str.begin() + pos);
return pos != std::wstring::npos;
}
void SkipChars(const MyString &str, MyStringIterator &i, WCHAR c1, WCHAR c2) { while (*i == c1 || *i == c2) i++; }
bool GetEnvVar(_In_z_ WCHAR *var, MyString &res)
{
WCHAR *buffer;
size_t size;
_wdupenv_s(&buffer, &size, var);
if (!size || !buffer)
return false;
res = buffer;
free(buffer); // Don't forget to free the buffer!
return true;
}
void ClrGetModuleFileName(HMODULE hModule, MyString& value)
{
WCHAR driverpath_tmp[_MAX_PATH];
GetModuleFileNameW(hModule, driverpath_tmp, _MAX_PATH);
value = driverpath_tmp;
}
#else
#error You must define either USE_SSTRING or USE_WSTRING to use this file
#endif
// This is a helper for loading localized string resource DLL files
HMODULE LoadLocalizedResourceDLLForSDK(_In_z_ LPCWSTR wzResourceDllName, _In_opt_z_ LPCWSTR modulePath, bool trySelf);
// This is a slight variation that can be used for anything else (ildasm.chm, for example)
typedef void* (__cdecl *LocalizedFileHandler)(LPCWSTR);
void* FindLocalizedFile(_In_z_ LPCWSTR wzResourceDllName, LocalizedFileHandler lfh, _In_opt_z_ LPCWSTR modulePath);
// Helper functions to combine paths
static MyString MakePath(const MyString &root, const MyString &file)
{
MyString res = root;
if (!EndsWithChar(res, W('\\')))
AppendChar(res, W('\\'));
AppendStr(res, file);
return res;
}
static MyString MakePath(const MyString &root, const MyString &dir, const MyString &file)
{
return MakePath(MakePath(root, dir), file);
}
// Helper to deal with occasional training back-slashes
static bool FileExists(const MyString &file)
{
if (!EndsWithChar(file, W('\\')))
return GetFileAttributesW(GetChars(file)) != INVALID_FILE_ATTRIBUTES;
else
{
MyString tmp(file);
TrimLastChar(tmp);
return GetFileAttributesW(GetChars(tmp)) != INVALID_FILE_ATTRIBUTES;
}
}
// Little helper function to get the codepage integer ID from the LocaleInfo
static UINT GetCodePage(LANGID LanguageID, DWORD locale)
{
WCHAR CodePageInt[12];
GetLocaleInfo(MAKELCID(LanguageID, SORT_DEFAULT), LOCALE_IDEFAULTCODEPAGE, CodePageInt, _countof(CodePageInt));
return _wtoi(CodePageInt);
}
// LCID helper macro
#define ENGLISH_LCID MAKELCID(MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ), SORT_DEFAULT)
// FindLocaleDirectory: Search the provided path for one of the expected code page subdirectories
// Returns empty string on failure, or the full path to the c:\my\directory\1033\myrcfile.dll
static MyString FindLocaleDirectory(const MyString &path, const MyString &dllName)
{
// We'll be checking for 3 different locales: The user's default locale
// The user's primary language locale, and english (in that order)
const LCID lcidUser = MAKELCID(GetUserDefaultUILanguage(), SORT_DEFAULT);
LCID rglcid[3] = {lcidUser, MAKELCID(MAKELANGID(PRIMARYLANGID(lcidUser), SUBLANG_DEFAULT), SORTIDFROMLCID(lcidUser)), ENGLISH_LCID};
for (int i = 0; i < _countof(rglcid); i++)
{
LCID lcid = rglcid[i];
// Turn the LCID into a string
WCHAR wzNumBuf[12];
_itow_s(lcid, wzNumBuf, _countof(wzNumBuf), 10);
MyString localePath = MakePath(path, wzNumBuf, dllName);
// Check to see if the file exists
if (FileExists(localePath))
{
// make sure the console can support a codepage for this language.
UINT ConsoleCP = GetConsoleOutputCP();
// Dev10 #843375: For a GUI application, GetConsoleOutputCP returns 0
// If that's the case, we don't care about capabilities of the console,
// since we're not outputting to the console, anyway...
if ( ConsoleCP != 0 && lcid != ENGLISH_LCID )
{
LANGID LanguageID = MAKELANGID( lcid, SUBLANGID(lcid) );
// we know the console cannot support arabic or hebrew (right to left scripts?)
if( PRIMARYLANGID(LanguageID) == LANG_ARABIC || PRIMARYLANGID(LanguageID) == LANG_HEBREW )
continue;
UINT LangOEMCodepage = GetCodePage(LanguageID, LOCALE_IDEFAULTCODEPAGE);
UINT LangANSICodepage = GetCodePage(LanguageID, LOCALE_IDEFAULTANSICODEPAGE);
// We can only support it if the console's code page is UTF8, OEM, or ANSI
if( ConsoleCP != CP_UTF8 && ConsoleCP != LangOEMCodepage && ConsoleCP != LangANSICodepage )
continue;
}
return localePath;
}
}
return W("");
}
// Attempt to load the resource file from the locale, first.
// If that fails, then just try any subdirectory of of the path provided
static void *LoadLocalFile(const MyString &path, const MyString &dllName, LocalizedFileHandler lfh)
{
if (IsEmptyStr(path) || IsEmptyStr(dllName))
return NULL;
MyString pathTemp = path;
// Languages are checked in the following order.
// 1) The UI language: this is returned by GetUserDefaultUILanguage.
// 2) As step 1, but with SUBLANG_DEFAULT
// 3) English
// 4) Any language that can be found!
MyString localePath = FindLocaleDirectory(pathTemp, dllName);
if (IsEmptyStr(localePath))
{
// None of the default choices exists, so now look for the first version of the dll in the given path.
// We don't bother to see if the console supports the dll's language.
MyString wildCard = MakePath(pathTemp, W("*.*"));
WIN32_FIND_DATAW wfdw;
HANDLE hDirs = FindFirstFileW(GetChars(wildCard), &wfdw);
if (hDirs == INVALID_HANDLE_VALUE)
return NULL;
do
{
// We are only interested in directories, since at this level, that should
// be the only thing in this directory, i.e, LCID sub dirs
if (wfdw.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
MyString file(wfdw.cFileName);
if (StrEquals(file, W(".")))
continue;
if (StrEquals(file, W("..")))
continue;
// Does this dir have the resource dll?
MyString fullPath = MakePath(pathTemp, file, dllName);
if (GetFileAttributesW(GetChars(fullPath)) != INVALID_FILE_ATTRIBUTES)
{
localePath = fullPath; // Got it - bail out of here
break;
}
}
} while (FindNextFileW(hDirs, &wfdw));
FindClose(hDirs);
if (IsEmptyStr(localePath))
{
//
// With CoreCLR we have the resource dll directly in the bin directory so check there now.
//
// Does this dir have the resource dll?
MyString fullPath = MakePath(path, dllName);
if (GetFileAttributesW(GetChars(fullPath)) != INVALID_FILE_ATTRIBUTES)
{
localePath = fullPath; // Got it - bail out of here
}
}
}
// Attempt to load the library
// Beware! A dll loaded with LOAD_LIBRARY_AS_DATAFILE won't
// let you use LoadIcon and things like that (only general calls like FindResource and LoadResource).
return IsEmptyStr(localePath) ? NULL : lfh(GetChars(localePath));
}
// Try to load the resource DLL from [each directory in %PATH%]/<lcid>/
static void *LoadSearchPath(const MyString &resourceDllName, LocalizedFileHandler lfh)
{
void *hmod = NULL;
// Get the PATH variable into a C++ string
MyString envPath;
if (ClrGetEnvironmentVariable("PATH", envPath))
return hmod;
MyStringIterator endOfChunk, startOfChunk = StrBeginIter(envPath);
MyString tryPath;
for (SkipChars(envPath, startOfChunk, W(' '), W(';'));
hmod == NULL && startOfChunk != StrEndIter(envPath);
SkipChars(envPath, startOfChunk, W(' '), W(';')))
{
// copy this chunk of the path into our trypath
endOfChunk = startOfChunk;
FindNext(envPath, endOfChunk, W(';'));
MakeString(tryPath, envPath, startOfChunk, endOfChunk);
// Don't try invalid locations
if (IsEmptyStr(tryPath) || CharLength(tryPath) >= _MAX_PATH)
continue;
// Try to load the dll
hmod = LoadLocalFile(tryPath, resourceDllName, lfh);
startOfChunk = endOfChunk;
}
return hmod;
}
void * __cdecl LibraryLoader(_In_z_ LPCWSTR lpFileName)
{
return (void *)(LoadLibraryExW(lpFileName, NULL, LOAD_LIBRARY_AS_DATAFILE));
}
void *FindLocalizedFile(_In_z_ LPCWSTR wzResourceDllName, LocalizedFileHandler lfh, _In_opt_z_ LPCWSTR modulePathW)
{
// find path of the modulePath
MyString driverPath;
MyString modulePath;
ClrGetModuleFileName(GetModuleHandleW(modulePathW), modulePath);
// Rip off the application name.
MyStringIterator trailingSlashLocation = StrEndIter(modulePath);
if (FindLast(modulePath, trailingSlashLocation, W('\\')))
MakeString(driverPath, modulePath, StrBeginIter(modulePath), trailingSlashLocation);
else
// If it's not a full path, look in the current directory
driverPath = W(".");
// return the first of the local directory's copy or the resource DLL on %PATH%
void *hmod = LoadLocalFile(driverPath, wzResourceDllName, lfh);
if (hmod == NULL)
hmod = LoadSearchPath(wzResourceDllName, lfh);
return hmod;
}
// load the satellite dll which contains string resources
HMODULE LoadLocalizedResourceDLLForSDK(_In_z_ LPCWSTR wzResourceDllName, _In_opt_z_ LPCWSTR modulePath, bool trySelf)
{
HMODULE hmod = (HMODULE)FindLocalizedFile(wzResourceDllName, &LibraryLoader, modulePath);
if (hmod == NULL && trySelf)
hmod = GetModuleHandleW(NULL);
return hmod;
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// Loads an localized string resource file
// this is used by sn.exe, ildasm.exe, peverify.exe, gacutil.exe, and fuslogvw.exe
// To use it by itself (not requiring utilcode*.lib), you'll need to use this CPP file
// along with safewrap, sstring
//
#include "stdafx.h"
#include "sstring.h"
#define USE_SSTRING
#include "loadrc-impl.cpp"
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册