From fd56d52ca4db7df1b0f148dd5726cfb8e77c3ec4 Mon Sep 17 00:00:00 2001 From: Joachim Lingner Date: Tue, 1 Mar 2011 10:55:20 +0100 Subject: jl164 #i109096# osl_loadModules did not work with long paths. --- sal/osl/w32/module.cxx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/sal/osl/w32/module.cxx b/sal/osl/w32/module.cxx index b730bd3347df..e628c8b9614c 100644 --- a/sal/osl/w32/module.cxx +++ b/sal/osl/w32/module.cxx @@ -65,10 +65,31 @@ oslModule SAL_CALL osl_loadModule(rtl_uString *strModuleName, sal_Int32 nRtldMod rtl_uString_assign(&Module, strModuleName); hInstance = LoadLibraryW(reinterpret_cast(Module->buffer)); + if (hInstance == NULL) hInstance = LoadLibraryExW(reinterpret_cast(Module->buffer), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + //In case of long path names (\\?\c:\...) try to shorten the filename. + //LoadLibrary cannot handle file names which exceed 260 letters. + if (hInstance == NULL && GetLastError() == ERROR_FILENAME_EXCED_RANGE) + { + wchar_t * buff = new wchar_t[Module->length + 1]; + DWORD len = GetShortPathNameW(reinterpret_cast(Module->buffer), + buff, Module->length + 1); + if (len ) + { + hInstance = LoadLibraryW(buff); + + if (hInstance == NULL) + hInstance = LoadLibraryExW(buff, NULL, + LOAD_WITH_ALTERED_SEARCH_PATH); + + } + delete[] buff; + } + + if (hInstance <= (HINSTANCE)HINSTANCE_ERROR) hInstance = 0; -- cgit From cfbddca53c5f0c795fa35612d739c3dabb8f0d48 Mon Sep 17 00:00:00 2001 From: Joachim Lingner Date: Wed, 2 Mar 2011 16:11:23 +0100 Subject: jl164 #i109096# osl_createProcesess failed if the executable had a long path on windows --- sal/osl/w32/module.cxx | 16 +++++++++------- sal/osl/w32/procimpl.cxx | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) mode change 100644 => 100755 sal/osl/w32/module.cxx mode change 100644 => 100755 sal/osl/w32/procimpl.cxx diff --git a/sal/osl/w32/module.cxx b/sal/osl/w32/module.cxx old mode 100644 new mode 100755 index e628c8b9614c..00737ebbbaa4 --- a/sal/osl/w32/module.cxx +++ b/sal/osl/w32/module.cxx @@ -36,6 +36,7 @@ #include #include #include +#include /* under WIN32, we use the void* oslModule @@ -72,21 +73,22 @@ oslModule SAL_CALL osl_loadModule(rtl_uString *strModuleName, sal_Int32 nRtldMod //In case of long path names (\\?\c:\...) try to shorten the filename. //LoadLibrary cannot handle file names which exceed 260 letters. - if (hInstance == NULL && GetLastError() == ERROR_FILENAME_EXCED_RANGE) + //In case the path is to long, the function will fail. However, the error + //code can be different. For example, it returned ERROR_FILENAME_EXCED_RANGE + //on Windows XP and ERROR_INSUFFICIENT_BUFFER on Windows 7 (64bit) + if (hInstance == NULL && Module->length > 260) { - wchar_t * buff = new wchar_t[Module->length + 1]; + std::vector > vec(Module->length + 1); DWORD len = GetShortPathNameW(reinterpret_cast(Module->buffer), - buff, Module->length + 1); + vec.begin(), Module->length + 1); if (len ) { - hInstance = LoadLibraryW(buff); + hInstance = LoadLibraryW(vec.begin()); if (hInstance == NULL) - hInstance = LoadLibraryExW(buff, NULL, + hInstance = LoadLibraryExW(vec.begin(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - } - delete[] buff; } diff --git a/sal/osl/w32/procimpl.cxx b/sal/osl/w32/procimpl.cxx old mode 100644 new mode 100755 index fc04d5b84a8f..13e7141edbad --- a/sal/osl/w32/procimpl.cxx +++ b/sal/osl/w32/procimpl.cxx @@ -300,6 +300,39 @@ namespace /* private */ return quoted.makeStringAndClear(); } + //The parameter path must be a system path. If it is longer than 260 characters + //then it is shortened using the GetShortPathName function. This function only + //works if the path exists. Because "path" can be the path to an executable, it + //may not have the file extension ".exe". However, if the file on disk has the + //".exe" extension, then the function will fail. In this case a second attempt + //is started by adding the parameter "extension" to "path". + rtl::OUString getShortPath(rtl::OUString const & path, rtl::OUString const & extension) + { + rtl::OUString ret(path); + if (path.getLength() > 260) + { + std::vector > vec(path.getLength() + 1); + //GetShortPathNameW only works if the file can be found! + const DWORD len = GetShortPathNameW( + path.getStr(), vec.begin(), path.getLength() + 1); + + if (!len && GetLastError() == ERROR_FILE_NOT_FOUND + && extension.getLength()) + { + const rtl::OUString extPath(path + extension); + std::vector > vec2( + extPath.getLength() + 1); + const DWORD len2 = GetShortPathNameW( + extPath.getStr(), vec2.begin(), extPath.getLength() + 1); + ret = rtl::OUString(vec2.begin(), len2); + } + else + { + ret = rtl::OUString(vec.begin(), len); + } + } + return ret; + } //########################################################## // Returns the system path of the executable which can either // be provided via the strImageName parameter or as first @@ -326,6 +359,8 @@ namespace /* private */ if (osl_File_E_None != osl::FileBase::getSystemPathFromFileURL(exe_url, exe_path)) return rtl::OUString(); + exe_path = getShortPath(exe_path, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".exe"))); + if (exe_path.indexOf(' ') != -1) exe_path = quote_string(exe_path); -- cgit From 0775f9eacec0e0758512c425c4e65190a651c3ae Mon Sep 17 00:00:00 2001 From: Joachim Lingner Date: Thu, 3 Mar 2011 12:04:04 +0100 Subject: jl164 #i109096# fixing use of vectors as smart array in osl_loadModules and osl_createprocesswithredirectedio, I introduced them in one of the previous changesets in this cws --- sal/osl/w32/module.cxx | 6 +++--- sal/osl/w32/procimpl.cxx | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sal/osl/w32/module.cxx b/sal/osl/w32/module.cxx index 00737ebbbaa4..65a17eb1352d 100755 --- a/sal/osl/w32/module.cxx +++ b/sal/osl/w32/module.cxx @@ -80,13 +80,13 @@ oslModule SAL_CALL osl_loadModule(rtl_uString *strModuleName, sal_Int32 nRtldMod { std::vector > vec(Module->length + 1); DWORD len = GetShortPathNameW(reinterpret_cast(Module->buffer), - vec.begin(), Module->length + 1); + &vec[0], Module->length + 1); if (len ) { - hInstance = LoadLibraryW(vec.begin()); + hInstance = LoadLibraryW(&vec[0]); if (hInstance == NULL) - hInstance = LoadLibraryExW(vec.begin(), NULL, + hInstance = LoadLibraryExW(&vec[0], NULL, LOAD_WITH_ALTERED_SEARCH_PATH); } } diff --git a/sal/osl/w32/procimpl.cxx b/sal/osl/w32/procimpl.cxx index 13e7141edbad..a2f86422df2a 100755 --- a/sal/osl/w32/procimpl.cxx +++ b/sal/osl/w32/procimpl.cxx @@ -314,7 +314,7 @@ namespace /* private */ std::vector > vec(path.getLength() + 1); //GetShortPathNameW only works if the file can be found! const DWORD len = GetShortPathNameW( - path.getStr(), vec.begin(), path.getLength() + 1); + path.getStr(), &vec[0], path.getLength() + 1); if (!len && GetLastError() == ERROR_FILE_NOT_FOUND && extension.getLength()) @@ -323,12 +323,12 @@ namespace /* private */ std::vector > vec2( extPath.getLength() + 1); const DWORD len2 = GetShortPathNameW( - extPath.getStr(), vec2.begin(), extPath.getLength() + 1); - ret = rtl::OUString(vec2.begin(), len2); + extPath.getStr(), &vec2[0], extPath.getLength() + 1); + ret = rtl::OUString(&vec2[0], len2); } else { - ret = rtl::OUString(vec.begin(), len); + ret = rtl::OUString(&vec[0], len); } } return ret; -- cgit