summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorJohn Chen (JOCHEN7) <jochen@microsoft.com>2016-02-23 20:36:07 -0800
committerJohn Chen (JOCHEN7) <jochen@microsoft.com>2016-02-29 13:55:49 -0800
commit488e6a16685241ed1aed3b3d386b78ed32e428f0 (patch)
tree9fd979bdde69b08216c6dde6a466fa3ff519c775 /src/vm
parent2d98b6a53263b9ad4b98e4a5dee35e703fd7ddf5 (diff)
downloadcoreclr-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.cpp34
-rw-r--r--src/vm/stdinterfaces.cpp17
-rw-r--r--src/vm/tlbexport.cpp17
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();
}
}