diff --git a/src/classlibnative/bcltype/system.cpp b/src/classlibnative/bcltype/system.cpp index c950039fad0f..e902734b23d1 100644 --- a/src/classlibnative/bcltype/system.cpp +++ b/src/classlibnative/bcltype/system.cpp @@ -218,34 +218,19 @@ FCIMPL1(Object*, SystemNative::_GetEnvironmentVariable, StringObject* strVarUNSA HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, strVar); - // We loop round getting the length of the env var and then trying to copy - // the value into a managed string. Usually we'll go through this loop - // precisely once, but the caution is ncessary in case the variable mutates - // beneath us. - int len, newLen; + int len; // Get the length of the environment variable. - WCHAR dummy; // prefix complains if pass a null ptr in, so rely on the final length parm instead - len = WszGetEnvironmentVariable(strVar->GetBuffer(), &dummy, 0); + PathString envPath; // prefix complains if pass a null ptr in, so rely on the final length parm instead + len = WszGetEnvironmentVariable(strVar->GetBuffer(), envPath); - while (len != 0) + if (len != 0) { // Allocate the string. refRetVal = StringObject::NewString(len); - - // Get the value. - newLen = WszGetEnvironmentVariable(strVar->GetBuffer(), refRetVal->GetBuffer(), len); - if (newLen != (len - 1)) - { - // The envvar changed, need to do this again. Let GC collect the - // string we just allocated. - refRetVal = NULL; - - // Go back and try again. - len = newLen; - } - else - break; + + wcscpy_s(refRetVal->GetBuffer(), len + 1, envPath); + } HELPER_METHOD_FRAME_END(); @@ -297,15 +282,15 @@ FCIMPL0(StringObject*, SystemNative::_GetModuleFileName) } else { - SString wszFilePathString; + PathString wszFilePathString; - WCHAR * wszFile = wszFilePathString.OpenUnicodeBuffer(MAX_LONGPATH); - DWORD lgth = WszGetModuleFileName(NULL, wszFile, MAX_LONGPATH); + + DWORD lgth = WszGetModuleFileName(NULL, wszFilePathString); if (!lgth) { COMPlusThrowWin32(); } - wszFilePathString.CloseBuffer(lgth); + refRetVal = StringObject::NewString(wszFilePathString.GetUnicode()); } diff --git a/src/debug/di/cordb.cpp b/src/debug/di/cordb.cpp index 3a4fdff901b7..497225fd6712 100644 --- a/src/debug/di/cordb.cpp +++ b/src/debug/di/cordb.cpp @@ -201,11 +201,11 @@ BOOL WINAPI DbgDllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) #if defined(LOGGING) { - WCHAR rcFile[_MAX_PATH]; - WszGetModuleFileName(hInstance, rcFile, NumItems(rcFile)); + PathString rcFile; + WszGetModuleFileName(hInstance, rcFile); LOG((LF_CORDB, LL_INFO10000, "DI::DbgDllMain: load right side support from file '%s'\n", - rcFile)); + rcFile.GetUnicode())); } #endif diff --git a/src/debug/di/module.cpp b/src/debug/di/module.cpp index 700a362c94d5..78c7599455d7 100644 --- a/src/debug/di/module.cpp +++ b/src/debug/di/module.cpp @@ -2568,8 +2568,9 @@ HRESULT CordbModule::CreateReaderForInMemorySymbols(REFIID riid, void** ppObj) #ifndef FEATURE_PAL // PDB format - use diasymreader.dll with COM activation InlineSString<_MAX_PATH> ssBuf; + IfFailThrow(GetHModuleDirectory(GetModuleInst(), ssBuf)); IfFailThrow(FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, - GetHModuleDirectory(GetModuleInst(), ssBuf).GetUnicode(), + ssBuf.GetUnicode(), IID_ISymUnmanagedBinder, (void**)&pBinder, NULL)); diff --git a/src/debug/di/shimprocess.cpp b/src/debug/di/shimprocess.cpp index f15ab3fff6c3..a6fc15407e79 100644 --- a/src/debug/di/shimprocess.cpp +++ b/src/debug/di/shimprocess.cpp @@ -1823,50 +1823,41 @@ HRESULT ShimProcess::FindLoadedCLR(CORDB_ADDRESS * pClrInstanceId) HMODULE ShimProcess::GetDacModule() { HModuleHolder hDacDll; - WCHAR wszAccessDllPath[MAX_LONGPATH]; + PathString wszAccessDllPath; #ifdef FEATURE_PAL - if (!PAL_GetPALDirectoryW(wszAccessDllPath, _countof(wszAccessDllPath))) + if (!PAL_GetPALDirectoryWrapper(wszAccessDllPath)) { ThrowLastError(); } - wcscat_s(wszAccessDllPath, _countof(wszAccessDllPath), MAKEDLLNAME_W(W("mscordaccore"))); + PCWSTR eeFlavor = MAKEDLLNAME_W(W("mscordaccore")); #else // // Load the access DLL from the same directory as the the current CLR Debugging Services DLL. // - if (!WszGetModuleFileName(GetModuleInst(), wszAccessDllPath, NumItems(wszAccessDllPath))) + if (!WszGetModuleFileName(GetModuleInst(), wszAccessDllPath)) { ThrowLastError(); } - PWSTR pPathTail = wcsrchr(wszAccessDllPath, DIRECTORY_SEPARATOR_CHAR_W); - if (!pPathTail) + if (!SUCCEEDED(CopySystemDirectory(wszAccessDllPath, wszAccessDllPath))) { ThrowHR(E_INVALIDARG); } - pPathTail++; // Dac Dll is named: // mscordaccore.dll <-- coreclr // mscordacwks.dll <-- desktop PCWSTR eeFlavor = #if defined(FEATURE_MAIN_CLR_MODULE_USES_CORE_NAME) - W("core"); + W("mscordaccore.dll"); #else - W("wks"); + W("mscordacwks.dll"); #endif - - if (_snwprintf_s(pPathTail, - _countof(wszAccessDllPath) + (wszAccessDllPath - pPathTail), - NumItems(wszAccessDllPath) - (pPathTail - wszAccessDllPath), - MAKEDLLNAME_W(W("mscordac%s")), - eeFlavor) <= 0) - { - ThrowHR(E_INVALIDARG); - } + #endif // FEATURE_PAL + wszAccessDllPath.Append(eeFlavor); hDacDll.Assign(WszLoadLibrary(wszAccessDllPath)); if (!hDacDll) diff --git a/src/debug/ee/debugger.cpp b/src/debug/ee/debugger.cpp index 5905965c8bd8..c063eb829f25 100644 --- a/src/debug/ee/debugger.cpp +++ b/src/debug/ee/debugger.cpp @@ -2244,9 +2244,9 @@ HRESULT Debugger::StartupPhase2(Thread * pThread) if (!CORDebuggerAttached()) { #define DBG_ATTACH_ON_STARTUP_ENV_VAR W("COMPlus_DbgAttachOnStartup") - + PathString temp; // We explicitly just check the env because we don't want a switch this invasive to be global. - DWORD fAttach = WszGetEnvironmentVariable(DBG_ATTACH_ON_STARTUP_ENV_VAR, NULL, 0) > 0; + DWORD fAttach = WszGetEnvironmentVariable(DBG_ATTACH_ON_STARTUP_ENV_VAR, temp) > 0; if (fAttach) { @@ -15166,8 +15166,7 @@ HRESULT Debugger::InitAppDomainIPC(void) } hEnsureCleanup(this); DWORD dwStrLen = 0; - SString szExeNamePathString; - WCHAR * szExeName = szExeNamePathString.OpenUnicodeBuffer(MAX_LONGPATH); + SString szExeName; int i; // all fields in the object can be zero initialized. @@ -15216,15 +15215,14 @@ HRESULT Debugger::InitAppDomainIPC(void) // also initialize the process name dwStrLen = WszGetModuleFileName(NULL, - szExeName, - MAX_LONGPATH); + szExeName); - szExeNamePathString.CloseBuffer(dwStrLen); + // If we couldn't get the name, then use a nice default. if (dwStrLen == 0) { - wcscpy_s(szExeName, COUNTOF(szExeName), W("")); - dwStrLen = (DWORD)wcslen(szExeName); + szExeName.Set(W("")); + dwStrLen = szExeName.GetCount(); } // If we got the name, copy it into a buffer. dwStrLen is the diff --git a/src/dlls/mscoree/delayload.cpp b/src/dlls/mscoree/delayload.cpp index 40fb24707b2d..d74f58b444e3 100644 --- a/src/dlls/mscoree/delayload.cpp +++ b/src/dlls/mscoree/delayload.cpp @@ -376,16 +376,16 @@ FARPROC __stdcall CorDelayLoadHook( // Always 0. // If we've not yet looked at our environment, then do so. if (!bInit) { - WCHAR rcBreak[16]; + PathString rcBreak; // set DelayLoadBreak=[0|1] - if (WszGetEnvironmentVariable(W("DelayLoadBreak"), rcBreak, NumItems(rcBreak))) + if (WszGetEnvironmentVariable(W("DelayLoadBreak"), rcBreak)) { // "1" means to break hard and display errors. - if (*rcBreak == '1') + if (rcBreak[0] == '1') bBreak = 1; // "2" means no break, but display errors. - else if (*rcBreak == '2') + else if (rcBreak[0] == '2') bBreak = 2; else bBreak = false; diff --git a/src/dlls/mscoree/mscoree.cpp b/src/dlls/mscoree/mscoree.cpp index 11863e936eb1..d42733ad35f9 100644 --- a/src/dlls/mscoree/mscoree.cpp +++ b/src/dlls/mscoree/mscoree.cpp @@ -14,7 +14,7 @@ #include #include "shimload.h" #include "metadataexports.h" - +#include "ex.h" #if !defined(FEATURE_CORECLR) #include "corsym.h" #endif @@ -121,7 +121,7 @@ extern "C" BOOL WINAPI CoreDllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpRe CoreClrCallbacks cccallbacks; cccallbacks.m_hmodCoreCLR = (HINSTANCE)hInstance; cccallbacks.m_pfnIEE = IEE; - cccallbacks.m_pfnGetCORSystemDirectory = GetCORSystemDirectoryInternal; + cccallbacks.m_pfnGetCORSystemDirectory = GetCORSystemDirectoryInternaL; cccallbacks.m_pfnGetCLRFunction = GetCLRFunction; InitUtilcode(cccallbacks); @@ -284,13 +284,18 @@ STDAPI InternalDllGetClassObject( { EX_TRY { - // PDB format - use diasymreader.dll with COM activation - InlineSString<_MAX_PATH> ssBuf; - hr = FakeCoCallDllGetClassObject(rclsid, - GetHModuleDirectory(GetModuleInst(), ssBuf).GetUnicode(), - riid, - ppv, - NULL); + + // PDB format - use diasymreader.dll with COM activation + InlineSString<_MAX_PATH> ssBuf; + if (SUCCEEDED(GetHModuleDirectory(GetModuleInst(), ssBuf))) + { + hr = FakeCoCallDllGetClassObject(rclsid, + ssBuf, + riid, + ppv, + NULL + ); + } } EX_CATCH_HRESULT(hr); } @@ -719,116 +724,6 @@ STDAPI LoadStringRCEx( #endif // CROSSGEN_COMPILE -#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE) - -extern HINSTANCE g_pMSCorEE; - -#ifndef FEATURE_PAL - -// -// Returns path name from a file name. The path name will be (null-terminated, incl. the last '\' if present). -// Example: For input "C:\Windows\System.dll" returns "C:\Windows\". -// Warning: The input file name string might be destroyed. -// -// Arguments: -// pFileName - [in] Null-terminated file name. Will be destroyed (an additional null-terminator might be -// written into the string). -// pBuffer - [out] buffer allocated by caller of size cchBuffer. -// cchBuffer - Size of pBuffer in characters. -// pdwLength - [out] Size of the path name in characters (incl. null-terminator). Will be filled even if -// ERROR_INSUFFICIENT_BUFFER is returned. -// -// Return Value: -// S_OK - Output buffer contains path name. -// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) - *pdwLength contains required size of the buffer in -// characters. -// other errors - If input parameters are incorrect (NULL). -// -static -HRESULT CopySystemDirectory(__in WCHAR *pFileName, - __out_ecount_z_opt(cchBuffer) LPWSTR pBuffer, - DWORD cchBuffer, - __out DWORD *pdwLength) -{ - if ((pBuffer != NULL) && (cchBuffer > 0)) - { // Initialize the output for case the function fails - *pBuffer = W('\0'); - } - - if (pdwLength == NULL) - return E_POINTER; - - HRESULT hr = S_OK; - if (pFileName == NULL) - return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - - SIZE_T dwFileNameLength = wcslen(pFileName); - LPWSTR pSeparator = wcsrchr(pFileName, W('\\')); - if (pSeparator != NULL) - { - dwFileNameLength = (DWORD)(pSeparator - pFileName + 1); - pFileName[dwFileNameLength] = W('\0'); - } - - dwFileNameLength++; // Add back in the null - *pdwLength = (DWORD)dwFileNameLength; - if ((dwFileNameLength > cchBuffer) || (pBuffer == NULL)) - { - hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - } - else - { - CopyMemory(pBuffer, - pFileName, - dwFileNameLength * sizeof(WCHAR)); - } - return hr; -} - -BOOL PAL_GetPALDirectory(__out_ecount(cchBuffer) LPWSTR pbuffer, - DWORD cchBuffer) -{ - - HRESULT hr = S_OK; - - WCHAR * pPath = new (nothrow) WCHAR[MAX_LONGPATH]; - if (pPath == NULL) - { - return FALSE; - } - - DWORD dwPath = MAX_LONGPATH; - -#ifndef CROSSGEN_COMPILE - _ASSERTE(g_pMSCorEE != NULL); -#endif - - dwPath = WszGetModuleFileName(g_pMSCorEE, pPath, dwPath); - - if(dwPath == 0) - { - hr = HRESULT_FROM_GetLastErrorNA(); - } - else - { - DWORD dwLength; - hr = CopySystemDirectory(pPath, pbuffer, cchBuffer, &dwLength); - } - - delete [] pPath; - - return (hr == S_OK); -} - -BOOL PAL_GetPALDirectoryW(__out_ecount(cchBuffer) LPWSTR pbuffer, - DWORD cchBuffer) -{ - return PAL_GetPALDirectory(pbuffer, cchBuffer); -} - -#endif // FEATURE_PAL - -#endif // FEATURE_CORECLR || CROSSGEN_COMPILE // Note that there are currently two callers of this function: code:CCompRC.LoadLibrary @@ -838,7 +733,7 @@ STDAPI GetRequestedRuntimeInfoInternal(LPCWSTR pExe, LPCWSTR pConfigurationFile, DWORD startupFlags, DWORD runtimeInfoFlags, - __out_ecount_opt(dwDirectory) LPWSTR pDirectory, + __out_ecount_opt(dwDirectory) LPWSTR pDirectory, DWORD dwDirectory, __out_opt DWORD *pdwDirectoryLength, __out_ecount_opt(cchBuffer) LPWSTR pVersion, @@ -850,18 +745,37 @@ STDAPI GetRequestedRuntimeInfoInternal(LPCWSTR pExe, NOTHROW; GC_NOTRIGGER; ENTRY_POINT; - PRECONDITION(pDirectory != NULL && pVersion != NULL && cchBuffer > 0); + PRECONDITION( pVersion != NULL && cchBuffer > 0); } CONTRACTL_END; // for simplicity we will cheat and return the entire system directory in pDirectory pVersion[0] = 0; if (pdwLength != NULL) *pdwLength = 0; + HRESULT hr; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return COR_E_STACKOVERFLOW;) + EX_TRY + { - if (pdwDirectoryLength == NULL) - pdwDirectoryLength = &dwDirectory; + PathString pDirectoryPath; + + hr = GetCORSystemDirectoryInternaL(pDirectoryPath); + *pdwLength = pDirectoryPath.GetCount() + 1; + if (dwDirectory >= *pdwLength) + { + wcscpy_s(pDirectory, pDirectoryPath.GetCount() + 1, pDirectoryPath); + } + else + { + hr = E_FAIL; + } + + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE - return GetCORSystemDirectoryInternal(pDirectory, dwDirectory, pdwDirectoryLength); + return hr; } // Replacement for legacy shim API GetCORRequiredVersion(...) used in linked libraries. @@ -890,31 +804,31 @@ CLRRuntimeHostInternal_GetImageVersionString( return hr; } // CLRRuntimeHostInternal_GetImageVersionString - -STDAPI GetCORSystemDirectoryInternal(__out_ecount_part_opt(cchBuffer, *pdwLength) LPWSTR pBuffer, - DWORD cchBuffer, - __out_opt DWORD* pdwLength) + //LONGPATH:TODO: Remove this once Desktop usage has been removed +#if !defined(FEATURE_CORECLR) +STDAPI GetCORSystemDirectoryInternal(__out_ecount_part_opt(cchBuffer, *pdwLength) LPWSTR pBuffer, + DWORD cchBuffer, + __out_opt DWORD* pdwLength) { -#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE) +#if defined(CROSSGEN_COMPILE) - CONTRACTL { + CONTRACTL{ NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - PRECONDITION(CheckPointer(pBuffer, NULL_OK)); - PRECONDITION(CheckPointer(pdwLength, NULL_OK)); + GC_NOTRIGGER; + ENTRY_POINT; + PRECONDITION(CheckPointer(pBuffer, NULL_OK)); + PRECONDITION(CheckPointer(pdwLength, NULL_OK)); } CONTRACTL_END; HRESULT hr = S_OK; BEGIN_ENTRYPOINT_NOTHROW; - - if(pdwLength == NULL) + + if (pdwLength == NULL) IfFailGo(E_POINTER); if (pBuffer == NULL) IfFailGo(E_POINTER); -#ifdef CROSSGEN_COMPILE if (WszGetModuleFileName(NULL, pBuffer, cchBuffer) == 0) { IfFailGo(HRESULT_FROM_GetLastError()); @@ -926,20 +840,15 @@ STDAPI GetCORSystemDirectoryInternal(__out_ecount_part_opt(cchBuffer, *pdwLength IfFailGo(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)); } *pSeparator = W('\0'); -#else - if (!PAL_GetPALDirectory(pBuffer, cchBuffer)) { - IfFailGo(HRESULT_FROM_GetLastError()); - } -#endif // Include the null terminator in the length - *pdwLength = (DWORD)wcslen(pBuffer)+1; + *pdwLength = (DWORD)wcslen(pBuffer) + 1; ErrExit: END_ENTRYPOINT_NOTHROW; return hr; -#else // FEATURE_CORECLR || CROSSGEN_COMPILE +#else // CROSSGEN_COMPILE // Simply forward the call to the ICLRRuntimeInfo implementation. STATIC_CONTRACT_WRAPPER; @@ -953,8 +862,8 @@ STDAPI GetCORSystemDirectoryInternal(__out_ecount_part_opt(cchBuffer, *pdwLength { // not invoked via shim (most probably loaded by Fusion) WCHAR wszPath[_MAX_PATH]; - DWORD dwLength = WszGetModuleFileName(g_hThisInst, wszPath,NumItems(wszPath)); - + DWORD dwLength = WszGetModuleFileName(g_hThisInst, wszPath, NumItems(wszPath)); + if (dwLength == 0 || (dwLength == NumItems(wszPath) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { @@ -968,7 +877,7 @@ STDAPI GetCORSystemDirectoryInternal(__out_ecount_part_opt(cchBuffer, *pdwLength } pwzSeparator[1] = W('\0'); // after '\' - LPWSTR pwzDirectoryName = wszPath; + LPWSTR pwzDirectoryName = wszPath; size_t cchLength = wcslen(pwzDirectoryName) + 1; @@ -982,9 +891,9 @@ STDAPI GetCORSystemDirectoryInternal(__out_ecount_part_opt(cchBuffer, *pdwLength { // all look good, copy the string over wcscpy_s(pBuffer, - cchLength, - pwzDirectoryName - ); + cchLength, + pwzDirectoryName + ); } } @@ -993,6 +902,70 @@ STDAPI GetCORSystemDirectoryInternal(__out_ecount_part_opt(cchBuffer, *pdwLength } return hr; +#endif // CROSSGEN_COMPILE +} +#endif // !FEATURE_CORECLR + +STDAPI GetCORSystemDirectoryInternaL(SString& pBuffer) +{ +#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE) + + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + ENTRY_POINT; + } CONTRACTL_END; + + HRESULT hr = S_OK; + BEGIN_ENTRYPOINT_NOTHROW; + + +#ifdef CROSSGEN_COMPILE + + if (WszGetModuleFileName(NULL, pBuffer) > 0) + { + hr = CopySystemDirectory(pBuffer, pBuffer); + } + else { + hr = HRESULT_FROM_GetLastError(); + } + +#else + + if (!PAL_GetPALDirectoryWrapper(pBuffer)) { + hr = HRESULT_FROM_GetLastError(); + } +#endif + + END_ENTRYPOINT_NOTHROW; + return hr; + +#else // FEATURE_CORECLR || CROSSGEN_COMPILE + DWORD cchBuffer; + // Simply forward the call to the ICLRRuntimeInfo implementation. + STATIC_CONTRACT_WRAPPER; + HRESULT hr = S_OK; + if (g_pCLRRuntime) + { + WCHAR* temp = pBuffer.OpenUnicodeBuffer(MAX_PATH - 1); + hr = g_pCLRRuntime->GetRuntimeDirectory(temp, &cchBuffer); + pBuffer.CloseBuffer(cchBuffer - 1); + } + else + { + // not invoked via shim (most probably loaded by Fusion) + DWORD dwLength = WszGetModuleFileName(g_hThisInst, pBuffer); + + + if (dwLength == 0 || ((dwLength == pBuffer.GetCount() + 1) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) + { + return E_UNEXPECTED; + } + + CopySystemDirectory(pBuffer, pBuffer); + } + return hr; + #endif // FEATURE_CORECLR || CROSSGEN_COMPILE } @@ -1227,34 +1200,33 @@ HRESULT SetInternalSystemDirectory() } CONTRACTL_END; HRESULT hr = S_OK; - if(g_dwSystemDirectory == 0) { - DWORD len; - // use local buffer for thread safety - NewArrayHolder wzSystemDirectory(new (nothrow) WCHAR[MAX_LONGPATH+1]); - if (wzSystemDirectory == NULL) - { - return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); - } - - hr = GetCORSystemDirectoryInternal(wzSystemDirectory, MAX_LONGPATH+1, &len); + DWORD len = 0; + NewArrayHolder pSystemDirectory; + EX_TRY{ + + // use local buffer for thread safety + PathString wzSystemDirectory; + + hr = GetCORSystemDirectoryInternaL(wzSystemDirectory); + + if (FAILED(hr)) { + wzSystemDirectory.Set(W('\0')); + } + + pSystemDirectory = wzSystemDirectory.GetCopyOfUnicodeString(); + if (pSystemDirectory == NULL) + { + hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + } + len = wzSystemDirectory.GetCount() + 1; - if(FAILED(hr)) { - *wzSystemDirectory = W('\0'); - len = 1; - } - - WCHAR * pSystemDirectory = new (nothrow) WCHAR[len]; - if (pSystemDirectory == NULL) - { - return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); } - - wcscpy_s(pSystemDirectory, len, wzSystemDirectory); - + EX_CATCH_HRESULT(hr); + // publish results idempotently with correct memory ordering - g_pSystemDirectory = pSystemDirectory; + g_pSystemDirectory = pSystemDirectory.Extract(); (void)InterlockedExchange((LONG *)&g_dwSystemDirectory, len); } diff --git a/src/dlls/mscorpe/ceefilegenwriter.cpp b/src/dlls/mscorpe/ceefilegenwriter.cpp index 67031484ed22..cfd1ebb64462 100644 --- a/src/dlls/mscorpe/ceefilegenwriter.cpp +++ b/src/dlls/mscorpe/ceefilegenwriter.cpp @@ -225,8 +225,8 @@ CeeFileGenWriter::CeeFileGenWriter() // ctor is protected #ifdef ENC_DELTA_HACK // for EnC we want the RVA to be right at the front of the IL stream - WCHAR szFileName[256]; - DWORD len = WszGetEnvironmentVariable(W("COMP_ENC_EMIT"), szFileName, NumItems(szFileName)); + PathString szFileName; + DWORD len = WszGetEnvironmentVariable(W("COMP_ENC_EMIT"), szFileName); if (len > 0) g_EnCMode = TRUE; #endif @@ -941,64 +941,25 @@ HRESULT CeeFileGenWriter::emitExeMain() return S_OK; } // HRESULT CeeFileGenWriter::emitExeMain() -// Like CreateProcess(), but waits for execution to finish -// Returns true if successful, false on failure. -// dwExitCode set to process' exitcode -HRESULT CopySystemDirectory(__in WCHAR* pPath, - __out_ecount_part(cchBuffer, *pdwLength) LPWSTR pbuffer, - DWORD cchBuffer, - __out DWORD* pdwLength) -{ - if (pdwLength == NULL) - return E_POINTER; - - HRESULT hr = S_OK; - if(pPath == NULL) - return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - - SIZE_T dwPath = wcslen(pPath); - LPWSTR pSep = wcsrchr(pPath, L'\\'); - if(pSep) { - dwPath = (DWORD)(pSep-pPath+1); - pPath[dwPath] = L'\0'; - } - - dwPath++; // Add back in the null - *pdwLength = (DWORD)dwPath; - if(dwPath > cchBuffer || pbuffer == NULL) - hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - else { - CopyMemory(pbuffer, - pPath, - dwPath*sizeof(WCHAR)); - } - return hr; -} - -HRESULT GetClrSystemDirectory(__out_ecount_part(cchBuffer, *pdwLength) LPWSTR pbuffer, - DWORD cchBuffer, - __out DWORD* pdwLength) +HRESULT GetClrSystemDirectory(SString& pbuffer) { HRESULT hr = S_OK; - if(pdwLength == NULL) - return E_POINTER; - WCHAR pPath[MAX_PATH]; - DWORD dwPath = MAX_PATH; + PathString pPath; + DWORD dwPath; - _ASSERTE (g_hThisInst); - dwPath = WszGetModuleFileName(g_hThisInst, pPath, dwPath); + dwPath = WszGetModuleFileName(g_hThisInst, pPath); if(dwPath == 0) { hr = HRESULT_FROM_GetLastErrorNA(); return (hr); } - else - return CopySystemDirectory(pPath, pbuffer, cchBuffer, pdwLength); + + return CopySystemDirectory(pPath, pbuffer); } #ifndef FEATURE_PAL @@ -1008,10 +969,8 @@ BOOL RunProcess(LPCWSTR tempResObj, LPCWSTR pszFilename, DWORD* pdwExitCode, PEW PROCESS_INFORMATION pi; - DWORD cchSystemDir = MAX_PATH + 1; - DWORD dwLen; - WCHAR wszSystemDir[MAX_PATH + 1]; - if (FAILED(GetClrSystemDirectory(wszSystemDir, cchSystemDir, &dwLen))) + PathString wszSystemDir; + if (FAILED(GetClrSystemDirectory(wszSystemDir))) return FALSE; WCHAR* wzMachine; @@ -1031,7 +990,7 @@ BOOL RunProcess(LPCWSTR tempResObj, LPCWSTR pszFilename, DWORD* pdwExitCode, PEW if(*ext == NULL) { ssCmdLine.Printf(L"%scvtres.exe /NOLOGO /READONLY /MACHINE:%s \"/OUT:%s\" \"%s.\"", - wszSystemDir, + wszSystemDir.GetUnicode(), wzMachine, tempResObj, pszFilename); @@ -1039,7 +998,7 @@ BOOL RunProcess(LPCWSTR tempResObj, LPCWSTR pszFilename, DWORD* pdwExitCode, PEW else { ssCmdLine.Printf(L"%scvtres.exe /NOLOGO /READONLY /MACHINE:%s \"/OUT:%s\" \"%s\"", - wszSystemDir, + wszSystemDir.GetUnicode(), wzMachine, tempResObj, pszFilename); @@ -1115,11 +1074,11 @@ HRESULT ConvertResource(const WCHAR * pszFilename, __in_ecount(cchTempFilename) return S_OK; } - WCHAR tempResObj[MAX_PATH+1]; - WCHAR tempResPath[MAX_PATH+1]; + PathString tempResObj; + PathString tempResPath; // Create the temp file where the temp path is at rather than where the application is at. - if (!WszGetTempPath(MAX_PATH, tempResPath)) + if (!WszGetTempPath( tempResPath)) { return HRESULT_FROM_GetLastError(); } diff --git a/src/dlls/mscorpe/pewriter.cpp b/src/dlls/mscorpe/pewriter.cpp index 6ad67609aeba..f3b5fb194d23 100644 --- a/src/dlls/mscorpe/pewriter.cpp +++ b/src/dlls/mscorpe/pewriter.cpp @@ -2181,14 +2181,14 @@ HRESULT PEWriter::write(__in LPCWSTR fileName) { HRESULT hr; #ifdef ENC_DELTA_HACK - WCHAR szFileName[256]; - DWORD len = WszGetEnvironmentVariable(L"COMP_ENC_EMIT", szFileName, NumItems(szFileName)); + PathString szFileName; + DWORD len = WszGetEnvironmentVariable(L"COMP_ENC_EMIT", szFileName); _ASSERTE(len < sizeof(szFileName)); if (len > 0) { _ASSERTE(!m_pSeedFileDecoder); - - wcscat_s(szFileName, sizeof(szFileName)/sizeof(szFileName[0]), L".dil"); + szFileName.Append(L".dil"); + HANDLE pDelta = WszCreateFile(szFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, diff --git a/src/ilasm/grammar_after.cpp b/src/ilasm/grammar_after.cpp index 61de517e0ea5..c8634801c731 100644 --- a/src/ilasm/grammar_after.cpp +++ b/src/ilasm/grammar_after.cpp @@ -858,23 +858,19 @@ int yylex() if((parser->wzIncludePath != NULL) &&(wcschr(wzFile,'\\')==NULL)&&(wcschr(wzFile,':')==NULL)) { - WCHAR* wzFullName = new WCHAR[MAX_FILENAME_LENGTH+1]; - if(wzFullName != NULL) + PathString wzFullName; + + WCHAR* pwz; + DWORD dw = WszSearchPath(parser->wzIncludePath,wzFile,NULL, + TRUE, wzFullName,&pwz); + if(dw != 0) { - WCHAR* pwz; - DWORD dw = WszSearchPath(parser->wzIncludePath,wzFile,NULL, - MAX_FILENAME_LENGTH+1,wzFullName,&pwz); - if(dw != 0) - { - wzFullName[dw] = 0; - delete [] wzFile; - wzFile = wzFullName; - } - else - { - delete [] wzFullName; - } + wzFullName.CloseBuffer((COUNT_T)(dw)); + delete [] wzFile; + + wzFile = wzFullName.GetCopyOfUnicodeString(); } + } if(PASM->m_fReportProgress) parser->msg("\nIncluding '%S'\n",wzFile); diff --git a/src/ilasm/main.cpp b/src/ilasm/main.cpp index 50131b2b0111..811c65640eee 100644 --- a/src/ilasm/main.cpp +++ b/src/ilasm/main.cpp @@ -95,7 +95,7 @@ WCHAR *pwzDeltaFiles[1024]; char szInputFilename[MAX_FILENAME_LENGTH*3]; WCHAR wzInputFilename[MAX_FILENAME_LENGTH]; WCHAR wzOutputFilename[MAX_FILENAME_LENGTH]; -WCHAR wzIncludePathBuffer[MAX_FILENAME_LENGTH]; + #ifdef _PREFAST_ #pragma warning(push) @@ -628,8 +628,12 @@ extern "C" int _cdecl wmain(int argc, __in WCHAR **argv) } if(wzIncludePath == NULL) { - if(0!=WszGetEnvironmentVariable(W("ILASM_INCLUDE"),wzIncludePathBuffer,MAX_FILENAME_LENGTH)) - wzIncludePath = wzIncludePathBuffer; + PathString wzIncludePathBuffer; + if (0 != WszGetEnvironmentVariable(W("ILASM_INCLUDE"), wzIncludePathBuffer)) + { + wzIncludePath = wzIncludePathBuffer.GetCopyOfUnicodeString(); + + } } //------------ Assembler initialization done. Now, to business ----------------------- if((pParser = new AsmParse(NULL, pAsm))) diff --git a/src/inc/corpriv.h b/src/inc/corpriv.h index f90d2ab4702d..1a8f67170103 100644 --- a/src/inc/corpriv.h +++ b/src/inc/corpriv.h @@ -641,10 +641,16 @@ STDAPI LoadLibraryShimInternal( LPVOID pvReserved, HMODULE *phModDll); +STDAPI GetCORSystemDirectoryInternaL( + SString& pBuffer + ); + +//LONGPATH:TODO: Remove this once Desktop usage has been removed STDAPI GetCORSystemDirectoryInternal( - __out_ecount_part_opt(cchBuffer, *pdwLength) LPWSTR pBuffer, - DWORD cchBuffer, - __out_opt DWORD* pdwLength); + __out_ecount_part_opt(cchBuffer, *pdwLength) LPWSTR pBuffer, + DWORD cchBuffer, + __out_opt DWORD* pdwLength + ); STDAPI GetCORVersionInternal( __out_ecount_z_opt(cchBuffer) LPWSTR pBuffer, @@ -656,7 +662,7 @@ STDAPI GetRequestedRuntimeInfoInternal(LPCWSTR pExe, LPCWSTR pConfigurationFile, DWORD startupFlags, DWORD runtimeInfoFlags, - __out_ecount_opt(dwDirectory) LPWSTR pDirectory, + __out_ecount_opt(dwDirectory) LPWSTR pDirectory, DWORD dwDirectory, __out_opt DWORD *pdwDirectoryLength, __out_ecount_opt(cchBuffer) LPWSTR pVersion, diff --git a/src/inc/longfilepathwrappers.h b/src/inc/longfilepathwrappers.h new file mode 100644 index 000000000000..b3fc6ad1db45 --- /dev/null +++ b/src/inc/longfilepathwrappers.h @@ -0,0 +1,277 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#ifndef _WIN_PATH_APIS_WRAPPER_ +#define _WIN_PATH_APIS_WRAPPER_ +class SString; + +HMODULE +LoadLibraryExWrapper( + _In_ LPCWSTR lpLibFileName, + _Reserved_ HANDLE hFile = NULL, + _In_ DWORD dwFlags = 0 + ); + +HANDLE +CreateFileWrapper( + _In_ LPCWSTR lpFileName, + _In_ DWORD dwDesiredAccess, + _In_ DWORD dwShareMode, + _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, + _In_ DWORD dwCreationDisposition, + _In_ DWORD dwFlagsAndAttributes, + _In_opt_ HANDLE hTemplateFile + ); + +BOOL +SetFileAttributesWrapper( + _In_ LPCWSTR lpFileName, + _In_ DWORD dwFileAttributes + ); + +DWORD +GetFileAttributesWrapper( + _In_ LPCWSTR lpFileName + ); + +BOOL +GetFileAttributesExWrapper( + _In_ LPCWSTR lpFileName, + _In_ GET_FILEEX_INFO_LEVELS fInfoLevelId, + _Out_writes_bytes_(sizeof(WIN32_FILE_ATTRIBUTE_DATA)) LPVOID lpFileInformation + ); +BOOL +DeleteFileWrapper( + _In_ LPCWSTR lpFileName + ); + +HANDLE +FindFirstFileExWrapper( + _In_ LPCWSTR lpFileName, + _In_ FINDEX_INFO_LEVELS fInfoLevelId, + _Out_writes_bytes_(sizeof(WIN32_FIND_DATAW)) LPVOID lpFindFileData, + _In_ FINDEX_SEARCH_OPS fSearchOp, + _Reserved_ LPVOID lpSearchFilter, + _In_ DWORD dwAdditionalFlags + ); + +BOOL +CopyFileWrapper( + _In_ LPCWSTR lpExistingFileName, + _In_ LPCWSTR lpNewFileName, + _In_ BOOL bFailIfExists + ); + +#ifndef FEATURE_PAL +BOOL +CopyFileExWrapper( + _In_ LPCWSTR lpExistingFileName, + _In_ LPCWSTR lpNewFileName, + _In_opt_ LPPROGRESS_ROUTINE lpProgressRoutine, + _In_opt_ LPVOID lpData, + _When_(pbCancel != NULL, _Pre_satisfies_(*pbCancel == FALSE)) + _Inout_opt_ LPBOOL pbCancel, + _In_ DWORD dwCopyFlags + ); +#endif //FEATURE_PAL + +BOOL +MoveFileWrapper( + _In_ LPCWSTR lpExistingFileName, + _In_ LPCWSTR lpNewFileName + ); + +BOOL +MoveFileExWrapper( + _In_ LPCWSTR lpExistingFileName, + _In_opt_ LPCWSTR lpNewFileName, + _In_ DWORD dwFlags + ); + +BOOL +CreateDirectoryWrapper( + _In_ LPCWSTR lpPathName, + _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes + ); + +BOOL +RemoveDirectoryWrapper( + _In_ LPCWSTR lpPathName + ); + +BOOL +CreateHardLinkWrapper( + _In_ LPCWSTR lpFileName, + _In_ LPCWSTR lpExistingFileName, + _Reserved_ LPSECURITY_ATTRIBUTES lpSecurityAttributes + ); + +DWORD +SearchPathWrapper( + _In_opt_ LPCWSTR lpPath, + _In_ LPCWSTR lpFileName, + _In_opt_ LPCWSTR lpExtension, + _In_ BOOL getPath, + SString& lpBuffer, + _Out_opt_ LPWSTR * lpFilePart + ); + + +DWORD +GetShortPathNameWrapper( + _In_ LPCWSTR lpszLongPath, + SString& lpszShortPath + ); + +DWORD +GetLongPathNameWrapper( + _In_ LPCWSTR lpszShortPath, + SString& lpszLongPath + ); + +UINT GetTempFileNameWrapper( + _In_ LPCTSTR lpPathName, + _In_ LPCTSTR lpPrefixString, + _In_ UINT uUnique, + SString& lpTempFileName + ); + +DWORD GetTempPathWrapper( + SString& lpBuffer + ); + +DWORD GetCurrentDirectoryWrapper( + SString& lpBuffer + ); + +DWORD +GetModuleFileNameWrapper( + _In_opt_ HMODULE hModule, + SString& buffer + ); + +DWORD GetEnvironmentVariableWrapper( + _In_opt_ LPCTSTR lpName, + _Out_opt_ SString& lpBuffer + ); + +BOOL PAL_GetPALDirectoryWrapper(SString& pbuffer); + +#ifndef FEATURE_CORECLR +//Temporarily providing direct OS Calls Till All of the Desktop CLR start using the above format +inline DWORD +SearchPathWrapper( + _In_opt_ LPCWSTR lpPath, + _In_ LPCWSTR lpFileName, + _In_opt_ LPCWSTR lpExtension, + _In_ BOOL getPath, + _Out_ LPWSTR lpBuffer, + _Out_opt_ LPWSTR * lpFilePart + ) +{ + return SearchPathW( + lpPath, + lpFileName, + lpExtension, + getPath, + lpBuffer, + lpFilePart + ); +} + + +inline DWORD +GetShortPathNameWrapper( + _In_ LPCWSTR lpszLongPath, + _Out_ LPWSTR lpszShortPath, + _In_ DWORD cchBuffer + ) +{ + return GetShortPathNameW( + lpszLongPath, + lpszShortPath, + cchBuffer + ); +} + +inline DWORD +GetLongPathNameWrapper( + _In_ LPCWSTR lpszShortPath, + _Out_ LPWSTR lpszLongPath, + _In_ DWORD cchBuffer + ) +{ + return GetLongPathNameW( + lpszShortPath, + lpszLongPath, + cchBuffer + ); +} + +inline UINT GetTempFileNameWrapper( + _In_ LPCWSTR lpPathName, + _In_ LPCWSTR lpPrefixString, + _In_ UINT uUnique, + _Out_ LPWSTR lpTempFileName + ) +{ + return GetTempFileNameW( + lpPathName, + lpPrefixString, + uUnique, + lpTempFileName + ); +} + +inline DWORD GetTempPathWrapper( + _In_ DWORD nBufferLength, + _Out_ LPWSTR lpBuffer + ) +{ + return GetTempPathW( + nBufferLength, + lpBuffer + ); +} + +inline DWORD GetCurrentDirectoryWrapper( + _In_ DWORD nBufferLength, + _Out_ LPWSTR lpBuffer + ) +{ + return GetCurrentDirectoryW( + nBufferLength, + lpBuffer + ); +} + +inline DWORD +GetModuleFileNameWrapper( + _In_opt_ HMODULE hModule, + _Out_ LPWSTR lpFilename, + _In_ DWORD nSize + ) +{ + return GetModuleFileNameW( + hModule, + lpFilename, + nSize + ); +} + +inline DWORD GetEnvironmentVariableWrapper( + _In_opt_ LPCWSTR lpName, + _Out_opt_ LPWSTR lpBuffer, + _In_ DWORD nSize + ) +{ + return GetEnvironmentVariableW( + lpName, + lpBuffer, + nSize + ); +} +#endif //FEATURE_CORECLR +#endif //_WIN_PATH_APIS_WRAPPER_ + diff --git a/src/inc/sstring.h b/src/inc/sstring.h index 3c5107a06cd1..bfbaa8142981 100644 --- a/src/inc/sstring.h +++ b/src/inc/sstring.h @@ -625,6 +625,9 @@ class SString : private SBuffer UTF8 *OpenUTF8Buffer(COUNT_T maxSingleCharCount); ANSI *OpenANSIBuffer(COUNT_T maxSingleCharCount); + //Returns the unicode string, the caller is reponsible for lifetime of the string + WCHAR *GetCopyOfUnicodeString(); + // Get the max size that can be passed to OpenUnicodeBuffer without causing allocations. COUNT_T GetUnicodeAllocation(); @@ -1009,9 +1012,11 @@ typedef InlineSString<32> SmallStackSString; #ifdef _DEBUG // This is a smaller version for debug builds to exercise the buffer allocation path typedef InlineSString<32> PathString; +typedef InlineSString<2 * 32> LongPathString; #else // Set it to the current MAX_PATH typedef InlineSString<260> PathString; +typedef InlineSString<2 * 260> LongPathString; #endif // ================================================================================ diff --git a/src/inc/sstring.inl b/src/inc/sstring.inl index b9c689548b00..6b587e17ba9b 100644 --- a/src/inc/sstring.inl +++ b/src/inc/sstring.inl @@ -1257,7 +1257,7 @@ inline WCHAR *SString::GetRawUnicode() const LIMITED_METHOD_CONTRACT; SUPPORTS_DAC_HOST_ONLY; - return (WCHAR *) m_buffer; + return (WCHAR *)m_buffer; } // Private helper: @@ -1689,6 +1689,28 @@ inline WCHAR *SString::OpenUnicodeBuffer(COUNT_T countChars) SS_RETURN GetRawUnicode(); } +//---------------------------------------------------------------------------- +// Return a copy of the underlying buffer, the caller is responsible for managing +// the returned memory +//---------------------------------------------------------------------------- +inline WCHAR *SString::GetCopyOfUnicodeString() +{ + SS_CONTRACT(WCHAR*) + { + GC_NOTRIGGER; + PRECONDITION(CheckPointer(this)); + SS_POSTCONDITION(CheckPointer(buffer)); + THROWS; + } + SS_CONTRACT_END; + NewArrayHolder buffer = NULL; + + buffer = new WCHAR[GetCount() +1]; + wcscpy_s(buffer, GetCount() + 1, GetUnicode()); + + SS_RETURN buffer.Extract(); +} + //---------------------------------------------------------------------------- // Return a writeable buffer that can store 'countChars'+1 ansi characters. // Call CloseBuffer when done. diff --git a/src/inc/utilcode.h b/src/inc/utilcode.h index 78dc438ddb62..a9cb0077fccf 100644 --- a/src/inc/utilcode.h +++ b/src/inc/utilcode.h @@ -843,7 +843,8 @@ FormatMessage( HRESULT GetLibrary(LocaleID langId, HRESOURCEDLL* phInst); #ifndef DACCESS_COMPILE HRESULT LoadLibraryHelper(HRESOURCEDLL *pHInst, - __out_ecount(rcPathSize) WCHAR *rcPath, const DWORD rcPathSize); + SString& rcPath); + HRESULT LoadLibraryThrows(HRESOURCEDLL * pHInst); HRESULT LoadLibrary(HRESOURCEDLL * pHInst); HRESULT LoadResourceFile(HRESOURCEDLL * pHInst, LPCWSTR lpFileName); #endif @@ -4467,7 +4468,7 @@ BOOL GetRegistryLongValue(HKEY hKeyParent, // Parent key. long *pValue, // Put value here, if found. BOOL fReadNonVirtualizedKey); // Whether to read 64-bit hive on WOW64 -HRESULT GetCurrentModuleFileName(__out_ecount(*pcchBuffer) LPWSTR pBuffer, __inout DWORD *pcchBuffer); +HRESULT GetCurrentModuleFileName(SString& pBuffer); //***************************************************************************** // Retrieve information regarding what registered default debugger @@ -5309,7 +5310,7 @@ BOOL IsIPInModule(HMODULE_TGT hModule, PCODE ip); struct CoreClrCallbacks { typedef IExecutionEngine* (__stdcall * pfnIEE_t)(); - typedef HRESULT (__stdcall * pfnGetCORSystemDirectory_t)(LPWSTR pbuffer, DWORD cchBuffer, DWORD* pdwlength); + typedef HRESULT (__stdcall * pfnGetCORSystemDirectory_t)(SString& pbuffer); typedef void* (__stdcall * pfnGetCLRFunction_t)(LPCSTR functionName); HINSTANCE m_hmodCoreCLR; @@ -5543,8 +5544,8 @@ inline T* InterlockedCompareExchangeT( // Returns the directory for HMODULE. So, if HMODULE was for "C:\Dir1\Dir2\Filename.DLL", // then this would return "C:\Dir1\Dir2\" (note the trailing backslash). -HRESULT GetHModuleDirectory(HMODULE hMod, __out_z __out_ecount(cchPath) LPWSTR wszPath, size_t cchPath); -SString & GetHModuleDirectory(HMODULE hMod, SString &ssDir); +HRESULT GetHModuleDirectory(HMODULE hMod, SString& wszPath); +HRESULT CopySystemDirectory(const SString& pPathString, SString& pbuffer); HMODULE LoadLocalizedResourceDLLForSDK(_In_z_ LPCWSTR wzResourceDllName, _In_opt_z_ LPCWSTR modulePath=NULL, bool trySelf=true); // This is a slight variation that can be used for anything else diff --git a/src/inc/winwrap.h b/src/inc/winwrap.h index 6896accab980..89a3220c6791 100644 --- a/src/inc/winwrap.h +++ b/src/inc/winwrap.h @@ -6,9 +6,9 @@ // // This file contains wrapper functions for Win32 API's that take strings. // -// The Common Language Runtime internally uses UNICODE as the internal state -// and string format. This file will undef the mapping macros so that one -// cannot mistakingly call a method that isn't going to work. Instead, you +// The Common Language Runtime internally uses UNICODE as the internal state +// and string format. This file will undef the mapping macros so that one +// cannot mistakingly call a method that isn't going to work. Instead, you // have to call the correct wrapper API. // //***************************************************************************** @@ -16,7 +16,6 @@ #ifndef __WIN_WRAP_H__ #define __WIN_WRAP_H__ - //********** Macros. ********************************************************** #if !defined(WIN32_LEAN_AND_MEAN) #define WIN32_LEAN_AND_MEAN @@ -48,6 +47,7 @@ #include #include "registrywrapper.h" +#include "longfilepathwrappers.h" #ifdef _PREFAST_ // @@ -75,288 +75,288 @@ #undef GetBinaryType #undef GetShortPathName #undef GetLongPathName -#undef GetEnvironmentStrings -#undef FreeEnvironmentStrings -#undef FormatMessage -#undef CreateMailslot -#undef EncryptFile -#undef DecryptFile -#undef OpenRaw -#undef QueryRecoveryAgents -#undef lstrcmp -#undef lstrcmpi -#undef lstrcpyn -#undef lstrcpy -#undef lstrcat -#undef lstrlen -#undef CreateMutex -#undef OpenMutex -#undef CreateEvent -#undef OpenEvent -#undef CreateSemaphore -#undef OpenSemaphore -#undef CreateWaitableTimer -#undef OpenWaitableTimer -#undef CreateFileMapping -#undef OpenFileMapping -#undef GetLogicalDriveStrings -#undef LoadLibrary -#undef LoadLibraryEx -#undef GetModuleFileName -#undef GetModuleHandle +#undef GetEnvironmentStrings +#undef FreeEnvironmentStrings +#undef FormatMessage +#undef CreateMailslot +#undef EncryptFile +#undef DecryptFile +#undef OpenRaw +#undef QueryRecoveryAgents +#undef lstrcmp +#undef lstrcmpi +#undef lstrcpyn +#undef lstrcpy +#undef lstrcat +#undef lstrlen +#undef CreateMutex +#undef OpenMutex +#undef CreateEvent +#undef OpenEvent +#undef CreateSemaphore +#undef OpenSemaphore +#undef CreateWaitableTimer +#undef OpenWaitableTimer +#undef CreateFileMapping +#undef OpenFileMapping +#undef GetLogicalDriveStrings +#undef LoadLibrary +#undef LoadLibraryEx +#undef GetModuleFileName +#undef GetModuleHandle #undef GetModuleHandleEx -#undef CreateProcess -#undef FatalAppExit -#undef GetStartupInfo -#undef GetCommandLine -#undef GetEnvironmentVariable -#undef SetEnvironmentVariable -#undef ExpandEnvironmentStrings -#undef OutputDebugString -#undef FindResource -#undef FindResourceEx -#undef EnumResourceTypes -#undef EnumResourceNames -#undef EnumResourceLanguages -#undef BeginUpdateResource -#undef UpdateResource -#undef EndUpdateResource -#undef GlobalAddAtom -#undef GlobalFindAtom -#undef GlobalGetAtomName -#undef AddAtom -#undef FindAtom -#undef GetAtomName -#undef GetProfileInt -#undef GetProfileString -#undef WriteProfileString -#undef GetProfileSection -#undef WriteProfileSection -#undef GetPrivateProfileInt -#undef GetPrivateProfileString -#undef WritePrivateProfileString -#undef GetPrivateProfileSection -#undef WritePrivateProfileSection -#undef GetPrivateProfileSectionNames -#undef GetPrivateProfileStruct -#undef WritePrivateProfileStruct -#undef GetDriveType -#undef GetSystemDirectory -#undef GetTempPath -#undef GetTempFileName -#undef GetWindowsDirectory -#undef SetCurrentDirectory -#undef GetCurrentDirectory -#undef GetDiskFreeSpace -#undef GetDiskFreeSpaceEx -#undef CreateDirectory -#undef CreateDirectoryEx -#undef RemoveDirectory -#undef GetFullPathName -#undef DefineDosDevice -#undef QueryDosDevice -#undef CreateFile -#undef SetFileAttributes -#undef GetFileAttributes +#undef CreateProcess +#undef FatalAppExit +#undef GetStartupInfo +#undef GetCommandLine +#undef GetEnvironmentVariable +#undef SetEnvironmentVariable +#undef ExpandEnvironmentStrings +#undef OutputDebugString +#undef FindResource +#undef FindResourceEx +#undef EnumResourceTypes +#undef EnumResourceNames +#undef EnumResourceLanguages +#undef BeginUpdateResource +#undef UpdateResource +#undef EndUpdateResource +#undef GlobalAddAtom +#undef GlobalFindAtom +#undef GlobalGetAtomName +#undef AddAtom +#undef FindAtom +#undef GetAtomName +#undef GetProfileInt +#undef GetProfileString +#undef WriteProfileString +#undef GetProfileSection +#undef WriteProfileSection +#undef GetPrivateProfileInt +#undef GetPrivateProfileString +#undef WritePrivateProfileString +#undef GetPrivateProfileSection +#undef WritePrivateProfileSection +#undef GetPrivateProfileSectionNames +#undef GetPrivateProfileStruct +#undef WritePrivateProfileStruct +#undef GetDriveType +#undef GetSystemDirectory +#undef GetTempPath +#undef GetTempFileName +#undef GetWindowsDirectory +#undef SetCurrentDirectory +#undef GetCurrentDirectory +#undef GetDiskFreeSpace +#undef GetDiskFreeSpaceEx +#undef CreateDirectory +#undef CreateDirectoryEx +#undef RemoveDirectory +#undef GetFullPathName +#undef DefineDosDevice +#undef QueryDosDevice +#undef CreateFile +#undef SetFileAttributes +#undef GetFileAttributes #undef GetFileAttributesEx -#undef GetCompressedFileSize -#undef DeleteFile -#undef FindFirstFileEx -#undef FindFirstFile -#undef FindNextFile -#undef SearchPath -#undef CopyFile -#undef CopyFileEx -#undef MoveFile -#undef MoveFileEx -#undef MoveFileWithProgress -#undef CreateSymbolicLink -#undef QuerySymbolicLink -#undef CreateHardLink -#undef CreateNamedPipe -#undef GetNamedPipeHandleState -#undef CallNamedPipe -#undef WaitNamedPipe -#undef SetVolumeLabel -#undef GetVolumeInformation -#undef ClearEventLog -#undef BackupEventLog -#undef OpenEventLog -#undef RegisterEventSource -#undef OpenBackupEventLog -#undef ReadEventLog -#undef ReportEvent -#undef AccessCheckAndAuditAlarm -#undef AccessCheckByTypeAndAuditAlarm -#undef AccessCheckByTypeResultListAndAuditAlarm -#undef ObjectOpenAuditAlarm -#undef ObjectPrivilegeAuditAlarm -#undef ObjectCloseAuditAlarm -#undef ObjectDeleteAuditAlarm -#undef PrivilegedServiceAuditAlarm -#undef SetFileSecurity -#undef GetFileSecurity -#undef FindFirstChangeNotification -#undef IsBadStringPtr +#undef GetCompressedFileSize +#undef DeleteFile +#undef FindFirstFileEx +#undef FindFirstFile +#undef FindNextFile +#undef SearchPath +#undef CopyFile +#undef CopyFileEx +#undef MoveFile +#undef MoveFileEx +#undef MoveFileWithProgress +#undef CreateSymbolicLink +#undef QuerySymbolicLink +#undef CreateHardLink +#undef CreateNamedPipe +#undef GetNamedPipeHandleState +#undef CallNamedPipe +#undef WaitNamedPipe +#undef SetVolumeLabel +#undef GetVolumeInformation +#undef ClearEventLog +#undef BackupEventLog +#undef OpenEventLog +#undef RegisterEventSource +#undef OpenBackupEventLog +#undef ReadEventLog +#undef ReportEvent +#undef AccessCheckAndAuditAlarm +#undef AccessCheckByTypeAndAuditAlarm +#undef AccessCheckByTypeResultListAndAuditAlarm +#undef ObjectOpenAuditAlarm +#undef ObjectPrivilegeAuditAlarm +#undef ObjectCloseAuditAlarm +#undef ObjectDeleteAuditAlarm +#undef PrivilegedServiceAuditAlarm +#undef SetFileSecurity +#undef GetFileSecurity +#undef FindFirstChangeNotification +#undef IsBadStringPtr #undef LookupAccountSid -#undef LookupAccountName -#undef LookupPrivilegeValue -#undef LookupPrivilegeName -#undef LookupPrivilegeDisplayName -#undef BuildCommDCB -#undef BuildCommDCBAndTimeouts -#undef CommConfigDialog -#undef GetDefaultCommConfig -#undef SetDefaultCommConfig -#undef GetComputerName -#undef SetComputerName -#undef GetUserName -#undef LogonUser -#undef CreateProcessAsUser -#undef GetCurrentHwProfile -#undef GetVersionEx -#undef CreateJobObject -#undef OpenJobObject - +#undef LookupAccountName +#undef LookupPrivilegeValue +#undef LookupPrivilegeName +#undef LookupPrivilegeDisplayName +#undef BuildCommDCB +#undef BuildCommDCBAndTimeouts +#undef CommConfigDialog +#undef GetDefaultCommConfig +#undef SetDefaultCommConfig +#undef GetComputerName +#undef SetComputerName +#undef GetUserName +#undef LogonUser +#undef CreateProcessAsUser +#undef GetCurrentHwProfile +#undef GetVersionEx +#undef CreateJobObject +#undef OpenJobObject +#undef SetDllDirectory // winuser.h -#undef MAKEINTRESOURCE -#undef wvsprintf -#undef wsprintf -#undef LoadKeyboardLayout -#undef GetKeyboardLayoutName -#undef CreateDesktop -#undef OpenDesktop -#undef EnumDesktops -#undef CreateWindowStation -#undef OpenWindowStation +#undef MAKEINTRESOURCE +#undef wvsprintf +#undef wsprintf +#undef LoadKeyboardLayout +#undef GetKeyboardLayoutName +#undef CreateDesktop +#undef OpenDesktop +#undef EnumDesktops +#undef CreateWindowStation +#undef OpenWindowStation #undef EnumWindowStations #undef GetUserObjectInformation #undef SetUserObjectInformation #undef RegisterWindowMessage #undef SIZEZOOMSHOW -#undef WS_TILEDWINDOW -#undef GetMessage -#undef DispatchMessage -#undef PeekMessage +#undef WS_TILEDWINDOW +#undef GetMessage +#undef DispatchMessage +#undef PeekMessage #undef SendMessage -#undef SendMessageTimeout -#undef SendNotifyMessage -#undef SendMessageCallback -#undef BroadcastSystemMessage -#undef RegisterDeviceNotification -#undef PostMessage -#undef PostThreadMessage -#undef PostAppMessage -#undef DefWindowProc -#undef CallWindowProc -#undef RegisterClass -#undef UnregisterClass -#undef GetClassInfo -#undef RegisterClassEx -#undef GetClassInfoEx -#undef CreateWindowEx -#undef CreateWindow -#undef CreateDialogParam -#undef CreateDialogIndirectParam -#undef CreateDialog -#undef CreateDialogIndirect -#undef DialogBoxParam -#undef DialogBoxIndirectParam -#undef DialogBox -#undef DialogBoxIndirect -#undef SetDlgItemText -#undef GetDlgItemText -#undef SendDlgItemMessage -#undef DefDlgProc -#undef CallMsgFilter -#undef RegisterClipboardFormat -#undef GetClipboardFormatName -#undef CharToOem -#undef OemToChar -#undef CharToOemBuff -#undef OemToCharBuff -#undef CharUpper -#undef CharUpperBuff -#undef CharLower -#undef CharLowerBuff -#undef CharNext -#undef IsCharAlpha -#undef IsCharAlphaNumeric -#undef IsCharUpper -#undef IsCharLower -#undef GetKeyNameText -#undef VkKeyScan -#undef VkKeyScanEx -#undef MapVirtualKey -#undef MapVirtualKeyEx -#undef LoadAccelerators -#undef CreateAcceleratorTable -#undef CopyAcceleratorTable -#undef TranslateAccelerator -#undef LoadMenu -#undef LoadMenuIndirect -#undef ChangeMenu -#undef GetMenuString -#undef InsertMenu -#undef AppendMenu -#undef ModifyMenu -#undef InsertMenuItem -#undef GetMenuItemInfo -#undef SetMenuItemInfo -#undef DrawText -#undef DrawTextEx -#undef GrayString -#undef DrawState -#undef TabbedTextOut -#undef GetTabbedTextExtent -#undef SetProp -#undef GetProp -#undef RemoveProp -#undef EnumPropsEx -#undef EnumProps -#undef SetWindowText -#undef GetWindowText -#undef GetWindowTextLength -#undef MessageBox -#undef MessageBoxEx -#undef MessageBoxIndirect -#undef COLOR_3DSHADOW -#undef GetWindowLong -#undef SetWindowLong -#undef GetClassLong -#undef SetClassLong -#undef FindWindow -#undef FindWindowEx -#undef GetClassName -#undef SetWindowsHook -#undef SetWindowsHook -#undef SetWindowsHookEx -#undef MFT_OWNERDRAW -#undef LoadBitmap -#undef LoadCursor -#undef LoadCursorFromFile -#undef LoadIcon -#undef LoadImage -#undef LoadString -#undef IsDialogMessage -#undef DlgDirList -#undef DlgDirSelectEx -#undef DlgDirListComboBox -#undef DlgDirSelectComboBoxEx -#undef DefFrameProc -#undef DefMDIChildProc -#undef CreateMDIWindow -#undef WinHelp -#undef ChangeDisplaySettings -#undef ChangeDisplaySettingsEx -#undef EnumDisplaySettings -#undef EnumDisplayDevices -#undef SystemParametersInfo -#undef GetMonitorInfo -#undef GetWindowModuleFileName -#undef RealGetWindowClass +#undef SendMessageTimeout +#undef SendNotifyMessage +#undef SendMessageCallback +#undef BroadcastSystemMessage +#undef RegisterDeviceNotification +#undef PostMessage +#undef PostThreadMessage +#undef PostAppMessage +#undef DefWindowProc +#undef CallWindowProc +#undef RegisterClass +#undef UnregisterClass +#undef GetClassInfo +#undef RegisterClassEx +#undef GetClassInfoEx +#undef CreateWindowEx +#undef CreateWindow +#undef CreateDialogParam +#undef CreateDialogIndirectParam +#undef CreateDialog +#undef CreateDialogIndirect +#undef DialogBoxParam +#undef DialogBoxIndirectParam +#undef DialogBox +#undef DialogBoxIndirect +#undef SetDlgItemText +#undef GetDlgItemText +#undef SendDlgItemMessage +#undef DefDlgProc +#undef CallMsgFilter +#undef RegisterClipboardFormat +#undef GetClipboardFormatName +#undef CharToOem +#undef OemToChar +#undef CharToOemBuff +#undef OemToCharBuff +#undef CharUpper +#undef CharUpperBuff +#undef CharLower +#undef CharLowerBuff +#undef CharNext +#undef IsCharAlpha +#undef IsCharAlphaNumeric +#undef IsCharUpper +#undef IsCharLower +#undef GetKeyNameText +#undef VkKeyScan +#undef VkKeyScanEx +#undef MapVirtualKey +#undef MapVirtualKeyEx +#undef LoadAccelerators +#undef CreateAcceleratorTable +#undef CopyAcceleratorTable +#undef TranslateAccelerator +#undef LoadMenu +#undef LoadMenuIndirect +#undef ChangeMenu +#undef GetMenuString +#undef InsertMenu +#undef AppendMenu +#undef ModifyMenu +#undef InsertMenuItem +#undef GetMenuItemInfo +#undef SetMenuItemInfo +#undef DrawText +#undef DrawTextEx +#undef GrayString +#undef DrawState +#undef TabbedTextOut +#undef GetTabbedTextExtent +#undef SetProp +#undef GetProp +#undef RemoveProp +#undef EnumPropsEx +#undef EnumProps +#undef SetWindowText +#undef GetWindowText +#undef GetWindowTextLength +#undef MessageBox +#undef MessageBoxEx +#undef MessageBoxIndirect +#undef COLOR_3DSHADOW +#undef GetWindowLong +#undef SetWindowLong +#undef GetClassLong +#undef SetClassLong +#undef FindWindow +#undef FindWindowEx +#undef GetClassName +#undef SetWindowsHook +#undef SetWindowsHook +#undef SetWindowsHookEx +#undef MFT_OWNERDRAW +#undef LoadBitmap +#undef LoadCursor +#undef LoadCursorFromFile +#undef LoadIcon +#undef LoadImage +#undef LoadString +#undef IsDialogMessage +#undef DlgDirList +#undef DlgDirSelectEx +#undef DlgDirListComboBox +#undef DlgDirSelectComboBoxEx +#undef DefFrameProc +#undef DefMDIChildProc +#undef CreateMDIWindow +#undef WinHelp +#undef ChangeDisplaySettings +#undef ChangeDisplaySettingsEx +#undef EnumDisplaySettings +#undef EnumDisplayDevices +#undef SystemParametersInfo +#undef GetMonitorInfo +#undef GetWindowModuleFileName +#undef RealGetWindowClass #undef GetAltTabInfo #undef GetCalendarInfo #undef GetDateFormat @@ -369,10 +369,8 @@ // Win32 Fusion API's #undef QueryActCtxW - #endif // !defined(__TODO_PORT_TO_WRAPPERS__) - // // NT supports the wide entry points. So we redefine the wrappers right back // to the *W entry points as macros. This way no client code needs a wrapper on NT. @@ -385,9 +383,6 @@ #define WszCryptVerifySignature CryptVerifySignatureW // winbase.h -#define WszGetBinaryType GetBinaryTypeW -#define WszGetShortPathName GetShortPathNameW -#define WszGetLongPathName GetLongPathNameW #define WszGetEnvironmentStrings GetEnvironmentStringsW #define WszFreeEnvironmentStrings FreeEnvironmentStringsW #ifndef USE_FORMATMESSAGE_WRAPPER @@ -396,8 +391,6 @@ #define WszFormatMessage CCompRC::FormatMessage #endif #define WszCreateMailslot CreateMailslotW -#define WszEncryptFile EncryptFileW -#define WszDecryptFile DecryptFileW #define WszOpenRaw OpenRawW #define WszQueryRecoveryAgents QueryRecoveryAgentsW #define Wszlstrcmp lstrcmpW @@ -413,16 +406,11 @@ #define WszCreateFileMapping CreateFileMappingW #define WszOpenFileMapping OpenFileMappingW #define WszGetLogicalDriveStrings GetLogicalDriveStringsW -#define WszLoadLibrary(_filename) LoadLibraryExW((_filename), NULL, 0) -#define WszLoadLibraryEx LoadLibraryExW -#define WszSetDllDirectory SetDllDirectoryW -#define WszGetModuleFileName GetModuleFileNameW #define WszGetModuleHandle GetModuleHandleW #define WszGetModuleHandleEx GetModuleHandleExW #define WszFatalAppExit FatalAppExitW #define WszGetStartupInfo GetStartupInfoW #define WszGetCommandLine GetCommandLineW -#define WszGetEnvironmentVariable GetEnvironmentVariableW #define WszSetEnvironmentVariable SetEnvironmentVariableW #define WszExpandEnvironmentStrings ExpandEnvironmentStringsW #define WszOutputDebugString OutputDebugStringW @@ -455,37 +443,12 @@ #define WszWritePrivateProfileStruct WritePrivateProfileStructW #define WszGetDriveType GetDriveTypeW #define WszGetSystemDirectory GetSystemDirectoryW -#define WszGetTempPath GetTempPathW -#define WszGetTempFileName GetTempFileNameW #define WszGetWindowsDirectory GetWindowsDirectoryW -#define WszSetCurrentDirectory SetCurrentDirectoryW -#define WszGetCurrentDirectory GetCurrentDirectoryW #define WszGetDiskFreeSpace GetDiskFreeSpaceW #define WszGetDiskFreeSpaceEx GetDiskFreeSpaceExW -#define WszCreateDirectory CreateDirectoryW -#define WszCreateDirectoryEx CreateDirectoryExW -#define WszRemoveDirectory RemoveDirectoryW -#define WszGetFullPathName GetFullPathNameW #define WszDefineDosDevice DefineDosDeviceW #define WszQueryDosDevice QueryDosDeviceW -#define WszCreateFile CreateFileW -#define WszSetFileAttributes SetFileAttributesW -#define WszGetFileAttributes GetFileAttributesW -#define WszGetFileAttributesEx GetFileAttributesExW -#define WszGetCompressedFileSize GetCompressedFileSizeW -#define WszDeleteFile DeleteFileW -#define WszFindFirstFileEx FindFirstFileExW -#define WszFindFirstFile FindFirstFileW -#define WszFindNextFile FindNextFileW -#define WszSearchPath SearchPathW -#define WszCopyFile CopyFileW -#define WszCopyFileEx CopyFileExW -#define WszMoveFile MoveFileW -#define WszMoveFileEx MoveFileExW -#define WszMoveFileWithProgress MoveFileWithProgressW -#define WszCreateSymbolicLink CreateSymbolicLinkW #define WszQuerySymbolicLink QuerySymbolicLinkW -#define WszCreateHardLink CreateHardLinkW #define WszCreateNamedPipe CreateNamedPipeW #define WszGetNamedPipeHandleState GetNamedPipeHandleStateW #define WszCallNamedPipe CallNamedPipeW @@ -507,9 +470,6 @@ #define WszObjectCloseAuditAlarm ObjectCloseAuditAlarmW #define WszObjectDeleteAuditAlarm ObjectDeleteAuditAlarmW #define WszPrivilegedServiceAuditAlarm PrivilegedServiceAuditAlarmW -#define WszSetFileSecurity SetFileSecurityW -#define WszGetFileSecurity GetFileSecurityW -#define WszFindFirstChangeNotification FindFirstChangeNotificationW #define WszIsBadStringPtr __DO_NOT_USE__WszIsBadStringPtr__ #if !defined(FEATURE_CORESYSTEM) || defined(CROSSGEN_COMPILE) #define WszLookupAccountSid LookupAccountSidW @@ -678,7 +638,6 @@ #define WszRegQueryValueExTrue RegQueryValueExW #define WszRegQueryStringValueEx RegQueryValueExW - #ifndef FEATURE_CORECLR #define WszRegDeleteKey RegDeleteKeyW #define WszRegCreateKeyEx ClrRegCreateKeyEx @@ -723,13 +682,66 @@ #define _T(str) W(str) #endif - // on win98 and higher #define Wszlstrlen lstrlenW #define Wszlstrcpy lstrcpyW #define Wszlstrcat lstrcatW - +//File and Directory Functions which need special handling for LongFile Names +//Note only the functions which are currently used are defined +#define WszLoadLibrary LoadLibraryExWrapper +#define WszLoadLibraryEx LoadLibraryExWrapper +#define WszCreateFile CreateFileWrapper +#define WszSetFileAttributes SetFileAttributesWrapper +#define WszGetFileAttributes GetFileAttributesWrapper +#define WszGetFileAttributesEx GetFileAttributesExWrapper +#define WszDeleteFile DeleteFileWrapper +#define WszFindFirstFileEx FindFirstFileExWrapper +#define WszFindNextFile FindNextFileW +#define WszCopyFile CopyFileWrapper +#define WszCopyFileEx CopyFileExWrapper +#define WszMoveFile MoveFileWrapper +#define WszMoveFileEx MoveFileExWrapper +#define WszCreateDirectory CreateDirectoryWrapper +#define WszRemoveDirectory RemoveDirectoryWrapper +#define WszCreateHardLink CreateHardLinkWrapper + +//Can not use extended syntax +#define WszGetFullPathName GetFullPathNameW + +//Long Files will not work on these till redstone +#define WszGetCurrentDirectory GetCurrentDirectoryWrapper +#define WszGetTempFileName GetTempFileNameWrapper +#define WszGetTempPath GetTempPathWrapper + +//APIS which have a buffer as an out parameter +#define WszGetEnvironmentVariable GetEnvironmentVariableWrapper +#define WszSearchPath SearchPathWrapper +#define WszGetShortPathName GetShortPathNameWrapper +#define WszGetLongPathName GetLongPathNameWrapper +#define WszGetModuleFileName GetModuleFileNameWrapper + +//NOTE: IF the following API's are enabled ensure that they can work with LongFile Names +//See the usage and implementation of above API's +// +//#define WszGetCompressedFileSize GetCompressedFileSizeW +//#define WszMoveFileWithProgress MoveFileWithProgressW +//#define WszEncryptFile EncryptFileW +//#define WszDecryptFile DecryptFileW +//#define WszSetFileSecurity SetFileSecurityW +//#define WszGetFileSecurity GetFileSecurityW +//#define WszFindFirstChangeNotification FindFirstChangeNotificationW +//#define WszSetDllDirectory SetDllDirectoryW +//#define WszSetCurrentDirectory SetCurrentDirectoryW +//#define WszCreateDirectoryEx CreateDirectoryExW +//#define WszCreateSymbolicLink CreateSymbolicLinkW +//#define WszGetBinaryType GetBinaryTypeWrapper //Coresys does not seem to have this API + +#if FEATURE_PAL +#define WszFindFirstFile FindFirstFileW +#else +#define WszFindFirstFile(_lpFileName_, _lpFindData_) FindFirstFileExWrapper(_lpFileName_, FindExInfoStandard, _lpFindData_, FindExSearchNameMatch, NULL, 0) +#endif //FEATURE_PAL //***************************************************************************** // Prototypes for API's. //***************************************************************************** @@ -746,7 +758,7 @@ inline DWORD GetMaxDBCSCharByteSize() EnsureCharSetInfoInitialized(); _ASSERTE(g_dwMaxDBCSCharByteSize != 0); - return (g_dwMaxDBCSCharByteSize); + return (g_dwMaxDBCSCharByteSize); #else // FEATURE_PAL return 3; #endif // FEATURE_PAL @@ -758,7 +770,7 @@ BOOL RunningInteractive(); #define RunningInteractive() FALSE #endif // !FEATURE_PAL -// Determines if the process is running as Local System or as a service. Note that this function uses the +// Determines if the process is running as Local System or as a service. Note that this function uses the // process' identity and not the thread's (if the thread is impersonating). // // If the function succeeds, it returns ERROR_SUCCESS, else it returns the error code returned by GetLastError() @@ -768,7 +780,6 @@ DWORD RunningAsLocalSystemOrService(OUT BOOL& fIsLocalSystemOrService); #define Wsz_mbstowcs(szOut, szIn, iSize) WszMultiByteToWideChar(CP_ACP, 0, szIn, -1, szOut, iSize) #endif - #ifndef Wsz_wcstombs #define Wsz_wcstombs(szOut, szIn, iSize) WszWideCharToMultiByte(CP_ACP, 0, szIn, -1, szOut, iSize, 0, 0) #endif @@ -815,11 +826,11 @@ DWORD WszGetProcessHandleCount(); #define InterlockedOr _InterlockedOr // -// There is no _InterlockedCompareExchangePointer intrinsic in VC++ for x86. +// There is no _InterlockedCompareExchangePointer intrinsic in VC++ for x86. // winbase.h #defines InterlockedCompareExchangePointer as __InlineInterlockedCompareExchangePointer, // which calls the Win32 InterlockedCompareExchange, not the intrinsic _InterlockedCompareExchange. // We want the intrinsic, so we #undef the Windows version of this API, and define our own. -// +// #ifdef InterlockedCompareExchangePointer #undef InterlockedCompareExchangePointer #endif @@ -850,7 +861,7 @@ InterlockedCompareExchangePointer ( #if defined(_X86_) & !defined(InterlockedIncrement64) -// Interlockedxxx64 that do not have intrinsics are only supported on Windows Server 2003 +// Interlockedxxx64 that do not have intrinsics are only supported on Windows Server 2003 // or higher for X86 so define our own portable implementation #undef InterlockedIncrement64 @@ -918,7 +929,7 @@ __forceinline LONGLONG __InterlockedExchangeAdd64(LONGLONG volatile * Addend, LO // // RtlVerifyVersionInfo() type mask bits -// Making our copy of type mask bits as the original +// Making our copy of type mask bits as the original // macro name are redefined in public\internal\NDP\inc\product_version.h // // @@ -970,11 +981,11 @@ inline int LateboundMessageBoxW(HWND hWnd, #if defined(FEATURE_CORESYSTEM) && !defined(CROSSGEN_COMPILE) // Some CoreSystem OSs will support MessageBoxW via an extension library. The following technique is what // was recommeded by Philippe Joubert from the CoreSystem team. - HMODULE hGuiExtModule = LoadLibraryExW(W("ext-ms-win-ntuser-gui-l1"), NULL, 0); + HMODULE hGuiExtModule = WszLoadLibrary(W("ext-ms-win-ntuser-gui-l1"), NULL, 0); #else // Outside of CoreSystem, MessageBoxW lives in User32 HMODULE hGuiExtModule = WszLoadLibrary(W("user32")); -#endif +#endif if (hGuiExtModule) { int result = IDCANCEL; diff --git a/src/md/compiler/disp.cpp b/src/md/compiler/disp.cpp index 742cf1cfbc92..0f0bf88e6db2 100644 --- a/src/md/compiler/disp.cpp +++ b/src/md/compiler/disp.cpp @@ -78,7 +78,9 @@ Disp::DefineScope( { #ifdef FEATURE_METADATA_EMIT HRESULT hr = S_OK; - + PathString szFileName(PathString::Literal, W("file:")); + PathString szFileNameSuffix; + DWORD len; BEGIN_ENTRYPOINT_NOTHROW; RegMeta *pMeta = 0; @@ -111,13 +113,13 @@ Disp::DefineScope( #ifdef ENC_DELTA_HACK // Testers need this flag for their tests. - const int prefixLen = 5; - WCHAR szFileName[256 + prefixLen]; - wcscpy_s(szFileName, 256 + prefixLen, W("file:")); - WCHAR *szFileNamePrefix = szFileName + prefixLen; - DWORD cchFileNamePrefix = (DWORD) ((sizeof(szFileName)/sizeof(WCHAR))-prefixLen); - DWORD len = WszGetEnvironmentVariable(W("COMP_ENC_OPENSCOPE"), szFileNamePrefix, cchFileNamePrefix); - _ASSERTE(len < cchFileNamePrefix); + + EX_TRY{ + len = WszGetEnvironmentVariable(W("COMP_ENC_OPENSCOPE"), szFileNameSuffix); + szFileName.Append(szFileNameSuffix); + } + EX_CATCH_HRESULT(hr); + if (len > 0) { // _ASSERTE(!"ENC override on DefineScope"); @@ -150,7 +152,7 @@ Disp::DefineScope( BOOL fResult = SUCCEEDED(hr); // print out a message so people know what's happening printf("Defining scope for EnC using %S %s\n", - szFileName+prefixLen, fResult ? "succeeded" : "failed"); + szFileNameSuffix, fResult ? "succeeded" : "failed"); goto ErrExit; } diff --git a/src/md/compiler/mdutil.cpp b/src/md/compiler/mdutil.cpp index 691cd793c977..2e01258beade 100644 --- a/src/md/compiler/mdutil.cpp +++ b/src/md/compiler/mdutil.cpp @@ -473,20 +473,18 @@ HRESULT CORPATHService::GetClassFromCORPath( IUnknown **ppIScope, // [OUT] Scope in which the TypeRef resolves. mdTypeDef *ptd) // [OUT] typedef corresponding the typeref { - WCHAR rcCorPath[1024] = {W('\0')}; // The CORPATH environment variable. - LPWSTR szCorPath = rcCorPath; // Used to parse CORPATH. + PathString rcCorPath; // The CORPATH environment variable. + LPWSTR szCorPath; // Used to parse CORPATH. int iLen; // Length of the directory. - WCHAR rcCorDir[_MAX_PATH]; // Buffer for the directory. + PathString rcCorDir; // Buffer for the directory. WCHAR *temp; // Used as a parsing temp. WCHAR *szSemiCol; // Get the CORPATH environment variable. - if (WszGetEnvironmentVariable(W("CORPATH"), rcCorPath, - sizeof(rcCorPath) / sizeof(WCHAR))) + if (WszGetEnvironmentVariable(W("CORPATH"), rcCorPath)) { - // Force nul termination. - rcCorPath[lengthof(rcCorPath)-1] = 0; - + NewArrayHolder szCorPathHolder = rcCorPath.GetCopyOfUnicodeString(); + szCorPath = szCorPathHolder.GetValue(); // Try each directory in the path. for(;*szCorPath != W('\0');) { @@ -502,12 +500,11 @@ HRESULT CORPATHService::GetClassFromCORPath( temp = szCorPath; szCorPath += wcslen(temp); } - if ((iLen = (int)wcslen(temp)) >= _MAX_PATH) - continue; - wcscpy_s(rcCorDir, COUNTOF(rcCorDir), temp); + + rcCorDir.Set(temp); // Check if we can find the class in the directory. - if (CORPATHService::GetClassFromDir(wzClassname, rcCorDir, iLen, tr, pCommon, riid, ppIScope, ptd) == S_OK) + if (CORPATHService::GetClassFromDir(wzClassname, rcCorDir, tr, pCommon, riid, ppIScope, ptd) == S_OK) return S_OK; } } @@ -516,24 +513,20 @@ HRESULT CORPATHService::GetClassFromCORPath( // some headaches right now, so we'll give them a little time to transition. // Try the current directory first. - if ((iLen = WszGetCurrentDirectory(_MAX_PATH, rcCorDir)) > 0 && - CORPATHService::GetClassFromDir(wzClassname, rcCorDir, iLen, tr, pCommon, riid, ppIScope, ptd) == S_OK) + if ((iLen = WszGetCurrentDirectory( rcCorDir)) > 0 && + CORPATHService::GetClassFromDir(wzClassname, rcCorDir, tr, pCommon, riid, ppIScope, ptd) == S_OK) { return S_OK; } - + // Try the app directory next. - if ((iLen = WszGetModuleFileName(NULL, rcCorDir, _MAX_PATH)) > 0) + if ((iLen = WszGetModuleFileName(NULL, rcCorDir)) > 0) { - // Back up to the last path separator. - while (--iLen >= 0 && rcCorDir[iLen] != W('\\') && rcCorDir[iLen] != W('/')) - { - } - if (iLen > 0 && - CORPATHService::GetClassFromDir( + + if(SUCCEEDED(CopySystemDirectory(rcCorDir, rcCorDir)) && + CORPATHService::GetClassFromDir( wzClassname, rcCorDir, - iLen, tr, pCommon, riid, @@ -550,15 +543,11 @@ HRESULT CORPATHService::GetClassFromCORPath( //***************************************************************************** // This is used in conjunction with GetClassFromCORPath. See it for details -// of the algorithm. One thing to note is that the dir passed here must be -// _MAX_PATH size and will be written to by this routine. This routine will -// frequently leave junk at the end of the directory string and dir[iLen] may -// not be '\0' on return. +// of the algorithm. //***************************************************************************** HRESULT CORPATHService::GetClassFromDir( __in __in_z LPWSTR wzClassname, // Fully qualified class name. - __in __in_z LPWSTR dir, // Directory to try. - int iLen, // Length of the directory. + __in SString& directory, // Directory to try. at most appended with a '\\' mdTypeRef tr, // TypeRef to resolve. IMetaModelCommon *pCommon, // Scope in which the TypeRef is defined. REFIID riid, @@ -569,58 +558,48 @@ HRESULT CORPATHService::GetClassFromDir( int iTmp; bool bContinue; // Flag to check if the for loop should end. LPWSTR wzSaveClassname = NULL; // Saved offset into the class name string. - int iSaveLen = 0; // Saved length of the dir string. - - PREFIX_ASSUME(iLen >= 0); // Process the class name appending each segment of the name to the // directory until we find a DLL. + PathString dir; + if (!directory.EndsWith(DIRECTORY_SEPARATOR_CHAR_W)) + { + directory.Append(DIRECTORY_SEPARATOR_CHAR_W); + } + for(;;) { bContinue = false; + dir.Set(directory); + if ((temp = wcschr(wzClassname, NAMESPACE_SEPARATOR_WCHAR)) != NULL) { - iTmp = (int) (temp - wzClassname); - // Check for buffer overflow with correct integer overflow check. - // "if (iLen + 5 + iTmp >= _MAX_PATH)" - if (ovadd_ge(iLen, iTmp, (_MAX_PATH - 5))) - break; + *temp = W('\0'); //terminate with null so that it can be appended + dir.Append(wzClassname); + *temp = NAMESPACE_SEPARATOR_WCHAR; //recover the '.' - // Append the next segment from the class spec to the directory. - dir[iLen++] = W('\\'); - wcsncpy_s(dir+iLen, iTmp+1, wzClassname, iTmp); - iLen += iTmp; - dir[iLen] = W('\0'); wzClassname = temp+1; - // Check if a directory by this name exists. DWORD iAttrs = WszGetFileAttributes(dir); if (iAttrs != 0xffffffff && (iAttrs & FILE_ATTRIBUTE_DIRECTORY)) { // Next element in the class spec. bContinue = true; - iSaveLen = iLen; wzSaveClassname = wzClassname; } } else { - iTmp = (int)wcslen(wzClassname); - // Check for buffer overflow with correct integer overflow check. - // "if (iLen + 5 + iTmp >= _MAX_PATH)" - if (ovadd_ge(iLen, iTmp, (_MAX_PATH - 5))) - break; - dir[iLen++] = W('\\'); - wcscpy_s(dir+iLen, iTmp+1, wzClassname); + dir.Append(wzClassname); // Advance past the class name. - iLen += iTmp; + iTmp = (int)wcslen(wzClassname); wzClassname += iTmp; } // Try to load the image. - wcscpy_s(dir+iLen, 5, W(".dll")); - + dir.Append(W(".dll")); + // OpenScope given the dll name and make sure that the class is defined in the module. if ( SUCCEEDED( CORPATHService::FindTypeDef(dir, tr, pCommon, riid, ppIScope, ptd) ) ) { @@ -632,21 +611,25 @@ HRESULT CORPATHService::GetClassFromDir( { // Find the length of the next class name element. if ((temp = wcschr(wzClassname, NAMESPACE_SEPARATOR_WCHAR)) == NULL) + { temp = wzClassname + wcslen(wzClassname); - - iTmp = (int) (temp - wzClassname); - // Check for buffer overflow. - if ((iLen + 5 + iTmp) >= _MAX_PATH) - break; + } // Tack on ".element.dll" - dir[iLen++] = W('.'); - wcsncpy_s(dir+iLen, iTmp+1, wzClassname, iTmp); - iLen += iTmp; - + SString::Iterator iter = dir.End(); + BOOL findperiod = dir.FindBack(iter, NAMESPACE_SEPARATOR_WCHAR); + _ASSERTE(findperiod); + iter++; + dir.Truncate(iter); + + WCHAR save = *temp; + *temp = W('\0'); + dir.Append(wzClassname); //element + *temp = save; + // Try to load the image. - wcscpy_s(dir+iLen, 5, W(".dll")); - + dir.Append(W(".dll")); + // OpenScope given the dll name and make sure that the class is defined in the module. if ( SUCCEEDED( CORPATHService::FindTypeDef(dir, tr, pCommon, riid, ppIScope, ptd) ) ) { @@ -660,7 +643,7 @@ HRESULT CORPATHService::GetClassFromDir( } if (bContinue) { - iLen = iSaveLen; + wzClassname = wzSaveClassname; } else @@ -679,7 +662,7 @@ HRESULT CORPATHService::GetClassFromDir( // //************************************************************* HRESULT CORPATHService::FindTypeDef( - __in __in_z LPWSTR wzModule, // name of the module that we are going to open + __in __in_z LPCWSTR wzModule, // name of the module that we are going to open mdTypeRef tr, // TypeRef to resolve. IMetaModelCommon * pCommon, // Scope in which the TypeRef is defined. REFIID riid, diff --git a/src/md/compiler/mdutil.h b/src/md/compiler/mdutil.h index eda2bca877bf..58cdbf108a0f 100644 --- a/src/md/compiler/mdutil.h +++ b/src/md/compiler/mdutil.h @@ -43,9 +43,8 @@ class CORPATHService mdTypeDef *ptd); // [OUT] typedef corresponding the typeref static HRESULT GetClassFromDir( - __in __in_z LPWSTR wzClassname, // Fully qualified class name. - __in __in_z LPWSTR dir, // Directory to try. - int iLen, // Length of the directory. + __in __in_z LPWSTR wzClassname, // Fully qualified class name. + __in SString& dir, // Directory to try. mdTypeRef tr, // TypeRef to resolve. IMetaModelCommon *pCommon, // Scope in which the TypeRef is defined. REFIID riid, @@ -53,7 +52,7 @@ class CORPATHService mdTypeDef *ptd); // [OUT] typedef static HRESULT FindTypeDef( - __in __in_z LPWSTR wzModule, // name of the module that we are going to open + __in __in_z LPCWSTR wzModule, // name of the module that we are going to open mdTypeRef tr, // TypeRef to resolve. IMetaModelCommon *pCommon, // Scope in which the TypeRef is defined. REFIID riid, diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h index cb39a885a56a..b5f62742a4b2 100644 --- a/src/pal/inc/pal.h +++ b/src/pal/inc/pal.h @@ -1172,6 +1172,19 @@ typedef enum _GET_FILEEX_INFO_LEVELS { GetFileExInfoStandard } GET_FILEEX_INFO_LEVELS; +typedef enum _FINDEX_INFO_LEVELS { + FindExInfoStandard, + FindExInfoBasic, + FindExInfoMaxInfoLevel +} FINDEX_INFO_LEVELS; + +typedef enum _FINDEX_SEARCH_OPS { + FindExSearchNameMatch, + FindExSearchLimitToDirectories, + FindExSearchLimitToDevices, + FindExSearchMaxSearchOp +} FINDEX_SEARCH_OPS; + typedef struct _WIN32_FILE_ATTRIBUTE_DATA { DWORD dwFileAttributes; FILETIME ftCreationTime; diff --git a/src/pal/src/loader/module.cpp b/src/pal/src/loader/module.cpp index e380e2ed0e76..d05e27222786 100644 --- a/src/pal/src/loader/module.cpp +++ b/src/pal/src/loader/module.cpp @@ -541,6 +541,7 @@ GetModuleFileNameW( if (name_length >= (INT)nSize) { TRACE("Buffer too small (%u) to copy module's file name (%u).\n", nSize, name_length); + retval = (INT)nSize; SetLastError(ERROR_INSUFFICIENT_BUFFER); goto done; } diff --git a/src/strongname/api/strongnamecoreclr.cpp b/src/strongname/api/strongnamecoreclr.cpp index 1b81ff625260..1ed7f0e10cbb 100644 --- a/src/strongname/api/strongnamecoreclr.cpp +++ b/src/strongname/api/strongnamecoreclr.cpp @@ -47,10 +47,10 @@ IExecutionEngine * __stdcall SnIEE() return ApiShim("IEE")(); } -STDAPI SnGetCorSystemDirectory(_In_z_ LPWSTR pbuffer, DWORD cchBuffer, DWORD* dwLength) +STDAPI SnGetCorSystemDirectory(SString& pbuffer) { - typedef HRESULT (__stdcall *GetCorSystemDirectoryFn_t)(LPWSTR, DWORD, DWORD *); - return ApiShim("GetCORSystemDirectory")(pbuffer, cchBuffer, dwLength); + typedef HRESULT (__stdcall *GetCorSystemDirectoryFn_t)(SString&); + return ApiShim("GetCORSystemDirectory")(pbuffer); } // diff --git a/src/tools/crossgen/crossgen.cpp b/src/tools/crossgen/crossgen.cpp index 1d136b684f49..93d52661fb27 100644 --- a/src/tools/crossgen/crossgen.cpp +++ b/src/tools/crossgen/crossgen.cpp @@ -282,7 +282,7 @@ bool StringEndsWith(LPCWSTR pwzString, LPCWSTR pwzCandidate) // When using the Phone binding model (TrustedPlatformAssemblies), automatically // detect which path mscorlib.[ni.]dll lies in. // -bool ComputeMscorlibPathFromTrustedPlatformAssemblies(_In_z_ LPWSTR pwzMscorlibPath, DWORD cbMscorlibPath, LPCWSTR pwzTrustedPlatformAssemblies) +bool ComputeMscorlibPathFromTrustedPlatformAssemblies(SString& pwzMscorlibPath, LPCWSTR pwzTrustedPlatformAssemblies) { LPWSTR wszTrustedPathCopy = new WCHAR[wcslen(pwzTrustedPlatformAssemblies) + 1]; wcscpy_s(wszTrustedPathCopy, wcslen(pwzTrustedPlatformAssemblies) + 1, pwzTrustedPlatformAssemblies); @@ -302,18 +302,17 @@ bool ComputeMscorlibPathFromTrustedPlatformAssemblies(_In_z_ LPWSTR pwzMscorlibP if (StringEndsWith(wszSingleTrustedPath, DIRECTORY_SEPARATOR_STR_W W("mscorlib.dll")) || StringEndsWith(wszSingleTrustedPath, DIRECTORY_SEPARATOR_STR_W W("mscorlib.ni.dll"))) { - wcscpy_s(pwzMscorlibPath, cbMscorlibPath, wszSingleTrustedPath); + pwzMscorlibPath.Set(wszSingleTrustedPath); + SString::Iterator pwzSeparator = pwzMscorlibPath.End(); + bool retval = true; - LPWSTR pwzSeparator = wcsrchr(pwzMscorlibPath, DIRECTORY_SEPARATOR_CHAR_W); - if (pwzSeparator == NULL) + if (!SUCCEEDED(CopySystemDirectory(pwzMscorlibPath, pwzMscorlibPath))) { - delete [] wszTrustedPathCopy; - return false; + retval = false; } - pwzSeparator[1] = W('\0'); // after '\' delete [] wszTrustedPathCopy; - return true; + return retval; } wszSingleTrustedPath = wcstok_s(NULL, PATH_SEPARATOR_STR_W, &context); @@ -961,7 +960,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) PrintLogoHelper(); } - WCHAR wzTrustedPathRoot[MAX_LONGPATH]; + PathString wzTrustedPathRoot; #ifdef FEATURE_CORECLR SString ssTPAList; @@ -985,9 +984,9 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) if (pwzTrustedPlatformAssemblies != nullptr) { - if (ComputeMscorlibPathFromTrustedPlatformAssemblies(wzTrustedPathRoot, MAX_LONGPATH, pwzTrustedPlatformAssemblies)) + if (ComputeMscorlibPathFromTrustedPlatformAssemblies(wzTrustedPathRoot, pwzTrustedPlatformAssemblies)) { - pwzPlatformAssembliesPaths = wzTrustedPathRoot; + pwzPlatformAssembliesPaths = wzTrustedPathRoot.GetUnicode(); SetMscorlibPath(pwzPlatformAssembliesPaths); } } @@ -995,21 +994,23 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) if (pwzPlatformAssembliesPaths == NULL) { - if (!WszGetModuleFileName(NULL, wzTrustedPathRoot, MAX_LONGPATH)) + if (!WszGetModuleFileName(NULL, wzTrustedPathRoot)) { ERROR_WIN32(W("Error: GetModuleFileName failed (%d)\n"), GetLastError()); exit(CLR_INIT_ERROR); } - - wchar_t* pszSep = wcsrchr(wzTrustedPathRoot, DIRECTORY_SEPARATOR_CHAR_W); - if (pszSep == NULL) + + if (SUCCEEDED(CopySystemDirectory(wzTrustedPathRoot, wzTrustedPathRoot))) + { + pwzPlatformAssembliesPaths = wzTrustedPathRoot.GetUnicode(); + } + else { ERROR_HR(W("Error: wcsrchr returned NULL; GetModuleFileName must have given us something bad\n"), E_UNEXPECTED); exit(CLR_INIT_ERROR); } - *pszSep = '\0'; - - pwzPlatformAssembliesPaths = wzTrustedPathRoot; + + } // Initialize the logger diff --git a/src/utilcode/CMakeLists.txt b/src/utilcode/CMakeLists.txt index 117d4790f072..9aeb243790a2 100644 --- a/src/utilcode/CMakeLists.txt +++ b/src/utilcode/CMakeLists.txt @@ -60,6 +60,7 @@ set(UTILCODE_COMMON_SOURCES debug.cpp pedecoder.cpp winfix.cpp + longfilepathwrappers.cpp ) # These source file do not yet compile on Linux. diff --git a/src/utilcode/UtilCode.vcproj b/src/utilcode/UtilCode.vcproj index 3f147725b876..d43c2a02c38c 100644 --- a/src/utilcode/UtilCode.vcproj +++ b/src/utilcode/UtilCode.vcproj @@ -600,6 +600,10 @@ RelativePath=".\winfix.cpp" > + + diff --git a/src/utilcode/UtilCode.vcxproj b/src/utilcode/UtilCode.vcxproj index d0926fd8c692..b0cca8dd7013 100644 --- a/src/utilcode/UtilCode.vcxproj +++ b/src/utilcode/UtilCode.vcxproj @@ -435,6 +435,7 @@ + @@ -444,4 +445,4 @@ - \ No newline at end of file + diff --git a/src/utilcode/ccomprc.cpp b/src/utilcode/ccomprc.cpp index eccf42d98c65..a4c79fc127b4 100644 --- a/src/utilcode/ccomprc.cpp +++ b/src/utilcode/ccomprc.cpp @@ -918,13 +918,13 @@ HRESULT CCompRC::LoadResourceFile(HRESOURCEDLL * pHInst, LPCWSTR lpFileName) // Load the library for this thread's current language // Called once per language. // Search order is: -// 1. Dll in localized path (\\mscorrc.dll) -// 2. Dll in localized (parent) path (\ (en format)\mscorrc.dll) -// 3. Dll in root path (\mscorrc.dll) +// 1. Dll in localized path (\\mscorrc.dll) +// 2. Dll in localized (parent) path (\ (en format)\mscorrc.dll) +// 3. Dll in root path (\mscorrc.dll) // 4. Dll in current path (\mscorrc.dll) //***************************************************************************** HRESULT CCompRC::LoadLibraryHelper(HRESOURCEDLL *pHInst, - __out_ecount(rcPathSize) __out_z WCHAR *rcPath, const DWORD rcPathSize) + SString& rcPath) { CONTRACTL { @@ -937,19 +937,11 @@ HRESULT CCompRC::LoadLibraryHelper(HRESOURCEDLL *pHInst, CONTRACTL_END; HRESULT hr = E_FAIL; - - WCHAR rcDrive[_MAX_DRIVE]; // Volume name. - WCHAR rcDir[_MAX_PATH]; // Directory. - - size_t rcDriveLen; - size_t rcDirLen; size_t rcPartialPathLen; - + _ASSERTE(m_pResourceFile != NULL); - size_t rcMscorrcLen = wcslen(m_pResourceFile); - // must initialize before calling SString::Empty() SString::Startup(); @@ -972,58 +964,43 @@ HRESULT CCompRC::LoadLibraryHelper(HRESOURCEDLL *pHInst, if (hr == E_OUTOFMEMORY) return hr; - - rcDir[0] = W('\0'); - rcDrive[0] = W('\0'); - rcPath[rcPathSize - 1] = 0; - - SplitPath(rcPath, rcDrive, _MAX_DRIVE, rcDir, _MAX_PATH, 0, 0, 0, 0); - rcDriveLen = wcslen(rcDrive); - rcDirLen = wcslen(rcDir); - - // Length that does not include culture name length - rcPartialPathLen = rcDriveLen + rcDirLen + rcMscorrcLen + 1; - - - for (DWORD i=0; i< cultureNames.GetCount();i++) + EX_TRY { - SString& sLang = cultureNames[i]; - if (rcPartialPathLen + sLang.GetCount() <= rcPathSize) + for (DWORD i=0; i< cultureNames.GetCount();i++) { - wcscpy_s(rcPath, rcDriveLen+1, rcDrive); - WCHAR *rcPathPtr = rcPath + rcDriveLen; + SString& sLang = cultureNames[i]; + + PathString rcPathName(rcPath); - wcscpy_s(rcPathPtr, rcDirLen+1, rcDir); - rcPathPtr += rcDirLen; + if (!rcPathName.EndsWith(W("\\"))) + { + rcPathName.Append(W("\\")); + } - if(!sLang.IsEmpty()) + if (!sLang.IsEmpty()) { - wcscpy_s(rcPathPtr, sLang.GetCount()+1, sLang); - wcscpy_s(rcPathPtr+ sLang.GetCount(), rcMscorrcLen+1, W("\\")); - wcscpy_s(rcPathPtr + sLang.GetCount()+1, rcMscorrcLen+1, m_pResourceFile); + rcPathName.Append(sLang); + rcPathName.Append(W("\\")); + rcPathName.Append(m_pResourceFile); } else { - wcscpy_s(rcPathPtr + sLang.GetCount(), rcMscorrcLen+1, m_pResourceFile); + rcPathName.Append(m_pResourceFile); } // Feedback for debugging to eliminate unecessary loads. - DEBUG_STMT(DbgWriteEx(W("Loading %s to load strings.\n"), rcPath)); + DEBUG_STMT(DbgWriteEx(W("Loading %s to load strings.\n"), rcPath.GetUnicode())); // 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, rcPath); + hr = LoadResourceFile(pHInst, rcPathName); if (SUCCEEDED(hr)) break; - } - else - { - _ASSERTE(!"Buffer not big enough"); - hr = E_FAIL; - - } - }; + + } + } + EX_CATCH_HRESULT(hr); // Last ditch search effort in current directory if (FAILED(hr)) { @@ -1035,12 +1012,12 @@ HRESULT CCompRC::LoadLibraryHelper(HRESOURCEDLL *pHInst, // Two-stage approach: // First try module directory, then try CORSystemDirectory for default resource -HRESULT CCompRC::LoadLibrary(HRESOURCEDLL * pHInst) +HRESULT CCompRC::LoadLibraryThrows(HRESOURCEDLL * pHInst) { CONTRACTL { GC_NOTRIGGER; - NOTHROW; + THROWS; #ifdef MODE_PREEMPTIVE MODE_PREEMPTIVE; #endif @@ -1055,26 +1032,28 @@ HRESULT CCompRC::LoadLibrary(HRESOURCEDLL * pHInst) // The resources are embeded into the .exe itself for crossgen *pHInst = GetModuleInst(); #else - WCHAR rcPath[_MAX_PATH]; // Path to resource DLL. + PathString rcPath; // Path to resource DLL. // Try first in the same directory as this dll. #if defined(FEATURE_CORECLR) VALIDATECORECLRCALLBACKS(); - DWORD length = 0; - hr = g_CoreClrCallbacks.m_pfnGetCORSystemDirectory(rcPath, NumItems(rcPath), &length); + + hr = g_CoreClrCallbacks.m_pfnGetCORSystemDirectory(rcPath); if (FAILED(hr)) return hr; - hr = LoadLibraryHelper(pHInst, rcPath, NumItems(rcPath)); + hr = LoadLibraryHelper(pHInst, rcPath); #else // FEATURE_CORECLR - if (!WszGetModuleFileName(GetModuleInst(), rcPath, NumItems(rcPath))) + if (!WszGetModuleFileName(GetModuleInst(), rcPath)) return HRESULT_FROM_GetLastError(); - - hr = LoadLibraryHelper(pHInst, rcPath, NumItems(rcPath)); + + CopySystemDirectory(rcPath, rcPath); + + hr = LoadLibraryHelper(pHInst, rcPath); if (hr == E_OUTOFMEMORY) return hr; @@ -1096,36 +1075,39 @@ HRESULT CCompRC::LoadLibrary(HRESOURCEDLL * pHInst) // The reason for using GetRequestedRuntimeInfo is the ability to suppress message boxes // with RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG. + COUNT_T size = MAX_PATH; hr = LegacyActivationShim::GetRequestedRuntimeInfo( NULL, W("v")VER_PRODUCTVERSION_NO_QFE_STR_L, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION|RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG|RUNTIME_INFO_CONSIDER_POST_2_0, - rcPath, - NumItems(rcPath), + rcPath.OpenUnicodeBuffer(size-1), + size, &corSystemPathSize, rcVersion, NumItems(rcVersion), &rcVersionSize); + rcPath.CloseBuffer(corSystemPathSize); + if (SUCCEEDED(hr)) { if (rcVersionSize > 0) { - wcscat_s(rcPath, NumItems(rcPath), rcVersion) ; - wcscat_s(rcPath, NumItems(rcPath), W("\\")) ; + rcPath.Append(rcVersion); + rcPath.Append(W("\\")); } } #else // If we're hosted, we have the advantage of a CoreClrCallbacks reference. // More importantly, we avoid calling back to mscoree.dll. - DWORD cchPath; - hr = GetClrCallbacks().m_pfnGetCORSystemDirectory(rcPath, NumItems(rcPath), &cchPath); + + hr = GetClrCallbacks().m_pfnGetCORSystemDirectory(rcPath); #endif if (SUCCEEDED(hr)) { - hr = LoadLibraryHelper(pHInst, rcPath, NumItems(rcPath)); + hr = LoadLibraryHelper(pHInst, rcPath); } } #endif // !DACCESS_COMPILE @@ -1136,7 +1118,27 @@ HRESULT CCompRC::LoadLibrary(HRESOURCEDLL * pHInst) 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 diff --git a/src/utilcode/debug.cpp b/src/utilcode/debug.cpp index b1fb16524ba3..a96aca148ad3 100644 --- a/src/utilcode/debug.cpp +++ b/src/utilcode/debug.cpp @@ -239,8 +239,8 @@ VOID LogAssert( GetSystemTime(&st); #endif - WCHAR exename[300]; - WszGetModuleFileName(NULL, exename, sizeof(exename)/sizeof(WCHAR)); + PathString exename; + WszGetModuleFileName(NULL, exename); LOG((LF_ASSERT, LL_FATALERROR, @@ -259,7 +259,7 @@ VOID LogAssert( szFile, iLine, szExpr)); - LOG((LF_ASSERT, LL_FATALERROR, "RUNNING EXE: %ws\n", exename)); + LOG((LF_ASSERT, LL_FATALERROR, "RUNNING EXE: %ws\n", exename.GetUnicode())); } //***************************************************************************** diff --git a/src/utilcode/jitperf.cpp b/src/utilcode/jitperf.cpp index a1b29d5e17e9..808a10ccde2a 100644 --- a/src/utilcode/jitperf.cpp +++ b/src/utilcode/jitperf.cpp @@ -8,6 +8,7 @@ #include "clrhost.h" #include "contract.h" #include "utilcode.h" +#include "sstring.h" //============================================================================= // ALL THE JIT PERF STATS GATHERING CODE IS COMPILED ONLY IF THE ENABLE_JIT_PERF WAS DEFINED. @@ -62,10 +63,8 @@ void InitJitPerf(void) CANNOT_TAKE_LOCK; } CONTRACTL_END; - wchar_t lpszValue[2]; - DWORD cchValue = 2; - - g_fJitPerfOn = WszGetEnvironmentVariable (W("JIT_PERF_OUTPUT"), lpszValue, cchValue); + InlineSString<4> lpszValue; + g_fJitPerfOn = WszGetEnvironmentVariable (W("JIT_PERF_OUTPUT"), lpszValue); if (g_fJitPerfOn) { g_csJit = ClrCreateCriticalSection(CrstJitPerf,CRST_UNSAFE_ANYMODE); diff --git a/src/utilcode/longfilepathwrappers.cpp b/src/utilcode/longfilepathwrappers.cpp new file mode 100644 index 000000000000..0bb473095aec --- /dev/null +++ b/src/utilcode/longfilepathwrappers.cpp @@ -0,0 +1,1464 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include "stdafx.h" +#include "windows.h" +#include "longfilepathwrappers.h" +#include "sstring.h" +#include "ex.h" + +class LongFile +{ +private: +#ifndef FEATURE_PAL + static const WCHAR* ExtendedPrefix; + static const WCHAR* DevicePathPrefix; + static const WCHAR* UNCPathPrefix; + static const WCHAR* UNCExtendedPathPrefix; + static const WCHAR VolumeSeparatorChar; +#endif //FEATURE_PAL + static const WCHAR LongFile::DirectorySeparatorChar; + static const WCHAR LongFile::AltDirectorySeparatorChar; +public: + static BOOL IsExtended(SString & path); + static BOOL IsUNCExtended(SString & path); + static BOOL ContainsDirectorySeparator(SString & path); + static BOOL IsDirectorySeparator(WCHAR c); + static BOOL IsPathNotFullyQualified(SString & path); + static BOOL IsDevice(SString & path); + + static HRESULT NormalizePath(SString& path); +}; + +HMODULE +LoadLibraryExWrapper( + LPCWSTR lpLibFileName, + HANDLE hFile, + DWORD dwFlags + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + HMODULE ret = NULL; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return NULL;) + EX_TRY + { + + LongPathString path(LongPathString::Literal, lpLibFileName); + + if (LongFile::IsPathNotFullyQualified(path) || SUCCEEDED(LongFile::NormalizePath(path))) + { +#ifndef FEATURE_PAL + //Adding the assert to ensure relative paths which are not just filenames are not used for LoadLibrary Calls + _ASSERTE(!LongFile::IsPathNotFullyQualified(path) || !LongFile::ContainsDirectorySeparator(path)); +#endif //FEATURE_PAL + + ret = LoadLibraryExW(path.GetUnicode(), hFile, dwFlags); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK) + { + SetLastError(hr); + } + else if(ret == NULL) + { + SetLastError(lastError); + } + + return ret; +} + +HANDLE +CreateFileWrapper( + _In_ LPCWSTR lpFileName, + _In_ DWORD dwDesiredAccess, + _In_ DWORD dwShareMode, + _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, + _In_ DWORD dwCreationDisposition, + _In_ DWORD dwFlagsAndAttributes, + _In_opt_ HANDLE hTemplateFile + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + DWORD lastError; + HANDLE ret = INVALID_HANDLE_VALUE; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return NULL;) + + EX_TRY + { + LongPathString path(LongPathString::Literal, lpFileName); + + if (SUCCEEDED(LongFile::NormalizePath(path))) + { + ret = CreateFileW(path.GetUnicode(), + dwDesiredAccess, + dwShareMode, + lpSecurityAttributes, + dwCreationDisposition, + dwFlagsAndAttributes, + hTemplateFile); + + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == INVALID_HANDLE_VALUE) + { + SetLastError(lastError); + } + + return ret; +} + +BOOL +SetFileAttributesWrapper( + _In_ LPCWSTR lpFileName, + _In_ DWORD dwFileAttributes + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + BOOL ret = FALSE; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return FALSE;) + + EX_TRY + { + LongPathString path(LongPathString::Literal, lpFileName); + + if (SUCCEEDED(LongFile::NormalizePath(path))) + { + ret = SetFileAttributesW( + path.GetUnicode(), + dwFileAttributes + ); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == FALSE) + { + SetLastError(lastError); + } + + return ret; +} + +DWORD +GetFileAttributesWrapper( + _In_ LPCWSTR lpFileName + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + DWORD ret = INVALID_FILE_ATTRIBUTES; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return INVALID_FILE_ATTRIBUTES;) + + EX_TRY + { + LongPathString path(LongPathString::Literal, lpFileName); + + if (SUCCEEDED(LongFile::NormalizePath(path))) + { + ret = GetFileAttributesW( + path.GetUnicode() + ); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == INVALID_FILE_ATTRIBUTES) + { + SetLastError(lastError); + } + + return ret; +} + +BOOL +GetFileAttributesExWrapper( + _In_ LPCWSTR lpFileName, + _In_ GET_FILEEX_INFO_LEVELS fInfoLevelId, + _Out_writes_bytes_(sizeof(WIN32_FILE_ATTRIBUTE_DATA)) LPVOID lpFileInformation + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + BOOL ret = FALSE; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return FALSE;) + + EX_TRY + { + LongPathString path(LongPathString::Literal, lpFileName); + + if (SUCCEEDED(LongFile::NormalizePath(path))) + { + ret = GetFileAttributesExW( + path.GetUnicode(), + fInfoLevelId, + lpFileInformation + ); + + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == FALSE) + { + SetLastError(lastError); + } + + return ret; +} + +BOOL +DeleteFileWrapper( + _In_ LPCWSTR lpFileName + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + BOOL ret = FALSE; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return FALSE;) + + EX_TRY + { + LongPathString path(LongPathString::Literal, lpFileName); + + if (SUCCEEDED(LongFile::NormalizePath(path))) + { + ret = DeleteFileW( + path.GetUnicode() + ); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == FALSE) + { + SetLastError(lastError); + } + + return ret; +} + + +BOOL +CopyFileWrapper( + _In_ LPCWSTR lpExistingFileName, + _In_ LPCWSTR lpNewFileName, + _In_ BOOL bFailIfExists + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + BOOL ret = FALSE; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return FALSE;) + + EX_TRY + { + LongPathString Existingpath(LongPathString::Literal, lpExistingFileName); + LongPathString Newpath(LongPathString::Literal, lpNewFileName); + + if (SUCCEEDED(LongFile::NormalizePath(Existingpath)) && SUCCEEDED(LongFile::NormalizePath(Newpath))) + { + ret = CopyFileW( + Existingpath.GetUnicode(), + Newpath.GetUnicode(), + bFailIfExists + ); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == FALSE) + { + SetLastError(lastError); + } + + return ret; +} + + +BOOL +MoveFileWrapper( + _In_ LPCWSTR lpExistingFileName, + _In_ LPCWSTR lpNewFileName + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + BOOL ret = FALSE; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return FALSE;) + + EX_TRY + { + LongPathString Existingpath(LongPathString::Literal, lpExistingFileName); + LongPathString Newpath(LongPathString::Literal, lpNewFileName); + + if (SUCCEEDED(LongFile::NormalizePath(Existingpath)) && SUCCEEDED(LongFile::NormalizePath(Newpath))) + { + ret = MoveFileW( + Existingpath.GetUnicode(), + Newpath.GetUnicode() + ); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == FALSE) + { + SetLastError(lastError); + } + + return ret; +} + +BOOL +MoveFileExWrapper( + _In_ LPCWSTR lpExistingFileName, + _In_opt_ LPCWSTR lpNewFileName, + _In_ DWORD dwFlags + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + BOOL ret = FALSE; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return FALSE;) + + EX_TRY + { + LongPathString Existingpath(LongPathString::Literal, lpExistingFileName); + LongPathString Newpath(LongPathString::Literal, lpNewFileName); + + if (SUCCEEDED(LongFile::NormalizePath(Existingpath)) && SUCCEEDED(LongFile::NormalizePath(Newpath))) + { + ret = MoveFileExW( + Existingpath.GetUnicode(), + Newpath.GetUnicode(), + dwFlags + ); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == FALSE) + { + SetLastError(lastError); + } + + return ret; + +} + +DWORD +SearchPathWrapper( + _In_opt_ LPCWSTR lpPath, + _In_ LPCWSTR lpFileName, + _In_opt_ LPCWSTR lpExtension, + _In_ BOOL getPath, + SString& lpBuffer, + _Out_opt_ LPWSTR * lpFilePart + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + DWORD ret = 0; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return 0;) + + EX_TRY + { + LongPathString Existingpath(LongPathString::Literal, lpPath); + + if (lpPath != NULL) + { + if (FAILED(LongFile::NormalizePath(Existingpath))) + { + ret = FALSE; + } + else + { + lpPath = Existingpath.GetUnicode(); + } + } + + if (!getPath) + { + ret = SearchPathW( + lpPath, + lpFileName, + lpExtension, + 0, + NULL, + NULL + ); + } + else + { + COUNT_T size = lpBuffer.GetUnicodeAllocation() + 1; + + ret = SearchPathW( + lpPath, + lpFileName, + lpExtension, + size, + lpBuffer.OpenUnicodeBuffer(size - 1), + lpFilePart + ); + + if (ret > size) + { + lpBuffer.CloseBuffer(); + ret = SearchPathW( + lpPath, + lpFileName, + lpExtension, + ret, + lpBuffer.OpenUnicodeBuffer(ret - 1), + lpFilePart + ); + } + + lpBuffer.CloseBuffer(ret); + + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK) + { + SetLastError(hr); + } + else if (ret == 0) + { + SetLastError(lastError); + } + + return ret; + +} + +DWORD +GetShortPathNameWrapper( + _In_ LPCWSTR lpszLongPath, + SString& lpszShortPath + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + DWORD ret = 0; + HRESULT hr = S_OK; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return 0;) + + EX_TRY + { + LongPathString longPath(LongPathString::Literal, lpszLongPath); + + if (SUCCEEDED(LongFile::NormalizePath(longPath))) + { + COUNT_T size = lpszShortPath.GetUnicodeAllocation() + 1; + + ret = GetShortPathNameW( + longPath.GetUnicode(), + lpszShortPath.OpenUnicodeBuffer(size - 1), + (DWORD)size + ); + + if (ret > size) + { + lpszShortPath.CloseBuffer(); + ret = GetShortPathNameW( + longPath.GetUnicode(), + lpszShortPath.OpenUnicodeBuffer(ret -1), + ret + ); + } + + lpszShortPath.CloseBuffer(ret); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == 0) + { + SetLastError(lastError); + } + + return ret; +} + +DWORD +GetLongPathNameWrapper( + _In_ LPCWSTR lpszShortPath, + SString& lpszLongPath + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + DWORD ret = 0; + HRESULT hr = S_OK; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return 0;) + + EX_TRY + { + LongPathString shortPath(LongPathString::Literal, lpszShortPath); + + if (SUCCEEDED(LongFile::NormalizePath(shortPath))) + { + COUNT_T size = lpszLongPath.GetUnicodeAllocation() + 1; + + ret = GetLongPathNameW( + shortPath.GetUnicode(), + lpszLongPath.OpenUnicodeBuffer(size - 1), + (DWORD)size + ); + + if (ret > size) + { + lpszLongPath.CloseBuffer(); + ret = GetLongPathNameW( + shortPath.GetUnicode(), + lpszLongPath.OpenUnicodeBuffer(ret - 1), + ret + ); + + } + + lpszLongPath.CloseBuffer(ret); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == 0) + { + SetLastError(lastError); + } + + return ret; +} + +BOOL +CreateDirectoryWrapper( + _In_ LPCWSTR lpPathName, + _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + BOOL ret = FALSE; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return FALSE;) + + EX_TRY + { + LongPathString path(LongPathString::Literal, lpPathName); + + if (SUCCEEDED(LongFile::NormalizePath(path))) + { + ret = CreateDirectoryW( + path.GetUnicode(), + lpSecurityAttributes + ); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == FALSE) + { + SetLastError(lastError); + } + + return ret; +} + +BOOL +RemoveDirectoryWrapper( + _In_ LPCWSTR lpPathName + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + BOOL ret = FALSE; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return FALSE;) + + EX_TRY + { + LongPathString path(LongPathString::Literal, lpPathName); + + if (SUCCEEDED(LongFile::NormalizePath(path))) + { + ret = RemoveDirectoryW( + path.GetUnicode() + ); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == FALSE) + { + SetLastError(lastError); + } + + return ret; +} +DWORD +GetModuleFileNameWrapper( + _In_opt_ HMODULE hModule, + SString& buffer + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + DWORD ret = 0; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return 0;) + + EX_TRY + { + COUNT_T size = buffer.GetUnicodeAllocation() + 1; + + ret = GetModuleFileNameW( + hModule, + buffer.OpenUnicodeBuffer(size - 1), + (DWORD)size + ); + + + while (ret == size ) + { + buffer.CloseBuffer(); + size = size * 2; + ret = GetModuleFileNameW( + hModule, + buffer.OpenUnicodeBuffer(size - 1), + (DWORD)size + ); + + } + + + lastError = GetLastError(); + buffer.CloseBuffer(ret); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK) + { + SetLastError(hr); + } + else if (ret == 0) + { + SetLastError(lastError); + } + + return ret; +} + +UINT WINAPI GetTempFileNameWrapper( + _In_ LPCTSTR lpPathName, + _In_ LPCTSTR lpPrefixString, + _In_ UINT uUnique, + SString& lpTempFileName + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + UINT ret = 0; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return 0;) + + EX_TRY + { + //Change the behaviour in Redstone to retry + COUNT_T size = MAX_LONGPATH; + WCHAR* buffer = lpTempFileName.OpenUnicodeBuffer(size - 1); + ret = GetTempFileNameW( + lpPathName, + lpPrefixString, + uUnique, + buffer + ); + + lastError = GetLastError(); + size = (COUNT_T)wcslen(buffer); + lpTempFileName.CloseBuffer(size); + + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK) + { + SetLastError(hr); + } + else if (ret == 0) + { + SetLastError(lastError); + } + + return ret; +} +DWORD WINAPI GetTempPathWrapper( + SString& lpBuffer + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + DWORD ret = 0; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return 0;) + + EX_TRY + { + //Change the behaviour in Redstone to retry + COUNT_T size = MAX_LONGPATH; + + ret = GetTempPathW( + size, + lpBuffer.OpenUnicodeBuffer(size - 1) + ); + + lastError = GetLastError(); + lpBuffer.CloseBuffer(ret); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK) + { + SetLastError(hr); + } + else if (ret == 0) + { + SetLastError(lastError); + } + + return ret; +} + +DWORD WINAPI GetCurrentDirectoryWrapper( + SString& lpBuffer + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + DWORD ret = 0; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return 0;) + + EX_TRY + { + //Change the behaviour in Redstone to retry + COUNT_T size = MAX_LONGPATH; + + ret = GetCurrentDirectoryW( + size, + lpBuffer.OpenUnicodeBuffer(size - 1) + ); + + lastError = GetLastError(); + lpBuffer.CloseBuffer(ret); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK) + { + SetLastError(hr); + } + else if (ret == 0) + { + SetLastError(lastError); + } + + return ret; +} + +DWORD WINAPI GetEnvironmentVariableWrapper( + _In_opt_ LPCTSTR lpName, + _Out_opt_ SString& lpBuffer + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + DWORD ret = 0; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return 0;) + + EX_TRY + { + + COUNT_T size = lpBuffer.GetUnicodeAllocation() + 1; + + ret = GetEnvironmentVariableW( + lpName, + lpBuffer.OpenUnicodeBuffer(size - 1), + size + ); + + // We loop round getting the length of the env var and then trying to copy + // the value into a the allocated buffer. Usually we'll go through this loop + // precisely once, but the caution is ncessary in case the variable mutates + // beneath us, as the environment variable can be modified by another thread + //between two calls to GetEnvironmentVariableW + + while (ret > size) + { + size = ret; + lpBuffer.CloseBuffer(); + ret = GetEnvironmentVariableW( + lpName, + lpBuffer.OpenUnicodeBuffer(size - 1), + size); + } + + lastError = GetLastError(); + lpBuffer.CloseBuffer(ret); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK) + { + SetLastError(hr); + } + else if (ret == 0) + { + SetLastError(lastError); + } + + return ret; +} + + +#ifndef FEATURE_PAL + +BOOL +CreateHardLinkWrapper( + _In_ LPCWSTR lpFileName, + _In_ LPCWSTR lpExistingFileName, + _Reserved_ LPSECURITY_ATTRIBUTES lpSecurityAttributes + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + BOOL ret = FALSE; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return FALSE;) + + EX_TRY + { + LongPathString Existingpath(LongPathString::Literal, lpExistingFileName); + LongPathString FileName(LongPathString::Literal, lpFileName); + + if (SUCCEEDED(LongFile::NormalizePath(Existingpath)) && SUCCEEDED(LongFile::NormalizePath(FileName))) + { + ret = CreateHardLinkW( + Existingpath.GetUnicode(), + FileName.GetUnicode(), + lpSecurityAttributes + ); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == FALSE) + { + SetLastError(lastError); + } + + return ret; +} + +BOOL +CopyFileExWrapper( + _In_ LPCWSTR lpExistingFileName, + _In_ LPCWSTR lpNewFileName, + _In_opt_ LPPROGRESS_ROUTINE lpProgressRoutine, + _In_opt_ LPVOID lpData, + _When_(pbCancel != NULL, _Pre_satisfies_(*pbCancel == FALSE)) + _Inout_opt_ LPBOOL pbCancel, + _In_ DWORD dwCopyFlags + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + BOOL ret = FALSE; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return FALSE;) + + EX_TRY + { + LongPathString Existingpath(LongPathString::Literal, lpExistingFileName); + LongPathString Newpath(LongPathString::Literal, lpNewFileName); + + if (SUCCEEDED(LongFile::NormalizePath(Existingpath)) && SUCCEEDED(LongFile::NormalizePath(Newpath))) + { + ret = CopyFileExW( + Existingpath.GetUnicode(), + Newpath.GetUnicode(), + lpProgressRoutine, + lpData, + pbCancel, + dwCopyFlags + ); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == FALSE) + { + SetLastError(lastError); + } + + return ret; +} + +HANDLE +FindFirstFileExWrapper( + _In_ LPCWSTR lpFileName, + _In_ FINDEX_INFO_LEVELS fInfoLevelId, + _Out_writes_bytes_(sizeof(WIN32_FIND_DATAW)) LPVOID lpFindFileData, + _In_ FINDEX_SEARCH_OPS fSearchOp, + _Reserved_ LPVOID lpSearchFilter, + _In_ DWORD dwAdditionalFlags + ) +{ + CONTRACTL + { + NOTHROW; + SO_TOLERANT; + } + CONTRACTL_END; + + HRESULT hr = S_OK; + HANDLE ret = INVALID_HANDLE_VALUE; + DWORD lastError; + + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return FALSE;) + + EX_TRY + { + LongPathString path(LongPathString::Literal, lpFileName); + + if (SUCCEEDED(LongFile::NormalizePath(path))) + { + ret = FindFirstFileExW( + path.GetUnicode(), + fInfoLevelId, + lpFindFileData, + fSearchOp, + lpSearchFilter, + dwAdditionalFlags + ); + } + + lastError = GetLastError(); + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE + + if (hr != S_OK ) + { + SetLastError(hr); + } + else if(ret == INVALID_HANDLE_VALUE) + { + SetLastError(lastError); + } + + return ret; +} +#endif //!FEATURE_PAL + +#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE) + +#ifndef FEATURE_PAL + +#if ! defined(DACCESS_COMPILE) && !defined(SELF_NO_HOST) +extern HINSTANCE g_pMSCorEE; +#endif// ! defined(DACCESS_COMPILE) && !defined(SELF_NO_HOST) + +BOOL PAL_GetPALDirectoryWrapper(SString& pbuffer) +{ + + HRESULT hr = S_OK; + + PathString pPath; + DWORD dwPath; + HINSTANCE hinst = NULL; + +#if ! defined(DACCESS_COMPILE) && !defined(SELF_NO_HOST) + hinst = g_pMSCorEE; +#endif// ! defined(DACCESS_COMPILE) && !defined(SELF_NO_HOST) + +#ifndef CROSSGEN_COMPILE + _ASSERTE(hinst != NULL); +#endif + + dwPath = WszGetModuleFileName(hinst, pPath); + + if(dwPath == 0) + { + hr = HRESULT_FROM_GetLastErrorNA(); + } + else + { + DWORD dwLength; + hr = CopySystemDirectory(pPath, pbuffer); + } + + return (hr == S_OK); +} + +#else + +BOOL PAL_GetPALDirectoryWrapper(SString& pbuffer) +{ + BOOL retval; + COUNT_T size = MAX_LONGPATH; //Retry once the PAL Api is fixed to return the correct size + WCHAR* buffer = pbuffer.OpenUnicodeBuffer(size - 1); + + retval = PAL_GetPALDirectoryW(pbuffer.OpenUnicodeBuffer(size - 1), size); + size = (COUNT_T)wcslen(buffer); + pbuffer.CloseBuffer(size); + + return retval; +} + +#endif // FEATURE_PAL + +#endif // FEATURE_CORECLR || CROSSGEN_COMPILE + +//Implementation of LongFile Helpers +const WCHAR LongFile::DirectorySeparatorChar = W('\\'); +const WCHAR LongFile::AltDirectorySeparatorChar = W('/'); +#ifndef FEATURE_PAL +const WCHAR LongFile::VolumeSeparatorChar = W(':'); +const WCHAR* LongFile::ExtendedPrefix = W("\\\\?\\"); +const WCHAR* LongFile::DevicePathPrefix = W("\\\\.\\"); +const WCHAR* LongFile::UNCExtendedPathPrefix = W("\\\\?\\UNC\\"); +const WCHAR* LongFile::UNCPathPrefix = W("\\\\"); + +BOOL LongFile::IsExtended(SString & path) +{ + return path.BeginsWith(ExtendedPrefix); +} + +BOOL LongFile::IsUNCExtended(SString & path) +{ + + return path.BeginsWith(UNCExtendedPathPrefix); +} + +// Relative here means it could be relative to current directory on the relevant drive +// NOTE: Relative segments ( \..\) are not considered relative +// Returns true if the path specified is relative to the current drive or working directory. +// Returns false if the path is fixed to a specific drive or UNC path. This method does no +// validation of the path (URIs will be returned as relative as a result). +// Handles paths that use the alternate directory separator. It is a frequent mistake to +// assume that rooted paths (Path.IsPathRooted) are not relative. This isn't the case. + +BOOL LongFile::IsPathNotFullyQualified(SString & path) +{ + if (path.GetCount() < 2) + { + return TRUE; // It isn't fixed, it must be relative. There is no way to specify a fixed path with one character (or less). + } + + if (IsDirectorySeparator(path[0])) + { + return !IsDirectorySeparator(path[1]); // There is no valid way to specify a relative path with two initial slashes + } + + return !((path.GetCount() >= 3) //The only way to specify a fixed path that doesn't begin with two slashes is the drive, colon, slash format- i.e. C:\ + && (path[1] == VolumeSeparatorChar) + && IsDirectorySeparator(path[2])); +} + +BOOL LongFile::IsDevice(SString & path) +{ + return path.BeginsWith(DevicePathPrefix); +} + +// This function will normalize paths if the path length exceeds MAX_PATH +// The normalization examples are : +// C:\foo\\bar => \\?\C:\foo\\bar +// \\server\\bar => \\?\UNC\server\\bar +HRESULT LongFile::NormalizePath(SString & path) +{ + HRESULT hr = S_OK; + DWORD ret = 0; + COUNT_T prefixLen = 0; + if (path.IsEmpty()|| IsDevice(path) || IsExtended(path) || IsUNCExtended(path)) + return S_OK; + + if (!IsPathNotFullyQualified(path) && path.GetCount() < MAX_LONGPATH) + return S_OK; + + //Now the path will be normalized + + SString originalPath(path); + SString prefix(ExtendedPrefix); + prefixLen = prefix.GetCount(); + + if (path.BeginsWith(UNCPathPrefix)) + { + prefix.Set(UNCExtendedPathPrefix); + //In this case if path is \\server the extended syntax should be like \\?\UNC\server + //The below logic populates the path from prefixLen offset from the start. This ensures that first 2 characters are overwritten + // + prefixLen = prefix.GetCount() - 2; + } + + + COUNT_T size = path.GetUnicodeAllocation() + 1; + WCHAR* buffer = path.OpenUnicodeBuffer(size - 1); + + ret = GetFullPathNameW( + originalPath.GetUnicode(), + size - prefixLen, //memory avilable for path after reserving for prefix + (buffer + prefixLen), //reserve memory for prefix + NULL + ); + + if (ret == 0) + { + return E_FAIL; + } + + if (ret > size - prefixLen) + { + path.CloseBuffer(); + size = ret + prefixLen; + buffer = path.OpenUnicodeBuffer(size -1); + + ret = GetFullPathNameW( + originalPath.GetUnicode(), + ret, // memory required for the path + (buffer + prefixLen), //reserve memory for prefix + NULL + ); + + _ASSERTE(ret < size - prefixLen); + + if (ret == 0) + { + return E_FAIL; + } + } + + + //wcscpy_s always termintes with NULL, so we are saving the character that will be overwriiten + WCHAR temp = buffer[prefix.GetCount()]; + wcscpy_s(buffer, prefix.GetCount() + 1, prefix.GetUnicode()); + buffer[prefix.GetCount()] = temp; + path.CloseBuffer(ret + prefixLen); + + return S_OK; +} +#else +BOOL LongFile::IsExtended(SString & path) +{ + return FALSE; +} + +BOOL LongFile::IsUNCExtended(SString & path) +{ + return FALSE; +} + +BOOL LongFile::IsPathNotFullyQualified(SString & path) +{ + return TRUE; +} + +BOOL LongFile::IsDevice(SString & path) +{ + return FALSE; +} + +//Don't need to do anything For XPlat +HRESULT LongFile::NormalizePath(SString & path) +{ + return S_OK; +} +#endif //FEATURE_PAL + +BOOL LongFile::ContainsDirectorySeparator(SString & path) +{ + return path.Find(path.Begin(), DirectorySeparatorChar) || path.Find(path.Begin(), AltDirectorySeparatorChar); +} + +BOOL LongFile::IsDirectorySeparator(WCHAR c) +{ + return c == DirectorySeparatorChar || c == AltDirectorySeparatorChar; +} + + + diff --git a/src/utilcode/makepath.cpp b/src/utilcode/makepath.cpp index ab078a9d1221..3d948d53a1fa 100644 --- a/src/utilcode/makepath.cpp +++ b/src/utilcode/makepath.cpp @@ -183,15 +183,28 @@ HRESULT GetProcessExePath(LPCWSTR *pwszProcessExePath) if (g_wszProcessExePath == NULL) { - NewArrayHolder wszProcName = new (nothrow) WCHAR[_MAX_PATH]; - IfNullRet(wszProcName); - - DWORD cchProcName = WszGetModuleFileName(NULL, wszProcName, _MAX_PATH); - if (cchProcName == 0) + DWORD cchProcName = 0; + NewArrayHolder wszProcName; + EX_TRY { - return HRESULT_FROM_GetLastError(); + PathString wszProcNameString; + cchProcName = WszGetModuleFileName(NULL, wszProcNameString); + if (cchProcName == 0) + { + hr = HRESULT_FROM_GetLastError(); + } + else + { + wszProcName = wszProcNameString.GetCopyOfUnicodeString(); + } } + EX_CATCH_HRESULT(hr); + if (FAILED(hr)) + { + return hr; + } + if (InterlockedCompareExchangeT(&g_wszProcessExePath, const_cast(wszProcName.GetValue()), NULL) == NULL) { wszProcName.SuppressRelease(); @@ -205,3 +218,66 @@ HRESULT GetProcessExePath(LPCWSTR *pwszProcessExePath) } #endif +// Returns the directory for HMODULE. So, if HMODULE was for "C:\Dir1\Dir2\Filename.DLL", +// then this would return "C:\Dir1\Dir2\" (note the trailing backslash). +HRESULT GetHModuleDirectory( + __in HMODULE hMod, + SString& wszPath) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + CANNOT_TAKE_LOCK; + } + CONTRACTL_END; + + DWORD dwRet = WszGetModuleFileName(hMod, wszPath); + + if (dwRet == 0) + { // Some other error. + return HRESULT_FROM_GetLastError(); + } + + CopySystemDirectory(wszPath, wszPath); + + + return S_OK; +} + +// +// Returns path name from a file name. +// Example: For input "C:\Windows\System.dll" returns "C:\Windows\". +// Warning: The input file name string might be destroyed. +// +// Arguments: +// pPathString - [in] SString with file name +// +// pBuffer - [out] SString . +// +// Return Value: +// S_OK - Output buffer contains path name. +// other errors - If Sstring throws. +// +HRESULT CopySystemDirectory(const SString& pPathString, + SString& pbuffer) +{ + HRESULT hr = S_OK; + EX_TRY + { + pbuffer.Set(pPathString); + SString::Iterator iter = pbuffer.End(); + if (pbuffer.FindBack(iter,DIRECTORY_SEPARATOR_CHAR_W)) + { + iter++; + pbuffer.Truncate(iter); + } + else + { + hr = E_UNEXPECTED; + } + } + EX_CATCH_HRESULT(hr); + + return hr; +} diff --git a/src/utilcode/perflog.cpp b/src/utilcode/perflog.cpp index c84c1df2d41c..5e031fe4c50d 100644 --- a/src/utilcode/perflog.cpp +++ b/src/utilcode/perflog.cpp @@ -6,6 +6,7 @@ #include "perflog.h" #include "jitperf.h" #include +#include "sstring.h" //============================================================================= // ALL THE PERF LOG CODE IS COMPILED ONLY IF THE ENABLE_PERF_LOG WAS DEFINED. @@ -83,9 +84,9 @@ void PerfLog::PerfLogInitialize() // Special cases considered. Now turn on loggin if any of above want logging // or if PERF_OUTPUT says so. - wchar_t lpszValue[2]; + InlineSString<4> lpszValue; // Read the env var PERF_OUTPUT and if set continue. - m_fLogPerfData = WszGetEnvironmentVariable (W("PERF_OUTPUT"), lpszValue, sizeof(lpszValue)/sizeof(lpszValue[0])); + m_fLogPerfData = WszGetEnvironmentVariable (W("PERF_OUTPUT"), lpszValue); #if defined(ENABLE_JIT_PERF) if (!m_fLogPerfData) @@ -100,9 +101,9 @@ void PerfLog::PerfLogInitialize() #endif // See if we want to output to the database - wchar_t _lpszValue[11]; + PathString _lpszValue; DWORD _cchValue = 10; // 11 - 1 - _cchValue = WszGetEnvironmentVariable (W("PerfOutput"), _lpszValue, _cchValue); + _cchValue = WszGetEnvironmentVariable (W("PerfOutput"), _lpszValue); if (_cchValue && (wcscmp (_lpszValue, W("DBase")) == 0)) m_perfAutomationFormat = true; if (_cchValue && (wcscmp (_lpszValue, W("CSV")) == 0)) diff --git a/src/utilcode/regutil.cpp b/src/utilcode/regutil.cpp index 0536cfa828ea..1cb8990f0c65 100644 --- a/src/utilcode/regutil.cpp +++ b/src/utilcode/regutil.cpp @@ -16,6 +16,7 @@ #include "utilcode.h" #include "mscoree.h" #include "sstring.h" +#include "ex.h" #define COMPLUS_PREFIX W("COMPlus_") #define LEN_OF_COMPLUS_PREFIX 8 @@ -74,34 +75,38 @@ LPWSTR REGUTIL::EnvGetString(LPCWSTR name, BOOL fPrependCOMPLUS) FAULT_NOT_FATAL(); // We don't report OOM errors here, we return a default value. - for (;;) - { - DWORD len = WszGetEnvironmentVariable(buff, 0, 0); - if (len == 0) - { - return NULL; - } - - // If we can't get memory to return the string, then will simply pretend we didn't find it. - NewArrayHolder ret(new (nothrow) WCHAR [len]); - if (ret == NULL) - { - return NULL; - } - - DWORD actualLen = WszGetEnvironmentVariable(buff, ret, len); - if (actualLen == 0) - { - return NULL; - } - - if (actualLen < len) + + NewArrayHolder ret = NULL; + HRESULT hr = S_OK; + DWORD Len; + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return NULL;) + EX_TRY + { + PathString temp; + + Len = WszGetEnvironmentVariable(buff, temp); + if (Len != 0) { - return ret.Extract(); - } + ret = temp.GetCopyOfUnicodeString(); + } + + } + EX_CATCH_HRESULT(hr); + END_SO_INTOLERANT_CODE - // Variable was changed by other thread - retry + if (hr != S_OK) + { + SetLastError(hr); } + + if(ret != NULL) + { + return ret.Extract(); + } + + return NULL; + + } #ifdef ALLOW_REGISTRY diff --git a/src/utilcode/safewrap.cpp b/src/utilcode/safewrap.cpp index 0ea7b90e3a1e..6c17478014f0 100644 --- a/src/utilcode/safewrap.cpp +++ b/src/utilcode/safewrap.cpp @@ -35,27 +35,17 @@ void ClrGetCurrentDirectory(SString & value) CONTRACTL_END; // Get size needed - DWORD lenWithNull = WszGetCurrentDirectory(0, NULL); + DWORD len = WszGetCurrentDirectory(value); - // Now read it for content. - WCHAR * pCharBuf = value.OpenUnicodeBuffer(lenWithNull); - DWORD lenWithoutNull = WszGetCurrentDirectory(lenWithNull, pCharBuf); // An actual API failure in GetCurrentDirectory failure should be very rare, so we'll throw on those. - if (lenWithoutNull == 0) + if (len == 0) { value.CloseBuffer(0); ThrowLastError(); } - if (lenWithoutNull != (lenWithNull - 1)) - { - value.CloseBuffer(lenWithoutNull); - // must have changed underneath us. - ThrowHR(E_FAIL); - } - - value.CloseBuffer(lenWithoutNull); + value.CloseBuffer(); } // Nothrowing wrapper. diff --git a/src/utilcode/stacktrace.cpp b/src/utilcode/stacktrace.cpp index 0b6f3ea29383..7bfdb4514a39 100644 --- a/src/utilcode/stacktrace.cpp +++ b/src/utilcode/stacktrace.cpp @@ -274,9 +274,8 @@ IMGHLPFN_LOAD ailFuncList[] = #define MAX_SYM_PATH (1024*8) #define DEFAULT_SYM_PATH W("symsrv*symsrv.dll*\\\\symbols\\symbols;") #define STR_ENGINE_NAME MAIN_CLR_DLL_NAME_W -LPSTR FillSymbolSearchPath(CQuickBytes &qb) +LPSTR FillSymbolSearchPathThrows(CQuickBytes &qb) { - STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_GC_NOTRIGGER; STATIC_CONTRACT_CANNOT_TAKE_LOCK; SCAN_IGNORE_FAULT; // Faults from Wsz funcs are handled. @@ -287,21 +286,15 @@ LPSTR FillSymbolSearchPath(CQuickBytes &qb) return NULL; #endif - NewArrayHolder rcBuff = new (nothrow) WCHAR[MAX_SYM_PATH]; // Working buffer + InlineSString rcBuff ; // Working buffer WCHAR rcVerString[64]; // Extension for install directory. int chTotal = 0; // How full is working buffer. int ch; - - if (rcBuff == NULL) - return NULL; // Unable to allocate working buffer - fail - - ZeroMemory(rcBuff, MAX_SYM_PATH*sizeof(WCHAR)); - // If the NT symbol server path vars are there, then use those. - chTotal = WszGetEnvironmentVariable(W("_NT_SYMBOL_PATH"), rcBuff, MAX_SYM_PATH); // Cannot use NumItems(rcBuff) since NumItems does not work with holders + chTotal = WszGetEnvironmentVariable(W("_NT_SYMBOL_PATH"), rcBuff); if (chTotal + 1 < MAX_SYM_PATH) - rcBuff[chTotal++] = W(';'); + rcBuff.Append(W(';')); // Copy the defacto NT symbol path as well. size_t sympathLength = chTotal + NumItems(DEFAULT_SYM_PATH) + 1; @@ -313,13 +306,15 @@ LPSTR FillSymbolSearchPath(CQuickBytes &qb) if (sympathLength < MAX_SYM_PATH) { - wcsncpy_s(&rcBuff[chTotal], MAX_SYM_PATH-chTotal, DEFAULT_SYM_PATH, _TRUNCATE); - chTotal = (int) wcslen(rcBuff); + rcBuff.Append(DEFAULT_SYM_PATH); + chTotal = rcBuff.GetCount(); } // Next, if there is a URTTARGET, add that since that is where ndpsetup places // your symobls on an install. - ch = WszGetEnvironmentVariable(W("URTTARGET"), &rcBuff[chTotal], MAX_SYM_PATH - chTotal); + PathString rcBuffTemp; + ch = WszGetEnvironmentVariable(W("URTTARGET"), rcBuffTemp); + rcBuff.Append(rcBuffTemp); if (ch != 0 && (chTotal + ch + 1 < MAX_SYM_PATH)) { size_t chNewTotal = chTotal + ch; @@ -328,7 +323,7 @@ LPSTR FillSymbolSearchPath(CQuickBytes &qb) return NULL; } chTotal += ch; - rcBuff[chTotal++] = W(';'); + rcBuff.Append(W(';')); } #ifndef SELF_NO_HOST @@ -336,8 +331,10 @@ LPSTR FillSymbolSearchPath(CQuickBytes &qb) // in case URTARGET didn't cut it either. // For no-host builds of utilcode, we don't necessarily have an engine DLL in the // process, so skip this part. - ch = WszGetModuleFileName(GetCLRModuleHack(), - &rcBuff[chTotal], MAX_SYM_PATH - chTotal); + + ch = WszGetModuleFileName(GetCLRModuleHack(), rcBuffTemp); + + size_t pathLocationLength = chTotal + ch + 1; // integer overflow occurred if (pathLocationLength < (size_t)chTotal || pathLocationLength < (size_t)ch) @@ -348,14 +345,10 @@ LPSTR FillSymbolSearchPath(CQuickBytes &qb) if (ch != 0 && (pathLocationLength < MAX_SYM_PATH)) { chTotal = chTotal + ch - NumItems(STR_ENGINE_NAME); - rcBuff[chTotal++] = W(';'); - rcBuff[chTotal] = 0; + rcBuff.Append(W(';')); } #endif - // We want to ensure the resulting string is always NULL-terminated. - rcBuff[MAX_SYM_PATH-1] = W('\0'); - // Now we have a working buffer with a bunch of interesting stuff. Time // to convert it back to ansi for the imagehlp api's. Allocate the buffer // 2x bigger to handle worst case for MBCS. @@ -366,7 +359,29 @@ LPSTR FillSymbolSearchPath(CQuickBytes &qb) WszWideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, rcBuff, -1, szRtn, ch+1, 0, 0); return (szRtn); } +LPSTR FillSymbolSearchPath(CQuickBytes &qb) +{ + STATIC_CONTRACT_NOTHROW; + STATIC_CONTRACT_GC_NOTRIGGER; + STATIC_CONTRACT_CANNOT_TAKE_LOCK; + SCAN_IGNORE_FAULT; // Faults from Wsz funcs are handled. + LPSTR retval; + HRESULT hr = S_OK; + EX_TRY + { + retval = FillSymbolSearchPathThrows(qb); + } + EX_CATCH_HRESULT(hr); + + if (hr != S_OK) + { + SetLastError(hr); + retval = NULL; + } + + return retval; +} /**************************************************************************** * MagicInit * diff --git a/src/utilcode/util.cpp b/src/utilcode/util.cpp index 6c5378e5d979..dcc6b83e21ed 100644 --- a/src/utilcode/util.cpp +++ b/src/utilcode/util.cpp @@ -3238,6 +3238,8 @@ FileLockHolder::~FileLockHolder() void FileLockHolder::Acquire(LPCWSTR lockName, HANDLE hInterrupt, BOOL* pInterrupted) { + WRAPPER_NO_CONTRACT; + DWORD dwErr = 0; DWORD dwAccessDeniedRetry = 0; const DWORD MAX_ACCESS_DENIED_RETRIES = 10; @@ -3557,53 +3559,7 @@ BOOL IsClrHostedLegacyComObject(REFCLSID rclsid) } #endif // FEATURE_COMINTEROP -// Returns the directory for HMODULE. So, if HMODULE was for "C:\Dir1\Dir2\Filename.DLL", -// then this would return "C:\Dir1\Dir2\" (note the trailing backslash). -HRESULT GetHModuleDirectory( - __in HMODULE hMod, - __out_z __out_ecount(cchPath) LPWSTR wszPath, - size_t cchPath) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - CANNOT_TAKE_LOCK; - } - CONTRACTL_END; - - DWORD dwRet = WszGetModuleFileName(hMod, wszPath, static_cast(cchPath)); - if (dwRet == cchPath) - { // If there are cchPath characters in the string, it means that the string - // itself is longer than cchPath and GetModuleFileName had to truncate at cchPath. - return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - } - else if (dwRet == 0) - { // Some other error. - return HRESULT_FROM_GetLastError(); - } - - LPWSTR wszEnd = wcsrchr(wszPath, W('\\')); - if (wszEnd == NULL) - { // There was no backslash? Not sure what's going on. - return E_UNEXPECTED; - } - - // Include the backslash in the resulting string. - *(++wszEnd) = W('\0'); - - return S_OK; -} - -SString & GetHModuleDirectory(HMODULE hMod, SString &ssDir) -{ - LPWSTR wzDir = ssDir.OpenUnicodeBuffer(_MAX_PATH); - HRESULT hr = GetHModuleDirectory(hMod, wzDir, _MAX_PATH); - ssDir.CloseBuffer(FAILED(hr) ? 0 : static_cast(wcslen(wzDir))); - IfFailThrow(hr); - return ssDir; -} #if !defined(FEATURE_CORECLR) && !defined(SELF_NO_HOST) && !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) @@ -3936,39 +3892,14 @@ namespace Win32 // Try to use what the SString already has allocated. If it does not have anything allocated // or it has < 20 characters allocated, then bump the size requested to _MAX_PATH. - DWORD dwSize = (DWORD)(ssFileName.GetUnicodeAllocation()) + 1; - dwSize = (dwSize < 20) ? (_MAX_PATH) : (dwSize); - DWORD dwResult = WszGetModuleFileName(hModule, ssFileName.OpenUnicodeBuffer(dwSize - 1), dwSize); + + DWORD dwResult = WszGetModuleFileName(hModule, ssFileName); - // if there was a failure, dwResult == 0; - // if there was insufficient buffer, dwResult == dwSize; - // if there was sufficient buffer and a successful write, dwResult < dwSize - ssFileName.CloseBuffer(dwResult < dwSize ? dwResult : 0); if (dwResult == 0) ThrowHR(HRESULT_FROM_GetLastError()); - // Ok, we didn't have enough buffer. Let's loop, doubling the buffer each time, until we succeed. - while (dwResult == dwSize) - { - dwSize = dwSize * 2; - dwResult = WszGetModuleFileName(hModule, ssFileName.OpenUnicodeBuffer(dwSize - 1), dwSize); - ssFileName.CloseBuffer(dwResult < dwSize ? dwResult : 0); - - if (dwResult == 0) - ThrowHR(HRESULT_FROM_GetLastError()); - } - - // Most of the runtime is not able to handle long filenames. fAllowLongFileNames - // has a default value of false, so that callers will not accidentally get long - // file names returned. - if (!fAllowLongFileNames && ssFileName.BeginsWith(SL(LONG_FILENAME_PREFIX_W))) - { - ssFileName.Clear(); - ThrowHR(E_UNEXPECTED); - } - - _ASSERTE(dwResult != 0 && dwResult < dwSize); + _ASSERTE(dwResult != 0 ); } // Returns heap-allocated string in *pwszFileName @@ -4030,16 +3961,6 @@ namespace Win32 if (!(dwLengthWritten < dwLengthRequired)) ThrowHR(E_UNEXPECTED); - // Most of the runtime is not able to handle long filenames. fAllowLongFileNames - // has a default value of false, so that callers will not accidentally get long - // file names returned. - if (!fAllowLongFileNames && ssFileName.BeginsWith(SL(LONG_FILENAME_PREFIX_W))) - { - ssPathName.Clear(); - if (pdwFilePartIdx != NULL) - *pdwFilePartIdx = 0; - ThrowHR(E_UNEXPECTED); - } } } // namespace Win32 diff --git a/src/utilcode/util_nodependencies.cpp b/src/utilcode/util_nodependencies.cpp index 0628637d3372..32d1c3550929 100644 --- a/src/utilcode/util_nodependencies.cpp +++ b/src/utilcode/util_nodependencies.cpp @@ -302,7 +302,6 @@ BOOL GetRegistryLongValue(HKEY hKeyParent, // // Arguments: // pBuffer - output string buffer -// pcchBuffer - the number of characters of the string buffer // // Return Value: // S_OK on success, else detailed error code. @@ -310,39 +309,19 @@ BOOL GetRegistryLongValue(HKEY hKeyParent, // Note: // //---------------------------------------------------------------------------- -HRESULT GetCurrentModuleFileName(__out_ecount(*pcchBuffer) LPWSTR pBuffer, __inout DWORD *pcchBuffer) +HRESULT GetCurrentModuleFileName(SString& pBuffer) { LIMITED_METHOD_CONTRACT; - if ((pBuffer == NULL) || (pcchBuffer == NULL)) - { - return E_INVALIDARG; - } - - // Get the appname to look up in the exclusion or inclusion list. - WCHAR appPath[MAX_LONGPATH + 2]; - - DWORD ret = WszGetModuleFileName(NULL, appPath, NumItems(appPath)); + + DWORD ret = WszGetModuleFileName(NULL, pBuffer); - if ((ret == NumItems(appPath)) || (ret == 0)) + if (ret == 0) { - // The module file name exceeded maxpath, or GetModuleFileName failed. return E_UNEXPECTED; } - // Pick off the part after the path. - WCHAR* appName = wcsrchr(appPath, W('\\')); - - // If no backslash, use the whole name; if there is a backslash, skip it. - appName = appName ? appName+1 : appPath; - - if (*pcchBuffer < wcslen(appName)) - { - *pcchBuffer = static_cast(wcslen(appName)) + 1; - return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - } - - wcscpy_s(pBuffer, *pcchBuffer, appName); + return S_OK; } @@ -383,11 +362,10 @@ BOOL IsCurrentModuleFileNameInAutoExclusionList() return FALSE; } - WCHAR wszAppName[MAX_LONGPATH]; - DWORD cchAppName = NumItems(wszAppName); - + PathString wszAppName; + // Get the appname to look up in the exclusion or inclusion list. - if (GetCurrentModuleFileName(wszAppName, &cchAppName) != S_OK) + if (GetCurrentModuleFileName(wszAppName) != S_OK) { // Assume it is not on the exclusion list if we cannot find the module's filename. return FALSE; @@ -552,12 +530,11 @@ HRESULT GetDebuggerSettingInfoWorker(__out_ecount_part_opt(*pcchDebuggerString, BOOL fAuto = FALSE; // Get the appname to look up in DebugApplications key. - WCHAR wzAppName[MAX_LONGPATH]; - DWORD cchAppName = NumItems(wzAppName); + PathString wzAppName; long iValue; // Check DebugApplications setting - if ((SUCCEEDED(GetCurrentModuleFileName(wzAppName, &cchAppName))) && + if ((SUCCEEDED(GetCurrentModuleFileName(wzAppName))) && ( GetRegistryLongValue(HKEY_LOCAL_MACHINE, kDebugApplicationsPoliciesKey, wzAppName, &iValue, TRUE) || GetRegistryLongValue(HKEY_LOCAL_MACHINE, kDebugApplicationsKey, wzAppName, &iValue, TRUE) || diff --git a/src/utilcode/utilcode.settings.targets b/src/utilcode/utilcode.settings.targets index fcb41dc0a4fa..690000d40273 100644 --- a/src/utilcode/utilcode.settings.targets +++ b/src/utilcode/utilcode.settings.targets @@ -38,6 +38,7 @@ + diff --git a/src/utilcode/utilmessagebox.cpp b/src/utilcode/utilmessagebox.cpp index e84ff8b2c678..4559d16b7f0d 100644 --- a/src/utilcode/utilmessagebox.cpp +++ b/src/utilcode/utilmessagebox.cpp @@ -354,20 +354,19 @@ int UtilMessageBoxNonLocalizedVA( StackSString formattedMessage; StackSString formattedTitle; SString details(lpDetails); - StackSString fileName; + PathString fileName; BOOL fDisplayMsgBox = TRUE; // Format message string using optional parameters formattedMessage.VPrintf(lpText, args); // Try to get filename of Module and add it to title - if (showFileNameInTitle && WszGetModuleFileName(NULL, fileName.OpenUnicodeBuffer(MAX_LONGPATH), MAX_LONGPATH)) + if (showFileNameInTitle && WszGetModuleFileName(NULL, fileName)) { LPCWSTR wszName = NULL; size_t cchName = 0; - // Close the buffer we opened before the call to WszGetModuleFileName. - fileName.CloseBuffer(); + SplitPathInterior(fileName, NULL, NULL, NULL, NULL, &wszName, &cchName, NULL, NULL); formattedTitle.Printf(W("%s - %s"), wszName, lpTitle); diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp index 9ab8c7dbc098..a841423ace6f 100644 --- a/src/vm/appdomain.cpp +++ b/src/vm/appdomain.cpp @@ -4770,12 +4770,10 @@ void SystemDomain::GetDevpathW(__out_ecount_opt(1) LPWSTR* pDevpath, DWORD* pdwD if(m_fDevpath == FALSE) { DWORD dwPath = 0; - dwPath = WszGetEnvironmentVariable(APPENV_DEVPATH, 0, 0); + PathString m_pwDevpathholder; + dwPath = WszGetEnvironmentVariable(APPENV_DEVPATH, m_pwDevpathholder); if(dwPath) { - m_pwDevpath = (WCHAR*) new WCHAR[dwPath]; - m_dwDevpath = WszGetEnvironmentVariable(APPENV_DEVPATH, - m_pwDevpath, - dwPath); + m_pwDevpath = m_pwDevpathholder.GetCopyOfUnicodeString(); } else { RegKeyHolder userKey; @@ -13831,14 +13829,30 @@ DWORD* SetupCompatibilityFlags() SO_TOLERANT; } CONTRACTL_END; - WCHAR buf[2] = { '\0', '\0' }; + LPCWSTR buf; + bool return_null = true; FAULT_NOT_FATAL(); // we can simply give up - if (WszGetEnvironmentVariable(W("UnsupportedCompatSwitchesEnabled"), buf, COUNTOF(buf)) == 0) - return NULL; + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return NULL;) + InlineSString<4> bufString; + + if (WszGetEnvironmentVariable(W("UnsupportedCompatSwitchesEnabled"), bufString) != 0) + { + buf = bufString.GetUnicode(); + if (buf[0] != '1' || buf[1] != '\0') + { + return_null = true; + } + else + { + return_null = false; + } + + } + END_SO_INTOLERANT_CODE - if (buf[0] != '1' || buf[1] != '\0') + if (return_null) return NULL; static const LPCWSTR rgFlagNames[] = { @@ -13852,17 +13866,21 @@ DWORD* SetupCompatibilityFlags() return NULL; ZeroMemory(pFlags, size * sizeof(DWORD)); + BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return NULL;) + InlineSString<4> bufEnvString; for (int i = 0; i < COUNTOF(rgFlagNames); i++) { - if (WszGetEnvironmentVariable(rgFlagNames[i], buf, COUNTOF(buf)) == 0) + if (WszGetEnvironmentVariable(rgFlagNames[i], bufEnvString) == 0) continue; + buf = bufEnvString.GetUnicode(); if (buf[0] != '1' || buf[1] != '\0') continue; pFlags[i / 32] |= 1 << (i % 32); } - + END_SO_INTOLERANT_CODE + return pFlags; } diff --git a/src/vm/assemblynative.cpp b/src/vm/assemblynative.cpp index 5720c201edbc..c89e92740496 100644 --- a/src/vm/assemblynative.cpp +++ b/src/vm/assemblynative.cpp @@ -2364,8 +2364,8 @@ void QCALLTYPE AssemblyNative::CreateVersionInfoResource(LPCWSTR pwzFilename, const void *pvData=0; // Pointer to the resource. ULONG cbData; // Size of the resource data. ULONG cbWritten; - WCHAR szFile[MAX_PATH_FNAME+1]; // File name for resource file. - WCHAR szPath[MAX_LONGPATH+1]; // Path name for resource file. + PathString szFile; // File name for resource file. + PathString szPath; // Path name for resource file. HandleHolder hFile; res.SetInfo(pwzFilename, @@ -2387,9 +2387,9 @@ void QCALLTYPE AssemblyNative::CreateVersionInfoResource(LPCWSTR pwzFilename, // messages including the path/file name // Persist to a file. - if (!WszGetTempPath(MAX_LONGPATH, szPath)) + if (!WszGetTempPath(szPath)) COMPlusThrowWin32(); - if (!WszGetTempFileName(szPath, W("RES"), 0, szFile)) + if (!WszGetTempFileName(szPath.GetUnicode(), W("RES"), 0, szFile)) COMPlusThrowWin32(); hFile = WszCreateFile(szFile, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp index d6391056abb9..e2419ac88fe1 100644 --- a/src/vm/ceemain.cpp +++ b/src/vm/ceemain.cpp @@ -2978,9 +2978,9 @@ static BOOL CacheCommandLine(__in LPWSTR pCmdLine, __in_opt LPWSTR* ArgvW) } if (ArgvW != NULL && ArgvW[0] != NULL) { - WCHAR wszModuleName[MAX_LONGPATH]; - WCHAR wszCurDir[MAX_LONGPATH]; - if (!WszGetCurrentDirectory(MAX_LONGPATH, wszCurDir)) + PathString wszModuleName; + PathString wszCurDir; + if (!WszGetCurrentDirectory(wszCurDir)) return FALSE; #ifdef _PREFAST_ @@ -2991,17 +2991,17 @@ static BOOL CacheCommandLine(__in LPWSTR pCmdLine, __in_opt LPWSTR* ArgvW) // usage of PathCombine is safe if we ensure that buffer specified by // parameter1 can accomodate buffers specified by paramater2, parameter3 // and one path separator - if (lstrlenW(wszCurDir) + lstrlenW(ArgvW[0]) + 1 >= COUNTOF(wszModuleName)) - return FALSE; + COUNT_T wszModuleName_len = wszCurDir.GetCount() + lstrlenW(ArgvW[0]); + WCHAR* wszModuleName_buf = wszModuleName.OpenUnicodeBuffer(wszModuleName_len); - if (PathCombine(wszModuleName, wszCurDir, ArgvW[0]) == NULL) + if (PathCombine(wszModuleName_buf, wszCurDir, ArgvW[0]) == NULL) return FALSE; - + wszModuleName.CloseBuffer(); #ifdef _PREFAST_ #pragma warning(pop) #endif - size_t len = wcslen(wszModuleName); + size_t len = wszModuleName.GetCount(); _ASSERT(g_pCachedModuleFileName== NULL); g_pCachedModuleFileName = new WCHAR[len+1]; wcscpy_s(g_pCachedModuleFileName, len+1, wszModuleName); @@ -3824,7 +3824,7 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error. CoreClrCallbacks cccallbacks; cccallbacks.m_hmodCoreCLR = (HINSTANCE)g_pMSCorEE; cccallbacks.m_pfnIEE = IEE; - cccallbacks.m_pfnGetCORSystemDirectory = GetCORSystemDirectoryInternal; + cccallbacks.m_pfnGetCORSystemDirectory = GetCORSystemDirectoryInternaL; cccallbacks.m_pfnGetCLRFunction = GetCLRFunction; InitUtilcode(cccallbacks); @@ -4279,30 +4279,47 @@ static HRESULT InitializeIPCManager(void) { // We failed to create the IPC block because it has already been created. This means that // two mscoree's have been loaded into the process. - WCHAR strFirstModule[256]; - WCHAR strSecondModule[256]; - - // Get the name and path of the first loaded MSCOREE.DLL. - if (!hInstIPCBlockOwner || !WszGetModuleFileName(hInstIPCBlockOwner, strFirstModule, 256)) - wcscpy_s(strFirstModule, COUNTOF(strFirstModule), W("")); - - // Get the name and path of the second loaded MSCOREE.DLL. - if (!WszGetModuleFileName(g_pMSCorEE, strSecondModule, 256)) - wcscpy_s(strSecondModule, COUNTOF(strSecondModule), W("")); + PathString strFirstModule; + PathString strSecondModule; + EX_TRY + { + // Get the name and path of the first loaded MSCOREE.DLL. + if (!hInstIPCBlockOwner || !WszGetModuleFileName(hInstIPCBlockOwner, strFirstModule)) + strFirstModule.Set(W("")); + // Get the name and path of the second loaded MSCOREE.DLL. + if (!WszGetModuleFileName(g_pMSCorEE, strSecondModule)) + strSecondModule.Set(W("")); + } + EX_CATCH_HRESULT(hr); // Load the format strings for the title and the message body. EEMessageBoxCatastrophic(IDS_EE_TWO_LOADED_MSCOREE_MSG, IDS_EE_TWO_LOADED_MSCOREE_TITLE, strFirstModule, strSecondModule); goto errExit; } else { - if (!WszGetModuleFileName(GetModuleInst(), (PWSTR) - g_pIPCManagerInterface-> - GetInstancePath(), - MAX_LONGPATH)) + PathString temp; + if (!WszGetModuleFileName(GetModuleInst(), + temp + )) { hr = HRESULT_FROM_GetLastErrorNA(); } + else + { + EX_TRY + { + if (temp.GetCount() + 1 > MAX_LONGPATH) + { + hr = E_FAIL; + } + else + { + wcscpy_s((PWSTR)g_pIPCManagerInterface->GetInstancePath(),temp.GetCount() + 1,temp); + } + } + EX_CATCH_HRESULT(hr); + } } // Generate public IPCBlock for our PID. @@ -4915,11 +4932,12 @@ HRESULT CorCommandLine::ReadClickOnceEnvVariables() EX_TRY { // Find out if this is a ClickOnce application being activated. - DWORD cAppFullName = WszGetEnvironmentVariable(g_pwzClickOnceEnv_FullName, NULL, 0); + PathString m_pwszAppFullNameHolder; + DWORD cAppFullName = WszGetEnvironmentVariable(g_pwzClickOnceEnv_FullName, m_pwszAppFullNameHolder); if (cAppFullName > 0) { // get the application full name. - m_pwszAppFullName = new WCHAR[cAppFullName]; - WszGetEnvironmentVariable(g_pwzClickOnceEnv_FullName, m_pwszAppFullName, cAppFullName); + m_pwszAppFullName = m_pwszAppFullNameHolder.GetCopyOfUnicodeString(); + // reset the variable now that we read it so child processes // do not think they are a clickonce app. WszSetEnvironmentVariable(g_pwzClickOnceEnv_FullName, NULL); @@ -4933,7 +4951,8 @@ HRESULT CorCommandLine::ReadClickOnceEnvVariables() _itow_s(dwManifestPaths, buf.OpenUnicodeBuffer(size), size, 10); buf.CloseBuffer(); manifestFile.Append(buf); - if (WszGetEnvironmentVariable(manifestFile.GetUnicode(), NULL, 0) > 0) + SString temp; + if (WszGetEnvironmentVariable(manifestFile.GetUnicode(), temp) > 0) dwManifestPaths++; else break; @@ -4946,10 +4965,11 @@ HRESULT CorCommandLine::ReadClickOnceEnvVariables() _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10); buf.CloseBuffer(); manifestFile.Append(buf); - DWORD cManifestPath = WszGetEnvironmentVariable(manifestFile.GetUnicode(), NULL, 0); + PathString m_ppwszManifestPathsHolder; + DWORD cManifestPath = WszGetEnvironmentVariable(manifestFile.GetUnicode(), m_ppwszManifestPathsHolder); if (cManifestPath > 0) { - m_ppwszManifestPaths[i] = new WCHAR[cManifestPath]; - WszGetEnvironmentVariable(manifestFile.GetUnicode(), m_ppwszManifestPaths[i], cManifestPath); + + m_ppwszManifestPaths[i] = m_ppwszManifestPathsHolder.GetCopyOfUnicodeString(); WszSetEnvironmentVariable(manifestFile.GetUnicode(), NULL); // reset the env. variable. } } @@ -4964,7 +4984,8 @@ HRESULT CorCommandLine::ReadClickOnceEnvVariables() _itow_s(dwActivationData, buf.OpenUnicodeBuffer(size), size, 10); buf.CloseBuffer(); activationData.Append(buf); - if (WszGetEnvironmentVariable(activationData.GetUnicode(), NULL, 0) > 0) + SString temp; + if (WszGetEnvironmentVariable(activationData.GetUnicode(), temp) > 0) dwActivationData++; else break; @@ -4977,10 +4998,10 @@ HRESULT CorCommandLine::ReadClickOnceEnvVariables() _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10); buf.CloseBuffer(); activationData.Append(buf); - DWORD cActivationData = WszGetEnvironmentVariable(activationData.GetUnicode(), NULL, 0); + PathString m_ppwszActivationDataHolder; + DWORD cActivationData = WszGetEnvironmentVariable(activationData.GetUnicode(), m_ppwszActivationDataHolder); if (cActivationData > 0) { - m_ppwszActivationData[i] = new WCHAR[cActivationData]; - WszGetEnvironmentVariable(activationData.GetUnicode(), m_ppwszActivationData[i], cActivationData); + m_ppwszActivationData[i] = m_ppwszActivationDataHolder.GetCopyOfUnicodeString(); WszSetEnvironmentVariable(activationData.GetUnicode(), NULL); // reset the env. variable. } } diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp index 9374a2c8a9f6..4f99539215b4 100644 --- a/src/vm/codeman.cpp +++ b/src/vm/codeman.cpp @@ -1386,10 +1386,12 @@ static void LoadAndInitializeJIT(LPCWSTR pwzJitName, OUT HINSTANCE* phJit, OUT I HRESULT hr = E_FAIL; #ifdef FEATURE_MERGE_JIT_AND_ENGINE - WCHAR CoreClrFolder[MAX_LONGPATH + 1]; + PathString CoreClrFolderHolder; extern HINSTANCE g_hThisInst; - if (WszGetModuleFileName(g_hThisInst, CoreClrFolder, MAX_LONGPATH)) + if (WszGetModuleFileName(g_hThisInst, CoreClrFolderHolder)) { + DWORD len = CoreClrFolderHolder.GetCount(); + WCHAR* CoreClrFolder = CoreClrFolderHolder.OpenUnicodeBuffer(len); WCHAR *filePtr = wcsrchr(CoreClrFolder, DIRECTORY_SEPARATOR_CHAR_W); if (filePtr) { @@ -1401,6 +1403,7 @@ static void LoadAndInitializeJIT(LPCWSTR pwzJitName, OUT HINSTANCE* phJit, OUT I hr = S_OK; } } + CoreClrFolderHolder.CloseBuffer(); } #else hr = g_pCLRRuntime->LoadLibrary(pwzJitName, phJit); diff --git a/src/vm/corhost.cpp b/src/vm/corhost.cpp index 2a7cf4524905..f0e90291b770 100644 --- a/src/vm/corhost.cpp +++ b/src/vm/corhost.cpp @@ -2471,10 +2471,9 @@ HRESULT CorHost2::ExecuteMain( AppDomain *pDomain = GetAppDomain(); _ASSERTE(pDomain); - WCHAR wzExeFileName[_MAX_PATH]; - DWORD cchExeFileName = _MAX_PATH; - cchExeFileName = WszGetModuleFileName(nullptr, wzExeFileName, cchExeFileName); - if (cchExeFileName == _MAX_PATH) + PathString wzExeFileName; + + if (WszGetModuleFileName(nullptr, wzExeFileName) == 0) IfFailThrow(E_UNEXPECTED); LPWSTR wzExeSimpleFileName = nullptr; diff --git a/src/vm/dwbucketmanager.hpp b/src/vm/dwbucketmanager.hpp index 48746d4816e7..a3aef9b2a8f1 100644 --- a/src/vm/dwbucketmanager.hpp +++ b/src/vm/dwbucketmanager.hpp @@ -323,7 +323,6 @@ class BaseBucketParamsManager void FindFaultingMethodInfo(); OBJECTREF GetRealExceptionObject(); WCHAR* GetParamBufferForIndex(BucketParameterIndex paramIndex); - int CopyStringToBucket(__out_ecount(targetMaxLength) LPWSTR pTargetParam, int targetMaxLength, __in_z LPCWSTR pSource, bool cannonicalize = false); void LogParam(__in_z LPCWSTR paramValue, BucketParameterIndex paramIndex); protected: @@ -349,7 +348,7 @@ class BaseBucketParamsManager public: BaseBucketParamsManager(GenericModeBlock* pGenericModeBlock, TypeOfReportedError typeOfError, PCODE initialFaultingPc, Thread* pFaultingThread, OBJECTREF* pThrownException); - + static int CopyStringToBucket(__out_ecount(targetMaxLength) LPWSTR pTargetParam, int targetMaxLength, __in_z LPCWSTR pSource, bool cannonicalize = false); // function that consumers should call to populate the GMB virtual void PopulateBucketParameters() = 0; }; @@ -485,10 +484,10 @@ void BaseBucketParamsManager::GetAppName(__out_ecount(maxLength) WCHAR* targetPa CONTRACTL_END; HMODULE hModule = WszGetModuleHandle(NULL); - WCHAR appPath[MAX_LONGPATH]; - DWORD cchAppPath = NumItems(appPath); + PathString appPath; + - if (GetCurrentModuleFileName(appPath, &cchAppPath) == S_OK) + if (GetCurrentModuleFileName(appPath) == S_OK) { CopyStringToBucket(targetParam, maxLength, appPath); } @@ -509,13 +508,13 @@ void BaseBucketParamsManager::GetAppVersion(__out_ecount(maxLength) WCHAR* targe CONTRACTL_END; HMODULE hModule = WszGetModuleHandle(NULL); - WCHAR appPath[MAX_LONGPATH]; - DWORD cchAppPath = NumItems(appPath); + PathString appPath; + WCHAR verBuf[23] = {0}; USHORT major, minor, build, revision; - if ((GetCurrentModuleFileName(appPath, &cchAppPath) == S_OK) && SUCCEEDED(DwGetFileVersionInfo(appPath, major, minor, build, revision))) + if ((GetCurrentModuleFileName(appPath) == S_OK) && SUCCEEDED(DwGetFileVersionInfo(appPath, major, minor, build, revision))) { _snwprintf_s(targetParam, maxLength, diff --git a/src/vm/dwreport.cpp b/src/vm/dwreport.cpp index 15a58c070196..77669b2f1453 100644 --- a/src/vm/dwreport.cpp +++ b/src/vm/dwreport.cpp @@ -214,15 +214,6 @@ BOOL RegisterOutOfProcessWatsonCallbacks() CONTRACTL_END; WCHAR wszDACName[] = MAIN_DAC_MODULE_NAME_W W(".dll"); - WCHAR wszDACPath[MAX_LONGPATH]; - DWORD dwSize = 0; - - if ((FAILED(::GetCORSystemDirectoryInternal(wszDACPath, NumItems(wszDACPath), &dwSize))) || - (wcscat_s(wszDACPath, _countof(wszDACPath), wszDACName) != 0)) - { - return FALSE; - } - WerModuleHolder hWerModule(WER_MODULE_NAME_W); #ifdef FEATURE_CORESYSTEM @@ -250,8 +241,23 @@ BOOL RegisterOutOfProcessWatsonCallbacks() { return FALSE; } + HRESULT hr = S_OK; - HRESULT hr = (*pFnWerRegisterRuntimeExceptionModule)(wszDACPath, (PDWORD)g_pMSCorEE); + EX_TRY + { + PathString wszDACPath; + if (SUCCEEDED(::GetCORSystemDirectoryInternaL(wszDACPath))) + { + wszDACPath.Append(wszDACName); + hr = (*pFnWerRegisterRuntimeExceptionModule)(wszDACPath, (PDWORD)g_pMSCorEE); + } + else { + hr = E_FAIL; + } + + } + EX_CATCH_HRESULT(hr); + if (FAILED(hr)) { STRESS_LOG0(LF_STARTUP, @@ -562,9 +568,9 @@ HRESULT DwCheckCompany( // S_OK or error. // None //------------------------------------------------------------------------------ int DwGetAppDescription( // Number of characters written. - __in_z LPWSTR wszFilePath, // Path to the executable. - __inout_ecount(cchBuf) WCHAR *pBuf, // Put description here. - int cchBuf) // Size of buf, wide chars. + __in_z LPCWSTR wszFilePath, // Path to the executable. + SString& pBuf // Put description here. + ) // Size of buf, wide chars. { CONTRACTL { @@ -663,8 +669,17 @@ int DwGetAppDescription( // Number of characters written. } // Copy back the description. - size = (int)size > cchBuf-1 ? cchBuf-1 : size; - wcsncpy_s(pBuf, cchBuf, fileDescription, size); + EX_TRY + { + wcsncpy_s(pBuf.OpenUnicodeBuffer(size), size, fileDescription, size); + pBuf.CloseBuffer(size); + } + EX_CATCH + { + size = 0; + } + EX_END_CATCH(SwallowAllExceptions); + return size; } // int DwGetAppDescription() @@ -685,7 +700,7 @@ int DwGetAppDescription( // Number of characters written. // None //------------------------------------------------------------------------------ int DwGetAssemblyVersion( // Number of characters written. - __in_z LPWSTR wszFilePath, // Path to the executable. + __in_z LPCWSTR wszFilePath, // Path to the executable. __inout_ecount(cchBuf) WCHAR *pBuf, // Put description here. int cchBuf) // Size of buf, wide chars. { @@ -1469,88 +1484,99 @@ BOOL RunWatson( memset(&startupInfo, 0, sizeof(STARTUPINFOW)); startupInfo.cb = sizeof(STARTUPINFOW); + HRESULT hr = S_OK; + PathString watsonAppName; + PathString watsonCommandLine; + EX_TRY + { + do + { - WCHAR watsonAppName[MAX_LONGPATH]; - WCHAR watsonCommandLine[MAX_LONGPATH+1]; - { -#if !defined(FEATURE_CORECLR) - // Use the version of DW20.exe that lives in the system directory. - DWORD ret; + - if (FAILED(GetCORSystemDirectoryInternal(watsonAppName, NumItems(watsonAppName), &ret))) - { - return false; - } - if (wcsncat_s(watsonAppName, NumItems(watsonAppName), kWatsonImageNameOnVista, _TRUNCATE) != 0) - { - return false; - } -#else // FEATURE_CORECLR - HKEYHolder hKey; - // Look for key \\HKLM\Software\Microsoft\PCHealth\ErrorReporting\DW\Installed" - DWORD ret = WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, - kWatsonPath, - 0, - KEY_READ | kWatsonRegKeyOptions, - &hKey); - - if (ERROR_SUCCESS != ret) { - return false; - } + #if !defined(FEATURE_CORECLR) + // Use the version of DW20.exe that lives in the system directory. + DWORD ret; + if (FAILED(GetCORSystemDirectoryInternaL(watsonAppName))) + { + hr = E_FAIL; + break; + } + watsonCommandLine.Set(watsonAppName); + watsonCommandLine.Append(kWatsonImageNameOnVista); + + #else // FEATURE_CORECLR + HKEYHolder hKey; + // Look for key \\HKLM\Software\Microsoft\PCHealth\ErrorReporting\DW\Installed" + DWORD ret = WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, + kWatsonPath, + 0, + KEY_READ | kWatsonRegKeyOptions, + &hKey); + + if (ERROR_SUCCESS != ret) + { + hr = E_FAIL; + break; + } - // Look in ...\DW\Installed for dw0200 (dw0201 on ia64). This will be - // the full path to the executable. - DWORD size = NumItems(watsonAppName); - ret = WszRegQueryValueEx(hKey, - kWatsonValue, - NULL, - NULL, - reinterpret_cast< LPBYTE >(watsonAppName), - &size); - - if (ERROR_SUCCESS != ret) - { - return false; - } -#endif // ! FEATURE_CORECLR + // Look in ...\DW\Installed for dw0200 (dw0201 on ia64). This will be + // the full path to the executable. + + ClrRegReadString(hKey, kWatsonValue, watsonAppName); + + #endif // ! FEATURE_CORECLR - _snwprintf_s(watsonCommandLine, - NumItems(watsonCommandLine)-1, - _TRUNCATE, - W("dw20.exe -x -s %lu"), - PtrToUlong(hWatsonSharedMemory)); - watsonCommandLine[NumItems(watsonCommandLine) - 1] = W('\0'); + COUNT_T len = watsonCommandLine.GetCount(); + WCHAR* buffer = watsonCommandLine.OpenUnicodeBuffer(len); + _snwprintf_s(buffer, + len, + _TRUNCATE, + W("dw20.exe -x -s %lu"), + PtrToUlong(hWatsonSharedMemory)); + watsonCommandLine.CloseBuffer(); + + } + } while (false); } + EX_CATCH_HRESULT(hr); + if (hr != S_OK) { - BOOL ret = WszCreateProcess(watsonAppName, - watsonCommandLine, - NULL, - NULL, - TRUE, - NULL, - NULL, - NULL, - &startupInfo, - &processInformation); + return false; + } - if (FALSE == ret) { - // - // Watson failed to start up. - // - // This can happen if e.g. Watson wasn't installed on the machine. - // - HRESULT hr = HRESULT_FROM_GetLastErrorNA(); - return false; + BOOL ret = WszCreateProcess(watsonAppName, + watsonCommandLine, + NULL, + NULL, + TRUE, + NULL, + NULL, + NULL, + &startupInfo, + &processInformation); + + if (FALSE == ret) + { + // + // Watson failed to start up. + // + // This can happen if e.g. Watson wasn't installed on the machine. + // + return E_FAIL; + + } + } - } + // Wait for watson to finish. // @@ -2426,9 +2452,11 @@ FaultReportResult DoFaultReportWorker( // Was Watson attempted, successful? pWatsonSharedMemory->bfmsoctdsLetRun = offerFlags; { + PathString wzModuleFileName; DWORD dwRet = WszGetModuleFileName(NULL, - pWatsonSharedMemory->wzModuleFileName, - NumItems(pWatsonSharedMemory->wzModuleFileName)); + wzModuleFileName); + BaseBucketParamsManager::CopyStringToBucket(pWatsonSharedMemory->wzModuleFileName, NumItems(pWatsonSharedMemory->wzModuleFileName), wzModuleFileName); + _ASSERTE(0 != dwRet); if (0 == dwRet) { @@ -2455,24 +2483,24 @@ FaultReportResult DoFaultReportWorker( // Was Watson attempted, successful? // do this just by using the executable name. // { - WCHAR buf[_MAX_PATH]; // Buffer for path for description. - WCHAR *pName = buf; // Pointer to filename or description. + PathString buf; // Buffer for path for description. + LPCWSTR pName ; // Pointer to filename or description. int size; // Size of description. HMODULE hModule; // Handle to module. DWORD result; // Return code // Get module name. hModule = WszGetModuleHandle(NULL); - result = WszGetModuleFileName(hModule, buf, NumItems(buf)); + result = WszGetModuleFileName(hModule, buf); if (result == 0) { // Couldn't get module name. This should never happen. - wcscpy_s(buf, COUNTOF(buf), W("<>")); + pName = W("<>"); } else { // re-use the buf for pathname and description. - size = DwGetAppDescription(buf, buf, NumItems(buf)); - + size = DwGetAppDescription(buf, buf); + pName = buf.GetUnicode(); // If the returned size was zero, buf wasn't changed, and still contains the path. // find just the filename part. if (size == 0) diff --git a/src/vm/dwreport.h b/src/vm/dwreport.h index a2750cefe79a..44306689ea7a 100644 --- a/src/vm/dwreport.h +++ b/src/vm/dwreport.h @@ -58,7 +58,7 @@ BOOL IsWatsonEnabled(); BOOL RegisterOutOfProcessWatsonCallbacks(); int DwGetAssemblyVersion( // Number of characters written. - __in_z LPWSTR wszFilePath, // Path to the executable. + __in_z LPCWSTR wszFilePath, // Path to the executable. __inout_ecount(cchBuf) WCHAR *pBuf, // Put description here. int cchBuf); diff --git a/src/vm/eeconfig.cpp b/src/vm/eeconfig.cpp index e322a63f5e83..973a4f4235a6 100644 --- a/src/vm/eeconfig.cpp +++ b/src/vm/eeconfig.cpp @@ -835,12 +835,12 @@ HRESULT EEConfig::sync() { bGCStressAndHeapVerifyAllowed = false; - WCHAR wszFileName[_MAX_PATH]; - if (WszGetModuleFileName(NULL, wszFileName, _MAX_PATH) != 0) + PathString wszFileName; + if (WszGetModuleFileName(NULL, wszFileName) != 0) { // just keep the name - LPWSTR pwszName = wcsrchr(wszFileName, W('\\')); - pwszName = (pwszName == NULL) ? wszFileName : (pwszName + 1); + LPCWSTR pwszName = wcsrchr(wszFileName, W('\\')); + pwszName = (pwszName == NULL) ? wszFileName.GetUnicode() : (pwszName + 1); if (SString::_wcsicmp(pwszName,pszGCStressExe) == 0) { @@ -1619,46 +1619,62 @@ HRESULT EEConfig::SetupConfiguration() // AppX process check to make sure no app.config file // exists unless launched with AO_DESIGNMODE. // ---------------------------------------------------- + + do { - WCHAR wzProcExe[_MAX_PATH]; - size_t cchProcExe = COUNTOF(wzProcExe); - - // Get name of file used to create process - if (g_pCachedModuleFileName) - { - IfFailRet(StringCchCopy(wzProcExe, COUNTOF(wzProcExe), g_pCachedModuleFileName)); - IfFailRet(StringCchLength(wzProcExe, COUNTOF(wzProcExe), &cchProcExe)); - } - else + size_t cchProcExe=0; + PathString wzProcExe; + EX_TRY { - cchProcExe = WszGetModuleFileName(NULL, wzProcExe, COUNTOF(wzProcExe)); - if (cchProcExe == 0) + + + // Get name of file used to create process + if (g_pCachedModuleFileName) { - return HRESULT_FROM_GetLastError(); + wzProcExe.Set(g_pCachedModuleFileName); + cchProcExe = wzProcExe.GetCount(); } - } + else + { + cchProcExe = WszGetModuleFileName(NULL, wzProcExe); - if (cchProcExe != 0) - { - IfFailRet(StringCchCat(wzProcExe, COUNTOF(wzProcExe), CONFIGURATION_EXTENSION)); + if (cchProcExe == 0) + { + hr = HRESULT_FROM_GetLastError(); + break; + } + } - if (AppX::IsAppXProcess() && !AppX::IsAppXDesignMode()) + if (cchProcExe != 0) { - if (clr::fs::Path::Exists(wzProcExe)) + wzProcExe.Append(CONFIGURATION_EXTENSION); + + if (AppX::IsAppXProcess() && !AppX::IsAppXDesignMode()) { - return CLR_E_APP_CONFIG_NOT_ALLOWED_IN_APPX_PROCESS; + if (clr::fs::Path::Exists(wzProcExe)) + { + hr = CLR_E_APP_CONFIG_NOT_ALLOWED_IN_APPX_PROCESS; + break; + } } } - + } + EX_CATCH_HRESULT(hr); + if (cchProcExe != 0) + { IfFailParseError(wzProcExe, true, AppendConfigurationFile(wzProcExe, version)); // We really should return a failure hresult if the app config file is bad, but that // would be a breaking change. Not sure if it's worth it yet. hr = S_OK; + break; } - } + } while (false); + + if (hr != S_OK) + return hr; // ---------------------------------------------------- // Import machine.config, if needed. // ---------------------------------------------------- diff --git a/src/vm/eepolicy.cpp b/src/vm/eepolicy.cpp index c67d06d596da..8c3f2ec6251a 100644 --- a/src/vm/eepolicy.cpp +++ b/src/vm/eepolicy.cpp @@ -530,11 +530,11 @@ void SafeExitProcess(UINT exitCode, BOOL fAbort = FALSE, ShutdownCompleteAction if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_BreakOnBadExit)) { // Workaround for aspnet - WCHAR wszFilename[_MAX_PATH]; + PathString wszFilename; bool bShouldAssert = true; - if (WszGetModuleFileName(NULL, wszFilename, _MAX_PATH)) + if (WszGetModuleFileName(NULL, wszFilename)) { - _wcslwr_s(wszFilename, COUNTOF(wszFilename)); + wszFilename.LowerCase(); if (wcsstr(wszFilename, W("aspnet_compiler"))) { diff --git a/src/vm/eventreporter.cpp b/src/vm/eventreporter.cpp index e07a6401cdac..567f4f5d51b6 100644 --- a/src/vm/eventreporter.cpp +++ b/src/vm/eventreporter.cpp @@ -47,8 +47,8 @@ EventReporter::EventReporter(EventReporterType type) m_eventType = type; HMODULE hModule = WszGetModuleHandle(NULL); - WCHAR appPath[MAX_LONGPATH]; - DWORD ret = WszGetModuleFileName(hModule, appPath, NumItems(appPath)); + PathString appPath; + DWORD ret = WszGetModuleFileName(hModule, appPath); fBufferFull = FALSE; @@ -65,7 +65,7 @@ EventReporter::EventReporter(EventReporterType type) if (ret != 0) { // If app name has a '\', consider the part after that; otherwise consider whole name. - WCHAR* appName = wcsrchr(appPath, W('\\')); + LPCWSTR appName = wcsrchr(appPath, W('\\')); appName = appName ? appName+1 : appPath; m_Description.Append(appName); m_Description.Append(W("\n")); @@ -808,8 +808,8 @@ void EventReporter::GetCoreCLRInstanceProductVersion(DWORD * pdwMajor, DWORD * p _ASSERTE(hModRuntime != NULL); // Get the path to the runtime - WCHAR runtimePath[MAX_LONGPATH]; - DWORD ret = WszGetModuleFileName(hModRuntime, runtimePath, NumItems(runtimePath)); + PathString runtimePath; + DWORD ret = WszGetModuleFileName(hModRuntime, runtimePath); if (ret != 0) { // Got the path - get the file version from the path diff --git a/src/vm/eventtrace.cpp b/src/vm/eventtrace.cpp index e6a25cc8532d..5e35f9a2b8f0 100644 --- a/src/vm/eventtrace.cpp +++ b/src/vm/eventtrace.cpp @@ -4869,7 +4869,7 @@ VOID ETW::InfoLog::RuntimeInformation(INT32 type) PCWSTR szDtraceOutput1=W(""),szDtraceOutput2=W(""); UINT8 startupMode = 0; UINT startupFlags = 0; - WCHAR dllPath[MAX_LONGPATH+1] = {0}; + PathString dllPath; UINT8 Sku = 0; _ASSERTE(g_fEEManagedEXEStartup || //CLR started due to a managed exe g_fEEIJWStartup || //CLR started as a mixed mode Assembly @@ -4899,7 +4899,7 @@ VOID ETW::InfoLog::RuntimeInformation(INT32 type) LPCGUID comGUID=&g_EEComObjectGuid; PCWSTR lpwszCommandLine = W(""); - PCWSTR lpwszRuntimeDllPath = (PCWSTR)dllPath; + #ifndef FEATURE_CORECLR startupFlags = CorHost2::GetStartupFlags(); @@ -4954,12 +4954,12 @@ VOID ETW::InfoLog::RuntimeInformation(INT32 type) startupMode = ETW::InfoLog::InfoStructs::Other; } - _ASSERTE (NumItems(dllPath) > MAX_LONGPATH); + // if WszGetModuleFileName fails, we return an empty string - if (!WszGetModuleFileName(GetCLRModule(), dllPath, MAX_LONGPATH)) { - dllPath[0] = 0; + if (!WszGetModuleFileName(GetCLRModule(), dllPath)) { + dllPath.Set(W("\0")); } - dllPath[MAX_LONGPATH] = 0; + if(type == ETW::InfoLog::InfoStructs::Callback) { @@ -4977,7 +4977,7 @@ VOID ETW::InfoLog::RuntimeInformation(INT32 type) startupMode, lpwszCommandLine, comGUID, - lpwszRuntimeDllPath ); + dllPath ); } else { @@ -4995,7 +4995,7 @@ VOID ETW::InfoLog::RuntimeInformation(INT32 type) startupMode, lpwszCommandLine, comGUID, - lpwszRuntimeDllPath ); + dllPath ); } } } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions); diff --git a/src/vm/mdaassistants.cpp b/src/vm/mdaassistants.cpp index de81a82f8336..cc598c0a6c49 100644 --- a/src/vm/mdaassistants.cpp +++ b/src/vm/mdaassistants.cpp @@ -995,12 +995,12 @@ void MdaPInvokeLog::LogPInvoke(NDirectMethodDesc* pMD, HINSTANCE hMod) StackSString sszEntryPoint; sszEntryPoint.SetUTF8(pMD->GetEntrypointName()); - WCHAR szDllFullName[_MAX_PATH] = {0}; + PathString szDllFullName ; WCHAR szDrive[_MAX_PATH] = {0}; WCHAR szPath[_MAX_PATH] = {0}; WCHAR szFileName[_MAX_PATH] = {0}; WCHAR szExt[_MAX_PATH] = {0}; - WszGetModuleFileName(hMod, szDllFullName, _MAX_PATH); + WszGetModuleFileName(hMod, szDllFullName); SplitPath(szDllFullName, szDrive, _MAX_PATH, szPath, _MAX_PATH, szFileName, _MAX_PATH, szExt, _MAX_PATH); StackSString sszDllName; @@ -1869,16 +1869,14 @@ void MdaLoaderLock::ReportViolation(HINSTANCE hInst) MdaXmlMessage msg(this->AsMdaAssistant(), TRUE, &pXml); DWORD cName = 0; - WCHAR szName[_MAX_PATH * 2]; + PathString szName; if (hInst) { - cName = _MAX_PATH * 2 - 1; - cName = WszGetModuleFileName(hInst, szName, cName); + cName = WszGetModuleFileName(hInst, szName); } if (cName) { - szName[cName] = W('\0'); msg.SendMessagef(MDARC_LOADER_LOCK_DLL, szName); } else diff --git a/src/vm/peimage.cpp b/src/vm/peimage.cpp index 27904ff47611..cb1dd50c9d0e 100644 --- a/src/vm/peimage.cpp +++ b/src/vm/peimage.cpp @@ -422,15 +422,8 @@ void PEImage::GetPathFromDll(HINSTANCE hMod, SString &result) } CONTRACTL_END; - DWORD ret; - DWORD length = MAX_LONGPATH; - do - { - WCHAR *buffer = result.OpenUnicodeBuffer(length); - ret = WszGetModuleFileName(hMod, buffer, length); - result.CloseBuffer(ret); - length *= 2; - } while (ret == 0); + WszGetModuleFileName(hMod, result); + } #endif // !FEATURE_PAL diff --git a/src/vm/peimage.inl b/src/vm/peimage.inl index 343b2bbbd9fb..c2f6957ba062 100644 --- a/src/vm/peimage.inl +++ b/src/vm/peimage.inl @@ -592,25 +592,9 @@ inline PTR_PEImage PEImage::FindByLongPath(LPCWSTR pPath) } CONTRACTL_END; - InlineSString sLongPath; - // Note: GetLongPathName return the number of characters written NOT INCLUDING the - // null character on success, and on failure returns the buffer size required - // INCLUDING the null. This means the result must not be equal to MAX_PATH - - // it must be greater or less then. - COUNT_T nLen = WszGetLongPathName(pPath, sLongPath.OpenUnicodeBuffer(MAX_PATH-1), MAX_PATH); - CONSISTENCY_CHECK(nLen != MAX_PATH); - - // If this was insufficient buffer, then try again with a reallocated buffer - if (nLen > MAX_PATH) - { - // Close the buffer before reopening - sLongPath.CloseBuffer(); - INDEBUG(SIZE_T nOldLen = nLen;) - nLen = WszGetLongPathName(pPath, sLongPath.OpenUnicodeBuffer(nLen-1), nLen); - CONSISTENCY_CHECK(nLen == (nOldLen - 1)); - } - sLongPath.CloseBuffer(nLen); - + PathString sLongPath; + COUNT_T nLen = WszGetLongPathName(pPath, sLongPath); + // Check for any kind of error other than an insufficient buffer result. if (nLen == 0) { @@ -619,7 +603,7 @@ inline PTR_PEImage PEImage::FindByLongPath(LPCWSTR pPath) ThrowHR(hr); return (PEImage*)INVALIDENTRY; } - return FindByPath(sLongPath); + return FindByPath(sLongPath.GetUnicode()); } /*static*/ @@ -634,24 +618,8 @@ inline PTR_PEImage PEImage::FindByShortPath(LPCWSTR pPath) } CONTRACTL_END; - InlineSString sShortPath; - // Note: GetLongPathName return the number of characters written NOT INCLUDING the - // null character on success, and on failure returns the buffer size required - // INCLUDING the null. This means the result must not be equal to MAX_PATH - - // it must be greater or less then. - COUNT_T nLen = WszGetShortPathName(pPath, sShortPath.OpenUnicodeBuffer(MAX_PATH-1), MAX_PATH); - CONSISTENCY_CHECK(nLen != MAX_PATH); - - // If this was insufficient buffer, then try again with a reallocated buffer - if (nLen > MAX_PATH) - { - // Close the buffer before reopening - sShortPath.CloseBuffer(); - INDEBUG(SIZE_T nOldLen = nLen;) - nLen = WszGetShortPathName(pPath, sShortPath.OpenUnicodeBuffer(nLen-1), nLen); - CONSISTENCY_CHECK(nLen == (nOldLen - 1)); - } - sShortPath.CloseBuffer(nLen); + PathString sShortPath; + COUNT_T nLen = WszGetShortPathName(pPath, sShortPath); // Check for any kind of error other than an insufficient buffer result. if (nLen == 0) @@ -661,7 +629,7 @@ inline PTR_PEImage PEImage::FindByShortPath(LPCWSTR pPath) ThrowHR(hr); return (PEImage*)INVALIDENTRY; } - return FindByPath(sShortPath); + return FindByPath(sShortPath.GetUnicode()); } #endif // !FEATURE_CORECLR diff --git a/src/vm/peimagelayout.cpp b/src/vm/peimagelayout.cpp index 3868386860f9..8fdf554557f5 100644 --- a/src/vm/peimagelayout.cpp +++ b/src/vm/peimagelayout.cpp @@ -319,9 +319,9 @@ RawImageLayout::RawImageLayout(const void *mapped, PEImage* pOwner, BOOL bTakeOw if (bTakeOwnership) { #ifndef FEATURE_PAL - WCHAR wszDllName[MAX_LONGPATH]; - WszGetModuleFileName((HMODULE)mapped, wszDllName, MAX_LONGPATH); - wszDllName[MAX_LONGPATH - 1] = W('\0'); + PathString wszDllName; + WszGetModuleFileName((HMODULE)mapped, wszDllName); + m_LibraryHolder=CLRLoadLibraryEx(wszDllName,NULL,GetLoadWithAlteredSearchPathFlag()); #else // !FEATURE_PAL _ASSERTE(!"bTakeOwnership Should not be used on FEATURE_PAL"); diff --git a/src/vm/securitypolicy.cpp b/src/vm/securitypolicy.cpp index 082be54f8889..fe1da90b8d8c 100644 --- a/src/vm/securitypolicy.cpp +++ b/src/vm/securitypolicy.cpp @@ -1,9 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -// - -// +//The .NET Foundation licenses this file to you under the MIT license. +//See the LICENSE file in the project root for more information. #include "common.h" @@ -676,12 +673,11 @@ void QCALLTYPE SecurityPolicy::_GetLongPathName(LPCWSTR wszPath, QCall::StringHa BEGIN_QCALL; #if !defined(PLATFORM_UNIX) - WCHAR wszBuffer[MAX_LONGPATH + 1]; - ZeroMemory(wszBuffer, sizeof(wszBuffer)); + PathString wszBuffer; - if (SecurityPolicy::GetLongPathNameHelper( wszPath, wszBuffer, MAX_LONGPATH ) != 0) + if (SecurityPolicy::GetLongPathNameHelper( wszPath, wszBuffer ) != 0) { - retLongPath.Set( wszBuffer ); + retLongPath.Set( wszBuffer.GetUnicode() ); } #endif // !PLATFORM_UNIX @@ -689,15 +685,15 @@ void QCALLTYPE SecurityPolicy::_GetLongPathName(LPCWSTR wszPath, QCall::StringHa } #if !defined(PLATFORM_UNIX) -size_t SecurityPolicy::GetLongPathNameHelper( const WCHAR* wszShortPath, __inout_ecount(cchBuffer) __inout_z WCHAR* wszBuffer, DWORD cchBuffer ) +size_t GetLongPathNameHelperthatThrows(const WCHAR* wszShortPath, SString& wszBuffer) { - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; + CONTRACTL{ + THROWS; + GC_NOTRIGGER; + MODE_ANY; } CONTRACTL_END; - DWORD size = WszGetLongPathName(wszShortPath, wszBuffer, cchBuffer); + DWORD size = WszGetLongPathName(wszShortPath, wszBuffer); if (size == 0) { @@ -707,66 +703,87 @@ size_t SecurityPolicy::GetLongPathNameHelper( const WCHAR* wszShortPath, __inout // trying GetLongPathName on every subdirectory until // it succeeds or we run out of string. - WCHAR wszIntermediateBuffer[MAX_LONGPATH]; + size_t len = wcslen(wszShortPath); + NewArrayHolder wszIntermediateBuffer = new (nothrow) WCHAR[len + 1]; - if (wcslen( wszShortPath ) >= MAX_LONGPATH) + if (wszIntermediateBuffer == NULL) + { return 0; + } - wcscpy_s( wszIntermediateBuffer, COUNTOF(wszIntermediateBuffer), wszShortPath ); + wcscpy_s(wszIntermediateBuffer, len + 1, wszShortPath); - size_t index = wcslen( wszIntermediateBuffer ); + size_t index = len; do { - while (index > 0 && (wszIntermediateBuffer[index-1] != W('\\') && wszIntermediateBuffer[index-1] != W('/'))) + while (index > 0 && (wszIntermediateBuffer[index - 1] != W('\\') && wszIntermediateBuffer[index - 1] != W('/'))) --index; if (index == 0) break; - #ifdef _PREFAST_ - #pragma prefast(push) - #pragma prefast(disable:26001, "suppress prefast warning about underflow by doing index-1 which is checked above.") - #endif // _PREFAST_ - - wszIntermediateBuffer[index-1] = W('\0'); +#ifdef _PREFAST_ +#pragma prefast(push) +#pragma prefast(disable:26001, "suppress prefast warning about underflow by doing index-1 which is checked above.") +#endif // _PREFAST_ + + wszIntermediateBuffer[index - 1] = W('\0'); - #ifdef _PREFAST_ - #pragma prefast(pop) - #endif +#ifdef _PREFAST_ +#pragma prefast(pop) +#endif - size = WszGetLongPathName(wszIntermediateBuffer, wszBuffer, MAX_LONGPATH); + size = WszGetLongPathName(wszIntermediateBuffer, wszBuffer); if (size != 0) { - size_t sizeBuffer = wcslen( wszBuffer ); - if (sizeBuffer + wcslen( &wszIntermediateBuffer[index] ) > MAX_LONGPATH - 2) - { - return 0; - } - else - { - if (wszBuffer[sizeBuffer-1] != W('\\') && wszBuffer[sizeBuffer-1] != W('/')) - wcscat_s( wszBuffer, cchBuffer, W("\\") ); - wcscat_s( wszBuffer, cchBuffer, &wszIntermediateBuffer[index] ); - return (DWORD)wcslen( wszBuffer ); - } + int sizeBuffer = wszBuffer.GetCount(); + + if (wszBuffer[sizeBuffer - 1] != W('\\') && wszBuffer[sizeBuffer - 1] != W('/')) + wszBuffer.Append(W("\\")); + + wszBuffer.Append(&wszIntermediateBuffer[index]); + + + return (DWORD)wszBuffer.GetCount(); + } - } - while( true ); + } while (true); return 0; } - else if (size > MAX_LONGPATH) + else { - return 0; + return (DWORD)wszBuffer.GetCount(); } - else +} +size_t SecurityPolicy::GetLongPathNameHelper(const WCHAR* wszShortPath, SString& wszBuffer) +{ + CONTRACTL{ + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + } CONTRACTL_END; + + HRESULT hr = S_OK; + size_t retval = 0; + + EX_TRY { - return wcslen( wszBuffer ); + retval = GetLongPathNameHelperthatThrows(wszShortPath,wszBuffer); } + EX_CATCH_HRESULT(hr); + + if (hr != S_OK) + { + retval = 0; + } + + return retval; } + #endif // !PLATFORM_UNIX void QCALLTYPE SecurityPolicy::GetDeviceName(LPCWSTR wszDriveLetter, QCall::StringHandleOnStack retDeviceName) diff --git a/src/vm/securitypolicy.h b/src/vm/securitypolicy.h index cf2b10f21c16..ba77bcbda885 100644 --- a/src/vm/securitypolicy.h +++ b/src/vm/securitypolicy.h @@ -198,7 +198,7 @@ namespace SecurityPolicy BOOL WasStrongNameEvidenceUsed(OBJECTREF evidence); #endif // Like WszGetLongPathName, but it works with nonexistant files too - size_t GetLongPathNameHelper( const WCHAR* wszShortPath, __inout_ecount(cchBuffer) __inout_z WCHAR* wszBuffer, DWORD cchBuffer ); + size_t GetLongPathNameHelper( const WCHAR* wszShortPath, SString& wszBuffer); #ifdef FEATURE_CAS_POLICY extern CrstStatic s_crstPolicyInit; diff --git a/src/zap/zapper.cpp b/src/zap/zapper.cpp index 42589874b11d..6d559d377b2e 100644 --- a/src/zap/zapper.cpp +++ b/src/zap/zapper.cpp @@ -730,15 +730,14 @@ void Zapper::LoadAndInitializeJITForNgen(LPCWSTR pwzJitName, OUT HINSTANCE* phJi HRESULT hr = E_FAIL; #ifdef FEATURE_MERGE_JIT_AND_ENGINE - WCHAR CoreClrFolder[MAX_LONGPATH + 1]; + PathString CoreClrFolder; extern HINSTANCE g_hThisInst; - if (WszGetModuleFileName(g_hThisInst, CoreClrFolder, MAX_LONGPATH)) + if (WszGetModuleFileName(g_hThisInst, CoreClrFolder)) { - WCHAR *filePtr = wcsrchr(CoreClrFolder, W('\\')); - if (filePtr) + if (SUCCEEDED(CopySystemDirectory(CoreClrFolder, CoreClrFolder))) { - filePtr[1] = W('\0'); - wcscat_s(CoreClrFolder, MAX_LONGPATH, pwzJitName); + CoreClrFolder.Append(pwzJitName); + *phJit = ::WszLoadLibrary(CoreClrFolder); if (*phJit == NULL) {