1*32b1fd08SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*32b1fd08SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*32b1fd08SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*32b1fd08SAndrew Rist * distributed with this work for additional information
6*32b1fd08SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*32b1fd08SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*32b1fd08SAndrew Rist * "License"); you may not use this file except in compliance
9*32b1fd08SAndrew Rist * with the License. You may obtain a copy of the License at
10*32b1fd08SAndrew Rist *
11*32b1fd08SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*32b1fd08SAndrew Rist *
13*32b1fd08SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*32b1fd08SAndrew Rist * software distributed under the License is distributed on an
15*32b1fd08SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*32b1fd08SAndrew Rist * KIND, either express or implied. See the License for the
17*32b1fd08SAndrew Rist * specific language governing permissions and limitations
18*32b1fd08SAndrew Rist * under the License.
19*32b1fd08SAndrew Rist *
20*32b1fd08SAndrew Rist *************************************************************/
21*32b1fd08SAndrew Rist
22*32b1fd08SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #undef UNICODE
25cdf0e10cSrcweir #undef _UNICODE
26cdf0e10cSrcweir
27cdf0e10cSrcweir #define _WIN32_WINDOWS 0x0410
28cdf0e10cSrcweir
29cdf0e10cSrcweir #ifdef _MSC_VER
30cdf0e10cSrcweir #pragma warning(push, 1) /* disable warnings within system headers */
31cdf0e10cSrcweir #endif
32cdf0e10cSrcweir #define WIN32_LEAN_AND_MEAN
33cdf0e10cSrcweir #include <windows.h>
34cdf0e10cSrcweir #include <msiquery.h>
35cdf0e10cSrcweir #ifdef _MSC_VER
36cdf0e10cSrcweir #pragma warning(pop)
37cdf0e10cSrcweir #endif
38cdf0e10cSrcweir
39cdf0e10cSrcweir #include <malloc.h>
40cdf0e10cSrcweir #include <assert.h>
41cdf0e10cSrcweir
42cdf0e10cSrcweir #include <tchar.h>
43cdf0e10cSrcweir #include <string>
44cdf0e10cSrcweir #include <systools/win32/uwinapi.h>
45cdf0e10cSrcweir
46cdf0e10cSrcweir #include <../tools/seterror.hxx>
47cdf0e10cSrcweir
48cdf0e10cSrcweir using namespace std;
49cdf0e10cSrcweir
50cdf0e10cSrcweir namespace
51cdf0e10cSrcweir {
GetMsiProperty(MSIHANDLE handle,const string & sProperty)52cdf0e10cSrcweir string GetMsiProperty(MSIHANDLE handle, const string& sProperty)
53cdf0e10cSrcweir {
54cdf0e10cSrcweir string result;
55cdf0e10cSrcweir TCHAR szDummy[1] = TEXT("");
56cdf0e10cSrcweir DWORD nChars = 0;
57cdf0e10cSrcweir
58cdf0e10cSrcweir if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
59cdf0e10cSrcweir {
60cdf0e10cSrcweir DWORD nBytes = ++nChars * sizeof(TCHAR);
61cdf0e10cSrcweir LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
62cdf0e10cSrcweir ZeroMemory( buffer, nBytes );
63cdf0e10cSrcweir MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
64cdf0e10cSrcweir result = buffer;
65cdf0e10cSrcweir }
66cdf0e10cSrcweir return result;
67cdf0e10cSrcweir }
68cdf0e10cSrcweir
IsSetMsiProperty(MSIHANDLE handle,const string & sProperty)69cdf0e10cSrcweir inline bool IsSetMsiProperty(MSIHANDLE handle, const string& sProperty)
70cdf0e10cSrcweir {
71cdf0e10cSrcweir return (GetMsiProperty(handle, sProperty).length() > 0);
72cdf0e10cSrcweir }
73cdf0e10cSrcweir
UnsetMsiProperty(MSIHANDLE handle,const string & sProperty)74cdf0e10cSrcweir inline void UnsetMsiProperty(MSIHANDLE handle, const string& sProperty)
75cdf0e10cSrcweir {
76cdf0e10cSrcweir MsiSetProperty(handle, sProperty.c_str(), NULL);
77cdf0e10cSrcweir }
78cdf0e10cSrcweir
SetMsiProperty(MSIHANDLE handle,const string & sProperty,const string &)79cdf0e10cSrcweir inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string&)
80cdf0e10cSrcweir {
81cdf0e10cSrcweir MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
82cdf0e10cSrcweir }
83cdf0e10cSrcweir
stripFinalBackslash(std::string * path)84cdf0e10cSrcweir void stripFinalBackslash(std::string * path) {
85cdf0e10cSrcweir std::string::size_type i = path->size();
86cdf0e10cSrcweir if (i > 1) {
87cdf0e10cSrcweir --i;
88cdf0e10cSrcweir if ((*path)[i] == '\\') {
89cdf0e10cSrcweir path->erase(i);
90cdf0e10cSrcweir }
91cdf0e10cSrcweir }
92cdf0e10cSrcweir }
93cdf0e10cSrcweir } // namespace
94cdf0e10cSrcweir
CreateLayerLinks(MSIHANDLE handle)95cdf0e10cSrcweir extern "C" UINT __stdcall CreateLayerLinks(MSIHANDLE handle)
96cdf0e10cSrcweir {
97cdf0e10cSrcweir string sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
98cdf0e10cSrcweir
99cdf0e10cSrcweir string sOfficeInstallPath = sInstallPath;
100cdf0e10cSrcweir string sBasisInstallPath = sInstallPath + TEXT("Basis\\");
101cdf0e10cSrcweir string sUreInstallPath = sInstallPath + TEXT("URE\\");
102cdf0e10cSrcweir
103cdf0e10cSrcweir string sBasisLinkPath = sInstallPath + TEXT("basis-link");
104cdf0e10cSrcweir string sUreLinkPath = sInstallPath + TEXT("Basis\\ure-link");
105cdf0e10cSrcweir
106cdf0e10cSrcweir if ( IsSetMsiProperty(handle, TEXT("ADMININSTALL")) )
107cdf0e10cSrcweir {
108cdf0e10cSrcweir sBasisInstallPath = TEXT("Basis");
109cdf0e10cSrcweir sUreInstallPath = TEXT("..\\URE");
110cdf0e10cSrcweir }
111cdf0e10cSrcweir
112cdf0e10cSrcweir stripFinalBackslash(&sBasisInstallPath);
113cdf0e10cSrcweir stripFinalBackslash(&sUreInstallPath);
114cdf0e10cSrcweir
115cdf0e10cSrcweir // string myText1 = TEXT("Creating Basis-Link: ") + sBasisLinkPath;
116cdf0e10cSrcweir // string myText2 = TEXT("Creating Ure-Link: ") + sUreLinkPath;
117cdf0e10cSrcweir // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK);
118cdf0e10cSrcweir // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK);
119cdf0e10cSrcweir
120cdf0e10cSrcweir // creating basis-link in brand layer
121cdf0e10cSrcweir
122cdf0e10cSrcweir HANDLE h1file = CreateFile(
123cdf0e10cSrcweir sBasisLinkPath.c_str(),
124cdf0e10cSrcweir GENERIC_WRITE,
125cdf0e10cSrcweir 0,
126cdf0e10cSrcweir NULL,
127cdf0e10cSrcweir CREATE_NEW,
128cdf0e10cSrcweir FILE_ATTRIBUTE_NORMAL,
129cdf0e10cSrcweir NULL);
130cdf0e10cSrcweir
131cdf0e10cSrcweir if (IsValidHandle(h1file))
132cdf0e10cSrcweir {
133cdf0e10cSrcweir DWORD dummy;
134cdf0e10cSrcweir
135cdf0e10cSrcweir // Converting string into UTF-8 encoding and writing into file "basis-link"
136cdf0e10cSrcweir
137cdf0e10cSrcweir int nCharsRequired = MultiByteToWideChar( CP_ACP, 0, sBasisInstallPath.c_str(), -1, NULL, 0 );
138cdf0e10cSrcweir if ( nCharsRequired )
139cdf0e10cSrcweir {
140cdf0e10cSrcweir LPWSTR lpPathW = new WCHAR[nCharsRequired];
141cdf0e10cSrcweir if ( MultiByteToWideChar( CP_ACP, 0, sBasisInstallPath.c_str(), -1, lpPathW, nCharsRequired ) )
142cdf0e10cSrcweir {
143cdf0e10cSrcweir nCharsRequired = WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, NULL, 0, NULL, NULL );
144cdf0e10cSrcweir if ( nCharsRequired )
145cdf0e10cSrcweir {
146cdf0e10cSrcweir LPSTR lpPathUTF8 = new CHAR[nCharsRequired];
147cdf0e10cSrcweir WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, lpPathUTF8, nCharsRequired, NULL, NULL );
148cdf0e10cSrcweir
149cdf0e10cSrcweir // WriteFile( h1file, sBasisInstallPath.c_str(), sBasisInstallPath.size() ,&dummy, 0 );
150cdf0e10cSrcweir WriteFile( h1file, lpPathUTF8, strlen(lpPathUTF8) ,&dummy, 0 );
151cdf0e10cSrcweir
152cdf0e10cSrcweir delete lpPathUTF8;
153cdf0e10cSrcweir }
154cdf0e10cSrcweir }
155cdf0e10cSrcweir
156cdf0e10cSrcweir delete lpPathW;
157cdf0e10cSrcweir }
158cdf0e10cSrcweir
159cdf0e10cSrcweir CloseHandle(h1file);
160cdf0e10cSrcweir }
161cdf0e10cSrcweir
162cdf0e10cSrcweir // creating ure-link in basis layer
163cdf0e10cSrcweir
164cdf0e10cSrcweir HANDLE h2file = CreateFile(
165cdf0e10cSrcweir sUreLinkPath.c_str(),
166cdf0e10cSrcweir GENERIC_WRITE,
167cdf0e10cSrcweir 0,
168cdf0e10cSrcweir NULL,
169cdf0e10cSrcweir CREATE_NEW,
170cdf0e10cSrcweir FILE_ATTRIBUTE_NORMAL,
171cdf0e10cSrcweir NULL);
172cdf0e10cSrcweir
173cdf0e10cSrcweir if (IsValidHandle(h2file))
174cdf0e10cSrcweir {
175cdf0e10cSrcweir DWORD dummy;
176cdf0e10cSrcweir
177cdf0e10cSrcweir // Converting string into UTF-8 encoding and writing into file "basis-link"
178cdf0e10cSrcweir
179cdf0e10cSrcweir int nCharsRequired = MultiByteToWideChar( CP_ACP, 0, sUreInstallPath.c_str(), -1, NULL, 0 );
180cdf0e10cSrcweir if ( nCharsRequired )
181cdf0e10cSrcweir {
182cdf0e10cSrcweir LPWSTR lpPathW = new WCHAR[nCharsRequired];
183cdf0e10cSrcweir if ( MultiByteToWideChar( CP_ACP, 0, sUreInstallPath.c_str(), -1, lpPathW, nCharsRequired ) )
184cdf0e10cSrcweir {
185cdf0e10cSrcweir nCharsRequired = WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, NULL, 0, NULL, NULL );
186cdf0e10cSrcweir if ( nCharsRequired )
187cdf0e10cSrcweir {
188cdf0e10cSrcweir LPSTR lpPathUTF8 = new CHAR[nCharsRequired];
189cdf0e10cSrcweir WideCharToMultiByte( CP_UTF8, 0, lpPathW, -1, lpPathUTF8, nCharsRequired, NULL, NULL );
190cdf0e10cSrcweir
191cdf0e10cSrcweir // WriteFile( h2file, sUreInstallPath.c_str(), sUreInstallPath.size() ,&dummy, 0 );
192cdf0e10cSrcweir WriteFile( h2file, lpPathUTF8, strlen(lpPathUTF8) ,&dummy, 0 );
193cdf0e10cSrcweir
194cdf0e10cSrcweir delete lpPathUTF8;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir }
197cdf0e10cSrcweir
198cdf0e10cSrcweir delete lpPathW;
199cdf0e10cSrcweir }
200cdf0e10cSrcweir
201cdf0e10cSrcweir CloseHandle(h2file);
202cdf0e10cSrcweir }
203cdf0e10cSrcweir
204cdf0e10cSrcweir return ERROR_SUCCESS;
205cdf0e10cSrcweir }
206cdf0e10cSrcweir
RemoveLayerLinks(MSIHANDLE handle)207cdf0e10cSrcweir extern "C" UINT __stdcall RemoveLayerLinks(MSIHANDLE handle)
208cdf0e10cSrcweir {
209cdf0e10cSrcweir string sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
210cdf0e10cSrcweir
211cdf0e10cSrcweir string sOfficeInstallPath = sInstallPath;
212cdf0e10cSrcweir string sBasisInstallPath = sInstallPath + TEXT("Basis\\");
213cdf0e10cSrcweir string sUreInstallPath = sInstallPath + TEXT("URE\\");
214cdf0e10cSrcweir
215cdf0e10cSrcweir string sBasisLinkPath = sOfficeInstallPath + TEXT("basis-link");
216cdf0e10cSrcweir string sUreLinkPath = sBasisInstallPath + TEXT("ure-link");
217cdf0e10cSrcweir string sUreDirName = sUreInstallPath + TEXT("bin");
218cdf0e10cSrcweir
219cdf0e10cSrcweir // string myText2 = TEXT("Deleting Ure-Link: ") + sUreLinkPath;
220cdf0e10cSrcweir // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK);
221cdf0e10cSrcweir
222cdf0e10cSrcweir // Deleting link to basis layer
223cdf0e10cSrcweir // string myText1 = TEXT("Deleting Basis-Link: ") + sBasisLinkPath;
224cdf0e10cSrcweir // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK);
225cdf0e10cSrcweir DeleteFile(sBasisLinkPath.c_str());
226cdf0e10cSrcweir
227cdf0e10cSrcweir // Check, if URE is still installed
228cdf0e10cSrcweir bool ureDirExists = true;
229cdf0e10cSrcweir WIN32_FIND_DATA aFindData;
230cdf0e10cSrcweir HANDLE hFindContent = FindFirstFile( sUreDirName.c_str(), &aFindData );
231cdf0e10cSrcweir if ( hFindContent == INVALID_HANDLE_VALUE ) { ureDirExists = false; }
232cdf0e10cSrcweir FindClose( hFindContent );
233cdf0e10cSrcweir
234cdf0e10cSrcweir // if ( ureDirExists )
235cdf0e10cSrcweir // {
236cdf0e10cSrcweir // string myText3 = TEXT("URE directory still exists: ") + sUreDirName;
237cdf0e10cSrcweir // MessageBox(NULL, myText3.c_str(), "DEBUG", MB_OK);
238cdf0e10cSrcweir // string myText4 = TEXT("URE link NOT removed: ") + sUreLinkPath;
239cdf0e10cSrcweir // MessageBox(NULL, myText4.c_str(), "DEBUG", MB_OK);
240cdf0e10cSrcweir // }
241cdf0e10cSrcweir
242cdf0e10cSrcweir // Deleting link to URE layer, if URE dir no longer exists
243cdf0e10cSrcweir if ( ! ureDirExists )
244cdf0e10cSrcweir {
245cdf0e10cSrcweir // string myText5 = TEXT("URE directory does not exist: ") + sUreDirName;
246cdf0e10cSrcweir // MessageBox(NULL, myText5.c_str(), "DEBUG", MB_OK);
247cdf0e10cSrcweir DeleteFile(sUreLinkPath.c_str());
248cdf0e10cSrcweir // string myText6 = TEXT("URE link removed: ") + sUreLinkPath;
249cdf0e10cSrcweir // MessageBox(NULL, myText6.c_str(), "DEBUG", MB_OK);
250cdf0e10cSrcweir }
251cdf0e10cSrcweir
252cdf0e10cSrcweir return ERROR_SUCCESS;
253cdf0e10cSrcweir }
254