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 void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string& sValue) 70 { 71 MsiSetProperty(handle, sProperty.c_str(), sValue.c_str()); 72 } 73 74 void stripFinalBackslash(std::string * path) { 75 std::string::size_type i = path->size(); 76 if (i > 1) { 77 --i; 78 if ((*path)[i] == '\\') { 79 path->erase(i); 80 } 81 } 82 } 83 84 // Copied more or less verbatim from 85 // desktop/source/deployment/inc/dp_version.hxx:1.5 and 86 // desktop/source/deployment/misc/dp_version.cxx:1.5: 87 88 enum Order { ORDER_LESS, ORDER_EQUAL, ORDER_GREATER }; 89 90 string getElement(string const & version, string::size_type * index) { 91 while (*index < version.size() && version[*index] == '0') { 92 ++*index; 93 } 94 string::size_type i = *index; 95 *index = version.find('.', i); 96 if (*index == string::npos) { 97 *index = version.size(); 98 return string(version, i); 99 } else { 100 ++*index; 101 return string(version, i, *index - 1 - i); 102 } 103 } 104 105 Order compareVersions(string const & version1, string const & version2) { 106 for (string::size_type i1 = 0, i2 = 0; 107 i1 < version1.size() || i2 < version2.size();) 108 { 109 string e1(getElement(version1, &i1)); 110 string e2(getElement(version2, &i2)); 111 112 // string myText1 = TEXT("e1: ") + e1; 113 // string myText2 = TEXT("e2: ") + e2; 114 // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK); 115 // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK); 116 117 if (e1.size() < e2.size()) { 118 return ORDER_LESS; 119 } else if (e1.size() > e2.size()) { 120 return ORDER_GREATER; 121 } else if (e1 < e2) { 122 return ORDER_LESS; 123 } else if (e1 > e2) { 124 return ORDER_GREATER; 125 } 126 } 127 return ORDER_EQUAL; 128 } 129 130 } // namespace 131 132 extern "C" UINT __stdcall DotNetCheck(MSIHANDLE handle) { 133 string present(GetMsiProperty(handle, TEXT("MsiNetAssemblySupport"))); 134 string required(GetMsiProperty(handle, TEXT("REQUIRED_DOTNET_VERSION"))); 135 136 // string myText1 = TEXT("MsiNetAssemblySupport: ") + present; 137 // string myText2 = TEXT("REQUIRED_DOTNET_VERSION: ") + required; 138 // MessageBox(NULL, myText1.c_str(), "DEBUG", MB_OK); 139 // MessageBox(NULL, myText2.c_str(), "DEBUG", MB_OK); 140 141 SetMsiProperty( 142 handle, TEXT("DOTNET_SUFFICIENT"), 143 (present.empty() || compareVersions(present, required) == ORDER_LESS ? 144 TEXT("0") : TEXT("1"))); 145 146 // string result(GetMsiProperty(handle, TEXT("DOTNET_SUFFICIENT"))); 147 // string myText3 = TEXT("DOTNET_SUFFICIENT: ") + result; 148 // MessageBox(NULL, myText3.c_str(), "DEBUG", MB_OK); 149 150 151 return ERROR_SUCCESS; 152 } 153 154 extern "C" UINT __stdcall ShowProperties(MSIHANDLE handle) 155 { 156 string property = GetMsiProperty(handle, TEXT("INSTALLLOCATION")); 157 string myText = TEXT("INSTALLLOCATION: ") + property; 158 MessageBox(NULL, myText.c_str(), "INSTALLLOCATION", MB_OK); 159 160 property = GetMsiProperty(handle, TEXT("Installed")); 161 myText = TEXT("Installed: ") + property; 162 MessageBox(NULL, myText.c_str(), "Installed", MB_OK); 163 164 property = GetMsiProperty(handle, TEXT("PATCH")); 165 myText = TEXT("PATCH: ") + property; 166 MessageBox(NULL, myText.c_str(), "PATCH", MB_OK); 167 168 property = GetMsiProperty(handle, TEXT("REMOVE")); 169 myText = TEXT("REMOVE: ") + property; 170 MessageBox(NULL, myText.c_str(), "REMOVE", MB_OK); 171 172 property = GetMsiProperty(handle, TEXT("ALLUSERS")); 173 myText = TEXT("ALLUSERS: ") + property; 174 MessageBox(NULL, myText.c_str(), "ALLUSERS", MB_OK); 175 176 return ERROR_SUCCESS; 177 } 178