From dcde5d7661533e78c01d219359ea6fdd7a6d2dbf Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 28 Nov 2025 16:41:09 +0800 Subject: [PATCH 01/12] Link mscorrc into coreclr --- src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt | 2 +- src/coreclr/dlls/mscorrc/CMakeLists.txt | 13 +------------ src/coreclr/dlls/mscorrc/mscorrc.rc | 7 ------- 3 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt index 8d9d152ce7f924..f6a5b7ec9285be 100644 --- a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt @@ -82,6 +82,7 @@ endif (CLR_CMAKE_HOST_UNIX AND NOT CLR_CMAKE_TARGET_ARCH_WASM) # order dependent and changing the order can result in undefined symbols in the shared # library. set(CORECLR_LIBRARIES + mscorrc utilcode ${START_LIBRARY_GROUP} # Start group of libraries that have circular references ${LIB_CORDBEE} @@ -137,7 +138,6 @@ if(CLR_CMAKE_TARGET_WIN32) else() list(APPEND CORECLR_LIBRARIES coreclrpal - mscorrc ) endif(CLR_CMAKE_TARGET_WIN32) diff --git a/src/coreclr/dlls/mscorrc/CMakeLists.txt b/src/coreclr/dlls/mscorrc/CMakeLists.txt index 16894714a4a633..70daa08a57ba2f 100644 --- a/src/coreclr/dlls/mscorrc/CMakeLists.txt +++ b/src/coreclr/dlls/mscorrc/CMakeLists.txt @@ -3,20 +3,9 @@ include_directories("../../pal/prebuilt/corerror") add_definitions(-DFX_VER_INTERNALNAME_STR=mscorrc.dll) if(CLR_CMAKE_HOST_WIN32) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NOENTRY") - - # remove /guard:cf, /guard:ehcont, and /CETCOMPAT from resource-only libraries - set_property(DIRECTORY PROPERTY CLR_CONTROL_FLOW_GUARD OFF) - - if (CLR_CMAKE_HOST_ARCH_AMD64) - set_property(DIRECTORY PROPERTY CLR_EH_CONTINUATION OFF) - string(REPLACE "/CETCOMPAT" "" CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS}) - endif (CLR_CMAKE_HOST_ARCH_AMD64) - - add_library_clr(mscorrc SHARED + add_library_clr(mscorrc OBJECT include.rc ) - install_clr(TARGETS mscorrc DESTINATIONS . sharedFramework COMPONENT runtime) else() build_resources(${CMAKE_CURRENT_SOURCE_DIR}/include.rc mscorrc TARGET_CPP_FILE) diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc index abd530f5836d37..f11fe9431c8dd7 100644 --- a/src/coreclr/dlls/mscorrc/mscorrc.rc +++ b/src/coreclr/dlls/mscorrc/mscorrc.rc @@ -12,13 +12,6 @@ #include -#ifndef FX_VER_FILEDESCRIPTION_STR -#define FX_VER_FILEDESCRIPTION_STR ".NET Runtime resources" -#endif - -#include -#include - ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources From 6290d8af2bf639eed6f4d47ebf154c38c901e238 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 28 Nov 2025 17:17:37 +0800 Subject: [PATCH 02/12] Load resource from __ImageBase --- src/coreclr/utilcode/ccomprc.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/coreclr/utilcode/ccomprc.cpp b/src/coreclr/utilcode/ccomprc.cpp index bf4a487f4a9ea5..fad4ba07a6ad01 100644 --- a/src/coreclr/utilcode/ccomprc.cpp +++ b/src/coreclr/utilcode/ccomprc.cpp @@ -251,6 +251,10 @@ HRESULT CCompRC::GetLibrary(HRESOURCEDLL* phInst) } #endif // HOST_WINDOWS +#ifdef HOST_WINDOWS +extern "C" IMAGE_DOS_HEADER __ImageBase; +#endif + //***************************************************************************** // Load the string // We load the localized libraries and cache the handle for future use. @@ -272,18 +276,12 @@ HRESULT CCompRC::LoadString(ResourceCategory eCategory, UINT iResourceID, _Out_w CONTRACTL_END; #ifdef HOST_WINDOWS - HRESULT hr; - HRESOURCEDLL hInst = 0; //instance of cultured resource dll + HRESULT hr = S_OK; int length; - hr = GetLibrary(&hInst); - if (SUCCEEDED(hr)) { - // Now that we have the proper dll handle, load the string - _ASSERTE(hInst != NULL); - - length = ::LoadString(hInst, iResourceID, szBuffer, iMax); + length = ::LoadString((HINSTANCE)&__ImageBase, iResourceID, szBuffer, iMax); if(length > 0) { if(pcwchUsed) From 8d342f133ab4f290503c97a0451695f642f4217c Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 28 Nov 2025 17:39:12 +0800 Subject: [PATCH 03/12] Remove dll loading --- src/coreclr/inc/utilcode.h | 81 ------- src/coreclr/utilcode/ccomprc.cpp | 352 +------------------------------ 2 files changed, 1 insertion(+), 432 deletions(-) diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index b6bffb5f4fb87a..9620e03eff661c 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -368,55 +368,6 @@ class noncopyable const noncopyable& operator=(const noncopyable&); }; -//***************************************************************************** -// Must associate each handle to an instance of a resource dll with the int -// that it represents -//***************************************************************************** -typedef HINSTANCE HRESOURCEDLL; - - -class CCulturedHInstance -{ - HRESOURCEDLL m_hInst; - BOOL m_fMissing; - -public: - CCulturedHInstance() - { - LIMITED_METHOD_CONTRACT; - m_hInst = NULL; - m_fMissing = FALSE; - } - - HRESOURCEDLL GetLibraryHandle() - { - return m_hInst; - } - - BOOL IsSet() - { - return m_hInst != NULL; - } - - BOOL IsMissing() - { - return m_fMissing; - } - - void SetMissing() - { - _ASSERTE(m_hInst == NULL); - m_fMissing = TRUE; - } - - void Set(HRESOURCEDLL hInst) - { - _ASSERTE(m_hInst == NULL); - _ASSERTE(m_fMissing == FALSE); - m_hInst = hInst; - } - }; - //***************************************************************************** // CCompRC manages string Resource access for CLR. This includes loading // the MsCorRC.dll for resources. No localization is supported. @@ -445,46 +396,14 @@ class CCompRC Optional }; - CCompRC() - { - // This constructor will be fired up on startup. Make sure it doesn't - // do anything besides zero-out out values. - m_csMap = NULL; - m_pResourceFile = NULL; - }// CCompRC - - HRESULT Init(LPCWSTR pResourceFile); - void Destroy(); - HRESULT LoadString(ResourceCategory eCategory, UINT iResourceID, _Out_writes_ (iMax) LPWSTR szBuffer, int iMax , int *pcwchUsed=NULL); // Get the default resource location (mscorrc.dll) static CCompRC* GetDefaultResourceDll(); private: -// String resources packaged as PE files only exist on Windows -#ifdef HOST_WINDOWS - HRESULT GetLibrary(HRESOURCEDLL* phInst); -#ifndef DACCESS_COMPILE - HRESULT LoadLibraryHelper(HRESOURCEDLL *pHInst, - SString& rcPath); - HRESULT LoadLibraryThrows(HRESOURCEDLL * pHInst); - HRESULT LoadLibrary(HRESOURCEDLL * pHInst); - HRESULT LoadResourceFile(HRESOURCEDLL * pHInst, LPCWSTR lpFileName); -#endif // DACCESS_COMPILE -#endif // HOST_WINDOWS - // We do not have global constructors any more - static LONG m_dwDefaultInitialized; static CCompRC m_DefaultResourceDll; - static LPCWSTR m_pDefaultResource; - - // Use a singleton since we don't support localization any more. - CCulturedHInstance m_Primary; - - CRITSEC_COOKIE m_csMap; - - LPCWSTR m_pResourceFile; }; HRESULT UtilLoadResourceString(CCompRC::ResourceCategory eCategory, UINT iResourceID, _Out_writes_ (iMax) LPWSTR szBuffer, int iMax); diff --git a/src/coreclr/utilcode/ccomprc.cpp b/src/coreclr/utilcode/ccomprc.cpp index fad4ba07a6ad01..0961ccd733f96c 100644 --- a/src/coreclr/utilcode/ccomprc.cpp +++ b/src/coreclr/utilcode/ccomprc.cpp @@ -20,125 +20,6 @@ __attribute__((visibility("default"))) DECLARE_NATIVE_STRING_RESOURCE_TABLE(NATI // External prototypes. extern void* GetClrModuleBase(); -//***************************************************************************** -// Initialize -//***************************************************************************** -LPCWSTR CCompRC::m_pDefaultResource = W("mscorrc.dll"); - -HRESULT CCompRC::Init(LPCWSTR pResourceFile) -{ - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; - INJECT_FAULT(return E_OUTOFMEMORY;); - } - CONTRACTL_END; - - // This function is called during Watson process. We need to make sure - // that this function is restartable. - // - // Make sure to NEVER null out the function callbacks in the Init - // function. They get set for the "Default CCompRC" during EEStartup - // and we want to make sure we don't wipe them out. - - if (m_pResourceFile == NULL) - { - if(pResourceFile) - { - NewArrayHolder pwszResourceFile(NULL); - - DWORD lgth = (DWORD) u16_strlen(pResourceFile) + 1; - pwszResourceFile = new(nothrow) WCHAR[lgth]; - if (pwszResourceFile) - { - wcscpy_s(pwszResourceFile, lgth, pResourceFile); - LPCWSTR pFile = pwszResourceFile.Extract(); - if (InterlockedCompareExchangeT(&m_pResourceFile, pFile, NULL) != NULL) - { - delete [] pFile; - } - } - } - else - InterlockedCompareExchangeT(&m_pResourceFile, m_pDefaultResource, NULL); - } - - if (m_pResourceFile == NULL) - { - return E_OUTOFMEMORY; - } - - if (m_csMap == NULL) - { - // NOTE: there are times when the debugger's helper thread is asked to do a favor for another thread in the - // process. Typically, this favor involves putting up a dialog for the user. Putting up a dialog usually ends - // up involving the CCompRC code since (of course) the strings in the dialog are in a resource file. Thus, the - // debugger's helper thread will attempt to acquire this CRST. This is okay, since the helper thread only does - // these favors for other threads when there is no debugger attached. Thus, there are no deadlock hazards with - // this lock, and its safe for the helper thread to take, so this CRST is marked with CRST_DEBUGGER_THREAD. - CRITSEC_COOKIE csMap = ClrCreateCriticalSection(CrstCCompRC, - (CrstFlags)(CRST_UNSAFE_ANYMODE | CRST_DEBUGGER_THREAD | CRST_TAKEN_DURING_SHUTDOWN)); - - if (csMap) - { - if (InterlockedCompareExchangeT(&m_csMap, csMap, NULL) != NULL) - { - ClrDeleteCriticalSection(csMap); - } - } - } - - if (m_csMap == NULL) - return E_OUTOFMEMORY; - - return S_OK; -} - -void CCompRC::Destroy() -{ - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; -#ifdef MODE_PREEMPTIVE - MODE_PREEMPTIVE; -#endif - } - CONTRACTL_END; - - // Free all resource libraries - - //***************************************************************************** - // Free the loaded library if we ever loaded it. This is done - // only in debug mode to make coverage runs accurate. - //***************************************************************************** - -#if defined(_DEBUG) - if (m_Primary.GetLibraryHandle()) { - ::FreeLibrary(m_Primary.GetLibraryHandle()); - } -#endif - - // destroy map structure - if(m_pResourceFile != m_pDefaultResource) - delete [] m_pResourceFile; - m_pResourceFile = NULL; - - if(m_csMap) { - ClrDeleteCriticalSection(m_csMap); - ZeroMemory(&(m_csMap), sizeof(CRITSEC_COOKIE)); - } -} - - -//***************************************************************************** -// Initialization is done lazily, for backwards compatibility "mscorrc.dll" -// is consider the default location for all strings that use CCompRC. -// An instance value for CCompRC can be created to load resources from a different -// resource dll. -//***************************************************************************** -LONG CCompRC::m_dwDefaultInitialized = 0; CCompRC CCompRC::m_DefaultResourceDll; CCompRC* CCompRC::GetDefaultResourceDll() @@ -153,108 +34,9 @@ CCompRC* CCompRC::GetDefaultResourceDll() } CONTRACTL_END; - if (m_dwDefaultInitialized) - return &m_DefaultResourceDll; - - if(FAILED(m_DefaultResourceDll.Init(NULL))) - { - return NULL; - } - m_dwDefaultInitialized = 1; - return &m_DefaultResourceDll; } -//***************************************************************************** -//***************************************************************************** - -// String resources packaged as PE files only exist on Windows -#ifdef HOST_WINDOWS -HRESULT CCompRC::GetLibrary(HRESOURCEDLL* phInst) -{ - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; -#ifdef MODE_PREEMPTIVE - MODE_PREEMPTIVE; -#endif - PRECONDITION(phInst != NULL); - } - CONTRACTL_END; - - HRESULT hr = E_FAIL; - HRESOURCEDLL hInst = 0; -#ifndef DACCESS_COMPILE - HRESOURCEDLL hLibInst = 0; //Holds early library instance - BOOL fLibAlreadyOpen = FALSE; //Determine if we can close the opened library. -#endif - - // Try to match the primary entry, or else use the primary if we don't care. - if (m_Primary.IsSet()) - { - hInst = m_Primary.GetLibraryHandle(); - hr = S_OK; - } - else if(m_Primary.IsMissing()) - { - // If primary is missing then the hash will not have anything either - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - } -#ifndef DACCESS_COMPILE - // If this is the first visit, we must set the primary entry - else - { - // Don't immediately return if LoadLibrary fails so we can indicate the file was missing - hr = LoadLibrary(&hLibInst); - // If it's a transient failure, don't cache the failure - if (FAILED(hr) && Exception::IsTransient(hr)) - { - return hr; - } - - CRITSEC_Holder csh (m_csMap); - // As we expected - if (!m_Primary.IsSet() && !m_Primary.IsMissing()) - { - hInst = hLibInst; - if (SUCCEEDED(hr)) - { - m_Primary.Set(hLibInst); - } - else - { - m_Primary.SetMissing(); - } - } - - // Someone got into this critical section before us and set the primary already - else - { - hInst = m_Primary.GetLibraryHandle(); - fLibAlreadyOpen = TRUE; - } - - IfFailRet(hr); - - if (fLibAlreadyOpen) - { - FreeLibrary(hLibInst); - fLibAlreadyOpen = FALSE; - } - } -#endif - - _ASSERTE(SUCCEEDED(hr) || hInst == NULL); - *phInst = hInst; - return hr; -} -#endif // HOST_WINDOWS - -#ifdef HOST_WINDOWS -extern "C" IMAGE_DOS_HEADER __ImageBase; -#endif - //***************************************************************************** // Load the string // We load the localized libraries and cache the handle for future use. @@ -281,7 +63,7 @@ HRESULT CCompRC::LoadString(ResourceCategory eCategory, UINT iResourceID, _Out_w if (SUCCEEDED(hr)) { - length = ::LoadString((HINSTANCE)&__ImageBase, iResourceID, szBuffer, iMax); + length = ::LoadString((HINSTANCE)GetClrModuleBase(), iResourceID, szBuffer, iMax); if(length > 0) { if(pcwchUsed) @@ -307,135 +89,3 @@ HRESULT CCompRC::LoadString(ResourceCategory eCategory, UINT iResourceID, _Out_w #endif // HOST_WINDOWS #endif } - -#ifndef DACCESS_COMPILE - -// String resources packaged as PE files only exist on Windows -#ifdef HOST_WINDOWS -HRESULT CCompRC::LoadResourceFile(HRESOURCEDLL * pHInst, LPCWSTR lpFileName) -{ - DWORD dwLoadLibraryFlags; - if(m_pResourceFile == m_pDefaultResource) - { - dwLoadLibraryFlags = LOAD_LIBRARY_AS_DATAFILE; - } - else - { - dwLoadLibraryFlags = 0; - } - - if((*pHInst = WszLoadLibrary(lpFileName, NULL, dwLoadLibraryFlags)) == NULL) - { - return HRESULT_FROM_GetLastError(); - } - return S_OK; -} - -//***************************************************************************** -// Load the library from root path (\mscorrc.dll). No locale support. -//***************************************************************************** -HRESULT CCompRC::LoadLibraryHelper(HRESOURCEDLL *pHInst, - SString& rcPath) -{ - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; -#ifdef MODE_PREEMPTIVE - MODE_PREEMPTIVE; -#endif - } - CONTRACTL_END; - - HRESULT hr = E_FAIL; - - - _ASSERTE(m_pResourceFile != NULL); - - // must initialize before calling SString::Empty() - SString::Startup(); - - EX_TRY - { - PathString rcPathName(rcPath); - - if (!rcPathName.EndsWith(SL(W("\\")))) - { - rcPathName.Append(W("\\")); - } - - { - rcPathName.Append(m_pResourceFile); - } - - // Load the resource library as a data file, so that the OS doesn't have - // to allocate it as code. This only works so long as the file contains - // only strings. - hr = LoadResourceFile(pHInst, rcPathName); - } - EX_CATCH_HRESULT(hr); - - return hr; -} - -// Two-stage approach: -// First try module directory, then try CORSystemDirectory for default resource -HRESULT CCompRC::LoadLibraryThrows(HRESOURCEDLL * pHInst) -{ - CONTRACTL - { - GC_NOTRIGGER; - THROWS; -#ifdef MODE_PREEMPTIVE - MODE_PREEMPTIVE; -#endif - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - _ASSERTE(pHInst != NULL); - - -#ifdef SELF_NO_HOST - _ASSERTE(!"CCompRC::LoadLibraryThrows not implemented for SELF_NO_HOST"); - hr = E_NOTIMPL; -#else // SELF_NO_HOST - PathString rcPath; // Path to resource DLL. - - // Try first in the same directory as this dll. - - hr = GetClrModuleDirectory(rcPath); - if (FAILED(hr)) - return hr; - - hr = LoadLibraryHelper(pHInst, rcPath); -#endif - - - return hr; -} - -HRESULT CCompRC::LoadLibrary(HRESOURCEDLL * pHInst) -{ - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; -#ifdef MODE_PREEMPTIVE - MODE_PREEMPTIVE; -#endif - } - CONTRACTL_END; - - HRESULT hr = S_OK; - EX_TRY - { - hr = LoadLibraryThrows(pHInst); - } - EX_CATCH_HRESULT(hr); - - return hr; -} -#endif // DACCESS_COMPILE -#endif //HOST_WINDOWS From 0e7cd54d0ac7b906bb5fbc874d76f5660007a211 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 28 Nov 2025 21:05:31 +0800 Subject: [PATCH 04/12] Remove instance method --- src/coreclr/inc/utilcode.h | 11 +---- src/coreclr/utilcode/ccomprc.cpp | 41 ++++------------ src/coreclr/utilcode/posterror.cpp | 33 +------------ src/coreclr/utilcode/sstring_com.cpp | 71 +++++++++++++--------------- 4 files changed, 44 insertions(+), 112 deletions(-) diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index 9620e03eff661c..d1dd177cc83cf8 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -396,18 +396,9 @@ class CCompRC Optional }; - HRESULT LoadString(ResourceCategory eCategory, UINT iResourceID, _Out_writes_ (iMax) LPWSTR szBuffer, int iMax , int *pcwchUsed=NULL); - - // Get the default resource location (mscorrc.dll) - static CCompRC* GetDefaultResourceDll(); - -private: - // We do not have global constructors any more - static CCompRC m_DefaultResourceDll; + static HRESULT LoadString(ResourceCategory eCategory, UINT iResourceID, _Out_writes_ (iMax) LPWSTR szBuffer, int iMax , int *pcwchUsed=NULL); }; -HRESULT UtilLoadResourceString(CCompRC::ResourceCategory eCategory, UINT iResourceID, _Out_writes_ (iMax) LPWSTR szBuffer, int iMax); - // The HRESULT_FROM_WIN32 macro evaluates its arguments three times. // TODO: All HRESULT_FROM_WIN32(GetLastError()) should be replaced by calls to // this helper function avoid code bloat diff --git a/src/coreclr/utilcode/ccomprc.cpp b/src/coreclr/utilcode/ccomprc.cpp index 0961ccd733f96c..6847e3ca3961c8 100644 --- a/src/coreclr/utilcode/ccomprc.cpp +++ b/src/coreclr/utilcode/ccomprc.cpp @@ -11,32 +11,12 @@ #define NATIVE_STRING_RESOURCE_NAME mscorrc __attribute__((visibility("default"))) DECLARE_NATIVE_STRING_RESOURCE_TABLE(NATIVE_STRING_RESOURCE_NAME); #endif -#include "sstring.h" -#include "stringarraylist.h" -#include "corpriv.h" #include // External prototypes. extern void* GetClrModuleBase(); -CCompRC CCompRC::m_DefaultResourceDll; - -CCompRC* CCompRC::GetDefaultResourceDll() -{ - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; -#ifdef MODE_PREEMPTIVE - MODE_PREEMPTIVE; -#endif - } - CONTRACTL_END; - - return &m_DefaultResourceDll; -} - //***************************************************************************** // Load the string // We load the localized libraries and cache the handle for future use. @@ -61,22 +41,19 @@ HRESULT CCompRC::LoadString(ResourceCategory eCategory, UINT iResourceID, _Out_w HRESULT hr = S_OK; int length; - if (SUCCEEDED(hr)) + length = ::LoadString((HINSTANCE)GetClrModuleBase(), iResourceID, szBuffer, iMax); + if(length > 0) { - length = ::LoadString((HINSTANCE)GetClrModuleBase(), iResourceID, szBuffer, iMax); - if(length > 0) + if(pcwchUsed) { - if(pcwchUsed) - { - *pcwchUsed = length; - } - return (S_OK); + *pcwchUsed = length; } - if(GetLastError()==ERROR_SUCCESS) - hr=HRESULT_FROM_WIN32(ERROR_NOT_FOUND); - else - hr=HRESULT_FROM_GetLastError(); + return (S_OK); } + if (SUCCEEDED(GetLastError())) + hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + else + hr = HRESULT_FROM_GetLastError(); // Return an empty string to save the people with a bad error handling if (szBuffer && iMax) diff --git a/src/coreclr/utilcode/posterror.cpp b/src/coreclr/utilcode/posterror.cpp index 3de8b3f5158e31..777b0efa3e5a97 100644 --- a/src/coreclr/utilcode/posterror.cpp +++ b/src/coreclr/utilcode/posterror.cpp @@ -34,38 +34,7 @@ STDAPI UtilLoadStringRC( ) { WRAPPER_NO_CONTRACT; - return UtilLoadResourceString(bQuiet? CCompRC::Optional : CCompRC::Required,iResourceID, szBuffer, iMax); -} - -HRESULT UtilLoadResourceString(CCompRC::ResourceCategory eCategory, UINT iResourceID, _Out_writes_ (iMax) LPWSTR szBuffer, int iMax) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_NOTRIGGER; - } - CONTRACTL_END; - - HRESULT retVal = E_OUTOFMEMORY; - - SString::Startup(); - EX_TRY - { - CCompRC *pResourceDLL = CCompRC::GetDefaultResourceDll(); - - if (pResourceDLL != NULL) - { - retVal = pResourceDLL->LoadString(eCategory, iResourceID, szBuffer, iMax); - } - } - EX_CATCH - { - // Catch any errors and return E_OUTOFMEMORY; - retVal = E_OUTOFMEMORY; - } - EX_END_CATCH - - return retVal; + return CCompRC::LoadString(bQuiet? CCompRC::Optional : CCompRC::Required, iResourceID, szBuffer, iMax); } //***************************************************************************** diff --git a/src/coreclr/utilcode/sstring_com.cpp b/src/coreclr/utilcode/sstring_com.cpp index 855b7c0620bf90..55b09ac50680a8 100644 --- a/src/coreclr/utilcode/sstring_com.cpp +++ b/src/coreclr/utilcode/sstring_com.cpp @@ -32,59 +32,54 @@ HRESULT SString::LoadResourceAndReturnHR(CCompRC::ResourceCategory eCategory, in HRESULT hr = E_FAIL; #ifndef FEATURE_UTILCODE_NO_DEPENDENCIES - CCompRC* pResourceDLL = CCompRC::GetDefaultResourceDll(); - if (pResourceDLL != NULL) - { + int size = 0; - int size = 0; + EX_TRY + { + if (GetRawCount() == 0) + Resize(DEFAULT_RESOURCE_STRING_SIZE, REPRESENTATION_UNICODE); - EX_TRY + while (TRUE) { - if (GetRawCount() == 0) - Resize(DEFAULT_RESOURCE_STRING_SIZE, REPRESENTATION_UNICODE); + // First try and load the string in the amount of space that we have. + // In fatal error reporting scenarios, we may not have enough memory to + // allocate a larger buffer. - while (TRUE) + hr = CCompRC::LoadString(eCategory, resourceID, GetRawUnicode(), GetRawCount()+1, &size); + if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { - // First try and load the string in the amount of space that we have. - // In fatal error reporting scenarios, we may not have enough memory to - // allocate a larger buffer. - - hr = pResourceDLL->LoadString(eCategory, resourceID, GetRawUnicode(), GetRawCount()+1, &size); - if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) + if (FAILED(hr)) { - if (FAILED(hr)) - { - Clear(); - break; - } - - // Although we cannot generally detect truncation, we can tell if we - // used up all the space (in which case we will assume truncation.) - if (size < (int)GetRawCount()) - { - break; - } + Clear(); + break; } - // Double the size and try again. - Resize(size*2, REPRESENTATION_UNICODE); - - } - - if (SUCCEEDED(hr)) - { - Truncate(Begin() + (COUNT_T) u16_strlen(GetRawUnicode())); + // Although we cannot generally detect truncation, we can tell if we + // used up all the space (in which case we will assume truncation.) + if (size < (int)GetRawCount()) + { + break; + } } - Normalize(); + // Double the size and try again. + Resize(size*2, REPRESENTATION_UNICODE); } - EX_CATCH + + if (SUCCEEDED(hr)) { - hr = E_FAIL; + Truncate(Begin() + (COUNT_T) u16_strlen(GetRawUnicode())); } - EX_END_CATCH + + Normalize(); + + } + EX_CATCH + { + hr = E_FAIL; } + EX_END_CATCH #endif //!FEATURE_UTILCODE_NO_DEPENDENCIES RETURN hr; From 7a2881b8d1f89a59d0c5a678fc636655cbc109f7 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 28 Nov 2025 21:33:37 +0800 Subject: [PATCH 05/12] Remove wrappers --- src/coreclr/inc/utilcode.h | 5 +---- src/coreclr/utilcode/ccomprc.cpp | 2 +- src/coreclr/utilcode/posterror.cpp | 16 +--------------- src/coreclr/utilcode/sstring_com.cpp | 2 +- src/coreclr/vm/excep.cpp | 4 ++-- 5 files changed, 6 insertions(+), 23 deletions(-) diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index d1dd177cc83cf8..532d6811f19d27 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -348,9 +348,6 @@ HMODULE CLRLoadLibraryEx(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); BOOL CLRFreeLibrary(HMODULE hModule); -// Load a string using the resources for the current module. -STDAPI UtilLoadStringRC(UINT iResourceID, _Out_writes_ (iMax) LPWSTR szBuffer, int iMax, int bQuiet=FALSE); - //***************************************************************************** // Use this class by privately deriving from noncopyable to disallow copying of // your class. @@ -396,7 +393,7 @@ class CCompRC Optional }; - static HRESULT LoadString(ResourceCategory eCategory, UINT iResourceID, _Out_writes_ (iMax) LPWSTR szBuffer, int iMax , int *pcwchUsed=NULL); + static HRESULT LoadString(UINT iResourceID, _Out_writes_ (iMax) LPWSTR szBuffer, int iMax , int *pcwchUsed=NULL); }; // The HRESULT_FROM_WIN32 macro evaluates its arguments three times. diff --git a/src/coreclr/utilcode/ccomprc.cpp b/src/coreclr/utilcode/ccomprc.cpp index 6847e3ca3961c8..61d288758c0ef2 100644 --- a/src/coreclr/utilcode/ccomprc.cpp +++ b/src/coreclr/utilcode/ccomprc.cpp @@ -22,7 +22,7 @@ extern void* GetClrModuleBase(); // We load the localized libraries and cache the handle for future use. // Mutliple threads may call this, so the cache structure is thread safe. //***************************************************************************** -HRESULT CCompRC::LoadString(ResourceCategory eCategory, UINT iResourceID, _Out_writes_(iMax) LPWSTR szBuffer, int iMax, int *pcwchUsed) +HRESULT CCompRC::LoadString(UINT iResourceID, _Out_writes_(iMax) LPWSTR szBuffer, int iMax, int *pcwchUsed) { #ifdef DBI_COMPONENT_MONO return E_NOTIMPL; diff --git a/src/coreclr/utilcode/posterror.cpp b/src/coreclr/utilcode/posterror.cpp index 777b0efa3e5a97..42011a513bbe72 100644 --- a/src/coreclr/utilcode/posterror.cpp +++ b/src/coreclr/utilcode/posterror.cpp @@ -23,20 +23,6 @@ // Local prototypes. HRESULT FillErrorInfo(LPCWSTR szMsg, DWORD dwHelpContext); -//***************************************************************************** -// Public function to load a resource string -//***************************************************************************** -STDAPI UtilLoadStringRC( - UINT iResourceID, - _Out_writes_(iMax) LPWSTR szBuffer, - int iMax, - int bQuiet -) -{ - WRAPPER_NO_CONTRACT; - return CCompRC::LoadString(bQuiet? CCompRC::Optional : CCompRC::Required, iResourceID, szBuffer, iMax); -} - //***************************************************************************** // Format a Runtime Error message. //***************************************************************************** @@ -63,7 +49,7 @@ static HRESULT FormatRuntimeErrorVA( // If this is one of our errors or if it is simply a resource ID, then grab the error from the rc file. if ((HRESULT_FACILITY(hrRpt) == FACILITY_URT) || (HIWORD(hrRpt) == 0)) { - hr = UtilLoadStringRC(LOWORD(hrRpt), rcBuf, ARRAY_SIZE(rcBuf), true); + hr = CCompRC::LoadString(LOWORD(hrRpt), rcBuf, ARRAY_SIZE(rcBuf)); if (hr == S_OK) { hr = E_OUTOFMEMORY; // Out of memory is possible diff --git a/src/coreclr/utilcode/sstring_com.cpp b/src/coreclr/utilcode/sstring_com.cpp index 55b09ac50680a8..818156f100f756 100644 --- a/src/coreclr/utilcode/sstring_com.cpp +++ b/src/coreclr/utilcode/sstring_com.cpp @@ -45,7 +45,7 @@ HRESULT SString::LoadResourceAndReturnHR(CCompRC::ResourceCategory eCategory, in // In fatal error reporting scenarios, we may not have enough memory to // allocate a larger buffer. - hr = CCompRC::LoadString(eCategory, resourceID, GetRawUnicode(), GetRawCount()+1, &size); + hr = CCompRC::LoadString(resourceID, GetRawUnicode(), GetRawCount()+1, &size); if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { if (FAILED(hr)) diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index d285f2b1f184d4..7096d95183f832 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -4766,7 +4766,7 @@ DefaultCatchHandlerExceptionMessageWorker(Thread* pThread, GCPROTECT_BEGIN(throwable); if (throwable != NULL) { - if (FAILED(UtilLoadResourceString(CCompRC::Error, IDS_EE_UNHANDLED_EXCEPTION, buf, buf_size))) + if (FAILED(CCompRC::LoadString(IDS_EE_UNHANDLED_EXCEPTION, buf, buf_size))) { wcsncpy_s(buf, buf_size, SZ_UNHANDLED_EXCEPTION, SZ_UNHANDLED_EXCEPTION_CHARLEN); } @@ -4961,7 +4961,7 @@ DefaultCatchHandler(PEXCEPTION_POINTERS pExceptionPointers, _ASSERTE(buf_size > 6); wcscpy_s(buf, buf_size, W("\n ")); - UtilLoadStringRC(IDS_EE_EXCEPTION_TOSTRING_FAILED, buf + 4, buf_size - 6); + CCompRC::LoadString(IDS_EE_EXCEPTION_TOSTRING_FAILED, buf + 4, buf_size - 6); wcscat_s(buf, buf_size, W("\n")); PrintToStdErrW(buf); From 3fe073f57c245535f17b92afe9a6d11baa0df5be Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 29 Nov 2025 00:00:17 +0800 Subject: [PATCH 06/12] Remove category --- src/coreclr/binder/bindertracing.cpp | 4 ++-- src/coreclr/inc/sstring.h | 4 ++-- src/coreclr/inc/utilcode.h | 23 +-------------------- src/coreclr/utilcode/ccomprc.cpp | 13 ++++-------- src/coreclr/utilcode/ex.cpp | 4 ++-- src/coreclr/utilcode/sstring_com.cpp | 6 +++--- src/coreclr/vm/assemblynative.cpp | 2 +- src/coreclr/vm/clrex.cpp | 2 +- src/coreclr/vm/comutilnative.cpp | 6 +++--- src/coreclr/vm/eepolicy.cpp | 2 +- src/coreclr/vm/eventreporter.cpp | 30 ++++++++++++++-------------- src/coreclr/vm/excep.cpp | 14 ++++++------- src/coreclr/vm/mlinfo.cpp | 4 ++-- src/coreclr/vm/profilinghelper.cpp | 2 -- 14 files changed, 44 insertions(+), 72 deletions(-) diff --git a/src/coreclr/binder/bindertracing.cpp b/src/coreclr/binder/bindertracing.cpp index 5a0f1a9470a3ed..b52f75878a0938 100644 --- a/src/coreclr/binder/bindertracing.cpp +++ b/src/coreclr/binder/bindertracing.cpp @@ -219,9 +219,9 @@ namespace BinderTracing if (mvidMismatch) { StackSString format; - format.LoadResource(CCompRC::Error, IDS_EE_FILELOAD_ERROR_GENERIC); + format.LoadResource(IDS_EE_FILELOAD_ERROR_GENERIC); StackSString details; - details.LoadResource(CCompRC::Error, IDS_HOST_ASSEMBLY_RESOLVER_ASSEMBLY_ALREADY_LOADED_IN_CONTEXT); + details.LoadResource(IDS_HOST_ASSEMBLY_RESOLVER_ASSEMBLY_ALREADY_LOADED_IN_CONTEXT); errorMsg.FormatMessage(FORMAT_MESSAGE_FROM_STRING, format.GetUnicode(), 0, 0, m_assemblyName, details); } diff --git a/src/coreclr/inc/sstring.h b/src/coreclr/inc/sstring.h index 9ca98ada6362c2..82463acc654601 100644 --- a/src/coreclr/inc/sstring.h +++ b/src/coreclr/inc/sstring.h @@ -572,8 +572,8 @@ class EMPTY_BASES_DECL SString : private SBuffer void AppendVPrintf(const CHAR *format, va_list args); public: - BOOL LoadResource(CCompRC::ResourceCategory eCategory, int resourceID); - HRESULT LoadResourceAndReturnHR(CCompRC::ResourceCategory eCategory, int resourceID); + BOOL LoadResource(int resourceID); + HRESULT LoadResourceAndReturnHR(int resourceID); BOOL FormatMessage(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, const SString &arg1 = Empty(), const SString &arg2 = Empty(), const SString &arg3 = Empty(), const SString &arg4 = Empty(), diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index 532d6811f19d27..280c26569c19ff 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -366,33 +366,12 @@ class noncopyable }; //***************************************************************************** -// CCompRC manages string Resource access for CLR. This includes loading -// the MsCorRC.dll for resources. No localization is supported. +// CCompRC manages string Resource access for CLR. //***************************************************************************** class CCompRC { public: - enum ResourceCategory - { - // must be present - Required, - - // present in Desktop CLR and Core CLR + debug pack, an error - // If missing, get a generic error message instead - Error, - - // present in Desktop CLR and Core CLR + debug pack, normal operation (e.g tracing) - // if missing, get a generic "resource not found" message instead - Debugging, - - // present in Desktop CLR, optional for CoreCLR - DesktopCLR, - - // might not be present, non essential - Optional - }; - static HRESULT LoadString(UINT iResourceID, _Out_writes_ (iMax) LPWSTR szBuffer, int iMax , int *pcwchUsed=NULL); }; diff --git a/src/coreclr/utilcode/ccomprc.cpp b/src/coreclr/utilcode/ccomprc.cpp index 61d288758c0ef2..d96622f31d2372 100644 --- a/src/coreclr/utilcode/ccomprc.cpp +++ b/src/coreclr/utilcode/ccomprc.cpp @@ -17,11 +17,6 @@ __attribute__((visibility("default"))) DECLARE_NATIVE_STRING_RESOURCE_TABLE(NATI // External prototypes. extern void* GetClrModuleBase(); -//***************************************************************************** -// Load the string -// We load the localized libraries and cache the handle for future use. -// Mutliple threads may call this, so the cache structure is thread safe. -//***************************************************************************** HRESULT CCompRC::LoadString(UINT iResourceID, _Out_writes_(iMax) LPWSTR szBuffer, int iMax, int *pcwchUsed) { #ifdef DBI_COMPONENT_MONO @@ -38,7 +33,7 @@ HRESULT CCompRC::LoadString(UINT iResourceID, _Out_writes_(iMax) LPWSTR szBuffer CONTRACTL_END; #ifdef HOST_WINDOWS - HRESULT hr = S_OK; + HRESULT hr; int length; length = ::LoadString((HINSTANCE)GetClrModuleBase(), iResourceID, szBuffer, iMax); @@ -50,10 +45,10 @@ HRESULT CCompRC::LoadString(UINT iResourceID, _Out_writes_(iMax) LPWSTR szBuffer } return (S_OK); } - if (SUCCEEDED(GetLastError())) - hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + if(SUCCEEDED(GetLastError())) + hr=HRESULT_FROM_WIN32(ERROR_NOT_FOUND); else - hr = HRESULT_FROM_GetLastError(); + hr=HRESULT_FROM_GetLastError(); // Return an empty string to save the people with a bad error handling if (szBuffer && iMax) diff --git a/src/coreclr/utilcode/ex.cpp b/src/coreclr/utilcode/ex.cpp index c1db6294af768f..efef912129e3f1 100644 --- a/src/coreclr/utilcode/ex.cpp +++ b/src/coreclr/utilcode/ex.cpp @@ -1005,7 +1005,7 @@ void DECLSPEC_NORETURN ThrowHR(HRESULT hr, UINT uText) // We won't check the return value here. If it fails, we'll just // throw the HR - sExceptionText.LoadResource(CCompRC::Error, uText); + sExceptionText.LoadResource(uText); EX_THROW(HRMsgException, (hr, sExceptionText)); } @@ -1156,7 +1156,7 @@ void GetHRMsg(HRESULT hr, SString &result, BOOL bNoGeekStuff/* = FALSE*/) if (FAILED(hr) && HRESULT_FACILITY(hr) == FACILITY_URT && HRESULT_CODE(hr) < MAX_URT_HRESULT_CODE) { - fHaveDescr = strDescr.LoadResource(CCompRC::Error, MSG_FOR_URT_HR(hr)); + fHaveDescr = strDescr.LoadResource(MSG_FOR_URT_HR(hr)); } else { diff --git a/src/coreclr/utilcode/sstring_com.cpp b/src/coreclr/utilcode/sstring_com.cpp index 818156f100f756..bc9c69c1481044 100644 --- a/src/coreclr/utilcode/sstring_com.cpp +++ b/src/coreclr/utilcode/sstring_com.cpp @@ -15,12 +15,12 @@ //---------------------------------------------------------------------------- // Load the string resource into this string. //---------------------------------------------------------------------------- -BOOL SString::LoadResource(CCompRC::ResourceCategory eCategory, int resourceID) +BOOL SString::LoadResource(int resourceID) { - return SUCCEEDED(LoadResourceAndReturnHR(eCategory, resourceID)); + return SUCCEEDED(LoadResourceAndReturnHR(resourceID)); } -HRESULT SString::LoadResourceAndReturnHR(CCompRC::ResourceCategory eCategory, int resourceID) +HRESULT SString::LoadResourceAndReturnHR(int resourceID) { CONTRACT(HRESULT) { diff --git a/src/coreclr/vm/assemblynative.cpp b/src/coreclr/vm/assemblynative.cpp index 26f35709a78604..a962e22b5fe31c 100644 --- a/src/coreclr/vm/assemblynative.cpp +++ b/src/coreclr/vm/assemblynative.cpp @@ -157,7 +157,7 @@ Assembly* AssemblyNative::LoadFromPEImage(AssemblyBinder* pBinder, PEImage *pIma // Give a more specific message for the case when we found the assembly with the same name already loaded. // Show the assembly name, since we know the error is about the assembly name. StackSString errorString; - errorString.LoadResource(CCompRC::Error, IDS_HOST_ASSEMBLY_RESOLVER_ASSEMBLY_ALREADY_LOADED_IN_CONTEXT); + errorString.LoadResource(IDS_HOST_ASSEMBLY_RESOLVER_ASSEMBLY_ALREADY_LOADED_IN_CONTEXT); COMPlusThrow(kFileLoadException, IDS_EE_FILELOAD_ERROR_GENERIC, name, errorString); } else diff --git a/src/coreclr/vm/clrex.cpp b/src/coreclr/vm/clrex.cpp index d4361419d14e74..ca64a95aebd36f 100644 --- a/src/coreclr/vm/clrex.cpp +++ b/src/coreclr/vm/clrex.cpp @@ -1050,7 +1050,7 @@ BOOL EEException::GetResourceMessage(UINT iResourceID, SString &result, BOOL ok; StackSString temp; - ok = temp.LoadResource(CCompRC::Error, iResourceID); + ok = temp.LoadResource(iResourceID); if (ok) result.FormatMessage(FORMAT_MESSAGE_FROM_STRING, diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index 4615f23cea66ae..c327f21631ced3 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -376,21 +376,21 @@ extern "C" void QCALLTYPE ExceptionNative_GetMessageFromNativeResources(Exceptio switch(kind) { case ExceptionMessageKind::ThreadAbort: - hr = buffer.LoadResourceAndReturnHR(CCompRC::Error, IDS_EE_THREAD_ABORT); + hr = buffer.LoadResourceAndReturnHR(IDS_EE_THREAD_ABORT); if (FAILED(hr)) { wszFallbackString = W("Thread was being aborted."); } break; case ExceptionMessageKind::ThreadInterrupted: - hr = buffer.LoadResourceAndReturnHR(CCompRC::Error, IDS_EE_THREAD_INTERRUPTED); + hr = buffer.LoadResourceAndReturnHR(IDS_EE_THREAD_INTERRUPTED); if (FAILED(hr)) { wszFallbackString = W("Thread was interrupted from a waiting state."); } break; case ExceptionMessageKind::OutOfMemory: - hr = buffer.LoadResourceAndReturnHR(CCompRC::Error, IDS_EE_OUT_OF_MEMORY); + hr = buffer.LoadResourceAndReturnHR(IDS_EE_OUT_OF_MEMORY); if (FAILED(hr)) { wszFallbackString = W("Insufficient memory to continue the execution of the program."); } diff --git a/src/coreclr/vm/eepolicy.cpp b/src/coreclr/vm/eepolicy.cpp index 9c8f1c460c90f8..0e22b1e39ad27e 100644 --- a/src/coreclr/vm/eepolicy.cpp +++ b/src/coreclr/vm/eepolicy.cpp @@ -304,7 +304,7 @@ inline void LogCallstackForLogWorker(Thread* pThread, PEXCEPTION_POINTERS pExcep SmallStackSString WordAt; - if (!WordAt.LoadResource(CCompRC::Optional, IDS_ER_WORDAT)) + if (!WordAt.LoadResource(IDS_ER_WORDAT)) { WordAt.Set(W(" at")); } diff --git a/src/coreclr/vm/eventreporter.cpp b/src/coreclr/vm/eventreporter.cpp index 77db465e801b0f..6affcbb19d9eea 100644 --- a/src/coreclr/vm/eventreporter.cpp +++ b/src/coreclr/vm/eventreporter.cpp @@ -49,7 +49,7 @@ EventReporter::EventReporter(EventReporterType type) InlineSString<256> ssMessage; - if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_APPLICATION)) + if(!ssMessage.LoadResource(IDS_ER_APPLICATION)) m_Description.Append(W("Application: ")); else { @@ -68,7 +68,7 @@ EventReporter::EventReporter(EventReporterType type) else { ssMessage.Clear(); - if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_UNKNOWN)) + if(!ssMessage.LoadResource(IDS_ER_UNKNOWN)) m_Description.Append(W("unknown\n")); else { @@ -78,7 +78,7 @@ EventReporter::EventReporter(EventReporterType type) } ssMessage.Clear(); - if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_FRAMEWORK_VERSION)) + if(!ssMessage.LoadResource(IDS_ER_FRAMEWORK_VERSION)) m_Description.Append(W("CoreCLR Version: ")); else { @@ -96,7 +96,7 @@ EventReporter::EventReporter(EventReporterType type) switch(m_eventType) { case ERT_UnhandledException: - if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_UNHANDLEDEXCEPTION)) + if(!ssMessage.LoadResource(IDS_ER_UNHANDLEDEXCEPTION)) m_Description.Append(W("Description: The process was terminated due to an unhandled exception.")); else { @@ -106,7 +106,7 @@ EventReporter::EventReporter(EventReporterType type) break; case ERT_ManagedFailFast: - if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_MANAGEDFAILFAST)) + if(!ssMessage.LoadResource(IDS_ER_MANAGEDFAILFAST)) m_Description.Append(W("Description: The application requested process termination through System.Environment.FailFast.")); else { @@ -116,7 +116,7 @@ EventReporter::EventReporter(EventReporterType type) break; case ERT_UnmanagedFailFast: - if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_UNMANAGEDFAILFAST)) + if(!ssMessage.LoadResource(IDS_ER_UNMANAGEDFAILFAST)) m_Description.Append(W("Description: The process was terminated due to an internal error in the .NET Runtime ")); else { @@ -126,7 +126,7 @@ EventReporter::EventReporter(EventReporterType type) case ERT_StackOverflow: // Fetch the localized Stack Overflow Error text or fall back on a hardcoded variant if things get dire. - if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_STACK_OVERFLOW)) + if(!ssMessage.LoadResource(IDS_ER_STACK_OVERFLOW)) m_Description.Append(W("Description: The process was terminated due to a stack overflow.")); else { @@ -136,7 +136,7 @@ EventReporter::EventReporter(EventReporterType type) break; case ERT_CodeContractFailed: - if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_CODECONTRACT_FAILED)) + if(!ssMessage.LoadResource(IDS_ER_CODECONTRACT_FAILED)) m_Description.Append(W("Description: The application encountered a bug. A managed code contract (precondition, postcondition, object invariant, or assert) failed.")); else { @@ -199,7 +199,7 @@ void EventReporter::AddDescription(SString& s) if (m_eventType == ERT_ManagedFailFast) { SmallStackSString ssMessage; - if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_MANAGEDFAILFASTMSG)) + if(!ssMessage.LoadResource(IDS_ER_MANAGEDFAILFASTMSG)) m_Description.Append(W("Message: ")); else { @@ -209,7 +209,7 @@ void EventReporter::AddDescription(SString& s) else if (m_eventType == ERT_UnhandledException) { SmallStackSString ssMessage; - if (!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_UNHANDLEDEXCEPTIONMSG)) + if (!ssMessage.LoadResource(IDS_ER_UNHANDLEDEXCEPTIONMSG)) { m_Description.Append(W("Exception Info: ")); } @@ -221,7 +221,7 @@ void EventReporter::AddDescription(SString& s) else if (m_eventType == ERT_CodeContractFailed) { SmallStackSString ssMessage; - if (!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_CODECONTRACT_DETAILMSG)) + if (!ssMessage.LoadResource(IDS_ER_CODECONTRACT_DETAILMSG)) m_Description.Append(W("Contract details: ")); else m_Description.Append(ssMessage); @@ -251,7 +251,7 @@ void EventReporter::BeginStackTrace() CONTRACTL_END; _ASSERTE (m_eventType == ERT_UnhandledException || m_eventType == ERT_ManagedFailFast || m_eventType == ERT_CodeContractFailed); InlineSString<80> ssMessage; - if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_STACK)) + if(!ssMessage.LoadResource(IDS_ER_STACK)) m_Description.Append(W("Stack:\n")); else { @@ -289,7 +289,7 @@ void EventReporter::AddStackTrace(SString& s) { // Load the truncation message StackSString truncate; - if (!truncate.LoadResource(CCompRC::Optional, IDS_ER_MESSAGE_TRUNCATE)) + if (!truncate.LoadResource(IDS_ER_MESSAGE_TRUNCATE)) { truncate.Set(W("The remainder of the message was truncated.")); } @@ -345,7 +345,7 @@ void EventReporter::AddFailFastStackTrace(SString& s) _ASSERTE(m_eventType == ERT_ManagedFailFast); InlineSString<80> ssMessage; - if (!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_UNHANDLEDEXCEPTION)) + if (!ssMessage.LoadResource(IDS_ER_UNHANDLEDEXCEPTION)) { m_Description.Append(W("Exception stack:\n")); } @@ -546,7 +546,7 @@ void LogCallstackForEventReporterWorker(EventReporter& reporter) Thread* pThread = GetThread(); SmallStackSString WordAt; - if (!WordAt.LoadResource(CCompRC::Optional, IDS_ER_WORDAT)) + if (!WordAt.LoadResource(IDS_ER_WORDAT)) { WordAt.Set(W(" at")); } diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index 7096d95183f832..7b694e634a7e31 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -5189,12 +5189,12 @@ LONG CallOutFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID pv) // Note: This is not general purpose routine. It handles only cases found // in TypeLoadException and FileLoadException. //========================================================================== -static BOOL GetManagedFormatStringForResourceID(CCompRC::ResourceCategory eCategory, UINT32 resId, SString & converted) +static BOOL GetManagedFormatStringForResourceID(UINT32 resId, SString & converted) { STANDARD_VM_CONTRACT; StackSString temp; - if (!temp.LoadResource(eCategory, resId)) + if (!temp.LoadResource(resId)) return FALSE; SString::Iterator itr = temp.Begin(); @@ -5243,7 +5243,7 @@ extern "C" void QCALLTYPE GetTypeLoadExceptionMessage(UINT32 resId, QCall::Strin BEGIN_QCALL; StackSString format; - GetManagedFormatStringForResourceID(CCompRC::Error, resId ? resId : IDS_CLASSLOAD_GENERAL, format); + GetManagedFormatStringForResourceID(resId ? resId : IDS_CLASSLOAD_GENERAL, format); retString.Set(format); END_QCALL; @@ -5262,7 +5262,7 @@ extern "C" void QCALLTYPE GetFileLoadExceptionMessage(UINT32 hr, QCall::StringHa BEGIN_QCALL; StackSString format; - GetManagedFormatStringForResourceID(CCompRC::Error, GetResourceIDForFileLoadExceptionHR(hr), format); + GetManagedFormatStringForResourceID(GetResourceIDForFileLoadExceptionHR(hr), format); retString.Set(format); END_QCALL; @@ -10532,16 +10532,16 @@ VOID ThrowBadFormatWorker(UINT resID, LPCWSTR imageName DEBUGARG(_In_z_ const ch SString msgStr; SString resStr; - if (resID == 0 || !resStr.LoadResource(CCompRC::Optional, resID)) + if (resID == 0 || !resStr.LoadResource(resID)) { - resStr.LoadResource(CCompRC::Error, BFA_BAD_IL); // "Bad IL format." + resStr.LoadResource(BFA_BAD_IL); // "Bad IL format." } msgStr.Append(resStr); if ((imageName != NULL) && (imageName[0] != 0)) { SString suffixResStr; - if (suffixResStr.LoadResource(CCompRC::Optional, COR_E_BADIMAGEFORMAT)) // "The format of the file '%1' is invalid." + if (suffixResStr.LoadResource(COR_E_BADIMAGEFORMAT)) // "The format of the file '%1' is invalid." { SString suffixMsgStr; suffixMsgStr.FormatMessage(FORMAT_MESSAGE_FROM_STRING, (LPCWSTR)suffixResStr, 0, 0, SString{ SString::Literal, imageName }); diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp index 780125df3d257f..6b231803d58087 100644 --- a/src/coreclr/vm/mlinfo.cpp +++ b/src/coreclr/vm/mlinfo.cpp @@ -331,7 +331,7 @@ VOID ThrowInteropParamException(UINT resID, UINT paramIdx) paramString.Printf("parameter #%u", paramIdx); SString errorString(W("Unknown error.")); - errorString.LoadResource(CCompRC::Error, resID); + errorString.LoadResource(resID); COMPlusThrow(kMarshalDirectiveException, IDS_EE_BADMARSHAL_ERROR_MSG, paramString.GetUnicode(), errorString.GetUnicode()); } @@ -2107,7 +2107,7 @@ void MarshalInfo::ThrowTypeLoadExceptionForInvalidFieldMarshal(FieldDesc* pField StackSString ssFieldName(SString::Utf8, pFieldDesc->GetName()); StackSString errorString(W("Unknown error.")); - errorString.LoadResource(CCompRC::Error, resID); + errorString.LoadResource(resID); COMPlusThrow(kTypeLoadException, IDS_EE_BADMARSHALFIELD_ERROR_MSG, GetFullyQualifiedNameForClassW(pFieldDesc->GetEnclosingMethodTable()), diff --git a/src/coreclr/vm/profilinghelper.cpp b/src/coreclr/vm/profilinghelper.cpp index ccf23ed65ef1be..4bee4177dbf5d8 100644 --- a/src/coreclr/vm/profilinghelper.cpp +++ b/src/coreclr/vm/profilinghelper.cpp @@ -250,7 +250,6 @@ void ProfilingAPIUtility::AppendSupplementaryInformation(int iStringResource, SS StackSString supplementaryInformation; if (!supplementaryInformation.LoadResource( - CCompRC::Debugging, IDS_PROF_SUPPLEMENTARY_INFO )) { @@ -302,7 +301,6 @@ void ProfilingAPIUtility::LogProfEventVA( StackSString messageFromResource; if (!messageFromResource.LoadResource( - CCompRC::Debugging, iStringResourceID )) { From 1866a86d80f4b742c1cf725c8e44048dc90209c6 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 29 Nov 2025 00:47:22 +0800 Subject: [PATCH 07/12] Disable DAC usage --- src/coreclr/utilcode/ccomprc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/utilcode/ccomprc.cpp b/src/coreclr/utilcode/ccomprc.cpp index d96622f31d2372..fbef9aee031c36 100644 --- a/src/coreclr/utilcode/ccomprc.cpp +++ b/src/coreclr/utilcode/ccomprc.cpp @@ -19,7 +19,7 @@ extern void* GetClrModuleBase(); HRESULT CCompRC::LoadString(UINT iResourceID, _Out_writes_(iMax) LPWSTR szBuffer, int iMax, int *pcwchUsed) { -#ifdef DBI_COMPONENT_MONO +#ifdef DACCESS_COMPILE return E_NOTIMPL; #else CONTRACTL From 4cefaa31ce2b4855504c5c05b6570d2a087cfaee Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 4 Dec 2025 14:01:36 +0800 Subject: [PATCH 08/12] Remove unused definition --- src/coreclr/dlls/mscorrc/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/dlls/mscorrc/CMakeLists.txt b/src/coreclr/dlls/mscorrc/CMakeLists.txt index 70daa08a57ba2f..9d704e9abf27b6 100644 --- a/src/coreclr/dlls/mscorrc/CMakeLists.txt +++ b/src/coreclr/dlls/mscorrc/CMakeLists.txt @@ -1,7 +1,5 @@ include_directories("../../pal/prebuilt/corerror") -add_definitions(-DFX_VER_INTERNALNAME_STR=mscorrc.dll) - if(CLR_CMAKE_HOST_WIN32) add_library_clr(mscorrc OBJECT include.rc From 6b0846b45c26a9512e6479deed399aba04c6f81f Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 4 Dec 2025 14:10:36 +0800 Subject: [PATCH 09/12] Remove resources.h usage from debug --- src/coreclr/debug/di/process.cpp | 1 - src/coreclr/debug/di/rsappdomain.cpp | 1 - src/coreclr/debug/di/rsassembly.cpp | 1 - src/coreclr/debug/di/rsmain.cpp | 1 - src/coreclr/debug/ee/debugger.cpp | 1 - src/coreclr/debug/ee/debuggermessagebox.cpp | 1 - src/coreclr/debug/ee/funceval.cpp | 1 - 7 files changed, 7 deletions(-) diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 0d5de9081d6ee6..79129e6cefe185 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -18,7 +18,6 @@ #include "corpriv.h" #include "corexcep.h" -#include "../../dlls/mscorrc/resource.h" #include #include diff --git a/src/coreclr/debug/di/rsappdomain.cpp b/src/coreclr/debug/di/rsappdomain.cpp index a4a59d09ffbd77..221c0791f53235 100644 --- a/src/coreclr/debug/di/rsappdomain.cpp +++ b/src/coreclr/debug/di/rsappdomain.cpp @@ -17,7 +17,6 @@ #endif #include "corpriv.h" -#include "../../dlls/mscorrc/resource.h" #include diff --git a/src/coreclr/debug/di/rsassembly.cpp b/src/coreclr/debug/di/rsassembly.cpp index 05f22a0006e584..991d44c06cb7b1 100644 --- a/src/coreclr/debug/di/rsassembly.cpp +++ b/src/coreclr/debug/di/rsassembly.cpp @@ -17,7 +17,6 @@ #endif #include "corpriv.h" -#include "../../dlls/mscorrc/resource.h" #include diff --git a/src/coreclr/debug/di/rsmain.cpp b/src/coreclr/debug/di/rsmain.cpp index 9a2de7bf42009f..35aa3a1b518b46 100644 --- a/src/coreclr/debug/di/rsmain.cpp +++ b/src/coreclr/debug/di/rsmain.cpp @@ -19,7 +19,6 @@ #endif #include "corpriv.h" -#include "../../dlls/mscorrc/resource.h" #include diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index eb5bc42d206f8a..ad0d9a3129a6bc 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -13,7 +13,6 @@ #include "debugdebugger.h" #include "../inc/common.h" #include "eeconfig.h" // This is here even for retail & free builds... -#include "../../dlls/mscorrc/resource.h" #include "vars.hpp" #include diff --git a/src/coreclr/debug/ee/debuggermessagebox.cpp b/src/coreclr/debug/ee/debuggermessagebox.cpp index af86529d3c5499..19c6da84fa2a27 100644 --- a/src/coreclr/debug/ee/debuggermessagebox.cpp +++ b/src/coreclr/debug/ee/debuggermessagebox.cpp @@ -9,7 +9,6 @@ #include // Utility helpers. #include #include -#include "../../dlls/mscorrc/resource.h" // Output printf-style formatted text to the debugger if it's present or stdout otherwise. static void DbgPrintf(const LPCSTR szFormat, ...) diff --git a/src/coreclr/debug/ee/funceval.cpp b/src/coreclr/debug/ee/funceval.cpp index 7b1dd71070c4cf..652ec434f1f077 100644 --- a/src/coreclr/debug/ee/funceval.cpp +++ b/src/coreclr/debug/ee/funceval.cpp @@ -16,7 +16,6 @@ #include "debugdebugger.h" #include "../inc/common.h" #include "eeconfig.h" // This is here even for retail & free builds... -#include "../../dlls/mscorrc/resource.h" #include "vars.hpp" #include "threads.h" From 028ddde64bd993ba80b081bfbd8326f82d90500e Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 5 Dec 2025 11:09:28 +0800 Subject: [PATCH 10/12] Remove other mentions of mscorrc.dll --- src/coreclr/scripts/superpmi_collect_setup.py | 1 - src/coreclr/tools/r2rtest/BuildFolder.cs | 12 ------------ .../sfx/Microsoft.NETCore.App/Directory.Build.props | 1 - .../src/System/TypeLoadException.cs | 2 +- src/tests/Common/CLRTest.Execute.Batch.targets | 1 - src/tests/Common/Directory.Build.targets | 1 - 6 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/coreclr/scripts/superpmi_collect_setup.py b/src/coreclr/scripts/superpmi_collect_setup.py index 9a829e77ff968b..9a45614beed191 100644 --- a/src/coreclr/scripts/superpmi_collect_setup.py +++ b/src/coreclr/scripts/superpmi_collect_setup.py @@ -166,7 +166,6 @@ "Microsoft.DiaSymReader.Native.x86.dll", "mscordaccore.dll", "mscordbi.dll", - "mscorrc.dll", "msdia140.dll", "msquic.dll", "msvcp140.dll", diff --git a/src/coreclr/tools/r2rtest/BuildFolder.cs b/src/coreclr/tools/r2rtest/BuildFolder.cs index d3a3da4cd84f36..e0eb4940342d6c 100644 --- a/src/coreclr/tools/r2rtest/BuildFolder.cs +++ b/src/coreclr/tools/r2rtest/BuildFolder.cs @@ -24,11 +24,6 @@ public class BuildFolder "mscordbi", }; - private static string[] s_runtimeWindowsOnlyLibraries = - { - "mscorrc", - }; - private List _compilationInputFiles; private List _mainExecutables; @@ -172,13 +167,6 @@ public static BuildFolder FromDirectory(string inputDirectory, IEnumerable - diff --git a/src/libraries/System.Private.CoreLib/src/System/TypeLoadException.cs b/src/libraries/System.Private.CoreLib/src/System/TypeLoadException.cs index b269f391316250..7fae1390466ce3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TypeLoadException.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TypeLoadException.cs @@ -71,7 +71,7 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont } // If ClassName != null, GetMessage will construct on the fly using it - // and ResourceId (mscorrc.dll). This allows customization of the + // and ResourceId (from mscorrc). This allows customization of the // class name format depending on the language environment. private string? _className; private string? _assemblyName; diff --git a/src/tests/Common/CLRTest.Execute.Batch.targets b/src/tests/Common/CLRTest.Execute.Batch.targets index 80b737c59ed930..33b5565f7f1e7a 100644 --- a/src/tests/Common/CLRTest.Execute.Batch.targets +++ b/src/tests/Common/CLRTest.Execute.Batch.targets @@ -298,7 +298,6 @@ IF defined DoLink ( REM Copy CORECLR native binaries and the test watcher to %LinkBin%, so that we can run the test based on that directory copy %CORE_ROOT%\clrjit.dll %LinkBin% > nul 2> nul copy %CORE_ROOT%\coreclr.dll %LinkBin% > nul 2> nul - copy %CORE_ROOT%\mscorrc.dll %LinkBin% > nul 2> nul copy %CORE_ROOT%\CoreRun.exe %LinkBin% > nul 2> nul copy %CORE_ROOT%\watchdog.exe %LinkBin% > nul 2> nul diff --git a/src/tests/Common/Directory.Build.targets b/src/tests/Common/Directory.Build.targets index 4e1a642f568031..cfd5edad2bdc85 100644 --- a/src/tests/Common/Directory.Build.targets +++ b/src/tests/Common/Directory.Build.targets @@ -50,7 +50,6 @@ - From e85ecb1455d0c15d0591f166089c86746ee54475 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 5 Dec 2025 12:50:57 +0800 Subject: [PATCH 11/12] Revert --- src/coreclr/scripts/superpmi_collect_setup.py | 1 + .../pkg/sfx/Microsoft.NETCore.App/Directory.Build.props | 1 + 2 files changed, 2 insertions(+) diff --git a/src/coreclr/scripts/superpmi_collect_setup.py b/src/coreclr/scripts/superpmi_collect_setup.py index 9a45614beed191..9a829e77ff968b 100644 --- a/src/coreclr/scripts/superpmi_collect_setup.py +++ b/src/coreclr/scripts/superpmi_collect_setup.py @@ -166,6 +166,7 @@ "Microsoft.DiaSymReader.Native.x86.dll", "mscordaccore.dll", "mscordbi.dll", + "mscorrc.dll", "msdia140.dll", "msquic.dll", "msvcp140.dll", diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props index e164eb38c614d8..708648df743f74 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -129,6 +129,7 @@ + From a4dcbe10c7ca255cfb54f2ec37119f9036bf0721 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 5 Dec 2025 14:12:36 +0800 Subject: [PATCH 12/12] Fix build break --- src/coreclr/tools/r2rtest/BuildFolder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tools/r2rtest/BuildFolder.cs b/src/coreclr/tools/r2rtest/BuildFolder.cs index e0eb4940342d6c..d65d48e99cfcd0 100644 --- a/src/coreclr/tools/r2rtest/BuildFolder.cs +++ b/src/coreclr/tools/r2rtest/BuildFolder.cs @@ -167,7 +167,7 @@ public static BuildFolder FromDirectory(string inputDirectory, IEnumerable