ReactOS 0.4.15-dev-8428-g6910fa6
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 */
110static const unsigned char table_dec85[0x80] = {
1110xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1120xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1130xff,0x00,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff,
1140x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0xff,0xff,0xff,0x16,0xff,0x17,
1150x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
1160x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0x34,0x35,0x36,
1170x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,
1180x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xff,0x53,0x54,0xff,
119};
120
121static 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;
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
269static WCHAR *get_user_sid(void)
270{
272 DWORD size = 256;
274 WCHAR *ret;
275
277 if (!(user = msi_alloc( size )))
278 {
280 return NULL;
281 }
283 {
284 msi_free( user );
286 {
288 return NULL;
289 }
291 }
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
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
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");
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
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");
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
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");
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);
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");
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");
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");
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");
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");
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");
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");
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");
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
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)
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)
1046
1047 return MsiEnumProductsExW( NULL, L"S-1-1-0", MSIINSTALLCONTEXT_ALL, index, lpguid,
1048 NULL, NULL, NULL );
1049}
1050
1051UINT 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
1078UINT 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 )
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{
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
1176found:
1177 if (sid_len)
1178 {
1179 if (*sid_len < 1)
1180 {
1181 *sid_len = 1;
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{
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
1245found:
1246 if (sid_len)
1247 {
1248 if (*sid_len < len_user + 1)
1249 {
1250 *sid_len = len_user + 1;
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
1266static 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
1296done:
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))
1313
1314 if (index && index - last_index != 1)
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
1328UINT 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 )
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
1355UINT 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)
1365
1366 if (MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkeyComp, FALSE) != ERROR_SUCCESS &&
1367 MSIREG_OpenUserDataComponentKey(szComponent, L"S-1-5-18", &hkeyComp, FALSE) != ERROR_SUCCESS)
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)
1379
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
1394UINT 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
1403UINT 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
1412static 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)
1424
1425 r = MSIREG_OpenUserComponentsKey( szComponent, &key, FALSE );
1426 if (r != ERROR_SUCCESS)
1428
1429 /* figure out how big the name is we want to return */
1430 name_max = 0x10;
1432 name = msi_alloc( name_max * sizeof(WCHAR) );
1433 if (!name)
1434 goto end;
1435
1436 val_max = 0x10;
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
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
1495end:
1496 msi_free(val);
1497 msi_free(name);
1499 return r;
1500}
1501
1502/*************************************************************************
1503 * MsiEnumComponentQualifiersA [MSI.@]
1504 */
1505UINT 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 */
1535UINT 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 */
1557UINT 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)
1569 if (NULL == lpProductBuf)
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 */
1588UINT 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 */
1618UINT 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)
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 {
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 {
1677 *pcchTargetUserSid = len * sizeof(WCHAR);
1678 }
1679 else
1680 *pcchTargetUserSid = len;
1681
1682done:
1683 msi_free(prodcode);
1684 msi_free(usersid);
1685 msi_free(targsid);
1686
1687 return r;
1688}
1689
1690static 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 ||
1718 val < MSIPATCHSTATE_APPLIED || val > MSIPATCHSTATE_REGISTERED)
1719 {
1721 goto done;
1722 }
1723
1724 *state = val;
1725 r = ERROR_SUCCESS;
1726
1727done:
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 {
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 {
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 {
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 {
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 }
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)
1887 }
1888
1889 if (sidsize)
1890 {
1891 *sidsize = lstrlenW(usersid);
1892 if (!targetsid)
1893 *sidsize *= sizeof(WCHAR);
1894 }
1895 }
1896
1897done:
1898 RegCloseKey(prod);
1899 msi_free(patches);
1900
1901 return r;
1902}
1903
1904static 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
1955done:
1956 LocalFree(usersid);
1957 return r;
1958}
1959
1960/***********************************************************************
1961 * MsiEnumPatchesExW [MSI.@]
1962 */
1963UINT 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 ))
1980
1981 if (szUserSid && !wcscmp( szUserSid, L"S-1-5-18" ))
1983
1984 if (dwContext & MSIINSTALLCONTEXT_MACHINE && szUserSid)
1986
1987 if (dwContext <= MSIINSTALLCONTEXT_NONE ||
1988 dwContext > MSIINSTALLCONTEXT_ALL)
1990
1991 if (dwFilter <= MSIPATCHSTATE_INVALID || dwFilter > MSIPATCHSTATE_ALL)
1993
1994 if (dwIndex && dwIndex - last_index != 1)
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 */
2016UINT 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)
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 {
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))
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
2060done:
2061 msi_free(transforms);
2062 msi_free(product);
2063
2064 return r;
2065}
2066
2067/***********************************************************************
2068 * MsiEnumPatchesW [MSI.@]
2069 */
2070UINT 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 ))
2083
2084 if (!lpPatchBuf || !lpTransformsBuf || !pcchTransformsBuf)
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 {
2107 *pcchTransformsBuf = lstrlenW(transforms);
2108 }
2109 else
2110 *pcchTransformsBuf = lstrlenW(transforms);
2111
2112done:
2113 msi_free(transforms);
2114 return r;
2115}
2116
2117UINT 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
2184found:
2185 if (sid_len && *sid_len < 1)
2186 {
2187 *sid_len = 1;
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
2205static 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
2268found:
2269 if (sid_len && *sid_len <= len_user)
2270 {
2271 *sid_len = len_user;
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
2290static 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
2321done:
2322 LocalFree( user );
2323 return r;
2324}
2325
2326UINT 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))
2339
2340 if (index && index - last_index != 1)
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}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static int state
Definition: maze.c:121
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define ARRAY_SIZE(A)
Definition: main.h:33
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define RegCloseKey(hKey)
Definition: registry.h:49
FT_UInt sid
Definition: cffcmap.c:139
LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR)
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
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:2504
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
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:2830
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
BOOL WINAPI ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
Definition: security.c:3583
static WCHAR * strdupAtoW(const char *str)
Definition: main.c:65
#define CloseHandle
Definition: compat.h:739
#define wcschr
Definition: compat.h:17
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define GetCurrentProcess()
Definition: compat.h:759
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
UINT msi_strcpy_to_awstring(const WCHAR *str, int len, awstring *awbuf, DWORD *sz)
Definition: install.c:158
BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
Definition: registry.c:41
UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode)
Definition: registry.c:829
UINT MSIREG_OpenProductKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:338
BOOL decode_base85_guid(LPCWSTR str, GUID *guid)
Definition: registry.c:132
UINT WINAPI MsiEnumComponentsA(DWORD index, char *lpguid)
Definition: registry.c:1099
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
LONG msi_reg_set_val_dword(HKEY hkey, LPCWSTR name, DWORD val)
Definition: registry.c:225
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
static UINT MSI_EnumComponentQualifiers(const WCHAR *szComponent, DWORD iIndex, awstring *lpQualBuf, DWORD *pcchQual, awstring *lpAppBuf, DWORD *pcchAppBuf)
Definition: registry.c:1412
BOOL squash_guid(LPCWSTR in, LPWSTR out)
Definition: registry.c:74
UINT MSIREG_DeleteLocalClassesFeaturesKey(LPCWSTR szProductCode)
Definition: registry.c:858
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
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
static const char table_enc85[]
Definition: registry.c:121
UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid, HKEY *key, BOOL create)
Definition: registry.c:526
UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY *key, BOOL create)
Definition: registry.c:390
LONG msi_reg_set_subkey_val(HKEY hkey, LPCWSTR path, LPCWSTR name, LPCWSTR val)
Definition: registry.c:230
UINT WINAPI MsiEnumProductsW(DWORD index, WCHAR *lpguid)
Definition: registry.c:1040
UINT WINAPI MsiEnumFeaturesW(const WCHAR *szProduct, DWORD index, WCHAR *szFeature, WCHAR *szParent)
Definition: registry.c:1078
UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY *key, BOOL create)
Definition: registry.c:798
UINT MSIREG_OpenUserDataProductPatchesKey(LPCWSTR product, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:666
UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY *key, BOOL create)
Definition: registry.c:783
UINT WINAPI MsiEnumPatchesW(const WCHAR *szProduct, DWORD iPatchIndex, WCHAR *lpPatchBuf, WCHAR *lpTransformsBuf, DWORD *pcchTransformsBuf)
Definition: registry.c:2070
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
UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY *key, BOOL create)
Definition: registry.c:875
LONG msi_reg_set_val_multi_str(HKEY hkey, LPCWSTR name, LPCWSTR value)
Definition: registry.c:217
UINT WINAPI MsiDecomposeDescriptorA(LPCSTR szDescriptor, LPSTR szProduct, LPSTR szFeature, LPSTR szComponent, LPDWORD pUsed)
Definition: registry.c:984
BOOL encode_base85_guid(GUID *guid, LPWSTR str)
Definition: registry.c:165
UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create)
Definition: registry.c:692
UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid)
Definition: registry.c:552
UINT MSIREG_OpenPatchesKey(LPCWSTR szPatch, HKEY *key, BOOL create)
Definition: registry.c:768
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
UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode)
Definition: registry.c:890
UINT WINAPI MsiEnumProductsA(DWORD index, char *lpguid)
Definition: registry.c:1024
UINT WINAPI MsiDecomposeDescriptorW(LPCWSTR szDescriptor, LPWSTR szProduct, LPWSTR szFeature, LPWSTR szComponent, LPDWORD pUsed)
Definition: registry.c:927
UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY *key, BOOL create)
Definition: registry.c:505
static const unsigned char table_dec85[0x80]
Definition: registry.c:110
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
UINT WINAPI MsiEnumClientsA(const char *szComponent, DWORD index, char *szProduct)
Definition: registry.c:1328
UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct)
Definition: registry.c:378
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
UINT WINAPI MsiEnumRelatedProductsW(const WCHAR *szUpgradeCode, DWORD dwReserved, DWORD iProductIndex, WCHAR *lpProductBuf)
Definition: registry.c:1557
static UINT msi_get_patch_state(LPCWSTR prodcode, LPCWSTR usersid, MSIINSTALLCONTEXT context, LPWSTR patch, MSIPATCHSTATE *state)
Definition: registry.c:1690
UINT WINAPI MsiEnumClientsW(const WCHAR *szComponent, DWORD index, WCHAR *szProduct)
Definition: registry.c:1355
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 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
UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:404
UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context)
Definition: registry.c:720
static WCHAR * get_user_sid(void)
Definition: registry.c:269
BOOL msi_reg_get_val_dword(HKEY hkey, LPCWSTR name, DWORD *val)
Definition: registry.c:262
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
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
UINT WINAPI MsiEnumRelatedProductsA(const char *szUpgradeCode, DWORD dwReserved, DWORD iProductIndex, char *lpProductBuf)
Definition: registry.c:1588
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_DeleteUpgradeCodesKey(const WCHAR *code)
Definition: registry.c:812
UINT WINAPI MsiEnumFeaturesA(const char *szProduct, DWORD index, char *szFeature, char *szParent)
Definition: registry.c:1051
UINT MSIREG_DeleteLocalClassesProductKey(LPCWSTR szProductCode)
Definition: registry.c:841
static UINT MSIREG_OpenInstallerFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
Definition: registry.c:457
UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct)
Definition: registry.c:445
UINT MSIREG_OpenUninstallKey(const WCHAR *product, enum platform platform, HKEY *key, BOOL create)
Definition: registry.c:302
UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext, HKEY *key, BOOL create)
Definition: registry.c:610
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
UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create)
Definition: registry.c:582
UINT WINAPI MsiEnumComponentQualifiersA(const char *szComponent, DWORD iIndex, char *lpQualifierBuf, DWORD *pcchQualifierBuf, char *lpApplicationDataBuf, DWORD *pcchApplicationDataBuf)
Definition: registry.c:1505
UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:472
UINT MSIREG_DeleteProductKey(LPCWSTR szProduct)
Definition: registry.c:751
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
UINT MSIREG_DeleteUninstallKey(const WCHAR *product, enum platform platform)
Definition: registry.c:319
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
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
UINT MSIREG_DeleteUserDataPatchKey(LPCWSTR patch, MSIINSTALLCONTEXT context)
Definition: registry.c:636
UINT WINAPI MsiEnumPatchesA(const char *szProduct, DWORD iPatchIndex, char *lpPatchBuf, char *lpTransformsBuf, DWORD *pcchTransformsBuf)
Definition: registry.c:2016
UINT WINAPI MsiEnumComponentsW(DWORD index, WCHAR *lpguid)
Definition: registry.c:1115
DWORD msi_version_str_to_dword(LPCWSTR p)
Definition: registry.c:188
UINT WINAPI MsiEnumComponentQualifiersW(const WCHAR *szComponent, DWORD iIndex, WCHAR *lpQualifierBuf, DWORD *pcchQualifierBuf, WCHAR *lpApplicationDataBuf, DWORD *pcchApplicationDataBuf)
Definition: registry.c:1535
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
#define RRF_RT_REG_DWORD
Definition: driver.c:578
#define RRF_RT_DWORD
Definition: driver.c:581
#define RRF_RT_REG_SZ
Definition: driver.c:575
#define swprintf
Definition: precomp.h:40
r parent
Definition: btrfs.c:3010
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLfloat f
Definition: glext.h:7540
GLuint in
Definition: glext.h:9616
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
GLuint GLfloat * val
Definition: glext.h:7180
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
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
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
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
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
#define REG_SZ
Definition: layer.c:22
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
const GUID * guid
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PVOID ptr
Definition: dispmode.c:27
static DNS_RECORDW r2
Definition: record.c:38
static const struct access_res create[16]
Definition: package.c:7644
INTERNETFEATURELIST feature
Definition: misc.c:1719
@ MSIPATCHSTATE_ALL
Definition: msi.h:58
@ MSIPATCHSTATE_APPLIED
Definition: msi.h:54
@ MSIPATCHSTATE_REGISTERED
Definition: msi.h:57
@ MSIPATCHSTATE_INVALID
Definition: msi.h:53
enum tagMSIINSTALLCONTEXT MSIINSTALLCONTEXT
Definition: action.c:49
enum tagMSIPATCHSTATE MSIPATCHSTATE
@ MSIINSTALLCONTEXT_MACHINE
Definition: msi.h:200
@ MSIINSTALLCONTEXT_ALL
Definition: msi.h:201
@ MSIINSTALLCONTEXT_NONE
Definition: msi.h:197
@ MSIINSTALLCONTEXT_USERUNMANAGED
Definition: msi.h:199
@ MSIINSTALLCONTEXT_USERMANAGED
Definition: msi.h:198
#define MAX_FEATURE_CHARS
Definition: msi.h:257
static void msi_free(void *mem)
Definition: msipriv.h:1159
#define GUID_SIZE
Definition: msipriv.h:733
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
platform
Definition: msipriv.h:364
@ PLATFORM_INTEL
Definition: msipriv.h:366
#define SQUASHED_GUID_SIZE
Definition: msipriv.h:734
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:95
unsigned int UINT
Definition: ndis.h:50
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
#define minor(rdev)
Definition: propsheet.cpp:929
#define major(rdev)
Definition: propsheet.cpp:928
static FILE * out
Definition: regtests2xml.c:44
const WCHAR * str
static calc_node_t temp
Definition: rpn_ieee.c:38
#define REG_DWORD
Definition: sdbapi.c:596
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR w
Definition: msipriv.h:743
LPSTR a
Definition: msipriv.h:742
union awstring::@499 str
BOOL unicode
Definition: msipriv.h:740
Definition: inflate.c:139
Definition: http.c:7252
Definition: copy.c:22
Definition: match.c:28
Definition: name.c:39
#define MAKEWORD(a, b)
Definition: typedefs.h:248
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t * LPDWORD
Definition: typedefs.h:59
#define MAKELONG(a, b)
Definition: typedefs.h:249
Definition: pdh_main.c:94
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define ERROR_UNKNOWN_PRODUCT
Definition: winerror.h:963
#define ERROR_UNKNOWN_COMPONENT
Definition: winerror.h:965
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
#define ERROR_BAD_CONFIGURATION
Definition: winerror.h:968
static const char appdata[]
Definition: shdocvw.c:39
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RRF_RT_ANY
Definition: winreg.h:64
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define HKEY_USERS
Definition: winreg.h:13
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenUser
Definition: setypes.h:966
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193