Update ooo320-m1
[ooovba.git] / setup_native / source / win32 / customactions / languagepacks / lngpckinsthelper.cxx
blob90307f5e2e8ad384b69d4136ad5610fb01db4809
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: lngpckinsthelper.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #ifdef _MSC_VER
32 #pragma warning(push, 1) /* disable warnings within system headers */
33 #endif
34 #define WIN32_LEAN_AND_MEAN
35 #include <windows.h>
36 #include <msiquery.h>
37 #ifdef _MSC_VER
38 #pragma warning(pop)
39 #endif
41 #include <malloc.h>
42 #include <tchar.h>
43 #include <string>
44 #include <stdexcept>
45 #include <vector>
47 class RegistryKeyGuard
49 public:
50 RegistryKeyGuard(HKEY hkey = 0) :
51 hkey_(hkey)
55 ~RegistryKeyGuard()
57 if (hkey_)
58 RegCloseKey(hkey_);
60 private:
61 HKEY hkey_;
63 private:
64 RegistryKeyGuard(const RegistryKeyGuard&);
65 RegistryKeyGuard& operator=(const RegistryKeyGuard&);
68 typedef std::vector<TCHAR> CharacterBuffer_t;
70 /* throws std::runtime_error when the value "Path" could
71 not be found or contains an empty string or is not of
72 type REG_SZ. All such conditions are invalid for a
73 properly installed product. */
74 std::string FindProductInstallationPath(HKEY hkey)
76 DWORD nSubKeys;
77 DWORD lLongestSubKey;
79 if (RegQueryInfoKey(hkey, NULL, NULL, NULL, &nSubKeys, &lLongestSubKey, NULL, NULL, NULL, NULL, NULL, NULL) !=
80 ERROR_SUCCESS)
81 throw std::runtime_error("Cannot query info for registery key");
83 CharacterBuffer_t buff(lLongestSubKey + 1);
85 for (DWORD i = 0; i < nSubKeys; i++)
87 buff[0] = 0;
88 LONG ret = RegEnumKey(hkey, i, &buff[0], buff.size());
90 if ((ret != ERROR_SUCCESS) && (ret != ERROR_MORE_DATA))
91 throw std::runtime_error("Error enumerating registry key");
93 HKEY hSubKey;
94 if (RegOpenKey(hkey, &buff[0], &hSubKey) != ERROR_SUCCESS)
95 continue;
97 RegistryKeyGuard guard(hSubKey);
99 DWORD type;
100 TCHAR pbuff[MAX_PATH];
101 DWORD size = sizeof(pbuff);
102 if ((RegQueryValueEx(
103 hSubKey, TEXT("Path"), NULL, &type, reinterpret_cast<LPBYTE>(pbuff), &size) != ERROR_SUCCESS) ||
104 (type != REG_SZ))
105 continue;
107 std::string path(pbuff);
108 std::string::size_type idx = path.rfind("program\\soffice.exe");
109 if (idx != std::string::npos)
110 return path.substr(0, idx);
111 } // for
113 throw std::runtime_error("No valid product path found");
116 UINT GetInstallProperty(MSIHANDLE handle, LPCTSTR name, CharacterBuffer_t* buffer)
118 DWORD size = buffer->size();
119 UINT ret = MsiGetProperty(handle, name, &(*buffer)[0], &size);
121 if (ret == ERROR_MORE_DATA)
123 buffer->resize(size + 1);
124 size = buffer->size();
125 ret = MsiGetProperty(handle, name, &(*buffer)[0], &size);
127 return ret;
131 Try to find the installation path to an already installed product.
132 The installation path will be written in the Windows registry
133 during the installation. There may exist different products in
134 parallel e.g. StarOffice, StarSuite, OpenOffice.org. It will be
135 searched in this order for an installed product. If a product
136 will be found the path to the product will be set in the property
137 "INSTALLLOCATION" else nothing will be done.
139 extern "C" UINT __stdcall SetProductInstallationPath(MSIHANDLE handle)
141 //MessageBox(NULL, TEXT("SetProductInstallationPath"), TEXT("Language Pack Installation Helper"), MB_OK | MB_ICONINFORMATION);
145 CharacterBuffer_t regKeyProdPath(MAX_PATH);
147 GetInstallProperty(handle, TEXT("REGKEYPRODPATH"), &regKeyProdPath);
149 HKEY hKey;
150 if ((RegOpenKey(HKEY_CURRENT_USER, &regKeyProdPath[0], &hKey) == ERROR_SUCCESS) ||
151 (RegOpenKey(HKEY_LOCAL_MACHINE, &regKeyProdPath[0], &hKey) == ERROR_SUCCESS))
153 RegistryKeyGuard guard(hKey);
154 std::string path = FindProductInstallationPath(hKey);
155 MsiSetProperty(handle, TEXT("INSTALLLOCATION"), path.c_str());
158 catch(std::runtime_error& ex)
160 ex = ex; // no warnings
162 return ERROR_SUCCESS;
165 void MakeCfgimportCommandLine(CharacterBuffer_t* productPath)
167 char* p = &(*productPath)[0] + lstrlen(&(*productPath)[0]) - 1;
169 if (*p != '\\')
170 lstrcat(&(*productPath)[0], "\\program\\configimport.exe --spool");
171 else
172 lstrcat(&(*productPath)[0], "program\\configimport.exe --spool");
176 Calls configimport.exe --spool
178 extern "C" UINT __stdcall RegisterLanguagePack(MSIHANDLE handle)
180 //MessageBox(NULL, TEXT("RegisterLanguagePack"), TEXT("Language Pack Installation Helper"), MB_OK | MB_ICONINFORMATION);
182 CharacterBuffer_t productPath(MAX_PATH);
183 GetInstallProperty(handle, TEXT("INSTALLLOCATION"), &productPath);
184 MakeCfgimportCommandLine(&productPath);
186 STARTUPINFO si;
187 ZeroMemory(&si, sizeof(si));
188 si.cb = sizeof(si);
190 PROCESS_INFORMATION pi;
191 ZeroMemory(&pi, sizeof(pi));
193 if (CreateProcess(
194 NULL, &productPath[0], NULL, NULL,
195 FALSE, CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS, NULL,
196 NULL, &si, &pi))
198 // Wait until child process exits.
199 WaitForSingleObject(pi.hProcess, INFINITE);
201 // Close process and thread handles.
202 CloseHandle(pi.hProcess);
203 CloseHandle(pi.hThread);
205 return ERROR_SUCCESS;