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