diff options
author | John Chen (JOCHEN7) <jochen@microsoft.com> | 2016-02-23 20:36:07 -0800 |
---|---|---|
committer | John Chen (JOCHEN7) <jochen@microsoft.com> | 2016-02-29 13:55:49 -0800 |
commit | 488e6a16685241ed1aed3b3d386b78ed32e428f0 (patch) | |
tree | 9fd979bdde69b08216c6dde6a466fa3ff519c775 | |
parent | 2d98b6a53263b9ad4b98e4a5dee35e703fd7ddf5 (diff) | |
download | coreclr-488e6a16685241ed1aed3b3d386b78ed32e428f0.tar.gz coreclr-488e6a16685241ed1aed3b3d386b78ed32e428f0.tar.bz2 coreclr-488e6a16685241ed1aed3b3d386b78ed32e428f0.zip |
Support long paths in CoreCLR runtime on Windows
The CoreCLR runtime is updated to support long file paths on Windows.
Pending updates to mscorlib.dll, the following scenarios are supported:
* Run managed apps from a long path.
* Load CoreCLR runtime and framework from a long path.
* Load user assemblies from a long path.
* Run CrossGen from a long path, with its input/output from a long path.
* Generate debug log file at a long path.
The following scenarios are not yet supported, and will be fixed in
future commits:
* Mscorlib.dll and framework assemblies are not yet long path compatible.
Note that until mscorlib.dll is fixed, most of the runtime changes can't
actually be used.
* Support on non-Windows platforms.
* Support for debugging and error reporting.
* Tools such as ilasm or ildasm.
-rw-r--r-- | src/binder/assemblybinder.cpp | 11 | ||||
-rw-r--r-- | src/binder/cdebuglog.cpp | 6 | ||||
-rw-r--r-- | src/coreclr/hosts/corerun/CMakeLists.txt | 7 | ||||
-rw-r--r-- | src/coreclr/hosts/corerun/coreRun.nativeproj | 6 | ||||
-rw-r--r-- | src/coreclr/hosts/corerun/corerun.cpp | 213 | ||||
-rw-r--r-- | src/inc/clr/fs/dir.h | 18 | ||||
-rw-r--r-- | src/inc/utilcode.h | 8 | ||||
-rw-r--r-- | src/inc/zapper.h | 2 | ||||
-rw-r--r-- | src/md/compiler/regmeta_emit.cpp | 14 | ||||
-rw-r--r-- | src/md/enc/liteweightstgdbrw.cpp | 4 | ||||
-rw-r--r-- | src/tools/crossgen/crossgen.cpp | 40 | ||||
-rw-r--r-- | src/utilcode/log.cpp | 61 | ||||
-rw-r--r-- | src/utilcode/makepath.cpp | 141 | ||||
-rw-r--r-- | src/utilcode/safewrap.cpp | 10 | ||||
-rw-r--r-- | src/utilcode/splitpath.cpp | 37 | ||||
-rw-r--r-- | src/vm/rtlfunctions.cpp | 34 | ||||
-rw-r--r-- | src/vm/stdinterfaces.cpp | 17 | ||||
-rw-r--r-- | src/vm/tlbexport.cpp | 17 | ||||
-rw-r--r-- | src/zap/zapper.cpp | 8 |
19 files changed, 390 insertions, 264 deletions
diff --git a/src/binder/assemblybinder.cpp b/src/binder/assemblybinder.cpp index 1e68e55002..1e760ee80a 100644 --- a/src/binder/assemblybinder.cpp +++ b/src/binder/assemblybinder.cpp @@ -173,9 +173,18 @@ namespace BINDER_SPACE dwCCFullAssemblyPath, pwzFullAssemblyPath, NULL); + if (dwCCFullAssemblyPath > MAX_LONGPATH) + { + fullAssemblyPath.CloseBuffer(); + pwzFullAssemblyPath = fullAssemblyPath.OpenUnicodeBuffer(dwCCFullAssemblyPath - 1); + dwCCFullAssemblyPath = WszGetFullPathName(assemblyPath.GetUnicode(), + dwCCFullAssemblyPath, + pwzFullAssemblyPath, + NULL); + } fullAssemblyPath.CloseBuffer(dwCCFullAssemblyPath); - if ((dwCCFullAssemblyPath == 0) || (dwCCFullAssemblyPath > (MAX_LONGPATH + 1))) + if (dwCCFullAssemblyPath == 0) { hr = HRESULT_FROM_GetLastError(); } diff --git a/src/binder/cdebuglog.cpp b/src/binder/cdebuglog.cpp index 98b9589240..3724f9ec8e 100644 --- a/src/binder/cdebuglog.cpp +++ b/src/binder/cdebuglog.cpp @@ -58,12 +58,6 @@ namespace BINDER_SPACE PathString szPathString; DWORD dw = 0; - // _ASSERTE (pszPath ) ; - if (wcslen(pszName) >= MAX_LONGPATH) - { - IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW)); - } - size_t pszNameLen = wcslen(pszName); WCHAR * szPath = szPathString.OpenUnicodeBuffer(static_cast<COUNT_T>(pszNameLen)); size_t cbSzPath = (sizeof(WCHAR)) * (pszNameLen + 1); // SString allocates extra byte for null diff --git a/src/coreclr/hosts/corerun/CMakeLists.txt b/src/coreclr/hosts/corerun/CMakeLists.txt index 841a7141d6..5c489bd3c8 100644 --- a/src/coreclr/hosts/corerun/CMakeLists.txt +++ b/src/coreclr/hosts/corerun/CMakeLists.txt @@ -23,7 +23,12 @@ else() ) target_link_libraries(CoreRun - msvcrt.lib + utilcodestaticnohost + advapi32.lib + oleaut32.lib + uuid.lib + user32.lib + msvcrt$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib ) # Can't compile on linux yet so only add for windows diff --git a/src/coreclr/hosts/corerun/coreRun.nativeproj b/src/coreclr/hosts/corerun/coreRun.nativeproj index d810fed311..0b1fd95a49 100644 --- a/src/coreclr/hosts/corerun/coreRun.nativeproj +++ b/src/coreclr/hosts/corerun/coreRun.nativeproj @@ -19,9 +19,15 @@ </PropertyGroup> <ItemGroup> + <LinkPreCrtLibs Include="$(ClrLibPath)\utilcodestaticnohost.lib" /> + <ProjectReference Include="$(ClrSrcDirectory)utilcode\staticnohost\staticnohost.nativeproj" /> + </ItemGroup> + <ItemGroup> <TargetLib Include="$(CoreSystemCrt)" /> <TargetLib Condition="'$(BuildForWindows7)'=='true'" Include="$(SdkLibPath)\mincore_fw.lib" /> <TargetLib Condition="'$(BuildForWindows7)'!='true'" Include="$(SdkLibPath)\mincore.lib" /> + <TargetLib Include="$(SdkLibPath)\oleaut32.lib" /> + <TargetLib Include="$(SdkLibPath)\uuid.lib" /> </ItemGroup> <ItemGroup> diff --git a/src/coreclr/hosts/corerun/corerun.cpp b/src/coreclr/hosts/corerun/corerun.cpp index 9a7ed4214c..d037fe80d7 100644 --- a/src/coreclr/hosts/corerun/corerun.cpp +++ b/src/coreclr/hosts/corerun/corerun.cpp @@ -12,6 +12,7 @@ #include "mscoree.h" #include <Logger.h> #include "palclr.h" +#include "sstring.h" // Utility macro for testing whether or not a flag is set. #define HAS_FLAG(value, flag) (((value) & (flag)) == (flag)) @@ -31,59 +32,20 @@ static const wchar_t *coreCLRDll = W("CoreCLR.dll"); // found in the same directory as the host, it will be looked for here. static const wchar_t *coreCLRInstallDirectory = W("%windir%\\system32\\"); -// Dynamically expanding string buffer to hold TPA list -class StringBuffer { - wchar_t* m_buffer; - size_t m_capacity; - size_t m_length; - - StringBuffer(const StringBuffer&); - StringBuffer& operator =(const StringBuffer&); - -public: - StringBuffer() : m_capacity(0), m_buffer(0), m_length(0) { - } - - ~StringBuffer() { - delete[] m_buffer; - } - - const wchar_t* CStr() const { - return m_buffer; - } - - void Append(const wchar_t* str, size_t strLen) { - if (!m_buffer) { - m_buffer = new wchar_t[4096]; - m_capacity = 4096; - } - if (m_length + strLen + 1 > m_capacity) { - size_t newCapacity = m_capacity * 2; - wchar_t* newBuffer = new wchar_t[newCapacity]; - wcsncpy_s(newBuffer, newCapacity, m_buffer, m_length); - delete[] m_buffer; - m_buffer = newBuffer; - m_capacity = newCapacity; - } - wcsncpy_s(m_buffer + m_length, m_capacity - m_length, str, strLen); - m_length += strLen; - } -}; - // Encapsulates the environment that CoreCLR will run in, including the TPALIST class HostEnvironment { // The path to this module - wchar_t m_hostPath[MAX_LONGPATH]; + PathString m_hostPath; // The path to the directory containing this module - wchar_t m_hostDirectoryPath[MAX_LONGPATH]; + PathString m_hostDirectoryPath; // The name of this module, without the path - wchar_t *m_hostExeName; + const wchar_t *m_hostExeName; // The list of paths to the assemblies that will be trusted by CoreCLR - StringBuffer m_tpaList; + SString m_tpaList; ICLRRuntimeHost2* m_CLRRuntimeHost; @@ -97,15 +59,14 @@ class HostEnvironment // On failure returns nullptr. HMODULE TryLoadCoreCLR(const wchar_t* directoryPath) { - wchar_t coreCLRPath[MAX_LONGPATH]; - wcscpy_s(coreCLRPath, directoryPath); - wcscat_s(coreCLRPath, coreCLRDll); + StackSString coreCLRPath(directoryPath); + coreCLRPath.Append(coreCLRDll); - *m_log << W("Attempting to load: ") << coreCLRPath << Logger::endl; + *m_log << W("Attempting to load: ") << coreCLRPath.GetUnicode() << Logger::endl; - HMODULE result = ::LoadLibraryExW(coreCLRPath, NULL, 0); + HMODULE result = WszLoadLibraryEx(coreCLRPath, NULL, 0); if (!result) { - *m_log << W("Failed to load: ") << coreCLRPath << Logger::endl; + *m_log << W("Failed to load: ") << coreCLRPath.GetUnicode() << Logger::endl; *m_log << W("Error code: ") << GetLastError() << Logger::endl; return nullptr; } @@ -113,51 +74,46 @@ class HostEnvironment // Pin the module - CoreCLR.dll does not support being unloaded. HMODULE dummy_coreCLRModule; if (!::GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN, coreCLRPath, &dummy_coreCLRModule)) { - *m_log << W("Failed to pin: ") << coreCLRPath << Logger::endl; + *m_log << W("Failed to pin: ") << coreCLRPath.GetUnicode() << Logger::endl; return nullptr; } - wchar_t coreCLRLoadedPath[MAX_LONGPATH]; - ::GetModuleFileNameW(result, coreCLRLoadedPath, MAX_LONGPATH); + StackSString coreCLRLoadedPath; + WszGetModuleFileName(result, coreCLRLoadedPath); - *m_log << W("Loaded: ") << coreCLRLoadedPath << Logger::endl; + *m_log << W("Loaded: ") << coreCLRLoadedPath.GetUnicode() << Logger::endl; return result; } public: // The path to the directory that CoreCLR is in - wchar_t m_coreCLRDirectoryPath[MAX_LONGPATH]; + PathString m_coreCLRDirectoryPath; HostEnvironment(Logger *logger) : m_log(logger), m_CLRRuntimeHost(nullptr) { // Discover the path to this exe's module. All other files are expected to be in the same directory. - DWORD thisModuleLength = ::GetModuleFileNameW(::GetModuleHandleW(nullptr), m_hostPath, MAX_LONGPATH); + WszGetModuleFileName(::GetModuleHandleW(nullptr), m_hostPath); // Search for the last backslash in the host path. - int lastBackslashIndex; - for (lastBackslashIndex = thisModuleLength-1; lastBackslashIndex >= 0; lastBackslashIndex--) { - if (m_hostPath[lastBackslashIndex] == W('\\')) { - break; - } - } + SString::CIterator lastBackslash = m_hostPath.End(); + m_hostPath.FindBack(lastBackslash, W('\\')); // Copy the directory path - ::wcsncpy_s(m_hostDirectoryPath, m_hostPath, lastBackslashIndex + 1); + m_hostDirectoryPath.Set(m_hostPath, m_hostPath.Begin(), lastBackslash + 1); // Save the exe name - m_hostExeName = m_hostPath + lastBackslashIndex + 1; + m_hostExeName = m_hostPath.GetUnicode(lastBackslash + 1); - *m_log << W("Host directory: ") << m_hostDirectoryPath << Logger::endl; + *m_log << W("Host directory: ") << m_hostDirectoryPath.GetUnicode() << Logger::endl; // Check for %CORE_ROOT% and try to load CoreCLR.dll from it if it is set - wchar_t coreRoot[MAX_LONGPATH]; - size_t outSize; + StackSString coreRoot; m_coreCLRModule = NULL; // Initialize this here since we don't call TryLoadCoreCLR if CORE_ROOT is unset. - if (_wgetenv_s(&outSize, coreRoot, MAX_LONGPATH, W("CORE_ROOT")) == 0 && outSize > 0) + if (WszGetEnvironmentVariable(W("CORE_ROOT"), coreRoot) > 0 && coreRoot.GetCount() > 0) { - wcscat_s(coreRoot, MAX_LONGPATH, W("\\")); + coreRoot.Append(W('\\')); m_coreCLRModule = TryLoadCoreCLR(coreRoot); } else @@ -184,15 +140,12 @@ public: if (m_coreCLRModule) { // Save the directory that CoreCLR was found in - DWORD modulePathLength = ::GetModuleFileNameW(m_coreCLRModule, m_coreCLRDirectoryPath, MAX_LONGPATH); + DWORD modulePathLength = WszGetModuleFileName(m_coreCLRModule, m_coreCLRDirectoryPath); // Search for the last backslash and terminate it there to keep just the directory path with trailing slash - for (lastBackslashIndex = modulePathLength-1; lastBackslashIndex >= 0; lastBackslashIndex--) { - if (m_coreCLRDirectoryPath[lastBackslashIndex] == W('\\')) { - m_coreCLRDirectoryPath[lastBackslashIndex + 1] = W('\0'); - break; - } - } + SString::Iterator lastBackslash = m_coreCLRDirectoryPath.End(); + m_coreCLRDirectoryPath.FindBack(lastBackslash, W('\\')); + m_coreCLRDirectoryPath.Truncate(lastBackslash + 1); } else { *m_log << W("Unable to load ") << coreCLRDll << Logger::endl; @@ -210,17 +163,17 @@ public: bool TPAListContainsFile(_In_z_ wchar_t* fileNameWithoutExtension, _In_reads_(countExtensions) wchar_t** rgTPAExtensions, int countExtensions) { - if (!m_tpaList.CStr()) return false; + if (m_tpaList.IsEmpty()) return false; for (int iExtension = 0; iExtension < countExtensions; iExtension++) { - wchar_t fileName[MAX_LONGPATH]; - wcscpy_s(fileName, MAX_LONGPATH, W("\\")); // So that we don't match other files that end with the current file name - wcscat_s(fileName, MAX_LONGPATH, fileNameWithoutExtension); - wcscat_s(fileName, MAX_LONGPATH, rgTPAExtensions[iExtension] + 1); - wcscat_s(fileName, MAX_LONGPATH, W(";")); // So that we don't match other files that begin with the current file name + StackSString fileName; + fileName.Append(W("\\")); // So that we don't match other files that end with the current file name + fileName.Append(fileNameWithoutExtension); + fileName.Append(rgTPAExtensions[iExtension] + 1); + fileName.Append(W(";")); // So that we don't match other files that begin with the current file name - if (wcsstr(m_tpaList.CStr(), fileName)) + if (m_tpaList.Find(m_tpaList.Begin(), fileName)) { return true; } @@ -248,22 +201,18 @@ public: } } - void AddFilesFromDirectoryToTPAList(_In_z_ wchar_t* targetPath, _In_reads_(countExtensions) wchar_t** rgTPAExtensions, int countExtensions) + void AddFilesFromDirectoryToTPAList(_In_z_ const wchar_t* targetPath, _In_reads_(countExtensions) wchar_t** rgTPAExtensions, int countExtensions) { *m_log << W("Adding assemblies from ") << targetPath << W(" to the TPA list") << Logger::endl; - wchar_t assemblyPath[MAX_LONGPATH]; + StackSString assemblyPath; + const size_t dirLength = wcslen(targetPath); for (int iExtension = 0; iExtension < countExtensions; iExtension++) { - wcscpy_s(assemblyPath, MAX_LONGPATH, targetPath); - - const size_t dirLength = wcslen(targetPath); - wchar_t* const fileNameBuffer = assemblyPath + dirLength; - const size_t fileNameBufferSize = MAX_LONGPATH - dirLength; - - wcscat_s(assemblyPath, rgTPAExtensions[iExtension]); + assemblyPath.Set(targetPath, (DWORD)dirLength); + assemblyPath.Append(rgTPAExtensions[iExtension]); WIN32_FIND_DATA data; - HANDLE findHandle = FindFirstFile(assemblyPath, &data); + HANDLE findHandle = WszFindFirstFile(assemblyPath, &data); if (findHandle != INVALID_HANDLE_VALUE) { do { @@ -289,18 +238,17 @@ public: // Add to the list if not already on it if (!TPAListContainsFile(fileNameWithoutExtension, rgTPAExtensions, countExtensions)) { - const size_t fileLength = wcslen(data.cFileName); - const size_t assemblyPathLength = dirLength + fileLength; - wcsncpy_s(fileNameBuffer, fileNameBufferSize, data.cFileName, fileLength); - m_tpaList.Append(assemblyPath, assemblyPathLength); - m_tpaList.Append(W(";"), 1); + assemblyPath.Truncate(assemblyPath.Begin() + (DWORD)dirLength); + assemblyPath.Append(data.cFileName); + m_tpaList.Append(assemblyPath); + m_tpaList.Append(W(';')); } else { *m_log << W("Not adding ") << targetPath << data.cFileName << W(" to the TPA list because another file with the same name is already present on the list") << Logger::endl; } } - } while (0 != FindNextFile(findHandle, &data)); + } while (0 != WszFindNextFile(findHandle, &data)); FindClose(findHandle); } @@ -310,7 +258,7 @@ public: // Returns the semicolon-separated list of paths to runtime dlls that are considered trusted. // On first call, scans the coreclr directory for dlls and adds them all to the list. const wchar_t * GetTpaList() { - if (!m_tpaList.CStr()) { + if (m_tpaList.IsEmpty()) { wchar_t *rgTPAExtensions[] = { W("*.ni.dll"), // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir W("*.dll"), @@ -321,11 +269,10 @@ public: }; // Add files from %CORE_LIBRARIES% if specified - wchar_t coreLibraries[MAX_LONGPATH]; - size_t outSize; - if (_wgetenv_s(&outSize, coreLibraries, MAX_LONGPATH, W("CORE_LIBRARIES")) == 0 && outSize > 0) + StackSString coreLibraries; + if (WszGetEnvironmentVariable(W("CORE_LIBRARIES"), coreLibraries) > 0 && coreLibraries.GetCount() > 0) { - wcscat_s(coreLibraries, MAX_LONGPATH, W("\\")); + coreLibraries.Append(W('\\')); AddFilesFromDirectoryToTPAList(coreLibraries, rgTPAExtensions, _countof(rgTPAExtensions)); } else @@ -338,7 +285,7 @@ public: AddFilesFromDirectoryToTPAList(m_coreCLRDirectoryPath, rgTPAExtensions, _countof(rgTPAExtensions)); } - return m_tpaList.CStr(); + return m_tpaList; } // Returns the path to the host module @@ -438,52 +385,60 @@ bool TryRun(const int argc, const wchar_t* argv[], Logger &log, const bool verbo return false; } - wchar_t appPath[MAX_LONGPATH] = W(""); - wchar_t appNiPath[MAX_LONGPATH * 2] = W(""); - wchar_t managedAssemblyFullName[MAX_LONGPATH] = W(""); - wchar_t appLocalWinmetadata[MAX_LONGPATH] = W(""); + StackSString appPath; + StackSString appNiPath; + StackSString managedAssemblyFullName; + StackSString appLocalWinmetadata; wchar_t* filePart = NULL; - if (!::GetFullPathName(exeName, MAX_LONGPATH, appPath, &filePart)) { + COUNT_T size = MAX_LONGPATH; + wchar_t* appPathPtr = appPath.OpenUnicodeBuffer(size - 1); + DWORD length = WszGetFullPathName(exeName, size, appPathPtr, &filePart); + if (length >= size) + { + appPath.CloseBuffer(); + size = length; + appPathPtr = appPath.OpenUnicodeBuffer(size - 1); + length = WszGetFullPathName(exeName, size, appPathPtr, &filePart); + } + if (length == 0 || length >= size) { log << W("Failed to get full path: ") << exeName << Logger::endl; log << W("Error code: ") << GetLastError() << Logger::endl; return false; } - wcscpy_s(managedAssemblyFullName, appPath); + managedAssemblyFullName.Set(appPathPtr); *(filePart) = W('\0'); + appPath.CloseBuffer(DWORD(filePart - appPathPtr)); - log << W("Loading: ") << managedAssemblyFullName << Logger::endl; + log << W("Loading: ") << managedAssemblyFullName.GetUnicode() << Logger::endl; - wcscpy_s(appLocalWinmetadata, appPath); - wcscat_s(appLocalWinmetadata, W("\\WinMetadata")); + appLocalWinmetadata.Set(appPath); + appLocalWinmetadata.Append(W("\\WinMetadata")); - DWORD dwAttrib = ::GetFileAttributes(appLocalWinmetadata); + DWORD dwAttrib = WszGetFileAttributes(appLocalWinmetadata); bool appLocalWinMDexists = dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY); if (!appLocalWinMDexists) { - wcscpy_s(appLocalWinmetadata, W("")); + appLocalWinmetadata.Clear(); } - wcscpy_s(appNiPath, appPath); - wcscat_s(appNiPath, W("NI")); - wcscat_s(appNiPath, MAX_LONGPATH * 2, W(";")); - wcscat_s(appNiPath, MAX_LONGPATH * 2, appPath); + appNiPath.Set(appPath); + appNiPath.Append(W("NI")); + appNiPath.Append(W(";")); + appNiPath.Append(appPath); // Construct native search directory paths - wchar_t nativeDllSearchDirs[MAX_LONGPATH * 3]; - - wcscpy_s(nativeDllSearchDirs, appPath); - wchar_t coreLibraries[MAX_LONGPATH]; - size_t outSize; - if (_wgetenv_s(&outSize, coreLibraries, MAX_LONGPATH, W("CORE_LIBRARIES")) == 0 && outSize > 0) + StackSString nativeDllSearchDirs(appPath); + StackSString coreLibraries; + if (WszGetEnvironmentVariable(W("CORE_LIBRARIES"), coreLibraries) > 0 && coreLibraries.GetCount() > 0) { - wcscat_s(nativeDllSearchDirs, MAX_LONGPATH * 3, W(";")); - wcscat_s(nativeDllSearchDirs, MAX_LONGPATH * 3, coreLibraries); + nativeDllSearchDirs.Append(W(";")); + nativeDllSearchDirs.Append(coreLibraries); } - wcscat_s(nativeDllSearchDirs, MAX_LONGPATH * 3, W(";")); - wcscat_s(nativeDllSearchDirs, MAX_LONGPATH * 3, hostEnvironment.m_coreCLRDirectoryPath); + nativeDllSearchDirs.Append(W(";")); + nativeDllSearchDirs.Append(hostEnvironment.m_coreCLRDirectoryPath); // Start the CoreCLR diff --git a/src/inc/clr/fs/dir.h b/src/inc/clr/fs/dir.h index 57ff54d4a5..2516151a55 100644 --- a/src/inc/clr/fs/dir.h +++ b/src/inc/clr/fs/dir.h @@ -75,16 +75,12 @@ namespace clr if (cchDirPath == 0) { - IfFailRet(StringCchLength(wzDirPath, _MAX_PATH, &cchDirPath)); - } - - if (cchDirPath >= _MAX_PATH) - { - return E_INVALIDARG; + cchDirPath = wcslen(wzDirPath); } // Try to create the path. If it fails, assume that's because the parent folder does // not exist. Try to create the parent then re-attempt. + WCHAR chOrig = wzDirPath[cchDirPath]; hr = Create(wzDirPath); if (hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) { @@ -118,11 +114,11 @@ namespace clr } // Make a writable copy of wzDirPath - WCHAR wzBuffer[_MAX_PATH]; - WCHAR * pPathEnd; - IfFailRet(StringCchCopyEx(wzBuffer, countof(wzBuffer), wzDirPath, - &pPathEnd, nullptr, STRSAFE_NULL_ON_FAILURE)); - IfFailRet(CreateRecursively(wzBuffer, pPathEnd - wzBuffer)); + size_t cchDirPath = wcslen(wzDirPath); + CQuickWSTR wzBuffer; + IfFailRet(wzBuffer.ReSizeNoThrow(cchDirPath + 1)); + wcscpy_s(wzBuffer.Ptr(), wzBuffer.Size(), wzDirPath); + IfFailRet(CreateRecursively(wzBuffer.Ptr(), cchDirPath)); return hr; } diff --git a/src/inc/utilcode.h b/src/inc/utilcode.h index a9cb0077fc..48d096ee7c 100644 --- a/src/inc/utilcode.h +++ b/src/inc/utilcode.h @@ -1162,11 +1162,19 @@ void SplitPathInterior( __out_opt LPCWSTR *pwszFileName, __out_opt size_t *pcchFileName, __out_opt LPCWSTR *pwszExt, __out_opt size_t *pcchExt); +#ifndef FEATURE_CORECLR void MakePath(__out_ecount (MAX_LONGPATH) register WCHAR *path, __in LPCWSTR drive, __in LPCWSTR dir, __in LPCWSTR fname, __in LPCWSTR ext); +#endif + +void MakePath(__out CQuickWSTR &path, + __in LPCWSTR drive, + __in LPCWSTR dir, + __in LPCWSTR fname, + __in LPCWSTR ext); WCHAR * FullPath(__out_ecount (maxlen) WCHAR *UserBuf, const WCHAR *path, size_t maxlen); diff --git a/src/inc/zapper.h b/src/inc/zapper.h index 2abcf0de0a..9e47ed3d23 100644 --- a/src/inc/zapper.h +++ b/src/inc/zapper.h @@ -102,7 +102,7 @@ class Zapper CORINFO_ASSEMBLY_HANDLE m_hAssembly; IMDInternalImport *m_pAssemblyImport; - WCHAR m_outputPath[MAX_LONGPATH]; // Temp folder for creating the output file + SString m_outputPath; // Temp folder for creating the output file IMetaDataAssemblyEmit *m_pAssemblyEmit; IMetaDataAssemblyEmit *CreateAssemblyEmitter(); diff --git a/src/md/compiler/regmeta_emit.cpp b/src/md/compiler/regmeta_emit.cpp index 33883107bd..22d2979343 100644 --- a/src/md/compiler/regmeta_emit.cpp +++ b/src/md/compiler/regmeta_emit.cpp @@ -67,17 +67,11 @@ STDMETHODIMP RegMeta::SetModuleProps( // S_OK or error. IfFailGo(m_pStgdb->m_MiniMd.GetModuleRecord(1, &pModule)); if (szName != NULL) { - WCHAR rcFile[_MAX_PATH]={0}; - WCHAR rcExt[_MAX_PATH]={0}; - WCHAR rcNewFileName[_MAX_PATH]={0}; + LPCWSTR szFile = NULL; + size_t cchFile; - // If the total name is less than _MAX_PATH, the components are, too. - if (wcslen(szName) >= _MAX_PATH) - IfFailGo(E_INVALIDARG); - - SplitPath(szName, NULL, 0, NULL, 0, rcFile, COUNTOF(rcFile), rcExt, COUNTOF(rcExt)); - MakePath(rcNewFileName, NULL, NULL, rcFile, rcExt); - IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_Module, ModuleRec::COL_Name, pModule, rcNewFileName)); + SplitPathInterior(szName, NULL, 0, NULL, 0, &szFile, &cchFile, NULL, 0); + IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_Module, ModuleRec::COL_Name, pModule, szFile)); } IfFailGo(UpdateENCLog(TokenFromRid(1, mdtModule))); diff --git a/src/md/enc/liteweightstgdbrw.cpp b/src/md/enc/liteweightstgdbrw.cpp index 667f24a312..12779f59c0 100644 --- a/src/md/enc/liteweightstgdbrw.cpp +++ b/src/md/enc/liteweightstgdbrw.cpp @@ -1251,6 +1251,9 @@ BOOL CLiteWeightStgdbRW::IsValidFileNameLength( const WCHAR * wszFileName) { +#ifdef FEATURE_CORECLR + return TRUE; +#else static const WCHAR const_wszLongPathPrefix[] = W("\\\\?\\"); if (wszFileName == NULL) @@ -1271,4 +1274,5 @@ CLiteWeightStgdbRW::IsValidFileNameLength( return TRUE; } return FALSE; +#endif } // CLiteWeightStgdbRW::IsValidFileNameLength diff --git a/src/tools/crossgen/crossgen.cpp b/src/tools/crossgen/crossgen.cpp index 973e775a03..16a2819511 100644 --- a/src/tools/crossgen/crossgen.cpp +++ b/src/tools/crossgen/crossgen.cpp @@ -464,7 +464,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) LPCWSTR pwzAppNiPaths = nullptr; LPCWSTR pwzPlatformAssembliesPaths = nullptr; LPCWSTR pwzPlatformWinmdPaths = nullptr; - WCHAR wzDirectoryToStorePDB[MAX_LONGPATH] = W("\0"); + StackSString wzDirectoryToStorePDB; bool fCreatePDB = false; bool fGeneratePDBLinesInfo = false; LPWSTR pwzSearchPathForManagedPDB = NULL; @@ -696,28 +696,14 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) dwFlags = dwFlags & ~(NGENWORKER_FLAGS_FULLTRUSTDOMAIN | NGENWORKER_FLAGS_READYTORUN); // Parse: <directory to store PDB> - if (wcscpy_s( - wzDirectoryToStorePDB, - _countof(wzDirectoryToStorePDB), - argv[0]) != 0) - { - Output(W("Unable to parse output directory to store PDB")); - exit(FAILURE_RESULT); - } + wzDirectoryToStorePDB.Set(argv[0]); argv++; argc--; // Ensure output dir ends in a backslash, or else diasymreader has issues - if (wzDirectoryToStorePDB[wcslen(wzDirectoryToStorePDB)-1] != DIRECTORY_SEPARATOR_CHAR_W) + if (wzDirectoryToStorePDB[wzDirectoryToStorePDB.GetCount()-1] != DIRECTORY_SEPARATOR_CHAR_W) { - if (wcscat_s( - wzDirectoryToStorePDB, - _countof(wzDirectoryToStorePDB), - DIRECTORY_SEPARATOR_STR_W) != 0) - { - Output(W("Unable to parse output directory to store PDB")); - exit(FAILURE_RESULT); - } + wzDirectoryToStorePDB.Append(DIRECTORY_SEPARATOR_STR_W); } if (argc == 0) @@ -773,28 +759,14 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) dwFlags = dwFlags & ~NGENWORKER_FLAGS_READYTORUN; // Parse: <directory to store PDB> - if (wcscpy_s( - wzDirectoryToStorePDB, - _countof(wzDirectoryToStorePDB), - argv[0]) != 0) - { - Output(W("Unable to parse output directory to store perfmap")); - exit(FAILURE_RESULT); - } + wzDirectoryToStorePDB.Set(argv[0]); argv++; argc--; // Ensure output dir ends in a backslash if (wzDirectoryToStorePDB[wcslen(wzDirectoryToStorePDB)-1] != DIRECTORY_SEPARATOR_CHAR_W) { - if (wcscat_s( - wzDirectoryToStorePDB, - _countof(wzDirectoryToStorePDB), - DIRECTORY_SEPARATOR_STR_W) != 0) - { - Output(W("Unable to parse output directory to store perfmap")); - exit(FAILURE_RESULT); - } + wzDirectoryToStorePDB.Append(DIRECTORY_SEPARATOR_STR_W); } if (argc == 0) diff --git a/src/utilcode/log.cpp b/src/utilcode/log.cpp index 03593a86fe..0dc85527c0 100644 --- a/src/utilcode/log.cpp +++ b/src/utilcode/log.cpp @@ -21,7 +21,7 @@ #ifdef LOGGING -#define DEFAULT_LOGFILE_NAME "COMPLUS.LOG" +#define DEFAULT_LOGFILE_NAME W("COMPLUS.LOG") #define LOG_ENABLE_FILE_LOGGING 0x0001 #define LOG_ENABLE_FLUSH_FILE 0x0002 @@ -32,7 +32,7 @@ static DWORD LogFlags = 0; -static char szLogFileName[MAX_LONGPATH+1] = DEFAULT_LOGFILE_NAME; +static CQuickWSTR szLogFileName; static HANDLE LogFileHandle = INVALID_HANDLE_VALUE; static MUTEX_COOKIE LogFileMutex = 0; static DWORD LogFacilityMask = LF_ALL; @@ -59,29 +59,36 @@ VOID InitLogging() LogFacilityMask2 = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_LogFacility2, LogFacilityMask2) | LF_ALWAYS; + if (SUCCEEDED(szLogFileName.ReSizeNoThrow(MAX_LONGPATH))) + { + wcscpy_s(szLogFileName.Ptr(), szLogFileName.Size(), DEFAULT_LOGFILE_NAME); + } + LPWSTR fileName = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_LogFile); if (fileName != 0) { - int ret; - ret = WszWideCharToMultiByte(CP_ACP, 0, fileName, -1, szLogFileName, sizeof(szLogFileName)-1, NULL, NULL); - _ASSERTE(ret != 0); + if (SUCCEEDED(szLogFileName.ReSizeNoThrow(wcslen(fileName) + 32))) + { + wcscpy_s(szLogFileName.Ptr(), szLogFileName.Size(), fileName); + } delete fileName; } if (REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_LogWithPid, FALSE)) { - char szPid[20]; - sprintf_s(szPid, COUNTOF(szPid), ".%d", GetCurrentProcessId()); - strcat_s(szLogFileName, _countof(szLogFileName), szPid); + WCHAR szPid[20]; + swprintf_s(szPid, COUNTOF(szPid), W(".%d"), GetCurrentProcessId()); + wcscat_s(szLogFileName.Ptr(), szLogFileName.Size(), szPid); } if ((LogFlags & LOG_ENABLE) && (LogFlags & LOG_ENABLE_FILE_LOGGING) && + (szLogFileName.Size() > 0) && (LogFileHandle == INVALID_HANDLE_VALUE)) { DWORD fdwCreate = (LogFlags & LOG_ENABLE_APPEND_FILE) ? OPEN_ALWAYS : CREATE_ALWAYS; - LogFileHandle = CreateFileA( - szLogFileName, + LogFileHandle = WszCreateFile( + szLogFileName.Ptr(), GENERIC_WRITE, FILE_SHARE_READ, NULL, @@ -99,17 +106,17 @@ VOID InitLogging() } // Some other logging may be going on, try again with another file name - if (LogFileHandle == INVALID_HANDLE_VALUE) + if (LogFileHandle == INVALID_HANDLE_VALUE && wcslen(szLogFileName.Ptr()) + 3 <= szLogFileName.Size()) { - char* ptr = szLogFileName + strlen(szLogFileName) + 1; - ptr[-1] = '.'; - ptr[0] = '0'; + WCHAR* ptr = szLogFileName.Ptr() + wcslen(szLogFileName.Ptr()) + 1; + ptr[-1] = W('.'); + ptr[0] = W('0'); ptr[1] = 0; for(int i = 0; i < 10; i++) { - LogFileHandle = CreateFileA( - szLogFileName, + LogFileHandle = WszCreateFile( + szLogFileName.Ptr(), GENERIC_WRITE, FILE_SHARE_READ, NULL, @@ -121,13 +128,23 @@ VOID InitLogging() *ptr = *ptr + 1; } if (LogFileHandle == INVALID_HANDLE_VALUE) { - DWORD written; - char buff[MAX_LONGPATH+60]; - strcpy(buff, "Could not open log file, logging to "); - strcat_s(buff, _countof(buff), szLogFileName); - // ARULM--Changed WriteConsoleA to WriteFile to be CE compat - WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buff, (DWORD)strlen(buff), &written, 0); + int ret = WszWideCharToMultiByte(CP_ACP, 0, szLogFileName.Ptr(), -1, NULL, 0, NULL, NULL); + const char *msg = "Could not open log file, logging to "; + DWORD msgLen = (DWORD)strlen(msg); + CQuickSTR buff; + if (SUCCEEDED(buff.ReSizeNoThrow(ret + msgLen))) + { + strcpy_s(buff.Ptr(), buff.Size(), msg); + WszWideCharToMultiByte(CP_ACP, 0, szLogFileName.Ptr(), -1, buff.Ptr() + msgLen, ret, NULL, NULL); + msg = buff.Ptr(); + } + else + { + msg = "Could not open log file"; } + DWORD written; + WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msg, (DWORD)strlen(msg), &written, 0); + } } if (LogFileHandle == INVALID_HANDLE_VALUE) UtilMessageBoxNonLocalized(NULL, W("Could not open log file"), W("CLR logging"), MB_OK | MB_ICONINFORMATION, FALSE, TRUE); diff --git a/src/utilcode/makepath.cpp b/src/utilcode/makepath.cpp index 3d948d53a1..37b7202dba 100644 --- a/src/utilcode/makepath.cpp +++ b/src/utilcode/makepath.cpp @@ -15,6 +15,7 @@ #include "utilcode.h" #include "ex.h" +#ifndef FEATURE_CORECLR /*** *void _makepath() - build path name from components * @@ -165,6 +166,146 @@ void MakePath ( *path = _T('\0'); } } +#endif // !FEATURE_CORECLR + +/*** +*void Makepath() - build path name from components +* +*Purpose: +* create a path name from its individual components +* +*Entry: +* CQuickWSTR &szPath - Buffer for constructed path +* WCHAR *drive - pointer to drive component, may or may not contain +* trailing ':' +* WCHAR *dir - pointer to subdirectory component, may or may not include +* leading and/or trailing '/' or '\' characters +* WCHAR *fname - pointer to file base name component +* WCHAR *ext - pointer to extension component, may or may not contain +* a leading '.'. +* +*Exit: +* path - pointer to constructed path name +* +*Exceptions: +* +*******************************************************************************/ + +void MakePath ( + __out CQuickWSTR &szPath, + __in LPCWSTR drive, + __in LPCWSTR dir, + __in LPCWSTR fname, + __in LPCWSTR ext + ) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + } + CONTRACTL_END + + SIZE_T maxCount = 4 // Possible separators between components, plus null terminator + + (drive != nullptr ? 2 : 0) + + (dir != nullptr ? wcslen(dir) : 0) + + (fname != nullptr ? wcslen(fname) : 0) + + (ext != nullptr ? wcslen(ext) : 0); + LPWSTR path = szPath.AllocNoThrow(maxCount); + + const WCHAR *p; + DWORD count = 0; + + /* we assume that the arguments are in the following form (although we + * do not diagnose invalid arguments or illegal filenames (such as + * names longer than 8.3 or with illegal characters in them) + * + * drive: + * A ; or + * A: + * dir: + * \top\next\last\ ; or + * /top/next/last/ ; or + * either of the above forms with either/both the leading + * and trailing / or \ removed. Mixed use of '/' and '\' is + * also tolerated + * fname: + * any valid file name + * ext: + * any valid extension (none if empty or null ) + */ + + /* copy drive */ + + if (drive && *drive) { + *path++ = *drive; + *path++ = _T(':'); + count += 2; + } + + /* copy dir */ + + if ((p = dir)) { + while (*p) { + *path++ = *p++; + count++; + + _ASSERTE(count < maxCount); + } + +#ifdef _MBCS + if (*(p=_mbsdec(dir,p)) != _T('/') && *p != _T('\\')) { +#else /* _MBCS */ + // suppress warning for the following line; this is safe but would require significant code + // delta for prefast to understand. +#ifdef _PREFAST_ + #pragma warning( suppress: 26001 ) +#endif + if (*(p-1) != _T('/') && *(p-1) != _T('\\')) { +#endif /* _MBCS */ + *path++ = _T('\\'); + count++; + + _ASSERTE(count < maxCount); + } + } + + /* copy fname */ + + if ((p = fname)) { + while (*p) { + *path++ = *p++; + count++; + + _ASSERTE(count < maxCount); + } + } + + /* copy ext, including 0-terminator - check to see if a '.' needs + * to be inserted. + */ + + if ((p = ext)) { + if (*p && *p != _T('.')) { + *path++ = _T('.'); + count++; + + _ASSERTE(count < maxCount); + } + + while ((*path++ = *p++)) { + count++; + + _ASSERTE(count < maxCount); + } + } + else { + /* better add the 0-terminator */ + *path = _T('\0'); + } + + szPath.Shrink(count + 1); +} #if !defined(FEATURE_CORECLR) static LPCWSTR g_wszProcessExePath = NULL; diff --git a/src/utilcode/safewrap.cpp b/src/utilcode/safewrap.cpp index 6c17478014..4a6ecdb93c 100644 --- a/src/utilcode/safewrap.cpp +++ b/src/utilcode/safewrap.cpp @@ -175,9 +175,13 @@ ClrDirectoryEnumerator::ClrDirectoryEnumerator(LPCWSTR pBaseDirectory, LPCWSTR p } CONTRACTL_END; - StackSString strMask; - SString s(SString::Literal, W("\\")); - strMask.Set(pBaseDirectory, s, pMask); + StackSString strMask(pBaseDirectory); + SString s(SString::Literal, DIRECTORY_SEPARATOR_STR_W); + if (!strMask.EndsWith(s)) + { + strMask.Append(s); + } + strMask.Append(pMask); dirHandle = WszFindFirstFile(strMask, &data); if (dirHandle == INVALID_HANDLE_VALUE) diff --git a/src/utilcode/splitpath.cpp b/src/utilcode/splitpath.cpp index 927e8828e1..f7a35fdd97 100644 --- a/src/utilcode/splitpath.cpp +++ b/src/utilcode/splitpath.cpp @@ -124,7 +124,7 @@ void SplitPathInterior( /* extract drive letter and :, if any */ - if ((wcslen(wszPath) >= (_MAX_DRIVE - 2)) && (*(wszPath + _MAX_DRIVE - 2) == _T(':'))) { + if ((wcslen(wszPath) > (_MAX_DRIVE - 2)) && (*(wszPath + _MAX_DRIVE - 2) == _T(':'))) { if (pwszDrive && pcchDrive) { *pwszDrive = wszPath; *pcchDrive = _MAX_DRIVE - 1; @@ -243,38 +243,25 @@ void SplitPath(__in SString const &path, __inout_opt SString *fname, __inout_opt SString *ext) { - LPWSTR wzDrive = NULL; - if (drive != NULL) - wzDrive = drive->OpenUnicodeBuffer(_MAX_DRIVE); - - LPWSTR wzDir = NULL; - if (dir != NULL) - wzDir = dir->OpenUnicodeBuffer(_MAX_DIR); - - LPWSTR wzFname = NULL; - if (fname != NULL) - wzFname = fname->OpenUnicodeBuffer(_MAX_FNAME); - - LPWSTR wzExt = NULL; - if (ext != NULL) - wzExt = ext->OpenUnicodeBuffer(_MAX_EXT); + LPCWSTR wzDrive, wzDir, wzFname, wzExt; + size_t cchDrive, cchDir, cchFname, cchExt; - SplitPath(path, - wzDrive, _MAX_DRIVE, - wzDir, _MAX_DIR, - wzFname, _MAX_FNAME, - wzExt, _MAX_EXT); + SplitPathInterior(path, + &wzDrive, &cchDrive, + &wzDir, &cchDir, + &wzFname, &cchFname, + &wzExt, &cchExt); if (drive != NULL) - drive->CloseBuffer(static_cast<COUNT_T>(wcslen(wzDrive))); + drive->Set(wzDrive, (COUNT_T)cchDrive); if (dir != NULL) - dir->CloseBuffer(static_cast<COUNT_T>(wcslen(wzDir))); + dir->Set(wzDir, (COUNT_T)cchDir); if (fname != NULL) - fname->CloseBuffer(static_cast<COUNT_T>(wcslen(wzFname))); + fname->Set(wzFname, (COUNT_T)cchFname); if (ext != NULL) - ext->CloseBuffer(static_cast<COUNT_T>(wcslen(wzExt))); + ext->Set(wzExt, (COUNT_T)cchExt); } diff --git a/src/vm/rtlfunctions.cpp b/src/vm/rtlfunctions.cpp index 7883f678b4..b7cb78761a 100644 --- a/src/vm/rtlfunctions.cpp +++ b/src/vm/rtlfunctions.cpp @@ -76,26 +76,42 @@ VOID InstallEEFunctionTable ( CONTRACTL_END; static LPWSTR wszModuleName = NULL; - static WCHAR rgwModuleName[MAX_LONGPATH] = {0}; + static WCHAR rgwModuleName[MAX_LONGPATH] = { 0 }; if (wszModuleName == NULL) { - WCHAR rgwTempName[MAX_LONGPATH] = {0}; - DWORD dwTempNameSize = MAX_LONGPATH; + StackSString ssTempName; + DWORD dwTempNameSize; // Leaves trailing backslash on path, producing something like "c:\windows\microsoft.net\framework\v4.0.x86dbg\" - HRESULT hr = GetInternalSystemDirectory(rgwTempName, &dwTempNameSize); + LPCWSTR pszSysDir = GetInternalSystemDirectory(&dwTempNameSize); //finish creating complete path and copy to buffer if we can - if (FAILED(hr) || - (wcscat_s(rgwTempName, MAX_LONGPATH, MAIN_DAC_MODULE_DLL_NAME_W) != 0) || - (wcscpy_s(rgwModuleName, MAX_LONGPATH, rgwTempName) != 0)) + if (pszSysDir == NULL) { // The CLR should become unavailable in this case. EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); } - // publish result - InterlockedExchangeT(&wszModuleName, rgwModuleName); + ssTempName.Set(pszSysDir); + ssTempName.Append(MAIN_DAC_MODULE_DLL_NAME_W); + + if (ssTempName.GetCount() < MAX_LONGPATH) + { + wcscpy_s(rgwModuleName, MAX_LONGPATH, ssTempName.GetUnicode()); + + // publish result + InterlockedExchangeT(&wszModuleName, rgwModuleName); + } + else + { + NewArrayHolder<WCHAR> wzTempName(DuplicateStringThrowing(ssTempName.GetUnicode())); + + // publish result + if (InterlockedCompareExchangeT(&wszModuleName, (LPWSTR)wzTempName, nullptr) == nullptr) + { + wzTempName.SuppressRelease(); + } + } } if (!RtlInstallFunctionTableCallback( diff --git a/src/vm/stdinterfaces.cpp b/src/vm/stdinterfaces.cpp index 6ffbb4abea..c80ec3fe22 100644 --- a/src/vm/stdinterfaces.cpp +++ b/src/vm/stdinterfaces.cpp @@ -776,8 +776,21 @@ HRESULT GetITypeLibForAssembly(Assembly *pAssembly, ITypeLib **ppTLB, int bAutoC // Add a ".tlb" extension and try again. IfFailGo(rName.ReSizeNoThrow((int)(wcslen(szModule) + 5))); - SplitPath(szModule, rcDrive, _MAX_DRIVE, rcDir, _MAX_DIR, rcFname, _MAX_FNAME, 0, 0); - MakePath(rName.Ptr(), rcDrive, rcDir, rcFname, W(".tlb")); + // Check if szModule already has an extension. + LPCWSTR ext; + size_t extSize; + SplitPathInterior(szModule, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &ext, &extSize); + if (ext != nullptr) + { + // szModule already has an extension. Make a copy without the extension. + wcsncpy_s(rName.Ptr(), rName.Size(), szModule, ext - szModule); + } + else + { + // szModule does not have an extension. Copy the whole string. + wcscpy_s(rName.Ptr(), rName.Size(), szModule); + } + wcscat_s(rName.Ptr(), rName.Size(), W(".tlb")); hr = LoadTypeLibExWithFlags(rName.Ptr(), flags, &pITLB); if(hr == S_OK) diff --git a/src/vm/tlbexport.cpp b/src/vm/tlbexport.cpp index 21f8b143a9..01f5239620 100644 --- a/src/vm/tlbexport.cpp +++ b/src/vm/tlbexport.cpp @@ -276,10 +276,13 @@ void ExportTypeLibFromLoadedAssembly( TypeLibExporter exporter; // Exporter object. LPCWSTR szModule=0; // Module filename. - WCHAR rcDrive[_MAX_DRIVE] = {0}; - WCHAR rcDir[_MAX_DIR] = {0}; - WCHAR rcFile[_MAX_FNAME] = {0}; - WCHAR rcTlb[_MAX_PATH+5] = {0}; // Buffer for the tlb filename. + StackSString ssDrive; + StackSString ssDir; + StackSString ssFile; + size_t cchDrive; + size_t cchDir; + size_t cchFile; + CQuickWSTR rcTlb; // Buffer for the tlb filename. int bDynamic=0; // If true, dynamic module. Module *pModule; // The Assembly's SecurityModule. @@ -310,9 +313,9 @@ void ExportTypeLibFromLoadedAssembly( szTlb = W(""); else { - SplitPath(szModule, rcDrive, _MAX_DRIVE, rcDir, _MAX_DIR, rcFile, _MAX_FNAME, 0, 0); - MakePath(rcTlb, rcDrive, rcDir, rcFile, szTypeLibExt); - szTlb = rcTlb; + SplitPath(szModule, &ssDrive, &ssDir, &ssFile, nullptr); + MakePath(rcTlb, ssDrive.GetUnicode(), ssDir.GetUnicode(), ssFile.GetUnicode(), szTypeLibExt); + szTlb = rcTlb.Ptr(); } } diff --git a/src/zap/zapper.cpp b/src/zap/zapper.cpp index 77bb114143..626e1a0f1e 100644 --- a/src/zap/zapper.cpp +++ b/src/zap/zapper.cpp @@ -546,6 +546,7 @@ Zapper::Zapper(NGenOptions *pOptions, bool fromDllHost) zo->m_compilerFlags |= CORJIT_FLG_PROF_ENTERLEAVE; } +#ifdef FEATURE_FUSION if (pOptions->lpszRepositoryDir != NULL && pOptions->lpszRepositoryDir[0] != '\0') { size_t buflen = wcslen(pOptions->lpszRepositoryDir) + 1; @@ -589,6 +590,7 @@ Zapper::Zapper(NGenOptions *pOptions, bool fromDllHost) if (zo->m_repositoryFlags == RepositoryDefault) zo->m_repositoryFlags = MoveFromRepository; } +#endif //FEATURE_FUSION if (pOptions->fInstrument) zo->m_compilerFlags |= CORJIT_FLG_BBINSTR; @@ -3238,7 +3240,7 @@ void Zapper::GetOutputFolder() // active use because process ID is unique), increment N, and try again. Give up if N gets too large. for (DWORD n = 0; ; n++) { - swprintf_s(m_outputPath, W("%s\\%x-%x"), (LPCWSTR)tempPath, GetCurrentProcessId(), n); + m_outputPath.Printf(W("%s\\%x-%x"), (LPCWSTR)tempPath, GetCurrentProcessId(), n); if (WszCreateDirectory(m_outputPath, NULL)) break; @@ -3576,11 +3578,11 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig) const WCHAR * pathend = wcsrchr( assemblyPath, DIRECTORY_SEPARATOR_CHAR_W ); if( pathend ) { - wcsncpy_s(m_outputPath, _countof(m_outputPath), assemblyPath, pathend - assemblyPath); + m_outputPath.Set(assemblyPath, COUNT_T(pathend - assemblyPath)); } else { - wcscpy_s(m_outputPath, _countof(m_outputPath), W(".") DIRECTORY_SEPARATOR_STR_W); + m_outputPath.Set(W(".") DIRECTORY_SEPARATOR_STR_W); } } #endif // FEATURE_FUSION |