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 /src/vm | |
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.
Diffstat (limited to 'src/vm')
-rw-r--r-- | src/vm/rtlfunctions.cpp | 34 | ||||
-rw-r--r-- | src/vm/stdinterfaces.cpp | 17 | ||||
-rw-r--r-- | src/vm/tlbexport.cpp | 17 |
3 files changed, 50 insertions, 18 deletions
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(); } } |