ReactOS  0.4.13-dev-52-g0efcfec
registry.c
Go to the documentation of this file.
1 /*
2  * Implementation of the Microsoft Installer (msi.dll)
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  * Copyright 2005 Aric Stewart for CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include <stdarg.h>
23 
24 #define COBJMACROS
25 
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "winnls.h"
30 #include "shlwapi.h"
31 #include "wine/debug.h"
32 #include "msi.h"
33 #include "msipriv.h"
34 #include "wincrypt.h"
35 #include "wine/unicode.h"
36 #include "winver.h"
37 #include "winuser.h"
38 #include "sddl.h"
39 
41 
42 /*
43  * This module will be all the helper functions for registry access by the
44  * installer bits.
45  */
46 
47 static const WCHAR szUserDataFeatures_fmt[] = {
48  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
49  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
50  'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
51  '%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\','F','e','a','t','u','r','e','s',0};
52 
53 static const WCHAR szUserDataComp_fmt[] = {
54  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
55  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
56  'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
57  '%','s','\\','C','o','m','p','o','n','e','n','t','s','\\','%','s',0};
58 
59 static const WCHAR szUserDataComponents_fmt[] = {
60  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
61  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
62  'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
63  '%','s','\\','C','o','m','p','o','n','e','n','t','s',0};
64 
65 static const WCHAR szUserDataProd_fmt[] = {
66  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
67  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
68  'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
69  '%','s','\\','P','r','o','d','u','c','t','s','\\','%','s',0};
70 
71 static const WCHAR szUserDataProducts_fmt[] = {
72  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
73  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
74  'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
75  '%','s','\\','P','r','o','d','u','c','t','s',0};
76 
77 static const WCHAR szUserDataPatch_fmt[] = {
78  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
79  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
80  'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
81  '%','s','\\','P','a','t','c','h','e','s','\\','%','s',0};
82 
83 static const WCHAR szUserDataPatches_fmt[] = {
84  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
85  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
86  'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
87  '%','s','\\','P','a','t','c','h','e','s',0};
88 
90  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
91  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
92  'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
93  '%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\','P','a','t','c','h','e','s',0};
94 
95 static const WCHAR szInstallProperties_fmt[] = {
96  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
97  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
98  'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
99  '%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\',
100  'I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0};
101 
103  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
104  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
105  'I','n','s','t','a','l','l','e','r','\\','M','a','n','a','g','e','d','\\','%','s','\\',
106  'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s','\\','%','s',0};
107 
109  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
110  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
111  'I','n','s','t','a','l','l','e','r','\\','M','a','n','a','g','e','d','\\','%','s','\\',
112  'I','n','s','t','a','l','l','e','r','\\','F','e','a','t','u','r','e','s','\\','%','s',0};
113 
114 static const WCHAR szInstaller_Products[] = {
115  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
116  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
117  'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s',0};
118 
119 static const WCHAR szInstaller_Patches[] = {
120  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
121  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
122  'I','n','s','t','a','l','l','e','r','\\','P','a','t','c','h','e','s',0};
123 
125  'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
126  'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s',0};
127 
129  'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
130  'I','n','s','t','a','l','l','e','r','\\','F','e','a','t','u','r','e','s',0};
131 
133  'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
134  'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s','\\',0};
135 
137  'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
138  'I','n','s','t','a','l','l','e','r','\\','F','e','a','t','u','r','e','s','\\',0};
139 
141  'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
142  'I','n','s','t','a','l','l','e','r','\\','U','p','g','r','a','d','e','C','o','d','e','s','\\',0};
143 
145  'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
146  'I','n','s','t','a','l','l','e','r','\\','U','p','g','r','a','d','e','C','o','d','e','s',0};
147 
148 static const WCHAR szInstaller_Features[] = {
149  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
150  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
151  'I','n','s','t','a','l','l','e','r','\\','F','e','a','t','u','r','e','s','\\',0};
152 
153 static const WCHAR szInstaller_UpgradeCodes[] = {
154  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
155  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
156  'I','n','s','t','a','l','l','e','r','\\','U','p','g','r','a','d','e','C','o','d','e','s','\\',0};
157 
159  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
160  'I','n','s','t','a','l','l','e','r','\\','U','p','g','r','a','d','e','C','o','d','e','s','\\',0};
161 
162 static const WCHAR szUninstall[] = {
163  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
164  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
165  'U','n','i','n','s','t','a','l','l','\\',0};
166 
167 static const WCHAR szUninstall_32node[] = {
168  'S','o','f','t','w','a','r','e','\\','W','o','w','6','4','3','2','N','o','d','e','\\',
169  'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
170  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','U','n','i','n','s','t','a','l','l','\\',0};
171 
172 static const WCHAR szUserComponents[] = {
173  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
174  'I','n','s','t','a','l','l','e','r','\\','C','o','m','p','o','n','e','n','t','s','\\',0};
175 
176 static const WCHAR szInstaller_Components[] = {
177  'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
178  'I','n','s','t','a','l','l','e','r','\\','C','o','m','p','o','n','e','n','t','s','\\',0};
179 
180 static const WCHAR szUserFeatures[] = {
181  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
182  'I','n','s','t','a','l','l','e','r','\\','F','e','a','t','u','r','e','s','\\',0};
183 
184 static const WCHAR szUserProducts[] = {
185  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
186  'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s','\\',0};
187 
188 static const WCHAR szUserPatches[] = {
189  'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
190  'I','n','s','t','a','l','l','e','r','\\','P','a','t','c','h','e','s','\\',0};
191 
193 {
194  DWORD i,n=0;
195 
196  if (lstrlenW(in) != 32)
197  return FALSE;
198 
199  out[n++]='{';
200  for(i=0; i<8; i++)
201  out[n++] = in[7-i];
202  out[n++]='-';
203  for(i=0; i<4; i++)
204  out[n++] = in[11-i];
205  out[n++]='-';
206  for(i=0; i<4; i++)
207  out[n++] = in[15-i];
208  out[n++]='-';
209  for(i=0; i<2; i++)
210  {
211  out[n++] = in[17+i*2];
212  out[n++] = in[16+i*2];
213  }
214  out[n++]='-';
215  for( ; i<8; i++)
216  {
217  out[n++] = in[17+i*2];
218  out[n++] = in[16+i*2];
219  }
220  out[n++]='}';
221  out[n]=0;
222  return TRUE;
223 }
224 
226 {
227  DWORD i,n=1;
228  GUID guid;
229 
230  out[0] = 0;
231 
232  if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
233  return FALSE;
234 
235  for(i=0; i<8; i++)
236  out[7-i] = in[n++];
237  n++;
238  for(i=0; i<4; i++)
239  out[11-i] = in[n++];
240  n++;
241  for(i=0; i<4; i++)
242  out[15-i] = in[n++];
243  n++;
244  for(i=0; i<2; i++)
245  {
246  out[17+i*2] = in[n++];
247  out[16+i*2] = in[n++];
248  }
249  n++;
250  for( ; i<8; i++)
251  {
252  out[17+i*2] = in[n++];
253  out[16+i*2] = in[n++];
254  }
255  out[32]=0;
256  return TRUE;
257 }
258 
259 
260 /* tables for encoding and decoding base85 */
261 static const unsigned char table_dec85[0x80] = {
262 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
263 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
264 0xff,0x00,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff,
265 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0xff,0xff,0xff,0x16,0xff,0x17,
266 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
267 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0x34,0x35,0x36,
268 0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,
269 0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xff,0x53,0x54,0xff,
270 };
271 
272 static const char table_enc85[] =
273 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
274 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
275 "yz{}~";
276 
277 /*
278  * Converts a base85 encoded guid into a GUID pointer
279  * Base85 encoded GUIDs should be 20 characters long.
280  *
281  * returns TRUE if successful, FALSE if not
282  */
284 {
285  DWORD i, val = 0, base = 1, *p;
286 
287  if (!str)
288  return FALSE;
289 
290  p = (DWORD*) guid;
291  for( i=0; i<20; i++ )
292  {
293  if( (i%5) == 0 )
294  {
295  val = 0;
296  base = 1;
297  }
298  val += table_dec85[str[i]] * base;
299  if( str[i] >= 0x80 )
300  return FALSE;
301  if( table_dec85[str[i]] == 0xff )
302  return FALSE;
303  if( (i%5) == 4 )
304  p[i/5] = val;
305  base *= 85;
306  }
307  return TRUE;
308 }
309 
310 /*
311  * Encodes a base85 guid given a GUID pointer
312  * Caller should provide a 21 character buffer for the encoded string.
313  *
314  * returns TRUE if successful, FALSE if not
315  */
317 {
318  unsigned int x, *p, i;
319 
320  p = (unsigned int*) guid;
321  for( i=0; i<4; i++ )
322  {
323  x = p[i];
324  *str++ = table_enc85[x%85];
325  x = x/85;
326  *str++ = table_enc85[x%85];
327  x = x/85;
328  *str++ = table_enc85[x%85];
329  x = x/85;
330  *str++ = table_enc85[x%85];
331  x = x/85;
332  *str++ = table_enc85[x%85];
333  }
334  *str = 0;
335 
336  return TRUE;
337 }
338 
340 {
341  DWORD major, minor = 0, build = 0, version = 0;
342 
343  if (!p)
344  return version;
345 
346  major = atoiW(p);
347 
348  p = strchrW(p, '.');
349  if (p)
350  {
351  minor = atoiW(p+1);
352  p = strchrW(p+1, '.');
353  if (p)
354  build = atoiW(p+1);
355  }
356 
357  return MAKELONG(build, MAKEWORD(minor, major));
358 }
359 
361 {
362  DWORD len;
363  if (!value) value = szEmpty;
364  len = (lstrlenW(value) + 1) * sizeof (WCHAR);
365  return RegSetValueExW( hkey, name, 0, REG_SZ, (const BYTE *)value, len );
366 }
367 
369 {
370  LPCWSTR p = value;
371  while (*p) p += lstrlenW(p) + 1;
372  return RegSetValueExW( hkey, name, 0, REG_MULTI_SZ,
373  (const BYTE *)value, (p + 1 - value) * sizeof(WCHAR) );
374 }
375 
377 {
378  return RegSetValueExW( hkey, name, 0, REG_DWORD, (LPBYTE)&val, sizeof (DWORD) );
379 }
380 
382 {
383  HKEY hsubkey = 0;
384  LONG r;
385 
386  r = RegCreateKeyW( hkey, path, &hsubkey );
387  if (r != ERROR_SUCCESS)
388  return r;
389  r = msi_reg_set_val_str( hsubkey, name, val );
390  RegCloseKey( hsubkey );
391  return r;
392 }
393 
395 {
396  DWORD len = 0;
397  LPWSTR val;
398  LONG r;
399 
400  r = RegQueryValueExW(hkey, name, NULL, NULL, NULL, &len);
401  if (r != ERROR_SUCCESS)
402  return NULL;
403 
404  len += sizeof (WCHAR);
405  val = msi_alloc( len );
406  if (!val)
407  return NULL;
408  val[0] = 0;
409  RegQueryValueExW(hkey, name, NULL, NULL, (LPBYTE) val, &len);
410  return val;
411 }
412 
414 {
415  DWORD type, len = sizeof (DWORD);
416  LONG r = RegQueryValueExW(hkey, name, NULL, &type, (LPBYTE) val, &len);
417  return r == ERROR_SUCCESS && type == REG_DWORD;
418 }
419 
420 static WCHAR *get_user_sid(void)
421 {
422  HANDLE token;
423  DWORD size = 256;
424  TOKEN_USER *user;
425  WCHAR *ret;
426 
428  if (!(user = msi_alloc( size )))
429  {
430  CloseHandle( token );
431  return NULL;
432  }
434  {
435  msi_free( user );
437  {
438  CloseHandle( token );
439  return NULL;
440  }
442  }
443  CloseHandle( token );
444  if (!ConvertSidToStringSidW( user->User.Sid, &ret ))
445  {
446  msi_free( user );
447  return NULL;
448  }
449  msi_free( user );
450  return ret;
451 }
452 
454 {
455  WCHAR keypath[0x200];
456 
457  TRACE("%s\n", debugstr_w(product));
458 
459  if (is_64bit && platform == PLATFORM_INTEL)
460  {
461  strcpyW(keypath, szUninstall_32node);
462  strcatW(keypath, product);
463  }
464  else
465  {
466  strcpyW(keypath, szUninstall);
467  strcatW(keypath, product);
468  }
469  if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, KEY_ALL_ACCESS, NULL, key, NULL);
470  return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, KEY_ALL_ACCESS, key);
471 }
472 
474 {
475  WCHAR keypath[0x200];
476 
477  TRACE("%s\n", debugstr_w(product));
478 
479  if (is_64bit && platform == PLATFORM_INTEL)
480  {
481  strcpyW(keypath, szUninstall_32node);
482  strcatW(keypath, product);
483  }
484  else
485  {
486  strcpyW(keypath, szUninstall);
487  strcatW(keypath, product);
488  }
489  return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
490 }
491 
493 {
496  WCHAR *usersid = NULL, squashed_pc[SQUASHED_GUID_SIZE], keypath[MAX_PATH];
497 
498  if (!squash_guid( szProduct, squashed_pc )) return ERROR_FUNCTION_FAILED;
499  TRACE("%s squashed %s\n", debugstr_w(szProduct), debugstr_w(squashed_pc));
500 
502  {
504  strcatW( keypath, squashed_pc );
505  }
507  {
509  strcpyW(keypath, szUserProducts);
510  strcatW( keypath, squashed_pc );
511  }
512  else
513  {
514  if (!szUserSid)
515  {
516  if (!(usersid = get_user_sid()))
517  {
518  ERR("Failed to retrieve user SID\n");
519  return ERROR_FUNCTION_FAILED;
520  }
521  szUserSid = usersid;
522  }
523  sprintfW( keypath, szInstaller_LocalManagedProd_fmt, szUserSid, squashed_pc );
524  LocalFree(usersid);
525  }
526  if (create) return RegCreateKeyExW(root, keypath, 0, NULL, 0, access, NULL, key, NULL);
527  return RegOpenKeyExW(root, keypath, 0, access, key);
528 }
529 
531 {
532  WCHAR squashed_pc[SQUASHED_GUID_SIZE], keypath[0x200];
533 
534  if (!squash_guid( szProduct, squashed_pc )) return ERROR_FUNCTION_FAILED;
535  TRACE("%s squashed %s\n", debugstr_w(szProduct), debugstr_w(squashed_pc));
536 
537  strcpyW(keypath, szUserProducts);
538  strcatW( keypath, squashed_pc );
539  return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
540 }
541 
543 {
544  WCHAR squashed_pc[SQUASHED_GUID_SIZE], keypath[0x200];
545 
546  if (!squash_guid( szPatch, squashed_pc )) return ERROR_FUNCTION_FAILED;
547  TRACE("%s squashed %s\n", debugstr_w(szPatch), debugstr_w(squashed_pc));
548 
549  strcpyW(keypath, szUserPatches);
550  strcatW( keypath, squashed_pc );
551 
552  if (create) return RegCreateKeyW(HKEY_CURRENT_USER, keypath, key);
553  return RegOpenKeyW(HKEY_CURRENT_USER, keypath, key);
554 }
555 
557  HKEY *key, BOOL create)
558 {
561  WCHAR squashed_pc[SQUASHED_GUID_SIZE], keypath[MAX_PATH], *usersid = NULL;
562 
563  if (!squash_guid( szProduct, squashed_pc )) return ERROR_FUNCTION_FAILED;
564  TRACE("%s squashed %s\n", debugstr_w(szProduct), debugstr_w(squashed_pc));
565 
567  {
569  strcatW( keypath, squashed_pc );
570  }
572  {
574  strcpyW(keypath, szUserFeatures);
575  strcatW( keypath, squashed_pc );
576  }
577  else
578  {
579  if (!szUserSid)
580  {
581  if (!(usersid = get_user_sid()))
582  {
583  ERR("Failed to retrieve user SID\n");
584  return ERROR_FUNCTION_FAILED;
585  }
586  szUserSid = usersid;
587  }
588  sprintfW( keypath, szInstaller_LocalManagedFeat_fmt, szUserSid, squashed_pc );
589  LocalFree(usersid);
590  }
591  if (create) return RegCreateKeyExW(root, keypath, 0, NULL, 0, access, NULL, key, NULL);
592  return RegOpenKeyExW(root, keypath, 0, access, key);
593 }
594 
596 {
597  WCHAR squashed_pc[SQUASHED_GUID_SIZE], keypath[0x200];
598 
599  if (!squash_guid( szProduct, squashed_pc )) return ERROR_FUNCTION_FAILED;
600  TRACE("%s squashed %s\n", debugstr_w(szProduct), debugstr_w(squashed_pc));
601 
602  strcpyW(keypath, szUserFeatures);
603  strcatW( keypath, squashed_pc );
604  return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
605 }
606 
608 {
610  WCHAR squashed_pc[SQUASHED_GUID_SIZE], keypath[0x200];
611 
612  if (!squash_guid( szProduct, squashed_pc )) return ERROR_FUNCTION_FAILED;
613  TRACE("%s squashed %s\n", debugstr_w(szProduct), debugstr_w(squashed_pc));
614 
615  strcpyW(keypath, szInstaller_Features);
616  strcatW( keypath, squashed_pc );
617 
618  if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
619  return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
620 }
621 
623  HKEY *key, BOOL create)
624 {
626  WCHAR squashed_pc[SQUASHED_GUID_SIZE], keypath[0x200], *usersid = NULL;
627 
628  if (!squash_guid( szProduct, squashed_pc )) return ERROR_FUNCTION_FAILED;
629  TRACE("%s squashed %s\n", debugstr_w(szProduct), debugstr_w(squashed_pc));
630 
632  {
633  sprintfW( keypath, szUserDataFeatures_fmt, szLocalSid, squashed_pc );
634  }
635  else
636  {
637  if (!szUserSid)
638  {
639  if (!(usersid = get_user_sid()))
640  {
641  ERR("Failed to retrieve user SID\n");
642  return ERROR_FUNCTION_FAILED;
643  }
644  szUserSid = usersid;
645  }
646  sprintfW( keypath, szUserDataFeatures_fmt, szUserSid, squashed_pc );
647  LocalFree(usersid);
648  }
649  if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
650  return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
651 }
652 
654 {
655  WCHAR squashed_cc[SQUASHED_GUID_SIZE], keypath[0x200];
657  UINT ret;
658 
659  if (!squash_guid( szComponent, squashed_cc)) return ERROR_FUNCTION_FAILED;
660  TRACE("%s squashed %s\n", debugstr_w(szComponent), debugstr_w(squashed_cc));
661 
662  strcpyW(keypath, szUserComponents);
663  strcatW( keypath, squashed_cc );
664 
665  if (create) return RegCreateKeyW(HKEY_CURRENT_USER, keypath, key);
666  ret = RegOpenKeyW(HKEY_CURRENT_USER, keypath, key);
667  if (ret != ERROR_FILE_NOT_FOUND) return ret;
668 
670  strcatW( keypath, squashed_cc );
671  return RegOpenKeyExW( HKEY_LOCAL_MACHINE, keypath, 0, access, key );
672 }
673 
675 {
677  WCHAR *usersid, squashed_comp[SQUASHED_GUID_SIZE], keypath[0x200];
678 
679  if (!squash_guid( szComponent, squashed_comp )) return ERROR_FUNCTION_FAILED;
680  TRACE("%s squashed %s\n", debugstr_w(szComponent), debugstr_w(squashed_comp));
681 
682  if (!szUserSid)
683  {
684  if (!(usersid = get_user_sid()))
685  {
686  ERR("Failed to retrieve user SID\n");
687  return ERROR_FUNCTION_FAILED;
688  }
689  sprintfW( keypath, szUserDataComp_fmt, usersid, squashed_comp );
690  LocalFree(usersid);
691  }
692  else
693  sprintfW( keypath, szUserDataComp_fmt, szUserSid, squashed_comp );
694 
695  if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
696  return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
697 }
698 
700 {
702  WCHAR *usersid, squashed_comp[SQUASHED_GUID_SIZE], keypath[0x200];
703  HKEY hkey;
704  LONG r;
705 
706  if (!squash_guid( szComponent, squashed_comp )) return ERROR_FUNCTION_FAILED;
707  TRACE("%s squashed %s\n", debugstr_w(szComponent), debugstr_w(squashed_comp));
708 
709  if (!szUserSid)
710  {
711  if (!(usersid = get_user_sid()))
712  {
713  ERR("Failed to retrieve user SID\n");
714  return ERROR_FUNCTION_FAILED;
715  }
716  sprintfW(keypath, szUserDataComponents_fmt, usersid);
717  LocalFree(usersid);
718  }
719  else
720  sprintfW(keypath, szUserDataComponents_fmt, szUserSid);
721 
722  if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey)) return ERROR_SUCCESS;
723  r = RegDeleteTreeW( hkey, squashed_comp );
724  RegCloseKey(hkey);
725  return r;
726 }
727 
729 {
731  WCHAR *usersid, squashed_pc[SQUASHED_GUID_SIZE], keypath[0x200];
732 
733  if (!squash_guid( szProduct, squashed_pc )) return ERROR_FUNCTION_FAILED;
734  TRACE("%s squashed %s\n", debugstr_w(szProduct), debugstr_w(squashed_pc));
735 
736  if (dwContext == MSIINSTALLCONTEXT_MACHINE)
737  sprintfW( keypath, szUserDataProd_fmt, szLocalSid, squashed_pc );
738  else if (szUserSid)
739  sprintfW( keypath, szUserDataProd_fmt, szUserSid, squashed_pc );
740  else
741  {
742  if (!(usersid = get_user_sid()))
743  {
744  ERR("Failed to retrieve user SID\n");
745  return ERROR_FUNCTION_FAILED;
746  }
747  sprintfW( keypath, szUserDataProd_fmt, usersid, squashed_pc );
748  LocalFree(usersid);
749  }
750  if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
751  return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
752 }
753 
755 {
757  WCHAR *usersid, squashed_patch[SQUASHED_GUID_SIZE], keypath[0x200];
758 
759  if (!squash_guid( szPatch, squashed_patch )) return ERROR_FUNCTION_FAILED;
760  TRACE("%s squashed %s\n", debugstr_w(szPatch), debugstr_w(squashed_patch));
761 
762  if (dwContext == MSIINSTALLCONTEXT_MACHINE)
763  sprintfW( keypath, szUserDataPatch_fmt, szLocalSid, squashed_patch );
764  else
765  {
766  if (!(usersid = get_user_sid()))
767  {
768  ERR("Failed to retrieve user SID\n");
769  return ERROR_FUNCTION_FAILED;
770  }
771  sprintfW( keypath, szUserDataPatch_fmt, usersid, squashed_patch );
772  LocalFree(usersid);
773  }
774  if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
775  return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
776 }
777 
779 {
781  WCHAR *usersid, squashed_patch[SQUASHED_GUID_SIZE], keypath[0x200];
782  HKEY hkey;
783  LONG r;
784 
785  if (!squash_guid( patch, squashed_patch )) return ERROR_FUNCTION_FAILED;
786  TRACE("%s squashed %s\n", debugstr_w(patch), debugstr_w(squashed_patch));
787 
790  else
791  {
792  if (!(usersid = get_user_sid()))
793  {
794  ERR("Failed to retrieve user SID\n");
795  return ERROR_FUNCTION_FAILED;
796  }
797  sprintfW(keypath, szUserDataPatches_fmt, usersid);
798  LocalFree(usersid);
799  }
800  if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey)) return ERROR_SUCCESS;
801  r = RegDeleteTreeW( hkey, squashed_patch );
802  RegCloseKey(hkey);
803  return r;
804 }
805 
807 {
809  WCHAR *usersid, squashed_product[SQUASHED_GUID_SIZE], keypath[0x200];
810 
811  if (!squash_guid( product, squashed_product )) return ERROR_FUNCTION_FAILED;
812  TRACE("%s squashed %s\n", debugstr_w(product), debugstr_w(squashed_product));
813 
815  sprintfW( keypath, szUserDataProductPatches_fmt, szLocalSid, squashed_product );
816  else
817  {
818  if (!(usersid = get_user_sid()))
819  {
820  ERR("Failed to retrieve user SID\n");
821  return ERROR_FUNCTION_FAILED;
822  }
823  sprintfW( keypath, szUserDataProductPatches_fmt, usersid, squashed_product );
824  LocalFree(usersid);
825  }
826  if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
827  return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
828 }
829 
831 {
833  WCHAR *usersid, squashed_pc[SQUASHED_GUID_SIZE], keypath[0x200];
834 
835  if (!squash_guid( szProduct, squashed_pc )) return ERROR_FUNCTION_FAILED;
836  TRACE("%s squashed %s\n", debugstr_w(szProduct), debugstr_w(squashed_pc));
837 
838  if (dwContext == MSIINSTALLCONTEXT_MACHINE)
839  sprintfW( keypath, szInstallProperties_fmt, szLocalSid, squashed_pc );
840  else if (szUserSid)
841  sprintfW( keypath, szInstallProperties_fmt, szUserSid, squashed_pc );
842  else
843  {
844  if (!(usersid = get_user_sid()))
845  {
846  ERR("Failed to retrieve user SID\n");
847  return ERROR_FUNCTION_FAILED;
848  }
849  sprintfW( keypath, szInstallProperties_fmt, usersid, squashed_pc );
850  LocalFree(usersid);
851  }
852  if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
853  return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
854 }
855 
857 {
859  WCHAR *usersid, squashed_pc[SQUASHED_GUID_SIZE], keypath[0x200];
860  HKEY hkey;
861  LONG r;
862 
863  if (!squash_guid( szProduct, squashed_pc )) return ERROR_FUNCTION_FAILED;
864  TRACE("%s squashed %s\n", debugstr_w(szProduct), debugstr_w(squashed_pc));
865 
868  else
869  {
870  if (!(usersid = get_user_sid()))
871  {
872  ERR("Failed to retrieve user SID\n");
873  return ERROR_FUNCTION_FAILED;
874  }
875  sprintfW(keypath, szUserDataProducts_fmt, usersid);
876  LocalFree(usersid);
877  }
878 
879  if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey)) return ERROR_SUCCESS;
880  r = RegDeleteTreeW( hkey, squashed_pc );
881  RegCloseKey(hkey);
882  return r;
883 }
884 
886 {
888  WCHAR squashed_pc[SQUASHED_GUID_SIZE];
889  HKEY hkey;
890  LONG r;
891 
892  if (!squash_guid( szProduct, squashed_pc )) return ERROR_FUNCTION_FAILED;
893  TRACE("%s squashed %s\n", debugstr_w(szProduct), debugstr_w(squashed_pc));
894 
896  r = RegDeleteTreeW( hkey, squashed_pc );
897  RegCloseKey(hkey);
898  return r;
899 }
900 
902 {
904  WCHAR squashed_pc[SQUASHED_GUID_SIZE], keypath[0x200];
905 
906  if (!squash_guid( szPatch, squashed_pc )) return ERROR_FUNCTION_FAILED;
907  TRACE("%s squashed %s\n", debugstr_w(szPatch), debugstr_w(squashed_pc));
908 
909  sprintfW( keypath, szInstaller_Patches, squashed_pc );
910 
911  if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
912  return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
913 }
914 
916 {
918  WCHAR squashed_uc[SQUASHED_GUID_SIZE], keypath[0x200];
919 
920  if (!squash_guid( szUpgradeCode, squashed_uc )) return ERROR_FUNCTION_FAILED;
921  TRACE("%s squashed %s\n", debugstr_w(szUpgradeCode), debugstr_w(squashed_uc));
922 
924  strcatW( keypath, squashed_uc );
925 
926  if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
927  return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
928 }
929 
931 {
932  WCHAR squashed_uc[SQUASHED_GUID_SIZE], keypath[0x200];
933 
934  if (!squash_guid( szUpgradeCode, squashed_uc )) return ERROR_FUNCTION_FAILED;
935  TRACE("%s squashed %s\n", debugstr_w(szUpgradeCode), debugstr_w(squashed_uc));
936 
938  strcatW( keypath, squashed_uc );
939 
940  if (create) return RegCreateKeyW(HKEY_CURRENT_USER, keypath, key);
941  return RegOpenKeyW(HKEY_CURRENT_USER, keypath, key);
942 }
943 
945 {
946  WCHAR squashed_code[SQUASHED_GUID_SIZE];
948  HKEY hkey;
949  LONG ret;
950 
951  if (!squash_guid( code, squashed_code )) return ERROR_FUNCTION_FAILED;
952  TRACE( "%s squashed %s\n", debugstr_w(code), debugstr_w(squashed_code) );
953 
955  ret = RegDeleteTreeW( hkey, squashed_code );
956  RegCloseKey( hkey );
957  return ret;
958 }
959 
961 {
962  WCHAR squashed_uc[SQUASHED_GUID_SIZE], keypath[0x200];
963 
964  if (!squash_guid( szUpgradeCode, squashed_uc )) return ERROR_FUNCTION_FAILED;
965  TRACE("%s squashed %s\n", debugstr_w(szUpgradeCode), debugstr_w(squashed_uc));
966 
968  strcatW( keypath, squashed_uc );
969  return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
970 }
971 
973 {
975  WCHAR squashed_pc[SQUASHED_GUID_SIZE];
976  HKEY hkey;
977  LONG r;
978 
979  if (!squash_guid( szProductCode, squashed_pc )) return ERROR_FUNCTION_FAILED;
980  TRACE("%s squashed %s\n", debugstr_w(szProductCode), debugstr_w(squashed_pc));
981 
983  r = RegDeleteTreeW( hkey, squashed_pc );
984  RegCloseKey(hkey);
985  return r;
986 }
987 
989 {
991  WCHAR squashed_pc[SQUASHED_GUID_SIZE];
992  HKEY hkey;
993  LONG r;
994 
995  if (!squash_guid( szProductCode, squashed_pc )) return ERROR_FUNCTION_FAILED;
996  TRACE("%s squashed %s\n", debugstr_w(szProductCode), debugstr_w(squashed_pc));
997 
999  r = RegDeleteTreeW( hkey, squashed_pc );
1000  RegCloseKey(hkey);
1001  return r;
1002 }
1003 
1005 {
1007  WCHAR squashed_uc[SQUASHED_GUID_SIZE], keypath[0x200];
1008 
1009  if (!squash_guid( szUpgradeCode, squashed_uc )) return ERROR_FUNCTION_FAILED;
1010  TRACE("%s squashed %s\n", debugstr_w(szUpgradeCode), debugstr_w(squashed_uc));
1011 
1013  strcatW( keypath, squashed_uc );
1014 
1015  if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
1016  return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
1017 }
1018 
1020 {
1022  WCHAR squashed_uc[SQUASHED_GUID_SIZE];
1023  HKEY hkey;
1024  LONG r;
1025 
1026  if (!squash_guid( szUpgradeCode, squashed_uc )) return ERROR_FUNCTION_FAILED;
1027  TRACE("%s squashed %s\n", debugstr_w(szUpgradeCode), debugstr_w(squashed_uc));
1028 
1030  r = RegDeleteTreeW( hkey, squashed_uc );
1031  RegCloseKey(hkey);
1032  return r;
1033 }
1034 
1035 /*************************************************************************
1036  * MsiDecomposeDescriptorW [MSI.@]
1037  *
1038  * Decomposes an MSI descriptor into product, feature and component parts.
1039  * An MSI descriptor is a string of the form:
1040  * [base 85 guid] [feature code] '>' [base 85 guid] or
1041  * [base 85 guid] [feature code] '<'
1042  *
1043  * PARAMS
1044  * szDescriptor [I] the descriptor to decompose
1045  * szProduct [O] buffer of MAX_FEATURE_CHARS+1 for the product guid
1046  * szFeature [O] buffer of MAX_FEATURE_CHARS+1 for the feature code
1047  * szComponent [O] buffer of MAX_FEATURE_CHARS+1 for the component guid
1048  * pUsed [O] the length of the descriptor
1049  *
1050  * RETURNS
1051  * ERROR_SUCCESS if everything worked correctly
1052  * ERROR_INVALID_PARAMETER if the descriptor was invalid
1053  *
1054  */
1056  LPWSTR szFeature, LPWSTR szComponent, LPDWORD pUsed )
1057 {
1058  UINT len;
1059  const WCHAR *p;
1060  GUID product, component;
1061 
1062  TRACE("%s %p %p %p %p\n", debugstr_w(szDescriptor), szProduct,
1063  szFeature, szComponent, pUsed);
1064 
1065  if (!decode_base85_guid( szDescriptor, &product ))
1066  return ERROR_INVALID_PARAMETER;
1067 
1068  TRACE("product %s\n", debugstr_guid( &product ));
1069 
1070  if (!(p = strchrW( &szDescriptor[20], '>' )))
1071  p = strchrW( &szDescriptor[20], '<' );
1072  if (!p)
1073  return ERROR_INVALID_PARAMETER;
1074 
1075  len = (p - &szDescriptor[20]);
1076  if( len > MAX_FEATURE_CHARS )
1077  return ERROR_INVALID_PARAMETER;
1078 
1079  TRACE("feature %s\n", debugstr_wn( &szDescriptor[20], len ));
1080 
1081  if (*p == '>')
1082  {
1083  if (!decode_base85_guid( p+1, &component ))
1084  return ERROR_INVALID_PARAMETER;
1085  TRACE( "component %s\n", debugstr_guid(&component) );
1086  }
1087 
1088  if (szProduct)
1089  StringFromGUID2( &product, szProduct, MAX_FEATURE_CHARS+1 );
1090  if (szComponent)
1091  {
1092  if (*p == '>')
1093  StringFromGUID2( &component, szComponent, MAX_FEATURE_CHARS+1 );
1094  else
1095  szComponent[0] = 0;
1096  }
1097  if (szFeature)
1098  {
1099  memcpy( szFeature, &szDescriptor[20], len*sizeof(WCHAR) );
1100  szFeature[len] = 0;
1101  }
1102 
1103  len = p - szDescriptor + 1;
1104  if (*p == '>') len += 20;
1105 
1106  TRACE("length = %d\n", len);
1107  if (pUsed) *pUsed = len;
1108 
1109  return ERROR_SUCCESS;
1110 }
1111 
1113  LPSTR szFeature, LPSTR szComponent, LPDWORD pUsed )
1114 {
1115  WCHAR product[MAX_FEATURE_CHARS+1];
1117  WCHAR component[MAX_FEATURE_CHARS+1];
1118  LPWSTR str = NULL, p = NULL, f = NULL, c = NULL;
1119  UINT r;
1120 
1121  TRACE("%s %p %p %p %p\n", debugstr_a(szDescriptor), szProduct,
1122  szFeature, szComponent, pUsed);
1123 
1124  str = strdupAtoW( szDescriptor );
1125  if( szDescriptor && !str )
1126  return ERROR_OUTOFMEMORY;
1127 
1128  if (szProduct)
1129  p = product;
1130  if (szFeature)
1131  f = feature;
1132  if (szComponent)
1133  c = component;
1134 
1135  r = MsiDecomposeDescriptorW( str, p, f, c, pUsed );
1136 
1137  if (r == ERROR_SUCCESS)
1138  {
1139  WideCharToMultiByte( CP_ACP, 0, p, -1,
1140  szProduct, MAX_FEATURE_CHARS+1, NULL, NULL );
1141  WideCharToMultiByte( CP_ACP, 0, f, -1,
1142  szFeature, MAX_FEATURE_CHARS+1, NULL, NULL );
1143  WideCharToMultiByte( CP_ACP, 0, c, -1,
1144  szComponent, MAX_FEATURE_CHARS+1, NULL, NULL );
1145  }
1146 
1147  msi_free( str );
1148 
1149  return r;
1150 }
1151 
1153 {
1154  DWORD r;
1155  WCHAR szwGuid[GUID_SIZE];
1156 
1157  TRACE("%d %p\n", index, lpguid);
1158 
1159  if (NULL == lpguid)
1160  return ERROR_INVALID_PARAMETER;
1161  r = MsiEnumProductsW(index, szwGuid);
1162  if( r == ERROR_SUCCESS )
1163  WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);
1164 
1165  return r;
1166 }
1167 
1169 {
1170  TRACE("%d %p\n", index, lpguid);
1171 
1172  if (NULL == lpguid)
1173  return ERROR_INVALID_PARAMETER;
1174 
1176  NULL, NULL, NULL );
1177 }
1178 
1180  LPSTR szFeature, LPSTR szParent)
1181 {
1182  DWORD r;
1183  WCHAR szwFeature[GUID_SIZE], szwParent[GUID_SIZE];
1184  LPWSTR szwProduct = NULL;
1185 
1186  TRACE("%s %d %p %p\n", debugstr_a(szProduct), index, szFeature, szParent);
1187 
1188  if( szProduct )
1189  {
1190  szwProduct = strdupAtoW( szProduct );
1191  if( !szwProduct )
1192  return ERROR_OUTOFMEMORY;
1193  }
1194 
1195  r = MsiEnumFeaturesW(szwProduct, index, szwFeature, szwParent);
1196  if( r == ERROR_SUCCESS )
1197  {
1198  WideCharToMultiByte(CP_ACP, 0, szwFeature, -1,
1199  szFeature, GUID_SIZE, NULL, NULL);
1200  WideCharToMultiByte(CP_ACP, 0, szwParent, -1,
1201  szParent, GUID_SIZE, NULL, NULL);
1202  }
1203 
1204  msi_free( szwProduct);
1205 
1206  return r;
1207 }
1208 
1210  LPWSTR szFeature, LPWSTR szParent)
1211 {
1212  HKEY hkeyProduct = 0;
1213  DWORD r, sz;
1214 
1215  TRACE("%s %d %p %p\n", debugstr_w(szProduct), index, szFeature, szParent);
1216 
1217  if( !szProduct )
1218  return ERROR_INVALID_PARAMETER;
1219 
1220  r = MSIREG_OpenInstallerFeaturesKey(szProduct,&hkeyProduct,FALSE);
1221  if( r != ERROR_SUCCESS )
1222  return ERROR_NO_MORE_ITEMS;
1223 
1224  sz = GUID_SIZE;
1225  r = RegEnumValueW(hkeyProduct, index, szFeature, &sz, NULL, NULL, NULL, NULL);
1226  RegCloseKey(hkeyProduct);
1227 
1228  return r;
1229 }
1230 
1232 {
1233  DWORD r;
1234  WCHAR szwGuid[GUID_SIZE];
1235 
1236  TRACE("%u, %p\n", index, lpguid);
1237 
1238  if (!lpguid) return ERROR_INVALID_PARAMETER;
1239 
1240  r = MsiEnumComponentsW(index, szwGuid);
1241  if( r == ERROR_SUCCESS )
1242  WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);
1243 
1244  return r;
1245 }
1246 
1248 {
1249  TRACE("%u, %p\n", index, lpguid);
1250 
1251  if (!lpguid) return ERROR_INVALID_PARAMETER;
1252 
1254 }
1255 
1257  MSIINSTALLCONTEXT *installed_ctx, LPSTR sid, LPDWORD sid_len )
1258 {
1259  UINT r;
1260  WCHAR *user_sidW = NULL, *sidW = NULL, guidW[GUID_SIZE];
1261 
1262  TRACE("%s, %u, %u, %p, %p, %p, %p\n", debugstr_a(user_sid), ctx, index, guid, installed_ctx,
1263  sid, sid_len);
1264 
1265  if (sid && !sid_len) return ERROR_INVALID_PARAMETER;
1266  if (user_sid && !(user_sidW = strdupAtoW( user_sid ))) return ERROR_OUTOFMEMORY;
1267  if (sid && !(sidW = msi_alloc( *sid_len * sizeof(WCHAR) )))
1268  {
1269  msi_free( user_sidW );
1270  return ERROR_OUTOFMEMORY;
1271  }
1272  r = MsiEnumComponentsExW( user_sidW, ctx, index, guidW, installed_ctx, sidW, sid_len );
1273  if (r == ERROR_SUCCESS)
1274  {
1276  if (sid) WideCharToMultiByte( CP_ACP, 0, sidW, *sid_len + 1, sid, *sid_len + 1, NULL, NULL );
1277  }
1278  msi_free( user_sidW );
1279  msi_free( sidW );
1280  return r;
1281 }
1282 
1284  MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len )
1285 {
1286  static const WCHAR componentsW[] =
1287  {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
1288  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1289  'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
1290  'S','-','1','-','5','-','1','8','\\','C','o','m','p','o','n','e','n','t','s',0};
1291  UINT r = ERROR_SUCCESS;
1292  WCHAR component[SQUASHED_GUID_SIZE];
1293  DWORD i = 0, len_component;
1295  HKEY key_components;
1296 
1297  if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, componentsW, 0, access, &key_components ))
1298  return ERROR_NO_MORE_ITEMS;
1299 
1300  len_component = sizeof(component)/sizeof(component[0]);
1301  while (!RegEnumKeyExW( key_components, i, component, &len_component, NULL, NULL, NULL, NULL ))
1302  {
1303  if (*idx == index) goto found;
1304  (*idx)++;
1305  len_component = sizeof(component)/sizeof(component[0]);
1306  i++;
1307  }
1308  RegCloseKey( key_components );
1309  return ERROR_NO_MORE_ITEMS;
1310 
1311 found:
1312  if (sid_len)
1313  {
1314  if (*sid_len < 1)
1315  {
1316  *sid_len = 1;
1317  r = ERROR_MORE_DATA;
1318  }
1319  else if (sid)
1320  {
1321  *sid_len = 0;
1322  sid[0] = 0;
1323  }
1324  }
1325  if (guid) unsquash_guid( component, guid );
1326  if (installed_ctx) *installed_ctx = MSIINSTALLCONTEXT_MACHINE;
1327  RegCloseKey( key_components );
1328  return r;
1329 }
1330 
1331 static UINT fetch_user_component( const WCHAR *usersid, DWORD ctx, DWORD index, DWORD *idx,
1332  WCHAR guid[39], MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid,
1333  LPDWORD sid_len )
1334 {
1335  static const WCHAR userdataW[] =
1336  {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
1337  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1338  'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a',0};
1339  static const WCHAR componentsW[] = {'\\','C','o','m','p','o','n','e','n','t','s',0};
1340  UINT r = ERROR_SUCCESS;
1341  WCHAR path[MAX_PATH], component[SQUASHED_GUID_SIZE], user[128];
1342  DWORD i = 0, j = 0, len_component, len_user;
1344  HKEY key_users, key_components;
1345 
1346  if (ctx == MSIINSTALLCONTEXT_USERMANAGED) /* FIXME: where to find these? */
1347  return ERROR_NO_MORE_ITEMS;
1348 
1349  if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, userdataW, 0, access, &key_users ))
1350  return ERROR_NO_MORE_ITEMS;
1351 
1352  len_user = sizeof(user)/sizeof(user[0]);
1353  while (!RegEnumKeyExW( key_users, i, user, &len_user, NULL, NULL, NULL, NULL ))
1354  {
1355  if ((strcmpW( usersid, szAllSid ) && strcmpW( usersid, user )) ||
1356  !strcmpW( szLocalSid, user ))
1357  {
1358  i++;
1359  len_user = sizeof(user)/sizeof(user[0]);
1360  continue;
1361  }
1362  strcpyW( path, user );
1363  strcatW( path, componentsW );
1364  if (RegOpenKeyExW( key_users, path, 0, access, &key_components ))
1365  {
1366  i++;
1367  len_user = sizeof(user)/sizeof(user[0]);
1368  continue;
1369  }
1370  len_component = sizeof(component)/sizeof(component[0]);
1371  while (!RegEnumKeyExW( key_components, j, component, &len_component, NULL, NULL, NULL, NULL ))
1372  {
1373  if (*idx == index) goto found;
1374  (*idx)++;
1375  len_component = sizeof(component)/sizeof(component[0]);
1376  j++;
1377  }
1378  RegCloseKey( key_components );
1379  len_user = sizeof(user)/sizeof(user[0]);
1380  i++;
1381  }
1382  RegCloseKey( key_users );
1383  return ERROR_NO_MORE_ITEMS;
1384 
1385 found:
1386  if (sid_len)
1387  {
1388  if (*sid_len < len_user + 1)
1389  {
1390  *sid_len = len_user + 1;
1391  r = ERROR_MORE_DATA;
1392  }
1393  else if (sid)
1394  {
1395  *sid_len = len_user;
1396  strcpyW( sid, user );
1397  }
1398  }
1399  if (guid) unsquash_guid( component, guid );
1400  if (installed_ctx) *installed_ctx = ctx;
1401  RegCloseKey( key_components );
1402  RegCloseKey( key_users );
1403  return r;
1404 }
1405 
1406 static UINT enum_components( const WCHAR *usersid, DWORD ctx, DWORD index, DWORD *idx, WCHAR guid[39],
1407  MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len )
1408 {
1410  WCHAR *user = NULL;
1411 
1412  if (!usersid)
1413  {
1414  usersid = user = get_user_sid();
1415  if (!user) return ERROR_FUNCTION_FAILED;
1416  }
1418  {
1420  installed_ctx, sid, sid_len );
1421  if (r != ERROR_NO_MORE_ITEMS) goto done;
1422  }
1424  {
1426  installed_ctx, sid, sid_len );
1427  if (r != ERROR_NO_MORE_ITEMS) goto done;
1428  }
1429  if (ctx & MSIINSTALLCONTEXT_MACHINE)
1430  {
1432  sid, sid_len );
1433  if (r != ERROR_NO_MORE_ITEMS) goto done;
1434  }
1435 
1436 done:
1437  LocalFree( user );
1438  return r;
1439 }
1440 
1442  MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len )
1443 {
1444  UINT r;
1445  DWORD idx = 0;
1446  static DWORD last_index;
1447 
1448  TRACE("%s, %u, %u, %p, %p, %p, %p\n", debugstr_w(user_sid), ctx, index, guid, installed_ctx,
1449  sid, sid_len);
1450 
1451  if ((sid && !sid_len) || !ctx || (user_sid && ctx == MSIINSTALLCONTEXT_MACHINE))
1452  return ERROR_INVALID_PARAMETER;
1453 
1454  if (index && index - last_index != 1)
1455  return ERROR_INVALID_PARAMETER;
1456 
1457  if (!index) last_index = 0;
1458 
1459  r = enum_components( user_sid, ctx, index, &idx, guid, installed_ctx, sid, sid_len );
1460  if (r == ERROR_SUCCESS)
1461  last_index = index;
1462  else
1463  last_index = 0;
1464 
1465  return r;
1466 }
1467 
1469 {
1470  DWORD r;
1471  WCHAR szwProduct[GUID_SIZE];
1472  LPWSTR szwComponent = NULL;
1473 
1474  TRACE("%s %d %p\n", debugstr_a(szComponent), index, szProduct);
1475 
1476  if ( !szProduct )
1477  return ERROR_INVALID_PARAMETER;
1478 
1479  if( szComponent )
1480  {
1481  szwComponent = strdupAtoW( szComponent );
1482  if( !szwComponent )
1483  return ERROR_OUTOFMEMORY;
1484  }
1485 
1486  r = MsiEnumClientsW(szComponent?szwComponent:NULL, index, szwProduct);
1487  if( r == ERROR_SUCCESS )
1488  {
1489  WideCharToMultiByte(CP_ACP, 0, szwProduct, -1,
1490  szProduct, GUID_SIZE, NULL, NULL);
1491  }
1492 
1493  msi_free( szwComponent);
1494 
1495  return r;
1496 }
1497 
1499 {
1500  HKEY hkeyComp = 0;
1501  DWORD r, sz;
1502  WCHAR szValName[SQUASHED_GUID_SIZE];
1503 
1504  TRACE("%s %d %p\n", debugstr_w(szComponent), index, szProduct);
1505 
1506  if (!szComponent || !*szComponent || !szProduct)
1507  return ERROR_INVALID_PARAMETER;
1508 
1509  if (MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkeyComp, FALSE) != ERROR_SUCCESS &&
1510  MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkeyComp, FALSE) != ERROR_SUCCESS)
1511  return ERROR_UNKNOWN_COMPONENT;
1512 
1513  /* see if there are any products at all */
1514  sz = SQUASHED_GUID_SIZE;
1515  r = RegEnumValueW(hkeyComp, 0, szValName, &sz, NULL, NULL, NULL, NULL);
1516  if (r != ERROR_SUCCESS)
1517  {
1518  RegCloseKey(hkeyComp);
1519 
1520  if (index != 0)
1521  return ERROR_INVALID_PARAMETER;
1522 
1523  return ERROR_UNKNOWN_COMPONENT;
1524  }
1525 
1526  sz = SQUASHED_GUID_SIZE;
1527  r = RegEnumValueW(hkeyComp, index, szValName, &sz, NULL, NULL, NULL, NULL);
1528  if( r == ERROR_SUCCESS )
1529  {
1530  unsquash_guid(szValName, szProduct);
1531  TRACE("-> %s\n", debugstr_w(szProduct));
1532  }
1533  RegCloseKey(hkeyComp);
1534  return r;
1535 }
1536 
1538  CHAR installed_product[GUID_SIZE],
1539  MSIINSTALLCONTEXT *installed_ctx, LPSTR sid, LPDWORD sid_len)
1540 {
1541  FIXME("%s, %s, %u, %u, %p, %p, %p, %p\n", debugstr_a(component), debugstr_a(usersid),
1542  ctx, index, installed_product, installed_ctx, sid, sid_len);
1543  return ERROR_ACCESS_DENIED;
1544 }
1545 
1547  WCHAR installed_product[GUID_SIZE],
1548  MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len)
1549 {
1550  FIXME("%s, %s, %u, %u, %p, %p, %p, %p\n", debugstr_w(component), debugstr_w(usersid),
1551  ctx, index, installed_product, installed_ctx, sid, sid_len);
1552  return ERROR_ACCESS_DENIED;
1553 }
1554 
1555 static UINT MSI_EnumComponentQualifiers( LPCWSTR szComponent, DWORD iIndex,
1556  awstring *lpQualBuf, LPDWORD pcchQual,
1557  awstring *lpAppBuf, LPDWORD pcchAppBuf )
1558 {
1559  DWORD name_sz, val_sz, name_max, val_max, type, ofs;
1560  LPWSTR name = NULL, val = NULL;
1561  UINT r, r2;
1562  HKEY key;
1563 
1564  TRACE("%s %08x %p %p %p %p\n", debugstr_w(szComponent), iIndex,
1565  lpQualBuf, pcchQual, lpAppBuf, pcchAppBuf);
1566 
1567  if (!szComponent)
1568  return ERROR_INVALID_PARAMETER;
1569 
1570  r = MSIREG_OpenUserComponentsKey( szComponent, &key, FALSE );
1571  if (r != ERROR_SUCCESS)
1572  return ERROR_UNKNOWN_COMPONENT;
1573 
1574  /* figure out how big the name is we want to return */
1575  name_max = 0x10;
1576  r = ERROR_OUTOFMEMORY;
1577  name = msi_alloc( name_max * sizeof(WCHAR) );
1578  if (!name)
1579  goto end;
1580 
1581  val_max = 0x10;
1582  r = ERROR_OUTOFMEMORY;
1583  val = msi_alloc( val_max );
1584  if (!val)
1585  goto end;
1586 
1587  /* loop until we allocate enough memory */
1588  while (1)
1589  {
1590  name_sz = name_max;
1591  val_sz = val_max;
1592  r = RegEnumValueW( key, iIndex, name, &name_sz,
1593  NULL, &type, (LPBYTE)val, &val_sz );
1594  if (r == ERROR_SUCCESS)
1595  break;
1596  if (r != ERROR_MORE_DATA)
1597  goto end;
1598 
1599  if (type != REG_MULTI_SZ)
1600  {
1601  ERR("component data has wrong type (%d)\n", type);
1602  goto end;
1603  }
1604 
1605  r = ERROR_OUTOFMEMORY;
1606  if (name_sz + 1 >= name_max)
1607  {
1608  name_max *= 2;
1609  msi_free( name );
1610  name = msi_alloc( name_max * sizeof (WCHAR) );
1611  if (!name)
1612  goto end;
1613  continue;
1614  }
1615  if (val_sz > val_max)
1616  {
1617  val_max = val_sz + sizeof (WCHAR);
1618  msi_free( val );
1619  val = msi_alloc( val_max * sizeof (WCHAR) );
1620  if (!val)
1621  goto end;
1622  continue;
1623  }
1624  ERR("should be enough data, but isn't %d %d\n", name_sz, val_sz );
1625  goto end;
1626  }
1627 
1628  ofs = 0;
1629  r = MsiDecomposeDescriptorW( val, NULL, NULL, NULL, &ofs );
1630  if (r != ERROR_SUCCESS)
1631  goto end;
1632 
1633  TRACE("Providing %s and %s\n", debugstr_w(name), debugstr_w(val+ofs));
1634 
1635  r = msi_strcpy_to_awstring( name, -1, lpQualBuf, pcchQual );
1636  r2 = msi_strcpy_to_awstring( val+ofs, -1, lpAppBuf, pcchAppBuf );
1637 
1638  if (r2 != ERROR_SUCCESS)
1639  r = r2;
1640 
1641 end:
1642  msi_free(val);
1643  msi_free(name);
1644  RegCloseKey(key);
1645  return r;
1646 }
1647 
1648 /*************************************************************************
1649  * MsiEnumComponentQualifiersA [MSI.@]
1650  */
1652  LPSTR lpQualifierBuf, LPDWORD pcchQualifierBuf,
1653  LPSTR lpApplicationDataBuf, LPDWORD pcchApplicationDataBuf )
1654 {
1655  awstring qual, appdata;
1656  LPWSTR comp;
1657  UINT r;
1658 
1659  TRACE("%s %08x %p %p %p %p\n", debugstr_a(szComponent), iIndex,
1660  lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
1661  pcchApplicationDataBuf);
1662 
1663  comp = strdupAtoW( szComponent );
1664  if (szComponent && !comp)
1665  return ERROR_OUTOFMEMORY;
1666 
1667  qual.unicode = FALSE;
1668  qual.str.a = lpQualifierBuf;
1669 
1670  appdata.unicode = FALSE;
1671  appdata.str.a = lpApplicationDataBuf;
1672 
1673  r = MSI_EnumComponentQualifiers( comp, iIndex,
1674  &qual, pcchQualifierBuf, &appdata, pcchApplicationDataBuf );
1675  msi_free( comp );
1676  return r;
1677 }
1678 
1679 /*************************************************************************
1680  * MsiEnumComponentQualifiersW [MSI.@]
1681  */
1683  LPWSTR lpQualifierBuf, LPDWORD pcchQualifierBuf,
1684  LPWSTR lpApplicationDataBuf, LPDWORD pcchApplicationDataBuf )
1685 {
1686  awstring qual, appdata;
1687 
1688  TRACE("%s %08x %p %p %p %p\n", debugstr_w(szComponent), iIndex,
1689  lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
1690  pcchApplicationDataBuf);
1691 
1692  qual.unicode = TRUE;
1693  qual.str.w = lpQualifierBuf;
1694 
1695  appdata.unicode = TRUE;
1696  appdata.str.w = lpApplicationDataBuf;
1697 
1698  return MSI_EnumComponentQualifiers( szComponent, iIndex,
1699  &qual, pcchQualifierBuf, &appdata, pcchApplicationDataBuf );
1700 }
1701 
1702 /*************************************************************************
1703  * MsiEnumRelatedProductsW [MSI.@]
1704  *
1705  */
1707  DWORD iProductIndex, LPWSTR lpProductBuf)
1708 {
1709  UINT r;
1710  HKEY hkey;
1711  WCHAR szKeyName[SQUASHED_GUID_SIZE];
1712  DWORD dwSize = sizeof(szKeyName)/sizeof(szKeyName[0]);
1713 
1714  TRACE("%s %u %u %p\n", debugstr_w(szUpgradeCode), dwReserved,
1715  iProductIndex, lpProductBuf);
1716 
1717  if (NULL == szUpgradeCode)
1718  return ERROR_INVALID_PARAMETER;
1719  if (NULL == lpProductBuf)
1720  return ERROR_INVALID_PARAMETER;
1721 
1723  if (r != ERROR_SUCCESS)
1724  return ERROR_NO_MORE_ITEMS;
1725 
1726  r = RegEnumValueW(hkey, iProductIndex, szKeyName, &dwSize, NULL, NULL, NULL, NULL);
1727  if( r == ERROR_SUCCESS )
1728  unsquash_guid(szKeyName, lpProductBuf);
1729  RegCloseKey(hkey);
1730 
1731  return r;
1732 }
1733 
1734 /*************************************************************************
1735  * MsiEnumRelatedProductsA [MSI.@]
1736  *
1737  */
1739  DWORD iProductIndex, LPSTR lpProductBuf)
1740 {
1741  LPWSTR szwUpgradeCode = NULL;
1742  WCHAR productW[GUID_SIZE];
1743  UINT r;
1744 
1745  TRACE("%s %u %u %p\n", debugstr_a(szUpgradeCode), dwReserved,
1746  iProductIndex, lpProductBuf);
1747 
1748  if (szUpgradeCode)
1749  {
1750  szwUpgradeCode = strdupAtoW( szUpgradeCode );
1751  if( !szwUpgradeCode )
1752  return ERROR_OUTOFMEMORY;
1753  }
1754 
1755  r = MsiEnumRelatedProductsW( szwUpgradeCode, dwReserved,
1756  iProductIndex, productW );
1757  if (r == ERROR_SUCCESS)
1758  {
1759  WideCharToMultiByte( CP_ACP, 0, productW, GUID_SIZE,
1760  lpProductBuf, GUID_SIZE, NULL, NULL );
1761  }
1762  msi_free( szwUpgradeCode);
1763  return r;
1764 }
1765 
1766 /***********************************************************************
1767  * MsiEnumPatchesExA [MSI.@]
1768  */
1770  DWORD dwContext, DWORD dwFilter, DWORD dwIndex, LPSTR szPatchCode,
1771  LPSTR szTargetProductCode, MSIINSTALLCONTEXT *pdwTargetProductContext,
1772  LPSTR szTargetUserSid, LPDWORD pcchTargetUserSid)
1773 {
1774  LPWSTR prodcode = NULL;
1775  LPWSTR usersid = NULL;
1776  LPWSTR targsid = NULL;
1777  WCHAR patch[GUID_SIZE];
1778  WCHAR targprod[GUID_SIZE];
1779  DWORD len;
1780  UINT r;
1781 
1782  TRACE("(%s, %s, %d, %d, %d, %p, %p, %p, %p, %p)\n",
1783  debugstr_a(szProductCode), debugstr_a(szUserSid), dwContext, dwFilter,
1784  dwIndex, szPatchCode, szTargetProductCode, pdwTargetProductContext,
1785  szTargetUserSid, pcchTargetUserSid);
1786 
1787  if (szTargetUserSid && !pcchTargetUserSid)
1788  return ERROR_INVALID_PARAMETER;
1789 
1790  if (szProductCode) prodcode = strdupAtoW(szProductCode);
1791  if (szUserSid) usersid = strdupAtoW(szUserSid);
1792 
1793  r = MsiEnumPatchesExW(prodcode, usersid, dwContext, dwFilter, dwIndex,
1794  patch, targprod, pdwTargetProductContext,
1795  NULL, &len);
1796  if (r != ERROR_SUCCESS)
1797  goto done;
1798 
1799  WideCharToMultiByte(CP_ACP, 0, patch, -1, szPatchCode,
1800  GUID_SIZE, NULL, NULL);
1801  WideCharToMultiByte(CP_ACP, 0, targprod, -1, szTargetProductCode,
1802  GUID_SIZE, NULL, NULL);
1803 
1804  if (!szTargetUserSid)
1805  {
1806  if (pcchTargetUserSid)
1807  *pcchTargetUserSid = len;
1808 
1809  goto done;
1810  }
1811 
1812  targsid = msi_alloc(++len * sizeof(WCHAR));
1813  if (!targsid)
1814  {
1815  r = ERROR_OUTOFMEMORY;
1816  goto done;
1817  }
1818 
1819  r = MsiEnumPatchesExW(prodcode, usersid, dwContext, dwFilter, dwIndex,
1820  patch, targprod, pdwTargetProductContext,
1821  targsid, &len);
1822  if (r != ERROR_SUCCESS || !szTargetUserSid)
1823  goto done;
1824 
1825  WideCharToMultiByte(CP_ACP, 0, targsid, -1, szTargetUserSid,
1826  *pcchTargetUserSid, NULL, NULL);
1827 
1828  len = lstrlenW(targsid);
1829  if (*pcchTargetUserSid < len + 1)
1830  {
1831  r = ERROR_MORE_DATA;
1832  *pcchTargetUserSid = len * sizeof(WCHAR);
1833  }
1834  else
1835  *pcchTargetUserSid = len;
1836 
1837 done:
1838  msi_free(prodcode);
1839  msi_free(usersid);
1840  msi_free(targsid);
1841 
1842  return r;
1843 }
1844 
1845 static UINT msi_get_patch_state(LPCWSTR prodcode, LPCWSTR usersid,
1847  LPWSTR patch, MSIPATCHSTATE *state)
1848 {
1849  DWORD type, val, size;
1850  HKEY prod, hkey = 0;
1851  HKEY udpatch = 0;
1852  LONG res;
1854 
1856 
1858  usersid, &prod, FALSE);
1859  if (r != ERROR_SUCCESS)
1860  return ERROR_NO_MORE_ITEMS;
1861 
1862  res = RegOpenKeyExW(prod, szPatches, 0, KEY_READ, &hkey);
1863  if (res != ERROR_SUCCESS)
1864  goto done;
1865 
1866  res = RegOpenKeyExW(hkey, patch, 0, KEY_READ, &udpatch);
1867  if (res != ERROR_SUCCESS)
1868  goto done;
1869 
1870  size = sizeof(DWORD);
1871  res = RegGetValueW(udpatch, NULL, szState, RRF_RT_DWORD, &type, &val, &size);
1872  if (res != ERROR_SUCCESS ||
1874  {
1876  goto done;
1877  }
1878 
1879  *state = val;
1880  r = ERROR_SUCCESS;
1881 
1882 done:
1883  RegCloseKey(udpatch);
1884  RegCloseKey(hkey);
1885  RegCloseKey(prod);
1886 
1887  return r;
1888 }
1889 
1892  LPWSTR patch, LPWSTR targetprod, MSIINSTALLCONTEXT *targetctx,
1893  LPWSTR targetsid, DWORD *sidsize, LPWSTR *transforms)
1894 {
1896  LPWSTR ptr, patches = NULL;
1897  HKEY prod, patchkey = 0;
1898  HKEY localprod = 0, localpatch = 0;
1899  DWORD type, size;
1900  LONG res;
1902 
1903  if (MSIREG_OpenProductKey(prodcode, usersid, context,
1904  &prod, FALSE) != ERROR_SUCCESS)
1905  return ERROR_NO_MORE_ITEMS;
1906 
1907  size = 0;
1909  &size);
1910  if (res != ERROR_SUCCESS)
1911  goto done;
1912 
1913  if (type != REG_MULTI_SZ)
1914  {
1916  goto done;
1917  }
1918 
1919  patches = msi_alloc(size);
1920  if (!patches)
1921  {
1922  r = ERROR_OUTOFMEMORY;
1923  goto done;
1924  }
1925 
1927  patches, &size);
1928  if (res != ERROR_SUCCESS)
1929  goto done;
1930 
1931  for (ptr = patches; *ptr && r == ERROR_NO_MORE_ITEMS; ptr += lstrlenW(ptr) + 1)
1932  {
1933  if (!unsquash_guid(ptr, patch))
1934  {
1936  goto done;
1937  }
1938 
1939  size = 0;
1941  &type, NULL, &size);
1942  if (res != ERROR_SUCCESS)
1943  continue;
1944 
1945  if (transforms)
1946  {
1947  *transforms = msi_alloc(size);
1948  if (!*transforms)
1949  {
1950  r = ERROR_OUTOFMEMORY;
1951  goto done;
1952  }
1953 
1955  &type, *transforms, &size);
1956  if (res != ERROR_SUCCESS)
1957  continue;
1958  }
1959 
1961  {
1962  if (!(filter & MSIPATCHSTATE_APPLIED))
1963  {
1964  temp = msi_get_patch_state(prodcode, usersid, context,
1965  ptr, &state);
1967  {
1969  goto done;
1970  }
1971 
1972  if (temp != ERROR_SUCCESS || !(filter & state))
1973  continue;
1974  }
1975  }
1977  {
1978  if (!(filter & MSIPATCHSTATE_APPLIED))
1979  {
1980  temp = msi_get_patch_state(prodcode, usersid, context,
1981  ptr, &state);
1983  {
1985  goto done;
1986  }
1987 
1988  if (temp != ERROR_SUCCESS || !(filter & state))
1989  continue;
1990  }
1991  else
1992  {
1994  &patchkey, FALSE);
1995  RegCloseKey(patchkey);
1996  if (temp != ERROR_SUCCESS)
1997  continue;
1998  }
1999  }
2000  else if (context == MSIINSTALLCONTEXT_MACHINE)
2001  {
2002  usersid = szEmpty;
2003 
2004  if (MSIREG_OpenUserDataProductKey(prodcode, context, NULL, &localprod, FALSE) == ERROR_SUCCESS &&
2005  RegOpenKeyExW(localprod, szPatches, 0, KEY_READ, &localpatch) == ERROR_SUCCESS &&
2006  RegOpenKeyExW(localpatch, ptr, 0, KEY_READ, &patchkey) == ERROR_SUCCESS)
2007  {
2009  &type, &state, &size);
2010 
2011  if (!(filter & state))
2013 
2014  RegCloseKey(patchkey);
2015  }
2016 
2017  RegCloseKey(localpatch);
2018  RegCloseKey(localprod);
2019 
2020  if (res != ERROR_SUCCESS)
2021  continue;
2022  }
2023 
2024  if (*idx < index)
2025  {
2026  (*idx)++;
2027  continue;
2028  }
2029 
2030  r = ERROR_SUCCESS;
2031  if (targetprod)
2032  lstrcpyW(targetprod, prodcode);
2033 
2034  if (targetctx)
2035  *targetctx = context;
2036 
2037  if (targetsid)
2038  {
2039  lstrcpynW(targetsid, usersid, *sidsize);
2040  if (lstrlenW(usersid) >= *sidsize)
2041  r = ERROR_MORE_DATA;
2042  }
2043 
2044  if (sidsize)
2045  {
2046  *sidsize = lstrlenW(usersid);
2047  if (!targetsid)
2048  *sidsize *= sizeof(WCHAR);
2049  }
2050  }
2051 
2052 done:
2053  RegCloseKey(prod);
2054  msi_free(patches);
2055 
2056  return r;
2057 }
2058 
2060  DWORD dwContext, DWORD dwFilter, DWORD dwIndex, DWORD *idx,
2061  LPWSTR szPatchCode, LPWSTR szTargetProductCode,
2062  MSIINSTALLCONTEXT *pdwTargetProductContext, LPWSTR szTargetUserSid,
2063  LPDWORD pcchTargetUserSid, LPWSTR *szTransforms)
2064 {
2065  LPWSTR usersid = NULL;
2067 
2068  if (!szUserSid)
2069  {
2070  szUserSid = usersid = get_user_sid();
2071  if (!usersid) return ERROR_FUNCTION_FAILED;
2072  }
2073 
2074  if (dwContext & MSIINSTALLCONTEXT_USERMANAGED)
2075  {
2078  dwIndex, idx, szPatchCode,
2079  szTargetProductCode,
2080  pdwTargetProductContext, szTargetUserSid,
2081  pcchTargetUserSid, szTransforms);
2082  if (r != ERROR_NO_MORE_ITEMS)
2083  goto done;
2084  }
2085 
2086  if (dwContext & MSIINSTALLCONTEXT_USERUNMANAGED)
2087  {
2090  dwIndex, idx, szPatchCode,
2091  szTargetProductCode,
2092  pdwTargetProductContext, szTargetUserSid,
2093  pcchTargetUserSid, szTransforms);
2094  if (r != ERROR_NO_MORE_ITEMS)
2095  goto done;
2096  }
2097 
2098  if (dwContext & MSIINSTALLCONTEXT_MACHINE)
2099  {
2101  MSIINSTALLCONTEXT_MACHINE, dwFilter,
2102  dwIndex, idx, szPatchCode,
2103  szTargetProductCode,
2104  pdwTargetProductContext, szTargetUserSid,
2105  pcchTargetUserSid, szTransforms);
2106  if (r != ERROR_NO_MORE_ITEMS)
2107  goto done;
2108  }
2109 
2110 done:
2111  LocalFree(usersid);
2112  return r;
2113 }
2114 
2115 /***********************************************************************
2116  * MsiEnumPatchesExW [MSI.@]
2117  */
2119  DWORD dwContext, DWORD dwFilter, DWORD dwIndex, LPWSTR szPatchCode,
2120  LPWSTR szTargetProductCode, MSIINSTALLCONTEXT *pdwTargetProductContext,
2121  LPWSTR szTargetUserSid, LPDWORD pcchTargetUserSid)
2122 {
2123  WCHAR squashed_pc[SQUASHED_GUID_SIZE];
2124  DWORD idx = 0;
2125  UINT r;
2126 
2127  static DWORD last_index;
2128 
2129  TRACE("(%s, %s, %d, %d, %d, %p, %p, %p, %p, %p)\n",
2130  debugstr_w(szProductCode), debugstr_w(szUserSid), dwContext, dwFilter,
2131  dwIndex, szPatchCode, szTargetProductCode, pdwTargetProductContext,
2132  szTargetUserSid, pcchTargetUserSid);
2133 
2134  if (!szProductCode || !squash_guid( szProductCode, squashed_pc ))
2135  return ERROR_INVALID_PARAMETER;
2136 
2137  if (szUserSid && !strcmpW( szUserSid, szLocalSid ))
2138  return ERROR_INVALID_PARAMETER;
2139 
2140  if (dwContext & MSIINSTALLCONTEXT_MACHINE && szUserSid)
2141  return ERROR_INVALID_PARAMETER;
2142 
2143  if (dwContext <= MSIINSTALLCONTEXT_NONE ||
2144  dwContext > MSIINSTALLCONTEXT_ALL)
2145  return ERROR_INVALID_PARAMETER;
2146 
2147  if (dwFilter <= MSIPATCHSTATE_INVALID || dwFilter > MSIPATCHSTATE_ALL)
2148  return ERROR_INVALID_PARAMETER;
2149 
2150  if (dwIndex && dwIndex - last_index != 1)
2151  return ERROR_INVALID_PARAMETER;
2152 
2153  if (dwIndex == 0)
2154  last_index = 0;
2155 
2156  r = msi_enum_patches(szProductCode, szUserSid, dwContext, dwFilter,
2157  dwIndex, &idx, szPatchCode, szTargetProductCode,
2158  pdwTargetProductContext, szTargetUserSid,
2159  pcchTargetUserSid, NULL);
2160 
2161  if (r == ERROR_SUCCESS)
2162  last_index = dwIndex;
2163  else
2164  last_index = 0;
2165 
2166  return r;
2167 }
2168 
2169 /***********************************************************************
2170  * MsiEnumPatchesA [MSI.@]
2171  */
2172 UINT WINAPI MsiEnumPatchesA(LPCSTR szProduct, DWORD iPatchIndex,
2173  LPSTR lpPatchBuf, LPSTR lpTransformsBuf, LPDWORD pcchTransformsBuf)
2174 {
2175  LPWSTR product, transforms;
2176  WCHAR patch[GUID_SIZE];
2177  DWORD len;
2178  UINT r;
2179 
2180  TRACE("(%s %d %p %p %p)\n", debugstr_a(szProduct), iPatchIndex,
2181  lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
2182 
2183  if (!szProduct || !lpPatchBuf || !lpTransformsBuf || !pcchTransformsBuf)
2184  return ERROR_INVALID_PARAMETER;
2185 
2186  product = strdupAtoW(szProduct);
2187  if (!product)
2188  return ERROR_OUTOFMEMORY;
2189 
2190  len = *pcchTransformsBuf;
2191  transforms = msi_alloc( len * sizeof(WCHAR) );
2192  if (!transforms)
2193  {
2194  r = ERROR_OUTOFMEMORY;
2195  goto done;
2196  }
2197 
2198  r = MsiEnumPatchesW(product, iPatchIndex, patch, transforms, &len);
2199  if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
2200  goto done;
2201 
2202  WideCharToMultiByte(CP_ACP, 0, patch, -1, lpPatchBuf,
2203  GUID_SIZE, NULL, NULL);
2204 
2205  if (!WideCharToMultiByte(CP_ACP, 0, transforms, -1, lpTransformsBuf,
2206  *pcchTransformsBuf, NULL, NULL))
2207  r = ERROR_MORE_DATA;
2208 
2209  if (r == ERROR_MORE_DATA)
2210  {
2211  lpTransformsBuf[*pcchTransformsBuf - 1] = '\0';
2212  *pcchTransformsBuf = len * 2;
2213  }
2214  else
2215  *pcchTransformsBuf = strlen( lpTransformsBuf );
2216 
2217 done:
2218  msi_free(transforms);
2219  msi_free(product);
2220 
2221  return r;
2222 }
2223 
2224 /***********************************************************************
2225  * MsiEnumPatchesW [MSI.@]
2226  */
2227 UINT WINAPI MsiEnumPatchesW(LPCWSTR szProduct, DWORD iPatchIndex,
2228  LPWSTR lpPatchBuf, LPWSTR lpTransformsBuf, LPDWORD pcchTransformsBuf)
2229 {
2230  WCHAR *transforms = NULL, squashed_pc[SQUASHED_GUID_SIZE];
2231  HKEY prod;
2232  DWORD idx = 0;
2233  UINT r;
2234 
2235  TRACE("(%s %d %p %p %p)\n", debugstr_w(szProduct), iPatchIndex,
2236  lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
2237 
2238  if (!szProduct || !squash_guid( szProduct, squashed_pc ))
2239  return ERROR_INVALID_PARAMETER;
2240 
2241  if (!lpPatchBuf || !lpTransformsBuf || !pcchTransformsBuf)
2242  return ERROR_INVALID_PARAMETER;
2243 
2245  &prod, FALSE) != ERROR_SUCCESS &&
2247  &prod, FALSE) != ERROR_SUCCESS &&
2249  &prod, FALSE) != ERROR_SUCCESS)
2250  return ERROR_UNKNOWN_PRODUCT;
2251 
2252  RegCloseKey(prod);
2253 
2255  MSIPATCHSTATE_ALL, iPatchIndex, &idx, lpPatchBuf,
2256  NULL, NULL, NULL, NULL, &transforms);
2257  if (r != ERROR_SUCCESS)
2258  goto done;
2259 
2260  lstrcpynW(lpTransformsBuf, transforms, *pcchTransformsBuf);
2261  if (*pcchTransformsBuf <= lstrlenW(transforms))
2262  {
2263  r = ERROR_MORE_DATA;
2264  *pcchTransformsBuf = lstrlenW(transforms);
2265  }
2266  else
2267  *pcchTransformsBuf = lstrlenW(transforms);
2268 
2269 done:
2270  msi_free(transforms);
2271  return r;
2272 }
2273 
2275  CHAR installed_product[GUID_SIZE],
2276  MSIINSTALLCONTEXT *installed_ctx, LPSTR sid, LPDWORD sid_len )
2277 {
2278  UINT r;
2279  WCHAR installed_productW[GUID_SIZE], *productW = NULL, *usersidW = NULL, *sidW = NULL;
2280 
2281  TRACE("%s, %s, %u, %u, %p, %p, %p, %p\n", debugstr_a(product), debugstr_a(usersid),
2282  ctx, index, installed_product, installed_ctx, sid, sid_len);
2283 
2284  if (sid && !sid_len) return ERROR_INVALID_PARAMETER;
2285  if (product && !(productW = strdupAtoW( product ))) return ERROR_OUTOFMEMORY;
2286  if (usersid && !(usersidW = strdupAtoW( usersid )))
2287  {
2288  msi_free( productW );
2289  return ERROR_OUTOFMEMORY;
2290  }
2291  if (sid && !(sidW = msi_alloc( *sid_len * sizeof(WCHAR) )))
2292  {
2293  msi_free( usersidW );
2294  msi_free( productW );
2295  return ERROR_OUTOFMEMORY;
2296  }
2297  r = MsiEnumProductsExW( productW, usersidW, ctx, index, installed_productW,
2298  installed_ctx, sidW, sid_len );
2299  if (r == ERROR_SUCCESS)
2300  {
2301  if (installed_product) WideCharToMultiByte( CP_ACP, 0, installed_productW, GUID_SIZE,
2302  installed_product, GUID_SIZE, NULL, NULL );
2303  if (sid) WideCharToMultiByte( CP_ACP, 0, sidW, *sid_len + 1, sid, *sid_len + 1, NULL, NULL );
2304  }
2305  msi_free( productW );
2306  msi_free( usersidW );
2307  msi_free( sidW );
2308  return r;
2309 }
2310 
2312  WCHAR installed_product[GUID_SIZE],
2313  MSIINSTALLCONTEXT *installed_ctx, WCHAR *sid, DWORD *sid_len )
2314 {
2315  static const WCHAR productsW[] =
2316  {'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
2317  'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s',0};
2318  UINT r;
2319  WCHAR product[SQUASHED_GUID_SIZE];
2320  DWORD i = 0, len;
2322  HKEY key;
2323 
2324  if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, productsW, 0, access, &key ))
2325  return ERROR_NO_MORE_ITEMS;
2326 
2327  len = sizeof(product)/sizeof(product[0]);
2328  while (!RegEnumKeyExW( key, i, product, &len, NULL, NULL, NULL, NULL ))
2329  {
2330  if (match && strcmpW( match, product ))
2331  {
2332  i++;
2333  len = sizeof(product)/sizeof(product[0]);
2334  continue;
2335  }
2336  if (*idx == index) goto found;
2337  (*idx)++;
2338  len = sizeof(product)/sizeof(product[0]);
2339  i++;
2340  }
2341  RegCloseKey( key );
2342  return ERROR_NO_MORE_ITEMS;
2343 
2344 found:
2345  if (sid_len && *sid_len < 1)
2346  {
2347  *sid_len = 1;
2348  r = ERROR_MORE_DATA;
2349  }
2350  else
2351  {
2352  if (installed_product) unsquash_guid( product, installed_product );
2353  if (installed_ctx) *installed_ctx = MSIINSTALLCONTEXT_MACHINE;
2354  if (sid)
2355  {
2356  sid[0] = 0;
2357  *sid_len = 0;
2358  }
2359  r = ERROR_SUCCESS;
2360  }
2361  RegCloseKey( key );
2362  return r;
2363 }
2364 
2365 static UINT fetch_user_product( const WCHAR *match, const WCHAR *usersid, DWORD ctx, DWORD index,
2366  DWORD *idx, WCHAR installed_product[GUID_SIZE],
2367  MSIINSTALLCONTEXT *installed_ctx, WCHAR *sid, DWORD *sid_len )
2368 {
2369  static const WCHAR managedW[] =
2370  {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
2371  'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s',
2372  'i','o','n','\\','I','n','s','t','a','l','l','e','r','\\','M','a','n','a','g','e','d',0};
2373  static const WCHAR managed_productsW[] =
2374  {'\\','I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s',0};
2375  static const WCHAR unmanaged_productsW[] =
2376  {'\\','S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
2377  'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s',0};
2378  UINT r;
2379  const WCHAR *subkey;
2380  WCHAR path[MAX_PATH], product[SQUASHED_GUID_SIZE], user[128];
2381  DWORD i = 0, j = 0, len_product, len_user;
2383  HKEY key_users, key_products;
2384 
2385  if (ctx == MSIINSTALLCONTEXT_USERMANAGED)
2386  {
2387  subkey = managed_productsW;
2388  if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, managedW, 0, access, &key_users ))
2389  return ERROR_NO_MORE_ITEMS;
2390  }
2391  else if (ctx == MSIINSTALLCONTEXT_USERUNMANAGED)
2392  {
2393  subkey = unmanaged_productsW;
2394  if (RegOpenKeyExW( HKEY_USERS, NULL, 0, access, &key_users ))
2395  return ERROR_NO_MORE_ITEMS;
2396  }
2397  else return ERROR_INVALID_PARAMETER;
2398 
2399  len_user = sizeof(user)/sizeof(user[0]);
2400  while (!RegEnumKeyExW( key_users, i, user, &len_user, NULL, NULL, NULL, NULL ))
2401  {
2402  if (strcmpW( usersid, user ) && strcmpW( usersid, szAllSid ))
2403  {
2404  i++;
2405  len_user = sizeof(user)/sizeof(user[0]);
2406  continue;
2407  }
2408  strcpyW( path, user );
2409  strcatW( path, subkey );
2410  if (RegOpenKeyExW( key_users, path, 0, access, &key_products ))
2411  {
2412  i++;
2413  len_user = sizeof(user)/sizeof(user[0]);
2414  continue;
2415  }
2416  len_product = sizeof(product)/sizeof(product[0]);
2417  while (!RegEnumKeyExW( key_products, j, product, &len_product, NULL, NULL, NULL, NULL ))
2418  {
2419  if (match && strcmpW( match, product ))
2420  {
2421  j++;
2422  len_product = sizeof(product)/sizeof(product[0]);
2423  continue;
2424  }
2425  if (*idx == index) goto found;
2426  (*idx)++;
2427  len_product = sizeof(product)/sizeof(product[0]);
2428  j++;
2429  }
2430  RegCloseKey( key_products );
2431  len_user = sizeof(user)/sizeof(user[0]);
2432  i++;
2433  }
2434  RegCloseKey( key_users );
2435  return ERROR_NO_MORE_ITEMS;
2436 
2437 found:
2438  if (sid_len && *sid_len <= len_user)
2439  {
2440  *sid_len = len_user;
2441  r = ERROR_MORE_DATA;
2442  }
2443  else
2444  {
2445  if (installed_product) unsquash_guid( product, installed_product );
2446  if (installed_ctx) *installed_ctx = ctx;
2447  if (sid)
2448  {
2449  strcpyW( sid, user );
2450  *sid_len = len_user;
2451  }
2452  r = ERROR_SUCCESS;
2453  }
2454  RegCloseKey( key_products );
2455  RegCloseKey( key_users );
2456  return r;
2457 }
2458 
2459 static UINT enum_products( const WCHAR *product, const WCHAR *usersid, DWORD ctx, DWORD index,
2460  DWORD *idx, WCHAR installed_product[GUID_SIZE],
2461  MSIINSTALLCONTEXT *installed_ctx, WCHAR *sid, DWORD *sid_len )
2462 {
2464  WCHAR *user = NULL;
2465 
2466  if (!usersid)
2467  {
2468  usersid = user = get_user_sid();
2469  if (!user) return ERROR_FUNCTION_FAILED;
2470  }
2471  if (ctx & MSIINSTALLCONTEXT_MACHINE)
2472  {
2473  r = fetch_machine_product( product, index, idx, installed_product, installed_ctx,
2474  sid, sid_len );
2475  if (r != ERROR_NO_MORE_ITEMS) goto done;
2476  }
2478  {
2480  idx, installed_product, installed_ctx, sid, sid_len );
2481  if (r != ERROR_NO_MORE_ITEMS) goto done;
2482  }
2484  {
2486  idx, installed_product, installed_ctx, sid, sid_len );
2487  if (r != ERROR_NO_MORE_ITEMS) goto done;
2488  }
2489 
2490 done:
2491  LocalFree( user );
2492  return r;
2493 }
2494 
2496  WCHAR installed_product[GUID_SIZE],
2497  MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len )
2498 {
2499  UINT r;
2500  DWORD idx = 0;
2501  static DWORD last_index;
2502 
2503  TRACE("%s, %s, %u, %u, %p, %p, %p, %p\n", debugstr_w(product), debugstr_w(usersid),
2504  ctx, index, installed_product, installed_ctx, sid, sid_len);
2505 
2506  if ((sid && !sid_len) || !ctx || (usersid && ctx == MSIINSTALLCONTEXT_MACHINE))
2507  return ERROR_INVALID_PARAMETER;
2508 
2509  if (index && index - last_index != 1)
2510  return ERROR_INVALID_PARAMETER;
2511 
2512  if (!index) last_index = 0;
2513 
2514  r = enum_products( product, usersid, ctx, index, &idx, installed_product, installed_ctx,
2515  sid, sid_len );
2516  if (r == ERROR_SUCCESS)
2517  last_index = index;
2518  else
2519  last_index = 0;
2520 
2521  return r;
2522 }
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1975
#define HKEY_USERS
Definition: winreg.h:13
LPWSTR msi_reg_get_val_str(HKEY hkey, LPCWSTR name)
Definition: registry.c:394
LONG msi_reg_set_val_str(HKEY hkey, LPCWSTR name, LPCWSTR value)
Definition: registry.c:360
LONG msi_reg_set_val_multi_str(HKEY hkey, LPCWSTR name, LPCWSTR value)
Definition: registry.c:368
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
LONG WINAPI RegCloseKey(IN HKEY hKey)
Definition: registry.c:512
static const WCHAR szPatches[]
Definition: msipriv.h:1117
INTERNETFEATURELIST feature
Definition: misc.c:1689
LONG msi_reg_set_subkey_val(HKEY hkey, LPCWSTR path, LPCWSTR name, LPCWSTR val)
Definition: registry.c:381
UINT WINAPI MsiEnumClientsExW(LPCWSTR component, LPCWSTR usersid, DWORD ctx, DWORD index, WCHAR installed_product[GUID_SIZE], MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len)
Definition: registry.c:1546
UINT WINAPI MsiDecomposeDescriptorW(LPCWSTR szDescriptor, LPWSTR szProduct, LPWSTR szFeature, LPWSTR szComponent, LPDWORD pUsed)
Definition: registry.c:1055
#define TRUE
Definition: types.h:120
BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
Definition: registry.c:192
static DWORD
Definition: registry.c:44
#define CloseHandle
Definition: compat.h:398
#define ERROR_SUCCESS
Definition: deptool.c:10
enum tagMSIINSTALLCONTEXT MSIINSTALLCONTEXT
Definition: action.c:41
#define WideCharToMultiByte
Definition: compat.h:101
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
Definition: registry.c:1168
WINE_DEFAULT_DEBUG_CHANNEL(msi)
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:95
UINT WINAPI MsiEnumClientsExA(LPCSTR component, LPCSTR usersid, DWORD ctx, DWORD index, CHAR installed_product[GUID_SIZE], MSIINSTALLCONTEXT *installed_ctx, LPSTR sid, LPDWORD sid_len)
Definition: registry.c:1537
LONG WINAPI RegCreateKeyExW(IN HKEY hKey, IN LPCWSTR lpSubKey, IN DWORD Reserved, IN LPWSTR lpClass OPTIONAL, IN DWORD dwOptions, IN REGSAM samDesired, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL, OUT PHKEY phkResult, OUT LPDWORD lpdwDisposition OPTIONAL)
Definition: registry.c:533
Definition: http.c:6587
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define MAKEWORD(a, b)
Definition: typedefs.h:247
static const WCHAR szUserProducts[]
Definition: registry.c:184
#define KEY_READ
Definition: nt_native.h:1023
Definition: match.c:28
static UINT msi_check_product_patches(LPCWSTR prodcode, LPCWSTR usersid, MSIINSTALLCONTEXT context, DWORD filter, DWORD index, DWORD *idx, LPWSTR patch, LPWSTR targetprod, MSIINSTALLCONTEXT *targetctx, LPWSTR targetsid, DWORD *sidsize, LPWSTR *transforms)
Definition: registry.c:1890
UINT WINAPI MsiEnumClientsA(LPCSTR szComponent, DWORD index, LPSTR szProduct)
Definition: registry.c:1468
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
#define CP_ACP
Definition: compat.h:99
UINT WINAPI MsiEnumComponentQualifiersA(LPCSTR szComponent, DWORD iIndex, LPSTR lpQualifierBuf, LPDWORD pcchQualifierBuf, LPSTR lpApplicationDataBuf, LPDWORD pcchApplicationDataBuf)
Definition: registry.c:1651
#define HKEY_CURRENT_USER
Definition: winreg.h:11
char CHAR
Definition: xmlstorage.h:175
static const WCHAR szInstaller_LocalClassesFeatures[]
Definition: registry.c:128
UINT WINAPI MsiEnumRelatedProductsA(LPCSTR szUpgradeCode, DWORD dwReserved, DWORD iProductIndex, LPSTR lpProductBuf)
Definition: registry.c:1738
UINT WINAPI MsiEnumFeaturesA(LPCSTR szProduct, DWORD index, LPSTR szFeature, LPSTR szParent)
Definition: registry.c:1179
LONG WINAPI RegCreateKeyW(IN HKEY hKey, IN LPCWSTR lpSubKey, OUT PHKEY phkResult)
Definition: registry.c:524
GLdouble n
Definition: glext.h:7729
UINT WINAPI MsiEnumComponentsExA(LPCSTR user_sid, DWORD ctx, DWORD index, CHAR guid[39], MSIINSTALLCONTEXT *installed_ctx, LPSTR sid, LPDWORD sid_len)
Definition: registry.c:1256
UINT WINAPI MsiEnumPatchesExW(LPCWSTR szProductCode, LPCWSTR szUserSid, DWORD dwContext, DWORD dwFilter, DWORD dwIndex, LPWSTR szPatchCode, LPWSTR szTargetProductCode, MSIINSTALLCONTEXT *pdwTargetProductContext, LPWSTR szTargetUserSid, LPDWORD pcchTargetUserSid)
Definition: registry.c:2118
static const WCHAR szInstaller_LocalClassesProd[]
Definition: registry.c:132
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
FT_UInt sid
Definition: cffcmap.c:139
#define RRF_RT_REG_SZ
Definition: driver.c:575
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
UINT WINAPI MsiDecomposeDescriptorA(LPCSTR szDescriptor, LPSTR szProduct, LPSTR szFeature, LPSTR szComponent, LPDWORD pUsed)
Definition: registry.c:1112
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY *key, BOOL create)
Definition: registry.c:1004
UINT WINAPI MsiEnumComponentsA(DWORD index, LPSTR lpguid)
Definition: registry.c:1231
UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY *key, BOOL create)
Definition: registry.c:653
GLuint GLuint end
Definition: gl.h:1545
static const WCHAR szUserDataProductPatches_fmt[]
Definition: registry.c:89
static const WCHAR szUserDataProd_fmt[]
Definition: registry.c:65
LPWSTR w
Definition: msipriv.h:720
static UINT fetch_user_component(const WCHAR *usersid, DWORD ctx, DWORD index, DWORD *idx, WCHAR guid[39], MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len)
Definition: registry.c:1331
static const WCHAR szAllSid[]
Definition: msipriv.h:1105
char * LPSTR
Definition: xmlstorage.h:182
UINT MSIREG_DeleteUpgradeCodesKey(const WCHAR *code)
Definition: registry.c:944
BOOL WINAPI ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
Definition: security.c:3259
#define lstrlenW
Definition: compat.h:407
static const WCHAR szUserDataComp_fmt[]
Definition: registry.c:53
static const BOOL is_64bit
Definition: msipriv.h:41
LONG WINAPI RegSetValueExW(IN HKEY hKey, IN LPCWSTR lpValueName OPTIONAL, IN ULONG Reserved, IN ULONG dwType, IN const UCHAR *lpData, IN ULONG cbData)
Definition: registry.c:656
static const WCHAR szInstaller_LocalManagedProd_fmt[]
Definition: registry.c:102
#define lstrcpynW
Definition: compat.h:397
UINT msi_strcpy_to_awstring(const WCHAR *str, int len, awstring *awbuf, DWORD *sz)
Definition: install.c:181
LONG msi_reg_set_val_dword(HKEY hkey, LPCWSTR name, DWORD val)
Definition: registry.c:376
UINT WINAPI MsiEnumRelatedProductsW(LPCWSTR szUpgradeCode, DWORD dwReserved, DWORD iProductIndex, LPWSTR lpProductBuf)
Definition: registry.c:1706
UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext, HKEY *key, BOOL create)
Definition: registry.c:754
UINT WINAPI MsiEnumPatchesA(LPCSTR szProduct, DWORD iPatchIndex, LPSTR lpPatchBuf, LPSTR lpTransformsBuf, LPDWORD pcchTransformsBuf)
Definition: registry.c:2172
UINT MSIREG_DeleteLocalClassesFeaturesKey(LPCWSTR szProductCode)
Definition: registry.c:988
static UINT fetch_machine_component(DWORD ctx, DWORD index, DWORD *idx, WCHAR guid[39], MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len)
Definition: registry.c:1283
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static UINT fetch_user_product(const WCHAR *match, const WCHAR *usersid, DWORD ctx, DWORD index, DWORD *idx, WCHAR installed_product[GUID_SIZE], MSIINSTALLCONTEXT *installed_ctx, WCHAR *sid, DWORD *sid_len)
Definition: registry.c:2365
const GUID * guid
UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY *key, BOOL create)
Definition: registry.c:915
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
unsigned char * LPBYTE
Definition: typedefs.h:52
UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode)
Definition: registry.c:960
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid)
Definition: registry.c:1247
unsigned int BOOL
Definition: ntddk_ex.h:94
static const WCHAR szUpgradeCode[]
Definition: msipriv.h:1170
GLuint base
Definition: 3dtext.c:35
long LONG
Definition: pedump.c:60
static const WCHAR szInstaller_LocalManagedFeat_fmt[]
Definition: registry.c:108
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
#define MAX_FEATURE_CHARS
Definition: msi.h:257
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define debugstr_w
Definition: kernel32.h:32
static UINT enum_components(const WCHAR *usersid, DWORD ctx, DWORD index, DWORD *idx, WCHAR guid[39], MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len)
Definition: registry.c:1406
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
unsigned int idx
Definition: utils.c:41
static const WCHAR szInstaller_LocalClassesProducts[]
Definition: registry.c:124
const WCHAR * str
#define MAKELONG(a, b)
Definition: typedefs.h:248
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:2867
DWORD msi_version_str_to_dword(LPCWSTR p)
Definition: registry.c:339
smooth NULL
Definition: ftsmooth.c:416
LPSTR a
Definition: msipriv.h:719
static const WCHAR szInstaller_Products[]
Definition: registry.c:114
static const WCHAR version[]
Definition: asmname.c:64
static const WCHAR szInstallProperties_fmt[]
Definition: registry.c:95
LONG WINAPI RegOpenKeyW(IN HKEY hKey, IN LPCWSTR lpSubKey, OUT PHKEY phkResult)
Definition: registry.c:647
GLuint index
Definition: glext.h:6031
static const WCHAR szInstaller_UpgradeCodes[]
Definition: registry.c:153
const char * LPCSTR
Definition: xmlstorage.h:183
static const char appdata[]
Definition: shdocvw.c:39
#define debugstr_guid
Definition: kernel32.h:35
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
GLuint GLfloat * val
Definition: glext.h:7180
platform
Definition: msipriv.h:356
#define RRF_RT_DWORD
Definition: driver.c:581
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid)
Definition: registry.c:699
static const WCHAR szUserDataPatch_fmt[]
Definition: registry.c:77
static const WCHAR szUserDataProducts_fmt[]
Definition: registry.c:71
static const WCHAR szUserDataComponents_fmt[]
Definition: registry.c:59
static const WCHAR szEmpty[]
Definition: provider.c:47
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY *key, BOOL create)
Definition: registry.c:930
static const WCHAR szInstaller_ClassesUpgradeCode[]
Definition: registry.c:140
static const WCHAR szInstaller_UserUpgradeCodes[]
Definition: registry.c:158
GLfloat f
Definition: glext.h:7540
#define TRACE(s)
Definition: solgame.cpp:4
BOOL decode_base85_guid(LPCWSTR str, GUID *guid)
Definition: registry.c:283
GLsizeiptr size
Definition: glext.h:5919
static const WCHAR szProductCode[]
Definition: msipriv.h:1127
#define TOKEN_QUERY
Definition: setypes.h:874
#define ERROR_BAD_CONFIGURATION
Definition: winerror.h:968
static const WCHAR szState[]
Definition: msipriv.h:1118
static const WCHAR szUserDataFeatures_fmt[]
Definition: registry.c:47
__wchar_t WCHAR
Definition: xmlstorage.h:180
UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct)
Definition: registry.c:530
UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create)
Definition: registry.c:830
#define debugstr_a
Definition: kernel32.h:31
#define ERROR_UNKNOWN_PRODUCT
Definition: winerror.h:963
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1168
UINT MSIREG_OpenPatchesKey(LPCWSTR szPatch, HKEY *key, BOOL create)
Definition: registry.c:901
static DNS_RECORDW r2
Definition: record.c:38
static const WCHAR szLocalSid[]
Definition: msipriv.h:1104
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2343
const GLubyte * c
Definition: glext.h:8905
static const WCHAR szUserComponents[]
Definition: registry.c:172
UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:622
static FILE * out
Definition: regtests2xml.c:44
UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:556
static const WCHAR szInstaller_LocalClassesFeat[]
Definition: registry.c:136
unsigned long DWORD
Definition: ntddk_ex.h:95
union awstring::@478 str
BOOL msi_reg_get_val_dword(HKEY hkey, LPCWSTR name, DWORD *val)
Definition: registry.c:413
static const unsigned char table_dec85[0x80]
Definition: registry.c:261
UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY *key, BOOL create)
Definition: registry.c:542
int ret
#define index(s, c)
Definition: various.h:29
static UINT MSI_EnumComponentQualifiers(LPCWSTR szComponent, DWORD iIndex, awstring *lpQualBuf, LPDWORD pcchQual, awstring *lpAppBuf, LPDWORD pcchAppBuf)
Definition: registry.c:1555
static const WCHAR szUserFeatures[]
Definition: registry.c:180
HKEY key
Definition: reg.c:42
static WCHAR * get_user_sid(void)
Definition: registry.c:420
static int state
Definition: maze.c:121
UINT WINAPI MsiEnumComponentQualifiersW(LPCWSTR szComponent, DWORD iIndex, LPWSTR lpQualifierBuf, LPDWORD pcchQualifierBuf, LPWSTR lpApplicationDataBuf, LPDWORD pcchApplicationDataBuf)
Definition: registry.c:1682
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
static const WCHAR szInstaller_ClassesUpgradeCodes[]
Definition: registry.c:144
enum tagMSIPATCHSTATE MSIPATCHSTATE
UINT MSIREG_OpenProductKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:492
UINT WINAPI MsiEnumPatchesW(LPCWSTR szProduct, DWORD iPatchIndex, LPWSTR lpPatchBuf, LPWSTR lpTransformsBuf, LPDWORD pcchTransformsBuf)
Definition: registry.c:2227
#define ERROR_MORE_DATA
Definition: dderror.h:13
GLsizei const GLfloat * value
Definition: glext.h:6069
UINT WINAPI MsiEnumProductsExW(LPCWSTR product, LPCWSTR usersid, DWORD ctx, DWORD index, WCHAR installed_product[GUID_SIZE], MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len)
Definition: registry.c:2495
#define debugstr_wn
Definition: kernel32.h:33
static const WCHAR szInstaller_Features[]
Definition: registry.c:148
UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid, HKEY *key, BOOL create)
Definition: registry.c:674
static const WCHAR szUserDataPatches_fmt[]
Definition: registry.c:83
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1755
#define ERR(fmt,...)
Definition: debug.h:109
static const WCHAR szInstaller_Patches[]
Definition: registry.c:119
static UINT MSIREG_OpenInstallerFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
Definition: registry.c:607
LONG WINAPI RegQueryValueExW(IN HKEY hKey, IN LPCWSTR lpValueName, IN PULONG lpReserved, OUT PULONG lpType OPTIONAL, OUT PUCHAR lpData OPTIONAL, IN OUT PULONG lpcbData OPTIONAL)
Definition: registry.c:862
static const WCHAR szUninstall[]
Definition: registry.c:162
static const WCHAR szUserPatches[]
Definition: registry.c:188
static UINT msi_enum_patches(LPCWSTR szProductCode, LPCWSTR szUserSid, DWORD dwContext, DWORD dwFilter, DWORD dwIndex, DWORD *idx, LPWSTR szPatchCode, LPWSTR szTargetProductCode, MSIINSTALLCONTEXT *pdwTargetProductContext, LPWSTR szTargetUserSid, LPDWORD pcchTargetUserSid, LPWSTR *szTransforms)
Definition: registry.c:2059
UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
Definition: registry.c:1498
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
static UINT msi_get_patch_state(LPCWSTR prodcode, LPCWSTR usersid, MSIINSTALLCONTEXT context, LPWSTR patch, MSIPATCHSTATE *state)
Definition: registry.c:1845
#define SQUASHED_GUID_SIZE
Definition: msipriv.h:711
#define lstrcpyW
Definition: compat.h:406
GLuint in
Definition: glext.h:9616
static calc_node_t temp
Definition: rpn_ieee.c:38
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
UINT WINAPI MsiEnumComponentsExW(LPCWSTR user_sid, DWORD ctx, DWORD index, WCHAR guid[39], MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len)
Definition: registry.c:1441
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
UINT MSIREG_DeleteUserDataPatchKey(LPCWSTR patch, MSIINSTALLCONTEXT context)
Definition: registry.c:778
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define major(rdev)
Definition: propsheet.cpp:879
Definition: services.c:325
#define sprintfW
Definition: unicode.h:58
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
ACCESS_MASK REGSAM
Definition: winreg.h:69
BOOL unicode
Definition: msipriv.h:717
#define ERROR_UNKNOWN_COMPONENT
Definition: winerror.h:965
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:296
UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context)
Definition: registry.c:856
UINT MSIREG_OpenUserDataProductPatchesKey(LPCWSTR product, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:806
static BOOL msi_free(void *mem)
Definition: msipriv.h:1227
Definition: name.c:36
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
GLuint res
Definition: glext.h:9613
uint32_t * LPDWORD
Definition: typedefs.h:57
BOOL encode_base85_guid(GUID *guid, LPWSTR str)
Definition: registry.c:316
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1204
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2247
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:413
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
UINT MSIREG_DeleteProductKey(LPCWSTR szProduct)
Definition: registry.c:885
#define minor(rdev)
Definition: propsheet.cpp:880
static UINT fetch_machine_product(const WCHAR *match, DWORD index, DWORD *idx, WCHAR installed_product[GUID_SIZE], MSIINSTALLCONTEXT *installed_ctx, WCHAR *sid, DWORD *sid_len)
Definition: registry.c:2311
#define RRF_RT_ANY
Definition: winreg.h:64
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2541
UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct)
Definition: registry.c:595
UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode)
Definition: registry.c:1019
static UINT enum_products(const WCHAR *product, const WCHAR *usersid, DWORD ctx, DWORD index, DWORD *idx, WCHAR installed_product[GUID_SIZE], MSIINSTALLCONTEXT *installed_ctx, WCHAR *sid, DWORD *sid_len)
Definition: registry.c:2459
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
UINT WINAPI MsiEnumProductsA(DWORD index, LPSTR lpguid)
Definition: registry.c:1152
#define GUID_SIZE
Definition: msipriv.h:710
static const WCHAR szPatch[]
Definition: msipriv.h:1120
static const struct access_res create[16]
Definition: package.c:7720
#define REG_DWORD
Definition: sdbapi.c:596
#define RRF_RT_REG_DWORD
Definition: driver.c:578
static const WCHAR szUninstall_32node[]
Definition: registry.c:167
UINT WINAPI MsiEnumPatchesExA(LPCSTR szProductCode, LPCSTR szUserSid, DWORD dwContext, DWORD dwFilter, DWORD dwIndex, LPSTR szPatchCode, LPSTR szTargetProductCode, MSIINSTALLCONTEXT *pdwTargetProductContext, LPSTR szTargetUserSid, LPDWORD pcchTargetUserSid)
Definition: registry.c:1769
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
void user(int argc, const char *argv[])
Definition: cmds.c:1350
UINT MSIREG_DeleteLocalClassesProductKey(LPCWSTR szProductCode)
Definition: registry.c:972
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
static WCHAR * strdupAtoW(const char *str)
Definition: main.c:67
static const WCHAR szInstaller_Components[]
Definition: registry.c:176
static const char table_enc85[]
Definition: registry.c:272
UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index, LPWSTR szFeature, LPWSTR szParent)
Definition: registry.c:1209
UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create)
Definition: registry.c:728
UINT MSIREG_DeleteUninstallKey(const WCHAR *product, enum platform platform)
Definition: registry.c:473
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
WINE_UNICODE_INLINE int atoiW(const WCHAR *str)
Definition: unicode.h:315
BOOL squash_guid(LPCWSTR in, LPWSTR out)
Definition: registry.c:225
Definition: path.c:42
UINT MSIREG_OpenUninstallKey(const WCHAR *product, enum platform platform, HKEY *key, BOOL create)
Definition: registry.c:453
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
UINT WINAPI MsiEnumProductsExA(LPCSTR product, LPCSTR usersid, DWORD ctx, DWORD index, CHAR installed_product[GUID_SIZE], MSIINSTALLCONTEXT *installed_ctx, LPSTR sid, LPDWORD sid_len)
Definition: registry.c:2274
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define REG_SZ
Definition: layer.c:22