diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2008-11-20 10:05:43 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2008-11-20 10:05:43 +0000 |
commit | 3b4c0c02bb6d45b84783be69e0823accf39cdb50 (patch) | |
tree | 194b390c4d760be28f965b82b3470d0fb56eb8c4 /cli_ure/source | |
parent | d4f58e06113ae5210c93cb052b45c74ff17f3c12 (diff) |
CWS-TOOLING: integrate CWS jl114_DEV300
Diffstat (limited to 'cli_ure/source')
-rw-r--r-- | cli_ure/source/native/makefile.mk | 3 | ||||
-rw-r--r-- | cli_ure/source/native/native_bootstrap.cxx | 288 | ||||
-rw-r--r-- | cli_ure/source/native/path.cxx | 221 |
3 files changed, 424 insertions, 88 deletions
diff --git a/cli_ure/source/native/makefile.mk b/cli_ure/source/native/makefile.mk index db27cc02fc45..a5e3731e114c 100644 --- a/cli_ure/source/native/makefile.mk +++ b/cli_ure/source/native/makefile.mk @@ -7,7 +7,7 @@ # OpenOffice.org - a multi-platform office productivity suite # # $RCSfile: makefile.mk,v $ -# $Revision: 1.26 $ +# $Revision: 1.26.8.1 $ # # This file is part of OpenOffice.org. # @@ -100,6 +100,7 @@ LINKFLAGS += -NOENTRY -NODEFAULTLIB:nochkclr.obj -INCLUDE:__DllMainCRTStartup@12 SLOFILES = \ $(SLO)$/native_bootstrap.obj \ + $(SLO)$/path.obj \ $(SLO)$/assembly_cppuhelper.obj diff --git a/cli_ure/source/native/native_bootstrap.cxx b/cli_ure/source/native/native_bootstrap.cxx index 60c5c783dc8d..fb7c2f21dcdf 100644 --- a/cli_ure/source/native/native_bootstrap.cxx +++ b/cli_ure/source/native/native_bootstrap.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: native_bootstrap.cxx,v $ - * $Revision: 1.14 $ + * $Revision: 1.14.12.5 $ * * This file is part of OpenOffice.org. * @@ -28,7 +28,7 @@ * ************************************************************************/ -// We are using the Windows UNICODE API +// Use UNICODE Windows and C API. #define _UNICODE #define UNICODE @@ -55,157 +55,271 @@ using namespace ::rtl; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; -#define OFFICE_LOCATION_REGISTRY_KEY L"Software\\OpenOffice.org\\Layer\\URE\\1" -#define UREINSTALLLOCATION L"UREINSTALLLOCATION" +namespace cli_ure { + WCHAR * resolveLink(WCHAR * path); +} + +#define INSTALL_PATH L"Software\\OpenOffice.org\\UNO\\InstallPath" +#define BASIS_LINK L"\\basis-link" +#define URE_LINK L"\\ure-link" #define URE_BIN L"\\bin" +#define UNO_PATH L"UNO_PATH" namespace { + /* + * Gets the installation path from the Windows Registry for the specified + * registry key. + * + * @param hroot open handle to predefined root registry key + * @param subKeyName name of the subkey to open + * + * @return the installation path or NULL, if no installation was found or + * if an error occured + */ +WCHAR* getPathFromRegistryKey( HKEY hroot, LPCWSTR subKeyName ) +{ + HKEY hkey; + DWORD type; + TCHAR* data = NULL; + DWORD size; + + /* open the specified registry key */ + if ( RegOpenKeyEx( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS ) + { + return NULL; + } + + /* find the type and size of the default value */ + if ( RegQueryValueEx( hkey, NULL, NULL, &type, NULL, &size) != ERROR_SUCCESS ) + { + RegCloseKey( hkey ); + return NULL; + } + + /* get memory to hold the default value */ + data = new WCHAR[size]; + + /* read the default value */ + if ( RegQueryValueEx( hkey, NULL, NULL, &type, (LPBYTE) data, &size ) != ERROR_SUCCESS ) + { + RegCloseKey( hkey ); + return NULL; + } + + /* release registry key handle */ + RegCloseKey( hkey ); + + return data; +} + +/* If the path does not end with '\' the las segment will be removed. + path: C:\a\b + -> C:\a + @param io_path + in/out parameter. The string is not reallocated. Simply a '\0' + will be inserted to shorten the string. +*/ +void oneDirUp(LPTSTR io_path) +{ + WCHAR * pEnd = io_path + lstrlen(io_path) - 1; + while (pEnd > io_path //prevent crashing if provided string does not contain a backslash + && *pEnd != L'\\') + pEnd --; + *pEnd = L'\0'; +} + -//Returns the path to the URE/bin folder. -//The caller must free the returned string with delete[] -wchar_t * getUnoPath() +/* Returns the path to the program folder of the brand layer, + for example c:/openoffice.org 3/program + This path is either obtained from the environment variable UNO_PATH + or the registry item + "Software\\OpenOffice.org\\UNO\\InstallPath" + either in HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE + The return value must be freed with delete[] +*/ +WCHAR * getInstallPath() { - wchar_t * theUnoPath = NULL; - bool failed = false; - HKEY hKey = 0; - if (RegOpenKeyEx(HKEY_CURRENT_USER,OFFICE_LOCATION_REGISTRY_KEY, - 0, KEY_READ, &hKey) != ERROR_SUCCESS) + WCHAR * szInstallPath = NULL; + + DWORD cChars = GetEnvironmentVariable(UNO_PATH, NULL, 0); + if (cChars > 0) { - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, OFFICE_LOCATION_REGISTRY_KEY, - 0, KEY_READ, &hKey) != ERROR_SUCCESS) + szInstallPath = new WCHAR[cChars]; + cChars = GetEnvironmentVariable(UNO_PATH, szInstallPath, cChars); + //If PATH is not set then it is no error + if (cChars == 0) { -#if OSL_DEBUG_LEVEL >= 2 - fprintf(stderr, "cli_cppuhelper: Office not properly installed. " - "Could not open registry keys."); -#endif - failed = true; + delete[] szInstallPath; + return NULL; } } - if (! failed) + + if (! szInstallPath) { - DWORD dwType = 0; - DWORD dwLen = 0; - wchar_t *arData = NULL; - //get the length for the path to office - if (RegQueryValueEx(hKey, UREINSTALLLOCATION, NULL, &dwType, NULL, - &dwLen) == ERROR_SUCCESS) + szInstallPath = getPathFromRegistryKey( HKEY_CURRENT_USER, INSTALL_PATH ); + if ( szInstallPath == NULL ) { - arData = new wchar_t[dwLen]; - arData[0] = '\0'; - if (RegQueryValueEx(hKey, UREINSTALLLOCATION, NULL, &dwType, (LPBYTE) arData, - & dwLen) == ERROR_SUCCESS) - { - int test = lstrlen(URE_BIN); - //attach the bin directory to the URE path - int sizePath = lstrlen(arData) + lstrlen(URE_BIN) + 1; - theUnoPath = new wchar_t[sizePath]; - theUnoPath[0] = '\0'; - lstrcat(theUnoPath, arData); - lstrcat(theUnoPath, URE_BIN); - delete[] arData; -#if OSL_DEBUG_LEVEL >=2 - fprintf(stdout,"[cli_cppuhelper]: Using path %S to load office libraries.", theUnoPath); -#endif - } + /* read the key's default value from HKEY_LOCAL_MACHINE */ + szInstallPath = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, INSTALL_PATH ); } - RegCloseKey(hKey); } - return theUnoPath; + return szInstallPath; } - -//Returns the path to the Ure/bin directory and expands the PATH by inserting the -// ure/bin path at the front. -wchar_t const * getUreBinPathAndSetPath() +/* Returns the path to the URE/bin path, where cppuhelper lib resides. + The returned string must be freed with delete[] +*/ +WCHAR* getUnoPath() { - static wchar_t * theBinPath = NULL; + WCHAR * szLinkPath = NULL; + WCHAR * szUrePath = NULL; + WCHAR * szUreBin = NULL; //the return value - if (theBinPath) - return theBinPath; + WCHAR * szInstallPath = getInstallPath(); + if (szInstallPath) + { + //build the path tho the basis-link file + oneDirUp(szInstallPath); + int sizeLinkPath = lstrlen(szInstallPath) + lstrlen(INSTALL_PATH) + 1; + if (sizeLinkPath < MAX_PATH) + sizeLinkPath = MAX_PATH; + szLinkPath = new WCHAR[sizeLinkPath]; + szLinkPath[0] = L'\0'; + lstrcat(szLinkPath, szInstallPath); + lstrcat(szLinkPath, BASIS_LINK); + + //get the path to the actual Basis folder + if (cli_ure::resolveLink(szLinkPath)) + { + //build the path to the ure-link file + int sizeUrePath = lstrlen(szLinkPath) + lstrlen(URE_LINK) + 1; + if (sizeUrePath < MAX_PATH) + sizeUrePath = MAX_PATH; + szUrePath = new WCHAR[sizeUrePath]; + szUrePath[0] = L'\0'; + lstrcat(szUrePath, szLinkPath); + lstrcat(szUrePath, URE_LINK); + + //get the path to the actual Ure folder + if (cli_ure::resolveLink(szUrePath)) + { + //build the path to the URE/bin directory + szUreBin = new WCHAR[lstrlen(szUrePath) + lstrlen(URE_BIN) + 1]; + szUreBin[0] = L'\0'; + lstrcat(szUreBin, szUrePath); + lstrcat(szUreBin, URE_BIN); + } + } + } +#if OSL_DEBUG_LEVEL >=2 + if (szUreBin) + { + fwprintf(stdout,L"[cli_cppuhelper]: Path to URE libraries:\n %s \n", szUreBin); + } + else + { + fwprintf(stdout,L"[cli_cppuhelper]: Failed to determine location of URE.\n"); + } +#endif + delete[] szInstallPath; + delete[] szLinkPath; + delete[] szUrePath; + return szUreBin; +} - wchar_t * unoPath = getUnoPath(); - if (!unoPath) - return NULL; - //We extend the path to contain the program directory of the office, - //so that components can use osl_loadModule with arguments, such as - //"reg3.dll". That is, the arguments are only the library names. +/*We extend the path to contain the Ure/bin folder, + so that components can use osl_loadModule with arguments, such as + "reg3.dll". That is, the arguments are only the library names. +*/ +void extendPath(LPCWSTR szUreBinPath) +{ + if (!szUreBinPath) + return; - wchar_t * sEnvPath = NULL; + WCHAR * sEnvPath = NULL; DWORD cChars = GetEnvironmentVariable(L"PATH", sEnvPath, 0); if (cChars > 0) { - sEnvPath = new wchar_t[cChars]; + sEnvPath = new WCHAR[cChars]; cChars = GetEnvironmentVariable(L"PATH", sEnvPath, cChars); //If PATH is not set then it is no error if (cChars == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND) { delete[] sEnvPath; - return NULL; + return; } } - //prepare the new PATH. Add the Ure/bin directory at the front - wchar_t * sNewPath = new wchar_t[lstrlen(sEnvPath) + lstrlen(unoPath) + 2]; - sNewPath[0] = '\0'; - lstrcat(sNewPath, unoPath); + //prepare the new PATH. Add the Ure/bin directory at the front. + //note also adding ';' + WCHAR * sNewPath = new WCHAR[lstrlen(sEnvPath) + lstrlen(szUreBinPath) + 2]; + sNewPath[0] = L'\0'; + lstrcat(sNewPath, szUreBinPath); if (lstrlen(sEnvPath)) { lstrcat(sNewPath, L";"); lstrcat(sNewPath, sEnvPath); } - BOOL bSet = SetEnvironmentVariable(L"PATH", sNewPath); - theBinPath = unoPath; delete[] sEnvPath; delete[] sNewPath; - - return theBinPath; } -HMODULE loadFromPath(wchar_t const * sLibName) + +HMODULE loadFromPath(LPCWSTR sLibName) { if (sLibName == NULL) return NULL; - wchar_t const * binPath = getUreBinPathAndSetPath(); - if (!binPath) + WCHAR * szUreBinPath = getUnoPath(); + if (!szUreBinPath) return NULL; + extendPath(szUreBinPath); - wchar_t* sFullPath = new wchar_t[lstrlen(sLibName) + lstrlen(binPath) + 2]; - sFullPath[0] = '\0'; - sFullPath = lstrcat(sFullPath, binPath); - sFullPath = lstrcat(sFullPath, L"\\"); - sFullPath = lstrcat(sFullPath, sLibName); - HMODULE handle = LoadLibraryEx(sFullPath, NULL, + WCHAR* szFullPath = new WCHAR[lstrlen(sLibName) + lstrlen(szUreBinPath) + 2]; + szFullPath[0] = L'\0'; + lstrcat(szFullPath, szUreBinPath); + lstrcat(szFullPath, L"\\"); + lstrcat(szFullPath, sLibName); + HMODULE handle = LoadLibraryEx(szFullPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - delete[] sFullPath; - return handle; + delete[] szFullPath; + delete[] szUreBinPath; + return handle; } -//Hook for delayed loading of libraries which this library is linked with. -extern "C" FARPROC WINAPI delayLoadHook( +/*Hook for delayed loading of libraries which this library is linked with. + This is a failure hook. That is, it is only called when the loading of + a library failed. It will be called when loading of cppuhelper failed. + Because we extend the PATH to the URE/bin folder while this function is + executed (see extendPath), all other libraries are found. +*/ +extern "C" FARPROC WINAPI delayLoadHook( unsigned dliNotify, PDelayLoadInfo pdli ) { if (dliNotify == dliFailLoadLib) { - //Convert the ansi file name to wchar_t* + LPWSTR szLibName = NULL; + //Convert the ansi file name to wchar_t* int size = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pdli->szDll, -1, NULL, 0); if (size > 0) { - wchar_t * buf = new wchar_t[size]; - if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pdli->szDll, -1, buf, size)) + szLibName = new WCHAR[size]; + if (! MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pdli->szDll, -1, szLibName, size)) { - HMODULE handle = NULL; - return (FARPROC) loadFromPath(buf); + return 0; } } + HANDLE h = loadFromPath(szLibName); + delete[] szLibName; + return (FARPROC) h; } return 0; } diff --git a/cli_ure/source/native/path.cxx b/cli_ure/source/native/path.cxx new file mode 100644 index 000000000000..075a3cdb75bd --- /dev/null +++ b/cli_ure/source/native/path.cxx @@ -0,0 +1,221 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: path.cxx,v $ + * $Revision: 1.1.2.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "sal/config.h" + +#if defined WNT + +#include <cstddef> + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include "sal/types.h" +#include "tools/pathutils.hxx" + +namespace cli_ure { + +WCHAR * filename(WCHAR * path) { + WCHAR * f = path; + for (WCHAR * p = path;;) { + switch (*p++) { + case L'\0': + return f; + case L'\\': + f = p; + break; + } + } +} + +WCHAR * buildPath( + WCHAR * path, WCHAR const * frontBegin, WCHAR const * frontEnd, + WCHAR const * backBegin, std::size_t backLength) +{ + // Remove leading ".." segments in the second path together with matching + // segments in the first path that are neither empty nor "." nor ".." nor + // end in ":" (which is not foolprove, as it can erroneously erase the start + // of a UNC path, but only if the input is bad data): + while (backLength >= 2 && backBegin[0] == L'.' && backBegin[1] == L'.' && + (backLength == 2 || backBegin[2] == L'\\')) + { + if (frontEnd - frontBegin < 2 || frontEnd[-1] != L'\\' || + frontEnd[-2] == L'\\' || frontEnd[-2] == L':' || + (frontEnd[-2] == L'.' && + (frontEnd - frontBegin < 3 || frontEnd[-3] == L'\\' || + (frontEnd[-3] == L'.' && + (frontEnd - frontBegin < 4 || frontEnd[-4] == L'\\'))))) + { + break; + } + WCHAR const * p = frontEnd - 1; + while (p != frontBegin && p[-1] != L'\\') { + --p; + } + if (p == frontBegin) { + break; + } + frontEnd = p; + if (backLength == 2) { + backBegin += 2; + backLength -= 2; + } else { + backBegin += 3; + backLength -= 3; + } + } + if (backLength < + static_cast< std::size_t >(MAX_PATH - (frontEnd - frontBegin))) + // hopefully std::size_t is large enough + { + WCHAR * p; + if (frontBegin == path) { + p = const_cast< WCHAR * >(frontEnd); + } else { + p = path; + while (frontBegin != frontEnd) { + *p++ = *frontBegin++; + } + } + for (; backLength > 0; --backLength) { + *p++ = *backBegin++; + } + *p = L'\0'; + return p; + } else { + SetLastError(ERROR_FILENAME_EXCED_RANGE); + return NULL; + } +} + +WCHAR * resolveLink(WCHAR * path) { + HANDLE h = CreateFileW( + path, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (h == INVALID_HANDLE_VALUE) { + return NULL; + } + char p1[MAX_PATH]; + DWORD n; + BOOL ok = ReadFile(h, p1, MAX_PATH, &n, NULL); + CloseHandle(h); + if (!ok) { + return NULL; + } + WCHAR p2[MAX_PATH]; + std::size_t n2 = 0; + bool colon = false; + for (DWORD i = 0; i < n;) { + unsigned char c = static_cast< unsigned char >(p1[i++]); + switch (c) { + case '\0': + SetLastError(ERROR_BAD_PATHNAME); + return NULL; + case '\x0A': + case '\x0D': + if (n2 == MAX_PATH) { + SetLastError(ERROR_FILENAME_EXCED_RANGE); + return NULL; + } + p2[n2] = L'\0'; + break; + case ':': + colon = true; + // fall through + default: + // Convert from UTF-8 to UTF-16: + if (c <= 0x7F) { + p2[n2++] = c; + } else if (c >= 0xC2 && c <= 0xDF && i < n && + static_cast< unsigned char >(p1[i]) >= 0x80 && + static_cast< unsigned char >(p1[i]) <= 0xBF) + { + p2[n2++] = ((c & 0x1F) << 6) | + (static_cast< unsigned char >(p1[i++]) & 0x3F); + } else if (n - i > 1 && + ((c == 0xE0 && + static_cast< unsigned char >(p1[i]) >= 0xA0 && + static_cast< unsigned char >(p1[i]) <= 0xBF) || + ((c >= 0xE1 && c <= 0xEC || c >= 0xEE && c <= 0xEF) && + static_cast< unsigned char >(p1[i]) >= 0x80 && + static_cast< unsigned char >(p1[i]) <= 0xBF) || + (c == 0xED && + static_cast< unsigned char >(p1[i]) >= 0x80 && + static_cast< unsigned char >(p1[i]) <= 0x9F)) && + static_cast< unsigned char >(p1[i + 1]) >= 0x80 && + static_cast< unsigned char >(p1[i + 1]) <= 0xBF) + { + p2[n2++] = ((c & 0x0F) << 12) | + ((static_cast< unsigned char >(p1[i]) & 0x3F) << 6) | + (static_cast< unsigned char >(p1[i + 1]) & 0x3F); + i += 2; + } else if (n - 2 > 1 && + ((c == 0xF0 && + static_cast< unsigned char >(p1[i]) >= 0x90 && + static_cast< unsigned char >(p1[i]) <= 0xBF) || + (c >= 0xF1 && c <= 0xF3 && + static_cast< unsigned char >(p1[i]) >= 0x80 && + static_cast< unsigned char >(p1[i]) <= 0xBF) || + (c == 0xF4 && + static_cast< unsigned char >(p1[i]) >= 0x80 && + static_cast< unsigned char >(p1[i]) <= 0x8F)) && + static_cast< unsigned char >(p1[i + 1]) >= 0x80 && + static_cast< unsigned char >(p1[i + 1]) <= 0xBF && + static_cast< unsigned char >(p1[i + 2]) >= 0x80 && + static_cast< unsigned char >(p1[i + 2]) <= 0xBF) + { + sal_Int32 u = ((c & 0x07) << 18) | + ((static_cast< unsigned char >(p1[i]) & 0x3F) << 12) | + ((static_cast< unsigned char >(p1[i + 1]) & 0x3F) << 6) | + (static_cast< unsigned char >(p1[i + 2]) & 0x3F); + i += 3; + p2[n2++] = static_cast< WCHAR >(((u - 0x10000) >> 10) | 0xD800); + p2[n2++] = static_cast< WCHAR >( + ((u - 0x10000) & 0x3FF) | 0xDC00); + } else { + SetLastError(ERROR_BAD_PATHNAME); + return NULL; + } + break; + } + } + WCHAR * end; + if (colon || p2[0] == L'\\') { + // Interpret p2 as an absolute path: + end = path; + } else { + // Interpret p2 as a relative path: + end = filename(path); + } + return buildPath(path, path, end, p2, n2); +} + +} + +#endif |