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