1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #undef UNICODE 29 #undef _UNICODE 30 31 #define _WIN32_WINDOWS 0x0410 32 33 #ifdef _MSC_VER 34 #pragma warning(push, 1) /* disable warnings within system headers */ 35 #endif 36 #define WIN32_LEAN_AND_MEAN 37 #include <windows.h> 38 #include <msiquery.h> 39 #ifdef _MSC_VER 40 #pragma warning(pop) 41 #endif 42 43 #include <malloc.h> 44 #include <assert.h> 45 46 #include <tchar.h> 47 #include <string> 48 #include <systools/win32/uwinapi.h> 49 50 #include <../tools/seterror.hxx> 51 52 using namespace std; 53 54 namespace 55 { 56 string GetMsiProperty(MSIHANDLE handle, const string& sProperty) 57 { 58 string result; 59 TCHAR szDummy[1] = TEXT(""); 60 DWORD nChars = 0; 61 62 if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA) 63 { 64 DWORD nBytes = ++nChars * sizeof(TCHAR); 65 LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes)); 66 ZeroMemory( buffer, nBytes ); 67 MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars); 68 result = buffer; 69 } 70 return result; 71 } 72 73 inline bool IsSetMsiProperty(MSIHANDLE handle, const string& sProperty) 74 { 75 return (GetMsiProperty(handle, sProperty).length() > 0); 76 } 77 78 inline void UnsetMsiProperty(MSIHANDLE handle, const string& sProperty) 79 { 80 MsiSetProperty(handle, sProperty.c_str(), NULL); 81 } 82 83 inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string&) 84 { 85 MsiSetProperty(handle, sProperty.c_str(), TEXT("1")); 86 } 87 } // namespace 88 89 extern "C" UINT __stdcall GetUserInstallMode(MSIHANDLE handle) 90 { 91 string sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION")); 92 93 // MessageBox(NULL, sOfficeInstallPath.c_str(), "DEBUG", MB_OK); 94 95 // unsetting all properties 96 97 UnsetMsiProperty( handle, TEXT("INVALIDDIRECTORY") ); 98 UnsetMsiProperty( handle, TEXT("ISWRONGPRODUCT") ); 99 UnsetMsiProperty( handle, TEXT("PATCHISOLDER") ); 100 UnsetMsiProperty( handle, TEXT("ALLUSERS") ); 101 102 // 1. Searching for "ProductCode" in setup.ini 103 104 string sSetupiniPath = sOfficeInstallPath + TEXT("program\\setup.ini"); 105 106 TCHAR szValue[32767]; 107 108 GetPrivateProfileString( 109 TEXT("Bootstrap"), 110 TEXT("ProductCode"), 111 TEXT("INVALIDDIRECTORY"), 112 szValue, 113 elementsof(szValue), 114 sSetupiniPath.c_str() 115 ); 116 117 if ( !_tcsicmp( szValue, TEXT("INVALIDDIRECTORY") ) ) 118 { 119 // No setup.ini or no "ProductCode" in setup.ini. This is an invalid directory. 120 SetMsiProperty( handle, TEXT("INVALIDDIRECTORY"), TEXT("YES") ); 121 // MessageBox(NULL, "INVALIDDIRECTORY set, no setup.ini or ProductCode in setup.ini.", "DEBUG", MB_OK); 122 SetMsiErrorCode( MSI_ERROR_INVALIDDIRECTORY ); 123 return ERROR_SUCCESS; 124 } 125 126 // 2. Comparing first three characters of "PRODUCTMAJOR" from property table and "buildid" from InfoFile 127 128 szValue[0] = '\0'; 129 130 GetPrivateProfileString( 131 TEXT("Bootstrap"), 132 TEXT("buildid"), 133 TEXT("ISWRONGPRODUCT"), 134 szValue, 135 elementsof(szValue), 136 sSetupiniPath.c_str() 137 ); 138 139 if ( !_tcsicmp( szValue, TEXT("ISWRONGPRODUCT") ) ) 140 { 141 SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") ); 142 // MessageBox(NULL, "ISWRONGPRODUCT 1 set after searching buildid", "DEBUG", MB_OK); 143 SetMsiErrorCode( MSI_ERROR_ISWRONGPRODUCT ); 144 return ERROR_SUCCESS; 145 } 146 147 string ProductMajor = GetMsiProperty(handle, TEXT("PRODUCTMAJOR")); 148 149 // Comparing the first three characters, for example "680" 150 // If not equal, this version is not suited for patch or language pack 151 152 if (_tcsnicmp(ProductMajor.c_str(), szValue, 3)) 153 { 154 SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") ); 155 // MessageBox(NULL, "ISWRONGPRODUCT 2 set after searching PRODUCTMAJOR", "DEBUG", MB_OK); 156 SetMsiErrorCode( MSI_ERROR_ISWRONGPRODUCT ); 157 return ERROR_SUCCESS; 158 } 159 160 // 3. Only for patch: Comparing "PRODUCTMINOR from property table and "ProductMinor" from InfoFile 161 162 string isPatch = GetMsiProperty(handle, TEXT("ISPATCH")); 163 164 if (isPatch=="1") 165 { 166 string ProductMinor = GetMsiProperty(handle, TEXT("PRODUCTBUILDID")); 167 int PatchProductMinor = atoi(ProductMinor.c_str()); 168 169 szValue[0] = '\0'; 170 171 GetPrivateProfileString( 172 TEXT("Bootstrap"), 173 TEXT("ProductBuildid"), 174 TEXT("8918"), 175 szValue, 176 elementsof(szValue), 177 sSetupiniPath.c_str() 178 ); 179 180 int InstalledProductMinor = atoi(szValue); 181 182 if ( InstalledProductMinor >= PatchProductMinor ) 183 { 184 SetMsiProperty( handle, TEXT("PATCHISOLDER"), TEXT("YES") ); 185 // MessageBox(NULL, "PATCHISOLDER set", "DEBUG", MB_OK); 186 SetMsiErrorCode( MSI_ERROR_PATCHISOLDER ); 187 return ERROR_SUCCESS; 188 } 189 } 190 191 // 4. Setting property ALLUSERS with value from "setup.ini" 192 193 szValue[0] = '\0'; 194 195 GetPrivateProfileString( 196 TEXT("Bootstrap"), 197 TEXT("ALLUSERS"), 198 TEXT(""), 199 szValue, 200 elementsof(szValue), 201 sSetupiniPath.c_str() 202 ); 203 204 if ( szValue[0] ) 205 { 206 SetMsiProperty( handle, TEXT("ALLUSERS"), szValue ); 207 // MessageBox(NULL, "ALLUSERS set", "DEBUG", MB_OK); 208 } 209 210 return ERROR_SUCCESS; 211 } 212