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