xref: /trunk/main/setup_native/source/win32/customactions/languagepacks/respintest.cxx (revision fdfd5b33ae5ed870678ef4a71a1a636776633a9e)
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 #undef UNICODE
23 #undef _UNICODE
24 
25 #define _WIN32_WINDOWS 0x0410
26 
27 #ifdef _MSC_VER
28 #pragma warning(push, 1) /* disable warnings within system headers */
29 #endif
30 #define WIN32_LEAN_AND_MEAN
31 #include <windows.h>
32 #include <msiquery.h>
33 #ifdef _MSC_VER
34 #pragma warning(pop)
35 #endif
36 
37 #include <malloc.h>
38 #include <assert.h>
39 
40 #include <tchar.h>
41 #include <string>
42 #include <systools/win32/uwinapi.h>
43 
44 #include <../tools/seterror.hxx>
45 
46 using namespace std;
47 
48 namespace
49 {
GetMsiProperty(MSIHANDLE handle,const string & sProperty)50     string GetMsiProperty(MSIHANDLE handle, const string& sProperty)
51     {
52         string  result;
53         TCHAR   szDummy[1] = TEXT("");
54         DWORD   nChars = 0;
55 
56         if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
57         {
58             DWORD nBytes = ++nChars * sizeof(TCHAR);
59             LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
60             ZeroMemory( buffer, nBytes );
61             MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
62             result = buffer;
63         }
64         return result;
65     }
66 
IsSetMsiProperty(MSIHANDLE handle,const string & sProperty)67     inline bool IsSetMsiProperty(MSIHANDLE handle, const string& sProperty)
68     {
69         return (GetMsiProperty(handle, sProperty).length() > 0);
70     }
71 
UnsetMsiProperty(MSIHANDLE handle,const string & sProperty)72     inline void UnsetMsiProperty(MSIHANDLE handle, const string& sProperty)
73     {
74         MsiSetProperty(handle, sProperty.c_str(), NULL);
75     }
76 
SetMsiProperty(MSIHANDLE handle,const string & sProperty,const string &)77     inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string&)
78     {
79         MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
80     }
81 } // namespace
82 
GetUserInstallMode(MSIHANDLE handle)83 extern "C" UINT __stdcall GetUserInstallMode(MSIHANDLE handle)
84 {
85     string sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
86 
87     // MessageBox(NULL, sOfficeInstallPath.c_str(), "DEBUG", MB_OK);
88 
89     // unsetting all properties
90 
91     UnsetMsiProperty( handle, TEXT("INVALIDDIRECTORY") );
92     UnsetMsiProperty( handle, TEXT("ISWRONGPRODUCT") );
93     UnsetMsiProperty( handle, TEXT("PATCHISOLDER") );
94     UnsetMsiProperty( handle, TEXT("ALLUSERS") );
95 
96     // 1. Searching for "ProductCode" in setup.ini
97 
98     string sSetupiniPath = sOfficeInstallPath + TEXT("program\\setup.ini");
99 
100     TCHAR szValue[32767];
101 
102     GetPrivateProfileString(
103         TEXT("Bootstrap"),
104         TEXT("ProductCode"),
105         TEXT("INVALIDDIRECTORY"),
106         szValue,
107         elementsof(szValue),
108         sSetupiniPath.c_str()
109         );
110 
111     if ( !_tcsicmp( szValue, TEXT("INVALIDDIRECTORY") ) )
112     {
113         // No setup.ini or no "ProductCode" in setup.ini. This is an invalid directory.
114         SetMsiProperty( handle, TEXT("INVALIDDIRECTORY"), TEXT("YES") );
115         // MessageBox(NULL, "INVALIDDIRECTORY set, no setup.ini or ProductCode in setup.ini.", "DEBUG", MB_OK);
116         SetMsiErrorCode( MSI_ERROR_INVALIDDIRECTORY );
117         return ERROR_SUCCESS;
118     }
119 
120     // 2. Comparing first three characters of "PRODUCTMAJOR" from property table and "buildid" from InfoFile
121 
122     szValue[0] = '\0';
123 
124     GetPrivateProfileString(
125         TEXT("Bootstrap"),
126         TEXT("buildid"),
127         TEXT("ISWRONGPRODUCT"),
128         szValue,
129         elementsof(szValue),
130         sSetupiniPath.c_str()
131         );
132 
133     if ( !_tcsicmp( szValue, TEXT("ISWRONGPRODUCT") ) )
134     {
135         SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") );
136         // MessageBox(NULL, "ISWRONGPRODUCT 1 set after searching buildid", "DEBUG", MB_OK);
137         SetMsiErrorCode( MSI_ERROR_ISWRONGPRODUCT );
138         return ERROR_SUCCESS;
139     }
140 
141     string ProductMajor = GetMsiProperty(handle, TEXT("PRODUCTMAJOR"));
142 
143     // Comparing the first three characters, for example "680"
144     // If not equal, this version is not suited for patch or language pack
145 
146     if (_tcsnicmp(ProductMajor.c_str(), szValue, 3))
147     {
148         SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") );
149         // MessageBox(NULL, "ISWRONGPRODUCT 2 set after searching PRODUCTMAJOR", "DEBUG", MB_OK);
150         SetMsiErrorCode( MSI_ERROR_ISWRONGPRODUCT );
151         return ERROR_SUCCESS;
152     }
153 
154     // 3. Only for patch: Comparing "PRODUCTMINOR from property table and "ProductMinor" from InfoFile
155 
156     string isPatch = GetMsiProperty(handle, TEXT("ISPATCH"));
157 
158     if (isPatch=="1")
159     {
160         string ProductMinor = GetMsiProperty(handle, TEXT("PRODUCTBUILDID"));
161         int PatchProductMinor = atoi(ProductMinor.c_str());
162 
163         szValue[0] = '\0';
164 
165         GetPrivateProfileString(
166             TEXT("Bootstrap"),
167             TEXT("ProductBuildid"),
168             TEXT("8918"),
169             szValue,
170             elementsof(szValue),
171             sSetupiniPath.c_str()
172             );
173 
174         int InstalledProductMinor = atoi(szValue);
175 
176         if ( InstalledProductMinor >= PatchProductMinor )
177         {
178             SetMsiProperty( handle, TEXT("PATCHISOLDER"), TEXT("YES") );
179             // MessageBox(NULL, "PATCHISOLDER set", "DEBUG", MB_OK);
180             SetMsiErrorCode( MSI_ERROR_PATCHISOLDER );
181             return ERROR_SUCCESS;
182         }
183     }
184 
185     // 4. Setting property ALLUSERS with value from "setup.ini"
186 
187     szValue[0] = '\0';
188 
189     GetPrivateProfileString(
190         TEXT("Bootstrap"),
191         TEXT("ALLUSERS"),
192         TEXT(""),
193         szValue,
194         elementsof(szValue),
195         sSetupiniPath.c_str()
196         );
197 
198     if ( szValue[0] )
199     {
200         SetMsiProperty( handle, TEXT("ALLUSERS"), szValue );
201         // MessageBox(NULL, "ALLUSERS set", "DEBUG", MB_OK);
202     }
203 
204     return ERROR_SUCCESS;
205 }
206 
207 /* vim: set noet sw=4 ts=4: */
208