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 { 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 69 inline bool IsSetMsiProperty(MSIHANDLE handle, const string& sProperty) 70 { 71 return (GetMsiProperty(handle, sProperty).length() > 0); 72 } 73 74 inline void UnsetMsiProperty(MSIHANDLE handle, const string& sProperty) 75 { 76 MsiSetProperty(handle, sProperty.c_str(), NULL); 77 } 78 79 inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string&) 80 { 81 MsiSetProperty(handle, sProperty.c_str(), TEXT("1")); 82 } 83 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 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 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