ReactOS  0.4.14-dev-384-g5b37caa
upgrade.c
Go to the documentation of this file.
1 /*
2  * Implementation of the Microsoft Installer (msi.dll)
3  *
4  * Copyright 2005 Aric Stewart for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 /*
22  * Actions focused on in this module
23  *
24  * FindRelatedProducts
25  * MigrateFeatureStates (TODO)
26  * RemoveExistingProducts (TODO)
27  */
28 
29 #include <stdarg.h>
30 
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winerror.h"
34 #include "winreg.h"
35 #include "wine/debug.h"
36 #include "msidefs.h"
37 #include "msipriv.h"
38 #include "winuser.h"
39 #include "wine/unicode.h"
40 
42 
43 static BOOL check_language(DWORD lang1, LPCWSTR lang2, DWORD attributes)
44 {
45  DWORD langdword;
46 
47  if (!lang2 || lang2[0]==0)
48  return TRUE;
49 
50  langdword = atoiW(lang2);
51 
53  return (lang1 != langdword);
54  else
55  return (lang1 == langdword);
56 }
57 
58 static void append_productcode(MSIPACKAGE* package, LPCWSTR action_property,
59  LPCWSTR productid)
60 {
61  LPWSTR prop;
62  LPWSTR newprop;
63  DWORD len;
64  UINT r;
65 
66  prop = msi_dup_property(package->db, action_property );
67  if (prop)
68  len = strlenW(prop);
69  else
70  len = 0;
71 
72  /*separator*/
73  len ++;
74 
75  len += strlenW(productid);
76 
77  /*null*/
78  len++;
79 
80  newprop = msi_alloc( len*sizeof(WCHAR) );
81 
82  if (prop)
83  {
84  strcpyW(newprop,prop);
85  strcatW(newprop,szSemiColon);
86  }
87  else
88  newprop[0] = 0;
89  strcatW(newprop,productid);
90 
91  r = msi_set_property( package->db, action_property, newprop, -1 );
92  if (r == ERROR_SUCCESS && !strcmpW( action_property, szSourceDir ))
93  msi_reset_folders( package, TRUE );
94 
95  TRACE("Found Related Product... %s now %s\n",
96  debugstr_w(action_property), debugstr_w(newprop));
97 
98  msi_free( prop );
99  msi_free( newprop );
100 }
101 
103 {
104  MSIPACKAGE *package = param;
105  WCHAR product[SQUASHED_GUID_SIZE];
106  DWORD index = 0, attributes = 0, sz = sizeof(product)/sizeof(product[0]);
107  LPCWSTR upgrade_code;
108  HKEY hkey = 0;
109  UINT rc = ERROR_SUCCESS;
110  MSIRECORD *uirow;
111 
112  upgrade_code = MSI_RecordGetString(rec,1);
113 
114  rc = MSIREG_OpenUpgradeCodesKey(upgrade_code, &hkey, FALSE);
115  if (rc != ERROR_SUCCESS)
116  return ERROR_SUCCESS;
117 
118  uirow = MSI_CreateRecord(1);
119  attributes = MSI_RecordGetInteger(rec,5);
120 
121  while (rc == ERROR_SUCCESS)
122  {
123  rc = RegEnumValueW(hkey, index, product, &sz, NULL, NULL, NULL, NULL);
124  if (rc == ERROR_SUCCESS)
125  {
126  WCHAR productid[GUID_SIZE];
127  LPCWSTR ver, language, action_property;
128  DWORD check = 0, comp_ver, sz = 0x100;
129  HKEY hukey;
130  INT r;
131 
132  TRACE("Looking at index %u product %s\n", index, debugstr_w(product));
133 
134  unsquash_guid(product, productid);
138  {
139  TRACE("product key not found\n");
140  rc = ERROR_SUCCESS;
141  index ++;
142  continue;
143  }
144 
145  sz = sizeof(DWORD);
147 
148  /* check version minimum */
149  ver = MSI_RecordGetString(rec,2);
150  if (ver)
151  {
152  comp_ver = msi_version_str_to_dword(ver);
153  r = check - comp_ver;
154  if (r < 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMinInclusive)))
155  {
156  TRACE("version below minimum\n");
157  RegCloseKey(hukey);
158  index ++;
159  continue;
160  }
161  }
162 
163  /* check version maximum */
164  ver = MSI_RecordGetString(rec,3);
165  if (ver)
166  {
167  comp_ver = msi_version_str_to_dword(ver);
168  r = check - comp_ver;
169  if (r > 0 || (r == 0 && !(attributes & msidbUpgradeAttributesVersionMaxInclusive)))
170  {
171  RegCloseKey(hukey);
172  index ++;
173  continue;
174  }
175  TRACE("version above maximum\n");
176  }
177 
178  /* check language */
179  sz = sizeof(DWORD);
181  RegCloseKey(hukey);
182  language = MSI_RecordGetString(rec,4);
183  if (!check_language(check, language, attributes))
184  {
185  index ++;
186  TRACE("language doesn't match\n");
187  continue;
188  }
189  TRACE("found related product\n");
190 
191  action_property = MSI_RecordGetString(rec, 7);
192  append_productcode(package, action_property, productid);
193  MSI_RecordSetStringW(uirow, 1, productid);
195  }
196  index ++;
197  }
198  RegCloseKey(hkey);
199  msiobj_release( &uirow->hdr);
200 
201  return ERROR_SUCCESS;
202 }
203 
205 {
206  static const WCHAR query[] = {
207  'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
208  '`','U','p','g','r','a','d','e','`',0};
209  MSIQUERY *view;
210  UINT rc;
211 
212  if (msi_get_property_int(package->db, szInstalled, 0))
213  {
214  TRACE("Skipping FindRelatedProducts action: product already installed\n");
215  return ERROR_SUCCESS;
216  }
218  {
219  TRACE("Skipping FindRelatedProducts action: already done in UI sequence\n");
220  return ERROR_SUCCESS;
221  }
222  else
224 
225  rc = MSI_DatabaseOpenViewW(package->db, query, &view);
226  if (rc != ERROR_SUCCESS)
227  return ERROR_SUCCESS;
228 
230  msiobj_release(&view->hdr);
231  return rc;
232 }
static const WCHAR szSemiColon[]
Definition: msipriv.h:1115
static void append_productcode(MSIPACKAGE *package, LPCWSTR action_property, LPCWSTR productid)
Definition: upgrade.c:58
#define TRUE
Definition: types.h:120
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:649
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define ERROR_SUCCESS
Definition: deptool.c:10
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
MSIOBJECTHDR hdr
Definition: msipriv.h:141
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
int msi_get_property_int(MSIDATABASE *package, LPCWSTR prop, int def) DECLSPEC_HIDDEN
Definition: package.c:2392
BOOL msi_action_is_unique(const MSIPACKAGE *package, const WCHAR *action)
Definition: custom.c:112
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:56
DWORD msi_version_str_to_dword(LPCWSTR p) DECLSPEC_HIDDEN
Definition: registry.c:339
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
unsigned int BOOL
Definition: ntddk_ex.h:94
#define debugstr_w
Definition: kernel32.h:32
static const WCHAR szFindRelatedProducts[]
Definition: msipriv.h:1137
INT MSI_ProcessMessage(MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD *) DECLSPEC_HIDDEN
Definition: package.c:1946
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2853
smooth NULL
Definition: ftsmooth.c:416
void msi_reset_folders(MSIPACKAGE *package, BOOL source) DECLSPEC_HIDDEN
Definition: package.c:2130
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:482
GLuint index
Definition: glext.h:6031
UINT MSIREG_OpenProductKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context, HKEY *key, BOOL create) DECLSPEC_HIDDEN
Definition: registry.c:492
#define TRACE(s)
Definition: solgame.cpp:4
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
GLfloat param
Definition: glext.h:5796
unsigned long DWORD
Definition: ntddk_ex.h:95
MSIDATABASE * db
Definition: msipriv.h:386
void check(CONTEXT *pContext)
Definition: NtContinue.c:61
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:242
static const WCHAR szSourceDir[]
Definition: msipriv.h:1100
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:79
static const WCHAR INSTALLPROPERTY_LANGUAGEW[]
Definition: msi.h:273
GLenum GLsizei len
Definition: glext.h:6722
int MSI_RecordGetInteger(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:245
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
UINT ACTION_FindRelatedProducts(MSIPACKAGE *package)
Definition: upgrade.c:204
#define SQUASHED_GUID_SIZE
Definition: msipriv.h:711
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
unsigned int UINT
Definition: ndis.h:50
UINT msi_set_property(MSIDATABASE *, const WCHAR *, const WCHAR *, int) DECLSPEC_HIDDEN
Definition: package.c:2149
WINE_DEFAULT_DEBUG_CHANNEL(msi)
UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szProduct, HKEY *key, BOOL create) DECLSPEC_HIDDEN
Definition: registry.c:915
static BOOL msi_free(void *mem)
Definition: msipriv.h:1227
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1204
static IOleDocumentView * view
Definition: activex.c:1749
static const WCHAR INSTALLPROPERTY_VERSIONW[]
Definition: msi.h:289
BOOL unsquash_guid(LPCWSTR in, LPWSTR out) DECLSPEC_HIDDEN
Definition: registry.c:192
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static UINT ITERATE_FindRelatedProducts(MSIRECORD *rec, LPVOID param)
Definition: upgrade.c:102
#define GUID_SIZE
Definition: msipriv.h:710
UINT MSI_IterateRecords(MSIQUERY *, LPDWORD, record_func, LPVOID) DECLSPEC_HIDDEN
Definition: msiquery.c:168
static BOOL check_language(DWORD lang1, LPCWSTR lang2, DWORD attributes)
Definition: upgrade.c:43
static const WCHAR szInstalled[]
Definition: msipriv.h:1122
WINE_UNICODE_INLINE int atoiW(const WCHAR *str)
Definition: unicode.h:315
UINT msi_register_unique_action(MSIPACKAGE *package, const WCHAR *action)
Definition: custom.c:94
LPWSTR msi_dup_property(MSIDATABASE *db, LPCWSTR prop) DECLSPEC_HIDDEN
Definition: package.c:2370
UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY **) DECLSPEC_HIDDEN
Definition: msiquery.c:111