msi/tests: Skip tests when the current user has insufficient rights.
[wine] / dlls / msi / tests / msi.c
1 /*
2  * tests for Microsoft Installer functionality
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_MSI 300
22
23 #include <stdio.h>
24 #include <windows.h>
25 #include <msi.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <sddl.h>
29
30 #include "wine/test.h"
31
32 static const char msifile[] = "winetest.msi";
33
34 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
35 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
36 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
37
38 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
39     (LPCSTR, LPCSTR, LPSTR, DWORD*);
40 static UINT (WINAPI *pMsiGetFileHashA)
41     (LPCSTR, DWORD, PMSIFILEHASHINFO);
42 static UINT (WINAPI *pMsiGetProductInfoExA)
43     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
44 static UINT (WINAPI *pMsiOpenPackageExA)
45     (LPCSTR, DWORD, MSIHANDLE*);
46 static UINT (WINAPI *pMsiOpenPackageExW)
47     (LPCWSTR, DWORD, MSIHANDLE*);
48 static UINT (WINAPI *pMsiEnumPatchesExA)
49     (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
50     MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
51 static UINT (WINAPI *pMsiQueryComponentStateA)
52     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
53 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
54     (LPCSTR, LPCSTR ,DWORD, DWORD);
55 static UINT (WINAPI *pMsiGetPatchInfoExA)
56     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
57
58 static void init_functionpointers(void)
59 {
60     HMODULE hmsi = GetModuleHandleA("msi.dll");
61     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
62     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
63
64 #define GET_PROC(dll, func) \
65     p ## func = (void *)GetProcAddress(dll, #func); \
66     if(!p ## func) \
67       trace("GetProcAddress(%s) failed\n", #func);
68
69     GET_PROC(hmsi, MsiGetComponentPathA)
70     GET_PROC(hmsi, MsiGetFileHashA)
71     GET_PROC(hmsi, MsiGetProductInfoExA)
72     GET_PROC(hmsi, MsiOpenPackageExA)
73     GET_PROC(hmsi, MsiOpenPackageExW)
74     GET_PROC(hmsi, MsiEnumPatchesExA)
75     GET_PROC(hmsi, MsiQueryComponentStateA)
76     GET_PROC(hmsi, MsiUseFeatureExA)
77     GET_PROC(hmsi, MsiGetPatchInfoExA)
78
79     GET_PROC(hadvapi32, ConvertSidToStringSidA)
80     GET_PROC(hadvapi32, RegDeleteKeyExA)
81     GET_PROC(hkernel32, IsWow64Process)
82
83 #undef GET_PROC
84 }
85
86 static UINT run_query(MSIHANDLE hdb, const char *query)
87 {
88     MSIHANDLE hview = 0;
89     UINT r;
90
91     r = MsiDatabaseOpenView(hdb, query, &hview);
92     if (r != ERROR_SUCCESS)
93         return r;
94
95     r = MsiViewExecute(hview, 0);
96     if (r == ERROR_SUCCESS)
97         r = MsiViewClose(hview);
98     MsiCloseHandle(hview);
99     return r;
100 }
101
102 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
103 {
104     UINT res;
105     MSIHANDLE suminfo;
106
107     /* build summary info */
108     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
109     ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
110
111     res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
112                                     "Installation Database");
113     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
114
115     res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
116                                     "Installation Database");
117     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
118
119     res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
120                                     "Wine Hackers");
121     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
122
123     res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
124                                     ";1033");
125     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
126
127     res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
128                                     "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
129     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
130
131     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
132     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
133
134     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
135     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
136
137     res = MsiSummaryInfoPersist(suminfo);
138     ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
139
140     res = MsiCloseHandle(suminfo);
141     ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
142
143     return res;
144 }
145
146 static MSIHANDLE create_package_db(LPSTR prodcode)
147 {
148     MSIHANDLE hdb = 0;
149     CHAR query[MAX_PATH];
150     UINT res;
151
152     DeleteFile(msifile);
153
154     /* create an empty database */
155     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
156     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
157     if (res != ERROR_SUCCESS)
158         return hdb;
159
160     res = MsiDatabaseCommit(hdb);
161     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
162
163     set_summary_info(hdb, prodcode);
164
165     res = run_query(hdb,
166             "CREATE TABLE `Directory` ( "
167             "`Directory` CHAR(255) NOT NULL, "
168             "`Directory_Parent` CHAR(255), "
169             "`DefaultDir` CHAR(255) NOT NULL "
170             "PRIMARY KEY `Directory`)");
171     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
172
173     res = run_query(hdb,
174             "CREATE TABLE `Property` ( "
175             "`Property` CHAR(72) NOT NULL, "
176             "`Value` CHAR(255) "
177             "PRIMARY KEY `Property`)");
178     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
179
180     sprintf(query, "INSERT INTO `Property` "
181             "(`Property`, `Value`) "
182             "VALUES( 'ProductCode', '%s' )", prodcode);
183     res = run_query(hdb, query);
184     ok(res == ERROR_SUCCESS , "Failed\n");
185
186     res = MsiDatabaseCommit(hdb);
187     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
188
189     return hdb;
190 }
191
192 static void test_usefeature(void)
193 {
194     INSTALLSTATE r;
195
196     if (!pMsiUseFeatureExA)
197     {
198         win_skip("MsiUseFeatureExA not implemented\n");
199         return;
200     }
201
202     r = MsiQueryFeatureState(NULL,NULL);
203     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
204
205     r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
206     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
207
208     r = pMsiUseFeatureExA(NULL,NULL,0,0);
209     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
210
211     r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
212     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
213
214     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
215                          NULL, -2, 0 );
216     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
217
218     r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}", 
219                          "WORDVIEWFiles", -2, 0 );
220     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
221
222     r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}", 
223                          "WORDVIEWFiles", -2, 0 );
224     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
225
226     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
227                          "WORDVIEWFiles", -2, 1 );
228     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
229 }
230
231 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
232 {
233     if (pRegDeleteKeyExA)
234         return pRegDeleteKeyExA( key, subkey, access, 0 );
235     return RegDeleteKeyA( key, subkey );
236 }
237
238 static void test_null(void)
239 {
240     MSIHANDLE hpkg;
241     UINT r;
242     HKEY hkey;
243     DWORD dwType, cbData;
244     LPBYTE lpData = NULL;
245     INSTALLSTATE state;
246     REGSAM access = KEY_ALL_ACCESS;
247     BOOL wow64;
248
249     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
250         access |= KEY_WOW64_64KEY;
251
252     r = pMsiOpenPackageExW(NULL, 0, &hpkg);
253     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
254
255     state = MsiQueryProductStateW(NULL);
256     ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
257
258     r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
259     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
260
261     r = MsiConfigureFeatureW(NULL, NULL, 0);
262     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
263
264     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
265     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
266
267     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
268     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
269
270     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
271     ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
272
273     /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
274      * necessary registry values */
275
276     /* empty product string */
277     r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
278     if (r == ERROR_ACCESS_DENIED)
279     {
280         skip("Not enough rights to perform tests\n");
281         return;
282     }
283     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
284
285     r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
286     ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
287     if ( r == ERROR_SUCCESS )
288     {
289         lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
290         if (!lpData)
291             skip("Out of memory\n");
292         else
293         {
294             r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
295             ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
296         }
297     }
298
299     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
300     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
301
302     r = MsiGetProductInfoA("", "", NULL, NULL);
303     ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
304
305     if (lpData)
306     {
307         r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
308         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
309
310         HeapFree(GetProcessHeap(), 0, lpData);
311     }
312     else
313     {
314         r = RegDeleteValueA(hkey, NULL);
315         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
316     }
317
318     r = RegCloseKey(hkey);
319     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
320
321     /* empty attribute */
322     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
323                         0, NULL, 0, access, NULL, &hkey, NULL);
324     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
325
326     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
327     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
328
329     r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
330     ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
331
332     r = RegCloseKey(hkey);
333     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
334
335     r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
336                    access & KEY_WOW64_64KEY);
337     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
338 }
339
340 static void test_getcomponentpath(void)
341 {
342     INSTALLSTATE r;
343     char buffer[0x100];
344     DWORD sz;
345
346     if(!pMsiGetComponentPathA)
347         return;
348
349     r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
350     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
351
352     r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
353     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
354
355     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
356     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
357
358     sz = sizeof buffer;
359     buffer[0]=0;
360     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
361     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
362
363     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
364         "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
365     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
366
367     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
368         "{00000000-0000-0000-0000-00000000}", buffer, &sz );
369     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
370
371     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
372         "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
373     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
374
375     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
376                             "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
377     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
378 }
379
380 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
381 {
382     HANDLE file;
383     DWORD written;
384
385     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
386     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
387     WriteFile(file, data, strlen(data), &written, NULL);
388
389     if (size)
390     {
391         SetFilePointer(file, size, NULL, FILE_BEGIN);
392         SetEndOfFile(file);
393     }
394
395     CloseHandle(file);
396 }
397
398 #define HASHSIZE sizeof(MSIFILEHASHINFO)
399
400 static const struct
401 {
402     LPCSTR data;
403     DWORD size;
404     MSIFILEHASHINFO hash;
405 } hash_data[] =
406 {
407     { "abc", 0,
408       { HASHSIZE,
409         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
410       },
411     },
412
413     { "C:\\Program Files\\msitest\\caesar\n", 0,
414       { HASHSIZE,
415         { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
416       },
417     },
418
419     { "C:\\Program Files\\msitest\\caesar\n", 500,
420       { HASHSIZE,
421         { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
422       },
423     },
424 };
425
426 static void test_MsiGetFileHash(void)
427 {
428     const char name[] = "msitest.bin";
429     UINT r;
430     MSIFILEHASHINFO hash;
431     DWORD i;
432
433     if (!pMsiGetFileHashA)
434     {
435         win_skip("MsiGetFileHash not implemented\n");
436         return;
437     }
438
439     hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
440
441     /* szFilePath is NULL */
442     r = pMsiGetFileHashA(NULL, 0, &hash);
443     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
444
445     /* szFilePath is empty */
446     r = pMsiGetFileHashA("", 0, &hash);
447     ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
448        "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
449
450     /* szFilePath is nonexistent */
451     r = pMsiGetFileHashA(name, 0, &hash);
452     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
453
454     /* dwOptions is non-zero */
455     r = pMsiGetFileHashA(name, 1, &hash);
456     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
457
458     /* pHash.dwFileHashInfoSize is not correct */
459     hash.dwFileHashInfoSize = 0;
460     r = pMsiGetFileHashA(name, 0, &hash);
461     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
462
463     /* pHash is NULL */
464     r = pMsiGetFileHashA(name, 0, NULL);
465     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
466
467     for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
468     {
469         int ret;
470
471         create_file(name, hash_data[i].data, hash_data[i].size);
472
473         memset(&hash, 0, sizeof(MSIFILEHASHINFO));
474         hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
475
476         r = pMsiGetFileHashA(name, 0, &hash);
477         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
478
479         ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
480         ok(ret == 0 ||
481            broken(ret != 0), /* win95 */
482            "Hash incorrect\n");
483
484         DeleteFile(name);
485     }
486 }
487
488 /* copied from dlls/msi/registry.c */
489 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
490 {
491     DWORD i,n=1;
492     GUID guid;
493
494     if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
495         return FALSE;
496
497     for(i=0; i<8; i++)
498         out[7-i] = in[n++];
499     n++;
500     for(i=0; i<4; i++)
501         out[11-i] = in[n++];
502     n++;
503     for(i=0; i<4; i++)
504         out[15-i] = in[n++];
505     n++;
506     for(i=0; i<2; i++)
507     {
508         out[17+i*2] = in[n++];
509         out[16+i*2] = in[n++];
510     }
511     n++;
512     for( ; i<8; i++)
513     {
514         out[17+i*2] = in[n++];
515         out[16+i*2] = in[n++];
516     }
517     out[32]=0;
518     return TRUE;
519 }
520
521 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
522 {
523     WCHAR guidW[MAX_PATH];
524     WCHAR squashedW[MAX_PATH];
525     GUID guid;
526     HRESULT hr;
527     int size;
528
529     hr = CoCreateGuid(&guid);
530     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
531
532     size = StringFromGUID2(&guid, guidW, MAX_PATH);
533     ok(size == 39, "Expected 39, got %d\n", hr);
534
535     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
536     squash_guid(guidW, squashedW);
537     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
538 }
539
540 static void get_user_sid(LPSTR *usersid)
541 {
542     HANDLE token;
543     DWORD size;
544     PTOKEN_USER user;
545
546     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
547
548     size = 0;
549     GetTokenInformation(token, TokenUser, NULL, size, &size);
550     user = HeapAlloc(GetProcessHeap(), 0, size);
551
552     GetTokenInformation(token, TokenUser, user, size, &size);
553     pConvertSidToStringSidA(user->User.Sid, usersid);
554
555     HeapFree(GetProcessHeap(), 0, user);
556     CloseHandle(token);
557 }
558
559 static void test_MsiQueryProductState(void)
560 {
561     CHAR prodcode[MAX_PATH];
562     CHAR prod_squashed[MAX_PATH];
563     CHAR keypath[MAX_PATH*2];
564     LPSTR usersid;
565     INSTALLSTATE state;
566     LONG res;
567     HKEY userkey, localkey, props;
568     HKEY prodkey;
569     DWORD data;
570     REGSAM access = KEY_ALL_ACCESS;
571     BOOL wow64;
572
573     create_test_guid(prodcode, prod_squashed);
574     get_user_sid(&usersid);
575
576     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
577         access |= KEY_WOW64_64KEY;
578
579     /* NULL prodcode */
580     state = MsiQueryProductStateA(NULL);
581     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
582
583     /* empty prodcode */
584     state = MsiQueryProductStateA("");
585     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
586
587     /* garbage prodcode */
588     state = MsiQueryProductStateA("garbage");
589     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
590
591     /* guid without brackets */
592     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
593     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
594
595     /* guid with brackets */
596     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
597     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
598
599     /* same length as guid, but random */
600     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
601     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
602
603     /* MSIINSTALLCONTEXT_USERUNMANAGED */
604
605     state = MsiQueryProductStateA(prodcode);
606     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
607
608     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
609     lstrcatA(keypath, prod_squashed);
610
611     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
612     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
613
614     /* user product key exists */
615     state = MsiQueryProductStateA(prodcode);
616     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
617
618     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
619     lstrcatA(keypath, prodcode);
620
621     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
622     if (res == ERROR_ACCESS_DENIED)
623     {
624         skip("Not enough rights to perform tests\n");
625         RegDeleteKeyA(userkey, "");
626         LocalFree(usersid);
627         return;
628     }
629     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
630
631     /* local uninstall key exists */
632     state = MsiQueryProductStateA(prodcode);
633     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
634
635     data = 1;
636     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
637     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
638
639     /* WindowsInstaller value exists */
640     state = MsiQueryProductStateA(prodcode);
641     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
642
643     RegDeleteValueA(localkey, "WindowsInstaller");
644     delete_key(localkey, "", access & KEY_WOW64_64KEY);
645
646     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
647     lstrcatA(keypath, usersid);
648     lstrcatA(keypath, "\\Products\\");
649     lstrcatA(keypath, prod_squashed);
650
651     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
653
654     /* local product key exists */
655     state = MsiQueryProductStateA(prodcode);
656     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
657
658     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
659     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
660
661     /* install properties key exists */
662     state = MsiQueryProductStateA(prodcode);
663     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
664
665     data = 1;
666     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
668
669     /* WindowsInstaller value exists */
670     state = MsiQueryProductStateA(prodcode);
671     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
672
673     data = 2;
674     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
675     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
676
677     /* WindowsInstaller value is not 1 */
678     state = MsiQueryProductStateA(prodcode);
679     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
680
681     RegDeleteKeyA(userkey, "");
682
683     /* user product key does not exist */
684     state = MsiQueryProductStateA(prodcode);
685     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
686
687     RegDeleteValueA(props, "WindowsInstaller");
688     delete_key(props, "", access & KEY_WOW64_64KEY);
689     RegCloseKey(props);
690     delete_key(localkey, "", access & KEY_WOW64_64KEY);
691     RegCloseKey(localkey);
692     RegDeleteKeyA(userkey, "");
693     RegCloseKey(userkey);
694
695     /* MSIINSTALLCONTEXT_USERMANAGED */
696
697     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
698     lstrcatA(keypath, usersid);
699     lstrcatA(keypath, "\\Installer\\Products\\");
700     lstrcatA(keypath, prod_squashed);
701
702     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
703     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
704
705     state = MsiQueryProductStateA(prodcode);
706     ok(state == INSTALLSTATE_ADVERTISED,
707        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
708
709     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
710     lstrcatA(keypath, usersid);
711     lstrcatA(keypath, "\\Products\\");
712     lstrcatA(keypath, prod_squashed);
713
714     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
715     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
716
717     state = MsiQueryProductStateA(prodcode);
718     ok(state == INSTALLSTATE_ADVERTISED,
719        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
720
721     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
723
724     state = MsiQueryProductStateA(prodcode);
725     ok(state == INSTALLSTATE_ADVERTISED,
726        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
727
728     data = 1;
729     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
730     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
731
732     /* WindowsInstaller value exists */
733     state = MsiQueryProductStateA(prodcode);
734     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
735
736     RegDeleteValueA(props, "WindowsInstaller");
737     delete_key(props, "", access & KEY_WOW64_64KEY);
738     RegCloseKey(props);
739     delete_key(localkey, "", access & KEY_WOW64_64KEY);
740     RegCloseKey(localkey);
741     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
742     RegCloseKey(prodkey);
743
744     /* MSIINSTALLCONTEXT_MACHINE */
745
746     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
747     lstrcatA(keypath, prod_squashed);
748
749     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
750     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
751
752     state = MsiQueryProductStateA(prodcode);
753     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
754
755     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
756     lstrcatA(keypath, "S-1-5-18\\Products\\");
757     lstrcatA(keypath, prod_squashed);
758
759     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
761
762     state = MsiQueryProductStateA(prodcode);
763     ok(state == INSTALLSTATE_ADVERTISED,
764        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
765
766     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
767     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
768
769     state = MsiQueryProductStateA(prodcode);
770     ok(state == INSTALLSTATE_ADVERTISED,
771        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
772
773     data = 1;
774     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
775     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
776
777     /* WindowsInstaller value exists */
778     state = MsiQueryProductStateA(prodcode);
779     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
780
781     RegDeleteValueA(props, "WindowsInstaller");
782     delete_key(props, "", access & KEY_WOW64_64KEY);
783     RegCloseKey(props);
784     delete_key(localkey, "", access & KEY_WOW64_64KEY);
785     RegCloseKey(localkey);
786     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
787     RegCloseKey(prodkey);
788
789     LocalFree(usersid);
790 }
791
792 static const char table_enc85[] =
793 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
794 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
795 "yz{}~";
796
797 /*
798  *  Encodes a base85 guid given a GUID pointer
799  *  Caller should provide a 21 character buffer for the encoded string.
800  */
801 static void encode_base85_guid( GUID *guid, LPWSTR str )
802 {
803     unsigned int x, *p, i;
804
805     p = (unsigned int*) guid;
806     for( i=0; i<4; i++ )
807     {
808         x = p[i];
809         *str++ = table_enc85[x%85];
810         x = x/85;
811         *str++ = table_enc85[x%85];
812         x = x/85;
813         *str++ = table_enc85[x%85];
814         x = x/85;
815         *str++ = table_enc85[x%85];
816         x = x/85;
817         *str++ = table_enc85[x%85];
818     }
819     *str = 0;
820 }
821
822 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
823 {
824     WCHAR guidW[MAX_PATH];
825     WCHAR base85W[MAX_PATH];
826     WCHAR squashedW[MAX_PATH];
827     GUID guid;
828     HRESULT hr;
829     int size;
830
831     hr = CoCreateGuid(&guid);
832     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
833
834     size = StringFromGUID2(&guid, guidW, MAX_PATH);
835     ok(size == 39, "Expected 39, got %d\n", hr);
836
837     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
838     encode_base85_guid(&guid, base85W);
839     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
840     squash_guid(guidW, squashedW);
841     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
842 }
843
844 static void test_MsiQueryFeatureState(void)
845 {
846     HKEY userkey, localkey, compkey, compkey2;
847     CHAR prodcode[MAX_PATH];
848     CHAR prod_squashed[MAX_PATH];
849     CHAR component[MAX_PATH];
850     CHAR comp_base85[MAX_PATH];
851     CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
852     CHAR keypath[MAX_PATH*2];
853     INSTALLSTATE state;
854     LPSTR usersid;
855     LONG res;
856     REGSAM access = KEY_ALL_ACCESS;
857     BOOL wow64;
858
859     create_test_guid(prodcode, prod_squashed);
860     compose_base85_guid(component, comp_base85, comp_squashed);
861     compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
862     get_user_sid(&usersid);
863
864     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
865         access |= KEY_WOW64_64KEY;
866
867     /* NULL prodcode */
868     state = MsiQueryFeatureStateA(NULL, "feature");
869     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
870
871     /* empty prodcode */
872     state = MsiQueryFeatureStateA("", "feature");
873     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
874
875     /* garbage prodcode */
876     state = MsiQueryFeatureStateA("garbage", "feature");
877     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
878
879     /* guid without brackets */
880     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
881     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
882
883     /* guid with brackets */
884     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
885     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
886
887     /* same length as guid, but random */
888     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
889     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
890
891     /* NULL szFeature */
892     state = MsiQueryFeatureStateA(prodcode, NULL);
893     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
894
895     /* empty szFeature */
896     state = MsiQueryFeatureStateA(prodcode, "");
897     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
898
899     /* feature key does not exist yet */
900     state = MsiQueryFeatureStateA(prodcode, "feature");
901     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
902
903     /* MSIINSTALLCONTEXT_USERUNMANAGED */
904
905     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
906     lstrcatA(keypath, prod_squashed);
907
908     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
909     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
910
911     /* feature key exists */
912     state = MsiQueryFeatureStateA(prodcode, "feature");
913     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
914
915     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
917
918     /* feature value exists */
919     state = MsiQueryFeatureStateA(prodcode, "feature");
920     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
921
922     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
923     lstrcatA(keypath, usersid);
924     lstrcatA(keypath, "\\Products\\");
925     lstrcatA(keypath, prod_squashed);
926     lstrcatA(keypath, "\\Features");
927
928     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
929     if (res == ERROR_ACCESS_DENIED)
930     {
931         skip("Not enough rights to perform tests\n");
932         RegDeleteKeyA(userkey, "");
933         RegCloseKey(userkey);
934         LocalFree(usersid);
935         return;
936     }
937     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
938
939     /* userdata features key exists */
940     state = MsiQueryFeatureStateA(prodcode, "feature");
941     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
942
943     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
945
946     state = MsiQueryFeatureStateA(prodcode, "feature");
947     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
948
949     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
951
952     state = MsiQueryFeatureStateA(prodcode, "feature");
953     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
954
955     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
957
958     state = MsiQueryFeatureStateA(prodcode, "feature");
959     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
960
961     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
963
964     state = MsiQueryFeatureStateA(prodcode, "feature");
965     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
966
967     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
968     lstrcatA(keypath, usersid);
969     lstrcatA(keypath, "\\Components\\");
970     lstrcatA(keypath, comp_squashed);
971
972     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
973     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
974
975     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
976     lstrcatA(keypath, usersid);
977     lstrcatA(keypath, "\\Components\\");
978     lstrcatA(keypath, comp_squashed2);
979
980     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
981     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
982
983     state = MsiQueryFeatureStateA(prodcode, "feature");
984     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
985
986     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
987     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
988
989     state = MsiQueryFeatureStateA(prodcode, "feature");
990     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
991
992     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
993     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
994
995     state = MsiQueryFeatureStateA(prodcode, "feature");
996     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
997
998     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
999     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1000
1001     /* INSTALLSTATE_LOCAL */
1002     state = MsiQueryFeatureStateA(prodcode, "feature");
1003     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1004
1005     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1006     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1007
1008     /* INSTALLSTATE_SOURCE */
1009     state = MsiQueryFeatureStateA(prodcode, "feature");
1010     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1011
1012     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1014
1015     /* bad INSTALLSTATE_SOURCE */
1016     state = MsiQueryFeatureStateA(prodcode, "feature");
1017     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1018
1019     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1020     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1021
1022     /* INSTALLSTATE_SOURCE */
1023     state = MsiQueryFeatureStateA(prodcode, "feature");
1024     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1025
1026     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1027     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1028
1029     /* bad INSTALLSTATE_SOURCE */
1030     state = MsiQueryFeatureStateA(prodcode, "feature");
1031     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1032
1033     RegDeleteValueA(compkey, prod_squashed);
1034     RegDeleteValueA(compkey2, prod_squashed);
1035     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1036     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1037     RegDeleteValueA(localkey, "feature");
1038     RegDeleteValueA(userkey, "feature");
1039     RegDeleteKeyA(userkey, "");
1040     RegCloseKey(compkey);
1041     RegCloseKey(compkey2);
1042     RegCloseKey(localkey);
1043     RegCloseKey(userkey);
1044
1045     /* MSIINSTALLCONTEXT_USERMANAGED */
1046
1047     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1048     lstrcatA(keypath, usersid);
1049     lstrcatA(keypath, "\\Installer\\Features\\");
1050     lstrcatA(keypath, prod_squashed);
1051
1052     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1054
1055     /* feature key exists */
1056     state = MsiQueryFeatureStateA(prodcode, "feature");
1057     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1058
1059     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1061
1062     /* feature value exists */
1063     state = MsiQueryFeatureStateA(prodcode, "feature");
1064     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1065
1066     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1067     lstrcatA(keypath, usersid);
1068     lstrcatA(keypath, "\\Products\\");
1069     lstrcatA(keypath, prod_squashed);
1070     lstrcatA(keypath, "\\Features");
1071
1072     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1073     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1074
1075     /* userdata features key exists */
1076     state = MsiQueryFeatureStateA(prodcode, "feature");
1077     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1078
1079     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1081
1082     state = MsiQueryFeatureStateA(prodcode, "feature");
1083     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1084
1085     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1087
1088     state = MsiQueryFeatureStateA(prodcode, "feature");
1089     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1090
1091     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1093
1094     state = MsiQueryFeatureStateA(prodcode, "feature");
1095     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1096
1097     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1098     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1099
1100     state = MsiQueryFeatureStateA(prodcode, "feature");
1101     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1102
1103     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1104     lstrcatA(keypath, usersid);
1105     lstrcatA(keypath, "\\Components\\");
1106     lstrcatA(keypath, comp_squashed);
1107
1108     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1110
1111     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1112     lstrcatA(keypath, usersid);
1113     lstrcatA(keypath, "\\Components\\");
1114     lstrcatA(keypath, comp_squashed2);
1115
1116     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1117     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1118
1119     state = MsiQueryFeatureStateA(prodcode, "feature");
1120     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1121
1122     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1124
1125     state = MsiQueryFeatureStateA(prodcode, "feature");
1126     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1127
1128     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1130
1131     state = MsiQueryFeatureStateA(prodcode, "feature");
1132     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1133
1134     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1136
1137     state = MsiQueryFeatureStateA(prodcode, "feature");
1138     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1139
1140     RegDeleteValueA(compkey, prod_squashed);
1141     RegDeleteValueA(compkey2, prod_squashed);
1142     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1143     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1144     RegDeleteValueA(localkey, "feature");
1145     RegDeleteValueA(userkey, "feature");
1146     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1147     RegCloseKey(compkey);
1148     RegCloseKey(compkey2);
1149     RegCloseKey(localkey);
1150     RegCloseKey(userkey);
1151
1152     /* MSIINSTALLCONTEXT_MACHINE */
1153
1154     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1155     lstrcatA(keypath, prod_squashed);
1156
1157     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1159
1160     /* feature key exists */
1161     state = MsiQueryFeatureStateA(prodcode, "feature");
1162     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1163
1164     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1166
1167     /* feature value exists */
1168     state = MsiQueryFeatureStateA(prodcode, "feature");
1169     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1170
1171     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1172     lstrcatA(keypath, "S-1-5-18\\Products\\");
1173     lstrcatA(keypath, prod_squashed);
1174     lstrcatA(keypath, "\\Features");
1175
1176     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1177     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1178
1179     /* userdata features key exists */
1180     state = MsiQueryFeatureStateA(prodcode, "feature");
1181     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1182
1183     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1184     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1185
1186     state = MsiQueryFeatureStateA(prodcode, "feature");
1187     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1188
1189     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1190     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1191
1192     state = MsiQueryFeatureStateA(prodcode, "feature");
1193     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1194
1195     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1197
1198     state = MsiQueryFeatureStateA(prodcode, "feature");
1199     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1200
1201     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1203
1204     state = MsiQueryFeatureStateA(prodcode, "feature");
1205     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1206
1207     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1208     lstrcatA(keypath, "S-1-5-18\\Components\\");
1209     lstrcatA(keypath, comp_squashed);
1210
1211     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1213
1214     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1215     lstrcatA(keypath, "S-1-5-18\\Components\\");
1216     lstrcatA(keypath, comp_squashed2);
1217
1218     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1219     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1220
1221     state = MsiQueryFeatureStateA(prodcode, "feature");
1222     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1223
1224     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1225     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1226
1227     state = MsiQueryFeatureStateA(prodcode, "feature");
1228     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1229
1230     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1231     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1232
1233     state = MsiQueryFeatureStateA(prodcode, "feature");
1234     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1235
1236     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1238
1239     state = MsiQueryFeatureStateA(prodcode, "feature");
1240     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1241
1242     RegDeleteValueA(compkey, prod_squashed);
1243     RegDeleteValueA(compkey2, prod_squashed);
1244     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1245     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1246     RegDeleteValueA(localkey, "feature");
1247     RegDeleteValueA(userkey, "feature");
1248     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1249     RegCloseKey(compkey);
1250     RegCloseKey(compkey2);
1251     RegCloseKey(localkey);
1252     RegCloseKey(userkey);
1253     LocalFree(usersid);
1254 }
1255
1256 static void test_MsiQueryComponentState(void)
1257 {
1258     HKEY compkey, prodkey;
1259     CHAR prodcode[MAX_PATH];
1260     CHAR prod_squashed[MAX_PATH];
1261     CHAR component[MAX_PATH];
1262     CHAR comp_base85[MAX_PATH];
1263     CHAR comp_squashed[MAX_PATH];
1264     CHAR keypath[MAX_PATH];
1265     INSTALLSTATE state;
1266     LPSTR usersid;
1267     LONG res;
1268     UINT r;
1269     REGSAM access = KEY_ALL_ACCESS;
1270     BOOL wow64;
1271
1272     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1273
1274     if (!pMsiQueryComponentStateA)
1275     {
1276         win_skip("MsiQueryComponentStateA not implemented\n");
1277         return;
1278     }
1279
1280     create_test_guid(prodcode, prod_squashed);
1281     compose_base85_guid(component, comp_base85, comp_squashed);
1282     get_user_sid(&usersid);
1283
1284     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
1285         access |= KEY_WOW64_64KEY;
1286
1287     /* NULL szProductCode */
1288     state = MAGIC_ERROR;
1289     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1290     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1291     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1292
1293     /* empty szProductCode */
1294     state = MAGIC_ERROR;
1295     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1296     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1297     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1298
1299     /* random szProductCode */
1300     state = MAGIC_ERROR;
1301     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1302     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1303     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1304
1305     /* GUID-length szProductCode */
1306     state = MAGIC_ERROR;
1307     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1308     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1309     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1310
1311     /* GUID-length with brackets */
1312     state = MAGIC_ERROR;
1313     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1314     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1315     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1316
1317     /* actual GUID */
1318     state = MAGIC_ERROR;
1319     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1320     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1321     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1322
1323     state = MAGIC_ERROR;
1324     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1325     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1326     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1327
1328     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1329     lstrcatA(keypath, prod_squashed);
1330
1331     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1332     if (res == ERROR_ACCESS_DENIED)
1333     {
1334         skip("Not enough rights to perform tests\n");
1335         LocalFree(usersid);
1336         return;
1337     }
1338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1339
1340     state = MAGIC_ERROR;
1341     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1342     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1343     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1344
1345     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1346     RegCloseKey(prodkey);
1347
1348     /* create local system product key */
1349     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1350     lstrcatA(keypath, prod_squashed);
1351     lstrcatA(keypath, "\\InstallProperties");
1352
1353     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1355
1356     /* local system product key exists */
1357     state = MAGIC_ERROR;
1358     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1359     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1360     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1361
1362     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1363     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1364
1365     /* LocalPackage value exists */
1366     state = MAGIC_ERROR;
1367     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1368     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1369     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1370
1371     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1372     lstrcatA(keypath, comp_squashed);
1373
1374     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1375     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1376
1377     /* component key exists */
1378     state = MAGIC_ERROR;
1379     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1380     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1381     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1382
1383     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1384     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1385
1386     /* component\product exists */
1387     state = MAGIC_ERROR;
1388     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1390     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1391        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1392
1393     /* NULL component, product exists */
1394     state = MAGIC_ERROR;
1395     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1396     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1397     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1398
1399     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1400     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1401
1402     /* INSTALLSTATE_LOCAL */
1403     state = MAGIC_ERROR;
1404     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1405     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1406     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1407
1408     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1409     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1410
1411     /* INSTALLSTATE_SOURCE */
1412     state = MAGIC_ERROR;
1413     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1414     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1415     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1416
1417     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1418     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1419
1420     /* bad INSTALLSTATE_SOURCE */
1421     state = MAGIC_ERROR;
1422     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1423     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1424     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1425
1426     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1427     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1428
1429     /* INSTALLSTATE_SOURCE */
1430     state = MAGIC_ERROR;
1431     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1432     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1433     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1434
1435     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1436     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1437
1438     /* bad INSTALLSTATE_SOURCE */
1439     state = MAGIC_ERROR;
1440     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1442     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1443
1444     RegDeleteValueA(prodkey, "LocalPackage");
1445     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1446     RegDeleteValueA(compkey, prod_squashed);
1447     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1448     RegCloseKey(prodkey);
1449     RegCloseKey(compkey);
1450
1451     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1452
1453     state = MAGIC_ERROR;
1454     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1455     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1456     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1457
1458     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1459     lstrcatA(keypath, prod_squashed);
1460
1461     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1462     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1463
1464     state = MAGIC_ERROR;
1465     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1466     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1467     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1468
1469     RegDeleteKeyA(prodkey, "");
1470     RegCloseKey(prodkey);
1471
1472     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1473     lstrcatA(keypath, usersid);
1474     lstrcatA(keypath, "\\Products\\");
1475     lstrcatA(keypath, prod_squashed);
1476     lstrcatA(keypath, "\\InstallProperties");
1477
1478     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1479     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1480
1481     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1482     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1483
1484     RegCloseKey(prodkey);
1485
1486     state = MAGIC_ERROR;
1487     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1488     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1489     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1490
1491     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1492     lstrcatA(keypath, usersid);
1493     lstrcatA(keypath, "\\Components\\");
1494     lstrcatA(keypath, comp_squashed);
1495
1496     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1497     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1498
1499     /* component key exists */
1500     state = MAGIC_ERROR;
1501     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1502     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1503     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1504
1505     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1506     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1507
1508     /* component\product exists */
1509     state = MAGIC_ERROR;
1510     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1511     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1512     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1513        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1514
1515     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1516     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1517
1518     state = MAGIC_ERROR;
1519     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1520     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1521     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1522
1523     /* MSIINSTALLCONTEXT_USERMANAGED */
1524
1525     state = MAGIC_ERROR;
1526     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1527     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1528     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1529
1530     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1531     lstrcatA(keypath, prod_squashed);
1532
1533     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1534     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1535
1536     state = MAGIC_ERROR;
1537     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1538     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1539     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1540
1541     RegDeleteKeyA(prodkey, "");
1542     RegCloseKey(prodkey);
1543
1544     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1545     lstrcatA(keypath, usersid);
1546     lstrcatA(keypath, "\\Installer\\Products\\");
1547     lstrcatA(keypath, prod_squashed);
1548
1549     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1551
1552     state = MAGIC_ERROR;
1553     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1554     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1555     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1556
1557     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1558     RegCloseKey(prodkey);
1559
1560     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1561     lstrcatA(keypath, usersid);
1562     lstrcatA(keypath, "\\Products\\");
1563     lstrcatA(keypath, prod_squashed);
1564     lstrcatA(keypath, "\\InstallProperties");
1565
1566     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1567     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1568
1569     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1570     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1571
1572     state = MAGIC_ERROR;
1573     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1574     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1575     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1576
1577     RegDeleteValueA(prodkey, "LocalPackage");
1578     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1579     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1580     RegDeleteValueA(compkey, prod_squashed);
1581     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1582     RegCloseKey(prodkey);
1583     RegCloseKey(compkey);
1584     LocalFree(usersid);
1585 }
1586
1587 static void test_MsiGetComponentPath(void)
1588 {
1589     HKEY compkey, prodkey, installprop;
1590     CHAR prodcode[MAX_PATH];
1591     CHAR prod_squashed[MAX_PATH];
1592     CHAR component[MAX_PATH];
1593     CHAR comp_base85[MAX_PATH];
1594     CHAR comp_squashed[MAX_PATH];
1595     CHAR keypath[MAX_PATH];
1596     CHAR path[MAX_PATH];
1597     INSTALLSTATE state;
1598     LPSTR usersid;
1599     DWORD size, val;
1600     REGSAM access = KEY_ALL_ACCESS;
1601     BOOL wow64;
1602     LONG res;
1603
1604     create_test_guid(prodcode, prod_squashed);
1605     compose_base85_guid(component, comp_base85, comp_squashed);
1606     get_user_sid(&usersid);
1607
1608     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
1609         access |= KEY_WOW64_64KEY;
1610
1611     /* NULL szProduct */
1612     size = MAX_PATH;
1613     state = MsiGetComponentPathA(NULL, component, path, &size);
1614     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1615     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1616
1617     /* NULL szComponent */
1618     size = MAX_PATH;
1619     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1620     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1621     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1622
1623     size = MAX_PATH;
1624     state = MsiLocateComponentA(NULL, path, &size);
1625     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1626     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1627
1628     /* NULL lpPathBuf */
1629     size = MAX_PATH;
1630     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1631     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1632     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1633
1634     size = MAX_PATH;
1635     state = MsiLocateComponentA(component, NULL, &size);
1636     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1637     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1638
1639     /* NULL pcchBuf */
1640     size = MAX_PATH;
1641     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1642     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1643     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1644
1645     size = MAX_PATH;
1646     state = MsiLocateComponentA(component, path, NULL);
1647     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1648     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1649
1650     /* all params valid */
1651     size = MAX_PATH;
1652     state = MsiGetComponentPathA(prodcode, component, path, &size);
1653     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1654     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1655
1656     size = MAX_PATH;
1657     state = MsiLocateComponentA(component, path, &size);
1658     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1659     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1660
1661     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1662     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1663     lstrcatA(keypath, comp_squashed);
1664
1665     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1666     if (res == ERROR_ACCESS_DENIED)
1667     {
1668         skip("Not enough rights to perform tests\n");
1669         LocalFree(usersid);
1670         return;
1671     }
1672     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1673
1674     /* local system component key exists */
1675     size = MAX_PATH;
1676     state = MsiGetComponentPathA(prodcode, component, path, &size);
1677     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1678     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1679
1680     size = MAX_PATH;
1681     state = MsiLocateComponentA(component, path, &size);
1682     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1683     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1684
1685     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1687
1688     /* product value exists */
1689     path[0] = 0;
1690     size = MAX_PATH;
1691     state = MsiGetComponentPathA(prodcode, component, path, &size);
1692     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1693     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1694     ok(size == 10, "Expected 10, got %d\n", size);
1695
1696     path[0] = 0;
1697     size = MAX_PATH;
1698     state = MsiLocateComponentA(component, path, &size);
1699     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1700     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1701     ok(size == 10, "Expected 10, got %d\n", size);
1702
1703     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1704     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1705     lstrcatA(keypath, prod_squashed);
1706     lstrcatA(keypath, "\\InstallProperties");
1707
1708     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1710
1711     val = 1;
1712     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1714
1715     /* install properties key exists */
1716     path[0] = 0;
1717     size = MAX_PATH;
1718     state = MsiGetComponentPathA(prodcode, component, path, &size);
1719     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1720     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1721     ok(size == 10, "Expected 10, got %d\n", size);
1722
1723     path[0] = 0;
1724     size = MAX_PATH;
1725     state = MsiLocateComponentA(component, path, &size);
1726     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1727     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1728     ok(size == 10, "Expected 10, got %d\n", size);
1729
1730     create_file("C:\\imapath", "C:\\imapath", 11);
1731
1732     /* file exists */
1733     path[0] = 0;
1734     size = MAX_PATH;
1735     state = MsiGetComponentPathA(prodcode, component, path, &size);
1736     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1737     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1738     ok(size == 10, "Expected 10, got %d\n", size);
1739
1740     path[0] = 0;
1741     size = MAX_PATH;
1742     state = MsiLocateComponentA(component, path, &size);
1743     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1744     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1745     ok(size == 10, "Expected 10, got %d\n", size);
1746
1747     RegDeleteValueA(compkey, prod_squashed);
1748     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1749     RegDeleteValueA(installprop, "WindowsInstaller");
1750     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1751     RegCloseKey(compkey);
1752     RegCloseKey(installprop);
1753     DeleteFileA("C:\\imapath");
1754
1755     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1756     lstrcatA(keypath, "Installer\\UserData\\");
1757     lstrcatA(keypath, usersid);
1758     lstrcatA(keypath, "\\Components\\");
1759     lstrcatA(keypath, comp_squashed);
1760
1761     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1762     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1763
1764     /* user managed component key exists */
1765     size = MAX_PATH;
1766     state = MsiGetComponentPathA(prodcode, component, path, &size);
1767     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1768     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1769
1770     size = MAX_PATH;
1771     state = MsiLocateComponentA(component, path, &size);
1772     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1773     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1774
1775     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1776     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1777
1778     /* product value exists */
1779     path[0] = 0;
1780     size = MAX_PATH;
1781     state = MsiGetComponentPathA(prodcode, component, path, &size);
1782     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1783     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1784     ok(size == 10, "Expected 10, got %d\n", size);
1785
1786     path[0] = 0;
1787     size = MAX_PATH;
1788     state = MsiLocateComponentA(component, path, &size);
1789     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1790     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1791     ok(size == 10, "Expected 10, got %d\n", size);
1792
1793     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1794     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1795     lstrcatA(keypath, prod_squashed);
1796     lstrcatA(keypath, "\\InstallProperties");
1797
1798     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1799     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1800
1801     val = 1;
1802     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1803     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1804
1805     /* install properties key exists */
1806     path[0] = 0;
1807     size = MAX_PATH;
1808     state = MsiGetComponentPathA(prodcode, component, path, &size);
1809     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1810     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1811     ok(size == 10, "Expected 10, got %d\n", size);
1812
1813     path[0] = 0;
1814     size = MAX_PATH;
1815     state = MsiLocateComponentA(component, path, &size);
1816     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1817     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1818     ok(size == 10, "Expected 10, got %d\n", size);
1819
1820     create_file("C:\\imapath", "C:\\imapath", 11);
1821
1822     /* file exists */
1823     path[0] = 0;
1824     size = MAX_PATH;
1825     state = MsiGetComponentPathA(prodcode, component, path, &size);
1826     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1827     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1828     ok(size == 10, "Expected 10, got %d\n", size);
1829
1830     path[0] = 0;
1831     size = MAX_PATH;
1832     state = MsiLocateComponentA(component, path, &size);
1833     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1834     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1835     ok(size == 10, "Expected 10, got %d\n", size);
1836
1837     RegDeleteValueA(compkey, prod_squashed);
1838     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1839     RegDeleteValueA(installprop, "WindowsInstaller");
1840     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1841     RegCloseKey(compkey);
1842     RegCloseKey(installprop);
1843     DeleteFileA("C:\\imapath");
1844
1845     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1846     lstrcatA(keypath, "Installer\\Managed\\");
1847     lstrcatA(keypath, usersid);
1848     lstrcatA(keypath, "\\Installer\\Products\\");
1849     lstrcatA(keypath, prod_squashed);
1850
1851     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1852     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1853
1854     /* user managed product key exists */
1855     size = MAX_PATH;
1856     state = MsiGetComponentPathA(prodcode, component, path, &size);
1857     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1858     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1859
1860     size = MAX_PATH;
1861     state = MsiLocateComponentA(component, path, &size);
1862     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1863     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1864
1865     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1866     lstrcatA(keypath, "Installer\\UserData\\");
1867     lstrcatA(keypath, usersid);
1868     lstrcatA(keypath, "\\Components\\");
1869     lstrcatA(keypath, comp_squashed);
1870
1871     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1872     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1873
1874     /* user managed component key exists */
1875     size = MAX_PATH;
1876     state = MsiGetComponentPathA(prodcode, component, path, &size);
1877     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1878     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1879
1880     size = MAX_PATH;
1881     state = MsiLocateComponentA(component, path, &size);
1882     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1883     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1884
1885     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1887
1888     /* product value exists */
1889     path[0] = 0;
1890     size = MAX_PATH;
1891     state = MsiGetComponentPathA(prodcode, component, path, &size);
1892     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1893     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1894     ok(size == 10, "Expected 10, got %d\n", size);
1895
1896     path[0] = 0;
1897     size = MAX_PATH;
1898     state = MsiLocateComponentA(component, path, &size);
1899     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1900     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1901     ok(size == 10, "Expected 10, got %d\n", size);
1902
1903     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1904     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1905     lstrcatA(keypath, prod_squashed);
1906     lstrcatA(keypath, "\\InstallProperties");
1907
1908     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1909     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1910
1911     val = 1;
1912     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1913     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1914
1915     /* install properties key exists */
1916     path[0] = 0;
1917     size = MAX_PATH;
1918     state = MsiGetComponentPathA(prodcode, component, path, &size);
1919     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1920     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1921     ok(size == 10, "Expected 10, got %d\n", size);
1922
1923     path[0] = 0;
1924     size = MAX_PATH;
1925     state = MsiLocateComponentA(component, path, &size);
1926     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1927     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1928     ok(size == 10, "Expected 10, got %d\n", size);
1929
1930     create_file("C:\\imapath", "C:\\imapath", 11);
1931
1932     /* file exists */
1933     path[0] = 0;
1934     size = MAX_PATH;
1935     state = MsiGetComponentPathA(prodcode, component, path, &size);
1936     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1937     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1938     ok(size == 10, "Expected 10, got %d\n", size);
1939
1940     path[0] = 0;
1941     size = MAX_PATH;
1942     state = MsiLocateComponentA(component, path, &size);
1943     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1944     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1945     ok(size == 10, "Expected 10, got %d\n", size);
1946
1947     RegDeleteValueA(compkey, prod_squashed);
1948     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1949     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1950     RegDeleteValueA(installprop, "WindowsInstaller");
1951     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1952     RegCloseKey(prodkey);
1953     RegCloseKey(compkey);
1954     RegCloseKey(installprop);
1955     DeleteFileA("C:\\imapath");
1956
1957     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1958     lstrcatA(keypath, prod_squashed);
1959
1960     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1962
1963     /* user unmanaged product key exists */
1964     size = MAX_PATH;
1965     state = MsiGetComponentPathA(prodcode, component, path, &size);
1966     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1967     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1968
1969     size = MAX_PATH;
1970     state = MsiLocateComponentA(component, path, &size);
1971     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1972     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1973
1974     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1975     lstrcatA(keypath, "Installer\\UserData\\");
1976     lstrcatA(keypath, usersid);
1977     lstrcatA(keypath, "\\Components\\");
1978     lstrcatA(keypath, comp_squashed);
1979
1980     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1981     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1982
1983     /* user unmanaged component key exists */
1984     size = MAX_PATH;
1985     state = MsiGetComponentPathA(prodcode, component, path, &size);
1986     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1987     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1988
1989     size = MAX_PATH;
1990     state = MsiLocateComponentA(component, path, &size);
1991     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1992     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1993
1994     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1996
1997     /* product value exists */
1998     path[0] = 0;
1999     size = MAX_PATH;
2000     state = MsiGetComponentPathA(prodcode, component, path, &size);
2001     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2002     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2003     ok(size == 10, "Expected 10, got %d\n", size);
2004
2005     path[0] = 0;
2006     size = MAX_PATH;
2007     state = MsiLocateComponentA(component, path, &size);
2008     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2009     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2010     ok(size == 10, "Expected 10, got %d\n", size);
2011
2012     create_file("C:\\imapath", "C:\\imapath", 11);
2013
2014     /* file exists */
2015     path[0] = 0;
2016     size = MAX_PATH;
2017     state = MsiGetComponentPathA(prodcode, component, path, &size);
2018     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2019     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2020     ok(size == 10, "Expected 10, got %d\n", size);
2021
2022     path[0] = 0;
2023     size = MAX_PATH;
2024     state = MsiLocateComponentA(component, path, &size);
2025     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2026     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2027     ok(size == 10, "Expected 10, got %d\n", size);
2028
2029     RegDeleteValueA(compkey, prod_squashed);
2030     RegDeleteKeyA(prodkey, "");
2031     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2032     RegCloseKey(prodkey);
2033     RegCloseKey(compkey);
2034     DeleteFileA("C:\\imapath");
2035
2036     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2037     lstrcatA(keypath, prod_squashed);
2038
2039     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2040     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2041
2042     /* local classes product key exists */
2043     size = MAX_PATH;
2044     state = MsiGetComponentPathA(prodcode, component, path, &size);
2045     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2046     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2047
2048     size = MAX_PATH;
2049     state = MsiLocateComponentA(component, path, &size);
2050     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2051     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2052
2053     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2054     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2055     lstrcatA(keypath, comp_squashed);
2056
2057     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2058     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2059
2060     /* local user component key exists */
2061     size = MAX_PATH;
2062     state = MsiGetComponentPathA(prodcode, component, path, &size);
2063     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2064     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2065
2066     size = MAX_PATH;
2067     state = MsiLocateComponentA(component, path, &size);
2068     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2069     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2070
2071     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2073
2074     /* product value exists */
2075     path[0] = 0;
2076     size = MAX_PATH;
2077     state = MsiGetComponentPathA(prodcode, component, path, &size);
2078     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2079     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2080     ok(size == 10, "Expected 10, got %d\n", size);
2081
2082     path[0] = 0;
2083     size = MAX_PATH;
2084     state = MsiLocateComponentA(component, path, &size);
2085     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2086     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2087     ok(size == 10, "Expected 10, got %d\n", size);
2088
2089     create_file("C:\\imapath", "C:\\imapath", 11);
2090
2091     /* file exists */
2092     path[0] = 0;
2093     size = MAX_PATH;
2094     state = MsiGetComponentPathA(prodcode, component, path, &size);
2095     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2096     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2097     ok(size == 10, "Expected 10, got %d\n", size);
2098
2099     path[0] = 0;
2100     size = MAX_PATH;
2101     state = MsiLocateComponentA(component, path, &size);
2102     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2103     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2104     ok(size == 10, "Expected 10, got %d\n", size);
2105
2106     RegDeleteValueA(compkey, prod_squashed);
2107     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2108     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2109     RegCloseKey(prodkey);
2110     RegCloseKey(compkey);
2111     DeleteFileA("C:\\imapath");
2112     LocalFree(usersid);
2113 }
2114
2115 static void test_MsiGetProductCode(void)
2116 {
2117     HKEY compkey, prodkey;
2118     CHAR prodcode[MAX_PATH];
2119     CHAR prod_squashed[MAX_PATH];
2120     CHAR prodcode2[MAX_PATH];
2121     CHAR prod2_squashed[MAX_PATH];
2122     CHAR component[MAX_PATH];
2123     CHAR comp_base85[MAX_PATH];
2124     CHAR comp_squashed[MAX_PATH];
2125     CHAR keypath[MAX_PATH];
2126     CHAR product[MAX_PATH];
2127     LPSTR usersid;
2128     LONG res;
2129     UINT r;
2130     REGSAM access = KEY_ALL_ACCESS;
2131     BOOL wow64;
2132
2133     create_test_guid(prodcode, prod_squashed);
2134     create_test_guid(prodcode2, prod2_squashed);
2135     compose_base85_guid(component, comp_base85, comp_squashed);
2136     get_user_sid(&usersid);
2137
2138     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
2139         access |= KEY_WOW64_64KEY;
2140
2141     /* szComponent is NULL */
2142     lstrcpyA(product, "prod");
2143     r = MsiGetProductCodeA(NULL, product);
2144     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2145     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2146
2147     /* szComponent is empty */
2148     lstrcpyA(product, "prod");
2149     r = MsiGetProductCodeA("", product);
2150     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2151     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2152
2153     /* garbage szComponent */
2154     lstrcpyA(product, "prod");
2155     r = MsiGetProductCodeA("garbage", product);
2156     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2157     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2158
2159     /* guid without brackets */
2160     lstrcpyA(product, "prod");
2161     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
2162     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2163     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2164
2165     /* guid with brackets */
2166     lstrcpyA(product, "prod");
2167     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
2168     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2169     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2170
2171     /* same length as guid, but random */
2172     lstrcpyA(product, "prod");
2173     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
2174     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2175     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2176
2177     /* all params correct, szComponent not published */
2178     lstrcpyA(product, "prod");
2179     r = MsiGetProductCodeA(component, product);
2180     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2181     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2182
2183     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2184     lstrcatA(keypath, "Installer\\UserData\\");
2185     lstrcatA(keypath, usersid);
2186     lstrcatA(keypath, "\\Components\\");
2187     lstrcatA(keypath, comp_squashed);
2188
2189     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2190     if (res == ERROR_ACCESS_DENIED)
2191     {
2192         skip("Not enough rights to perform tests\n");
2193         LocalFree(usersid);
2194         return;
2195     }
2196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2197
2198     /* user unmanaged component key exists */
2199     lstrcpyA(product, "prod");
2200     r = MsiGetProductCodeA(component, product);
2201     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2202     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2203
2204     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2205     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2206
2207     /* product value exists */
2208     lstrcpyA(product, "prod");
2209     r = MsiGetProductCodeA(component, product);
2210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2211     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2212
2213     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2214     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2215
2216     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2217     lstrcatA(keypath, "Installer\\Managed\\");
2218     lstrcatA(keypath, usersid);
2219     lstrcatA(keypath, "\\Installer\\Products\\");
2220     lstrcatA(keypath, prod_squashed);
2221
2222     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2223     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2224
2225     /* user managed product key of first product exists */
2226     lstrcpyA(product, "prod");
2227     r = MsiGetProductCodeA(component, product);
2228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2229     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2230
2231     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2232     RegCloseKey(prodkey);
2233
2234     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2235     lstrcatA(keypath, prod_squashed);
2236
2237     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2239
2240     /* user unmanaged product key exists */
2241     lstrcpyA(product, "prod");
2242     r = MsiGetProductCodeA(component, product);
2243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2244     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2245
2246     RegDeleteKeyA(prodkey, "");
2247     RegCloseKey(prodkey);
2248
2249     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2250     lstrcatA(keypath, prod_squashed);
2251
2252     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2253     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2254
2255     /* local classes product key exists */
2256     lstrcpyA(product, "prod");
2257     r = MsiGetProductCodeA(component, product);
2258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2259     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2260
2261     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2262     RegCloseKey(prodkey);
2263
2264     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2265     lstrcatA(keypath, "Installer\\Managed\\");
2266     lstrcatA(keypath, usersid);
2267     lstrcatA(keypath, "\\Installer\\Products\\");
2268     lstrcatA(keypath, prod2_squashed);
2269
2270     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2271     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2272
2273     /* user managed product key of second product exists */
2274     lstrcpyA(product, "prod");
2275     r = MsiGetProductCodeA(component, product);
2276     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2277     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2278
2279     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2280     RegCloseKey(prodkey);
2281     RegDeleteValueA(compkey, prod_squashed);
2282     RegDeleteValueA(compkey, prod2_squashed);
2283     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2284     RegCloseKey(compkey);
2285
2286     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2287     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2288     lstrcatA(keypath, comp_squashed);
2289
2290     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2292
2293     /* local user component key exists */
2294     lstrcpyA(product, "prod");
2295     r = MsiGetProductCodeA(component, product);
2296     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2297     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2298
2299     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2300     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2301
2302     /* product value exists */
2303     lstrcpyA(product, "prod");
2304     r = MsiGetProductCodeA(component, product);
2305     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2306     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2307
2308     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2309     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2310
2311     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2312     lstrcatA(keypath, "Installer\\Managed\\");
2313     lstrcatA(keypath, usersid);
2314     lstrcatA(keypath, "\\Installer\\Products\\");
2315     lstrcatA(keypath, prod_squashed);
2316
2317     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2319
2320     /* user managed product key of first product exists */
2321     lstrcpyA(product, "prod");
2322     r = MsiGetProductCodeA(component, product);
2323     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2324     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2325
2326     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2327     RegCloseKey(prodkey);
2328
2329     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2330     lstrcatA(keypath, prod_squashed);
2331
2332     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2333     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2334
2335     /* user unmanaged product key exists */
2336     lstrcpyA(product, "prod");
2337     r = MsiGetProductCodeA(component, product);
2338     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2339     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2340
2341     RegDeleteKeyA(prodkey, "");
2342     RegCloseKey(prodkey);
2343
2344     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2345     lstrcatA(keypath, prod_squashed);
2346
2347     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2349
2350     /* local classes product key exists */
2351     lstrcpyA(product, "prod");
2352     r = MsiGetProductCodeA(component, product);
2353     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2354     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2355
2356     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2357     RegCloseKey(prodkey);
2358
2359     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2360     lstrcatA(keypath, "Installer\\Managed\\");
2361     lstrcatA(keypath, usersid);
2362     lstrcatA(keypath, "\\Installer\\Products\\");
2363     lstrcatA(keypath, prod2_squashed);
2364
2365     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2366     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2367
2368     /* user managed product key of second product exists */
2369     lstrcpyA(product, "prod");
2370     r = MsiGetProductCodeA(component, product);
2371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2372     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2373
2374     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2375     RegCloseKey(prodkey);
2376     RegDeleteValueA(compkey, prod_squashed);
2377     RegDeleteValueA(compkey, prod2_squashed);
2378     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2379     RegCloseKey(compkey);
2380     LocalFree(usersid);
2381 }
2382
2383 static void test_MsiEnumClients(void)
2384 {
2385     HKEY compkey;
2386     CHAR prodcode[MAX_PATH];
2387     CHAR prod_squashed[MAX_PATH];
2388     CHAR prodcode2[MAX_PATH];
2389     CHAR prod2_squashed[MAX_PATH];
2390     CHAR component[MAX_PATH];
2391     CHAR comp_base85[MAX_PATH];
2392     CHAR comp_squashed[MAX_PATH];
2393     CHAR product[MAX_PATH];
2394     CHAR keypath[MAX_PATH];
2395     LPSTR usersid;
2396     LONG res;
2397     UINT r;
2398     REGSAM access = KEY_ALL_ACCESS;
2399     BOOL wow64;
2400
2401     create_test_guid(prodcode, prod_squashed);
2402     create_test_guid(prodcode2, prod2_squashed);
2403     compose_base85_guid(component, comp_base85, comp_squashed);
2404     get_user_sid(&usersid);
2405
2406     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
2407         access |= KEY_WOW64_64KEY;
2408
2409     /* NULL szComponent */
2410     product[0] = '\0';
2411     r = MsiEnumClientsA(NULL, 0, product);
2412     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2413     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2414
2415     /* empty szComponent */
2416     product[0] = '\0';
2417     r = MsiEnumClientsA("", 0, product);
2418     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2419     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2420
2421     /* NULL lpProductBuf */
2422     r = MsiEnumClientsA(component, 0, NULL);
2423     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2424
2425     /* all params correct, component missing */
2426     product[0] = '\0';
2427     r = MsiEnumClientsA(component, 0, product);
2428     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2429     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2430
2431     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2432     lstrcatA(keypath, "Installer\\UserData\\");
2433     lstrcatA(keypath, usersid);
2434     lstrcatA(keypath, "\\Components\\");
2435     lstrcatA(keypath, comp_squashed);
2436
2437     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2438     if (res == ERROR_ACCESS_DENIED)
2439     {
2440         skip("Not enough rights to perform tests\n");
2441         LocalFree(usersid);
2442         return;
2443     }
2444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2445
2446     /* user unmanaged component key exists */
2447     product[0] = '\0';
2448     r = MsiEnumClientsA(component, 0, product);
2449     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2450     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2451
2452     /* index > 0, no products exist */
2453     product[0] = '\0';
2454     r = MsiEnumClientsA(component, 1, product);
2455     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2456     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2457
2458     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2460
2461     /* product value exists */
2462     r = MsiEnumClientsA(component, 0, product);
2463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2464     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2465
2466     /* try index 0 again */
2467     product[0] = '\0';
2468     r = MsiEnumClientsA(component, 0, product);
2469     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2470     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2471
2472     /* try index 1, second product value does not exist */
2473     product[0] = '\0';
2474     r = MsiEnumClientsA(component, 1, product);
2475     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2476     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2477
2478     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2479     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2480
2481     /* try index 1, second product value does exist */
2482     product[0] = '\0';
2483     r = MsiEnumClientsA(component, 1, product);
2484     todo_wine
2485     {
2486         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2487         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2488     }
2489
2490     /* start the enumeration over */
2491     product[0] = '\0';
2492     r = MsiEnumClientsA(component, 0, product);
2493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2494     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2495        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2496
2497     /* correctly query second product */
2498     product[0] = '\0';
2499     r = MsiEnumClientsA(component, 1, product);
2500     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2501     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2502        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2503
2504     RegDeleteValueA(compkey, prod_squashed);
2505     RegDeleteValueA(compkey, prod2_squashed);
2506     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2507     RegCloseKey(compkey);
2508
2509     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2510     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2511     lstrcatA(keypath, comp_squashed);
2512
2513     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2514     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2515
2516     /* user local component key exists */
2517     product[0] = '\0';
2518     r = MsiEnumClientsA(component, 0, product);
2519     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2520     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2521
2522     /* index > 0, no products exist */
2523     product[0] = '\0';
2524     r = MsiEnumClientsA(component, 1, product);
2525     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2526     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2527
2528     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2530
2531     /* product value exists */
2532     product[0] = '\0';
2533     r = MsiEnumClientsA(component, 0, product);
2534     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2535     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2536
2537     /* try index 0 again */
2538     product[0] = '\0';
2539     r = MsiEnumClientsA(component, 0, product);
2540     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2541
2542     /* try index 1, second product value does not exist */
2543     product[0] = '\0';
2544     r = MsiEnumClientsA(component, 1, product);
2545     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2546     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2547
2548     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2549     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2550
2551     /* try index 1, second product value does exist */
2552     product[0] = '\0';
2553     r = MsiEnumClientsA(component, 1, product);
2554     todo_wine
2555     {
2556         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2557         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2558     }
2559
2560     /* start the enumeration over */
2561     product[0] = '\0';
2562     r = MsiEnumClientsA(component, 0, product);
2563     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2564     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2565        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2566
2567     /* correctly query second product */
2568     product[0] = '\0';
2569     r = MsiEnumClientsA(component, 1, product);
2570     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2571     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2572        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2573
2574     RegDeleteValueA(compkey, prod_squashed);
2575     RegDeleteValueA(compkey, prod2_squashed);
2576     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2577     RegCloseKey(compkey);
2578     LocalFree(usersid);
2579 }
2580
2581 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2582                              LPSTR *langcheck, LPDWORD langchecksz)
2583 {
2584     LPSTR version;
2585     VS_FIXEDFILEINFO *ffi;
2586     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2587     USHORT *lang;
2588
2589     version = HeapAlloc(GetProcessHeap(), 0, size);
2590     GetFileVersionInfoA(path, 0, size, version);
2591
2592     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2593     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2594     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2595             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2596             LOWORD(ffi->dwFileVersionLS));
2597     *verchecksz = lstrlenA(*vercheck);
2598
2599     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2600     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2601     sprintf(*langcheck, "%d", *lang);
2602     *langchecksz = lstrlenA(*langcheck);
2603
2604     HeapFree(GetProcessHeap(), 0, version);
2605 }
2606
2607 static void test_MsiGetFileVersion(void)
2608 {
2609     UINT r;
2610     DWORD versz, langsz;
2611     char version[MAX_PATH];
2612     char lang[MAX_PATH];
2613     char path[MAX_PATH];
2614     LPSTR vercheck, langcheck;
2615     DWORD verchecksz, langchecksz;
2616
2617     /* NULL szFilePath */
2618     versz = MAX_PATH;
2619     langsz = MAX_PATH;
2620     lstrcpyA(version, "version");
2621     lstrcpyA(lang, "lang");
2622     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2623     ok(r == ERROR_INVALID_PARAMETER,
2624        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2625     ok(!lstrcmpA(version, "version"),
2626        "Expected version to be unchanged, got %s\n", version);
2627     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2628     ok(!lstrcmpA(lang, "lang"),
2629        "Expected lang to be unchanged, got %s\n", lang);
2630     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2631
2632     /* empty szFilePath */
2633     versz = MAX_PATH;
2634     langsz = MAX_PATH;
2635     lstrcpyA(version, "version");
2636     lstrcpyA(lang, "lang");
2637     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2638     ok(r == ERROR_FILE_NOT_FOUND,
2639        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2640     ok(!lstrcmpA(version, "version"),
2641        "Expected version to be unchanged, got %s\n", version);
2642     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2643     ok(!lstrcmpA(lang, "lang"),
2644        "Expected lang to be unchanged, got %s\n", lang);
2645     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2646
2647     /* nonexistent szFilePath */
2648     versz = MAX_PATH;
2649     langsz = MAX_PATH;
2650     lstrcpyA(version, "version");
2651     lstrcpyA(lang, "lang");
2652     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2653     ok(r == ERROR_FILE_NOT_FOUND,
2654        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2655     ok(!lstrcmpA(version, "version"),
2656        "Expected version to be unchanged, got %s\n", version);
2657     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2658     ok(!lstrcmpA(lang, "lang"),
2659        "Expected lang to be unchanged, got %s\n", lang);
2660     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2661
2662     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2663     versz = MAX_PATH;
2664     langsz = MAX_PATH;
2665     lstrcpyA(version, "version");
2666     lstrcpyA(lang, "lang");
2667     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2668     ok(r == ERROR_INVALID_PARAMETER,
2669        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2670     ok(!lstrcmpA(version, "version"),
2671        "Expected version to be unchanged, got %s\n", version);
2672     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2673     ok(!lstrcmpA(lang, "lang"),
2674        "Expected lang to be unchanged, got %s\n", lang);
2675     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2676
2677     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2678     versz = MAX_PATH;
2679     langsz = MAX_PATH;
2680     lstrcpyA(version, "version");
2681     lstrcpyA(lang, "lang");
2682     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2683     ok(r == ERROR_INVALID_PARAMETER,
2684        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2685     ok(!lstrcmpA(version, "version"),
2686        "Expected version to be unchanged, got %s\n", version);
2687     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2688     ok(!lstrcmpA(lang, "lang"),
2689        "Expected lang to be unchanged, got %s\n", lang);
2690     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2691
2692     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2693     versz = 0;
2694     langsz = MAX_PATH;
2695     lstrcpyA(version, "version");
2696     lstrcpyA(lang, "lang");
2697     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2698     ok(r == ERROR_FILE_NOT_FOUND,
2699        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2700     ok(!lstrcmpA(version, "version"),
2701        "Expected version to be unchanged, got %s\n", version);
2702     ok(versz == 0, "Expected 0, got %d\n", versz);
2703     ok(!lstrcmpA(lang, "lang"),
2704        "Expected lang to be unchanged, got %s\n", lang);
2705     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2706
2707     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2708     versz = MAX_PATH;
2709     langsz = 0;
2710     lstrcpyA(version, "version");
2711     lstrcpyA(lang, "lang");
2712     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2713     ok(r == ERROR_FILE_NOT_FOUND,
2714        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2715     ok(!lstrcmpA(version, "version"),
2716        "Expected version to be unchanged, got %s\n", version);
2717     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2718     ok(!lstrcmpA(lang, "lang"),
2719        "Expected lang to be unchanged, got %s\n", lang);
2720     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2721
2722     /* nonexistent szFilePath, rest NULL */
2723     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2724     ok(r == ERROR_FILE_NOT_FOUND,
2725        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2726
2727     create_file("ver.txt", "ver.txt", 20);
2728
2729     /* file exists, no version information */
2730     versz = MAX_PATH;
2731     langsz = MAX_PATH;
2732     lstrcpyA(version, "version");
2733     lstrcpyA(lang, "lang");
2734     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2735     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2736     ok(!lstrcmpA(version, "version"),
2737        "Expected version to be unchanged, got %s\n", version);
2738     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2739     ok(!lstrcmpA(lang, "lang"),
2740        "Expected lang to be unchanged, got %s\n", lang);
2741     ok(r == ERROR_FILE_INVALID,
2742        "Expected ERROR_FILE_INVALID, got %d\n", r);
2743
2744     DeleteFileA("ver.txt");
2745
2746     /* relative path, has version information */
2747     versz = MAX_PATH;
2748     langsz = MAX_PATH;
2749     lstrcpyA(version, "version");
2750     lstrcpyA(lang, "lang");
2751     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2752     todo_wine
2753     {
2754         ok(r == ERROR_FILE_NOT_FOUND,
2755            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2756         ok(!lstrcmpA(version, "version"),
2757            "Expected version to be unchanged, got %s\n", version);
2758         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2759         ok(!lstrcmpA(lang, "lang"),
2760            "Expected lang to be unchanged, got %s\n", lang);
2761         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2762     }
2763
2764     GetSystemDirectoryA(path, MAX_PATH);
2765     lstrcatA(path, "\\kernel32.dll");
2766
2767     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2768
2769     /* absolute path, has version information */
2770     versz = MAX_PATH;
2771     langsz = MAX_PATH;
2772     lstrcpyA(version, "version");
2773     lstrcpyA(lang, "lang");
2774     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2775     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2776     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2777     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2778     ok(!lstrcmpA(version, vercheck),
2779         "Expected %s, got %s\n", vercheck, version);
2780
2781     /* only check version */
2782     versz = MAX_PATH;
2783     lstrcpyA(version, "version");
2784     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2786     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2787     ok(!lstrcmpA(version, vercheck),
2788        "Expected %s, got %s\n", vercheck, version);
2789
2790     /* only check language */
2791     langsz = MAX_PATH;
2792     lstrcpyA(lang, "lang");
2793     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2794     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2795     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2796
2797     /* check neither version nor language */
2798     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2799     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2800
2801     /* get pcchVersionBuf */
2802     versz = MAX_PATH;
2803     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2805     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2806
2807     /* get pcchLangBuf */
2808     langsz = MAX_PATH;
2809     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2810     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2811     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
2812
2813     /* pcchVersionBuf not big enough */
2814     versz = 5;
2815     lstrcpyA(version, "version");
2816     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2817     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2818     ok(!strncmp(version, vercheck, 4),
2819        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2820     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2821
2822     /* pcchLangBuf not big enough */
2823     langsz = 3;
2824     lstrcpyA(lang, "lang");
2825     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2826     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2827     ok(!strncmp(lang, langcheck, 2),
2828        "Expected first character of %s, got %s\n", langcheck, lang);
2829     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
2830
2831     HeapFree(GetProcessHeap(), 0, vercheck);
2832     HeapFree(GetProcessHeap(), 0, langcheck);
2833 }
2834
2835 static void test_MsiGetProductInfo(void)
2836 {
2837     UINT r;
2838     LONG res;
2839     HKEY propkey, source;
2840     HKEY prodkey, localkey;
2841     CHAR prodcode[MAX_PATH];
2842     CHAR prod_squashed[MAX_PATH];
2843     CHAR packcode[MAX_PATH];
2844     CHAR pack_squashed[MAX_PATH];
2845     CHAR buf[MAX_PATH];
2846     CHAR keypath[MAX_PATH];
2847     LPSTR usersid;
2848     DWORD sz, val = 42;
2849     REGSAM access = KEY_ALL_ACCESS;
2850     BOOL wow64;
2851
2852     create_test_guid(prodcode, prod_squashed);
2853     create_test_guid(packcode, pack_squashed);
2854     get_user_sid(&usersid);
2855
2856     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
2857         access |= KEY_WOW64_64KEY;
2858
2859     /* NULL szProduct */
2860     sz = MAX_PATH;
2861     lstrcpyA(buf, "apple");
2862     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2863     ok(r == ERROR_INVALID_PARAMETER,
2864        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2865     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2866     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2867
2868     /* empty szProduct */
2869     sz = MAX_PATH;
2870     lstrcpyA(buf, "apple");
2871     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2872     ok(r == ERROR_INVALID_PARAMETER,
2873        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2874     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2875     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2876
2877     /* garbage szProduct */
2878     sz = MAX_PATH;
2879     lstrcpyA(buf, "apple");
2880     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2881     ok(r == ERROR_INVALID_PARAMETER,
2882        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2883     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2884     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2885
2886     /* guid without brackets */
2887     sz = MAX_PATH;
2888     lstrcpyA(buf, "apple");
2889     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2890                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2891     ok(r == ERROR_INVALID_PARAMETER,
2892        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2893     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2894     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2895
2896     /* guid with brackets */
2897     sz = MAX_PATH;
2898     lstrcpyA(buf, "apple");
2899     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2900                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2901     ok(r == ERROR_UNKNOWN_PRODUCT,
2902        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2903     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2904     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2905
2906     /* same length as guid, but random */
2907     sz = MAX_PATH;
2908     lstrcpyA(buf, "apple");
2909     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2910                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2911     ok(r == ERROR_INVALID_PARAMETER,
2912        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2913     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2914     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2915
2916     /* not installed, NULL szAttribute */
2917     sz = MAX_PATH;
2918     lstrcpyA(buf, "apple");
2919     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2920     ok(r == ERROR_INVALID_PARAMETER,
2921        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2922     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2923     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2924
2925     /* not installed, NULL lpValueBuf */
2926     sz = MAX_PATH;
2927     lstrcpyA(buf, "apple");
2928     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2929     ok(r == ERROR_UNKNOWN_PRODUCT,
2930        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2931     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2932     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2933
2934     /* not installed, NULL pcchValueBuf */
2935     sz = MAX_PATH;
2936     lstrcpyA(buf, "apple");
2937     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2938     ok(r == ERROR_INVALID_PARAMETER,
2939        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2940     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2941     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2942
2943     /* created guid cannot possibly be an installed product code */
2944     sz = MAX_PATH;
2945     lstrcpyA(buf, "apple");
2946     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2947     ok(r == ERROR_UNKNOWN_PRODUCT,
2948        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2949     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2950     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2951
2952     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2953     lstrcatA(keypath, usersid);
2954     lstrcatA(keypath, "\\Installer\\Products\\");
2955     lstrcatA(keypath, prod_squashed);
2956
2957     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2958     if (res == ERROR_ACCESS_DENIED)
2959     {
2960         skip("Not enough rights to perform tests\n");
2961         LocalFree(usersid);
2962         return;
2963     }
2964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2965
2966     /* managed product code exists */
2967     sz = MAX_PATH;
2968     lstrcpyA(buf, "apple");
2969     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2970     ok(r == ERROR_UNKNOWN_PROPERTY,
2971        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2972     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2973     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2974
2975     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2976     RegCloseKey(prodkey);
2977
2978     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2979     lstrcatA(keypath, usersid);
2980     lstrcatA(keypath, "\\Products\\");
2981     lstrcatA(keypath, prod_squashed);
2982
2983     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2984     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2985
2986     /* local user product code exists */
2987     sz = MAX_PATH;
2988     lstrcpyA(buf, "apple");
2989     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2990     ok(r == ERROR_UNKNOWN_PRODUCT,
2991        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2992     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2993     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2994
2995     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2996     lstrcatA(keypath, usersid);
2997     lstrcatA(keypath, "\\Installer\\Products\\");
2998     lstrcatA(keypath, prod_squashed);
2999
3000     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3001     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3002
3003     /* both local and managed product code exist */
3004     sz = MAX_PATH;
3005     lstrcpyA(buf, "apple");
3006     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3007     ok(r == ERROR_UNKNOWN_PROPERTY,
3008        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3009     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3010     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3011
3012     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3014
3015     /* InstallProperties key exists */
3016     sz = MAX_PATH;
3017     lstrcpyA(buf, "apple");
3018     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3019     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3020     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3021     ok(sz == 0, "Expected 0, got %d\n", sz);
3022
3023     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3025
3026     /* HelpLink value exists */
3027     sz = MAX_PATH;
3028     lstrcpyA(buf, "apple");
3029     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3030     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3031     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3032     ok(sz == 4, "Expected 4, got %d\n", sz);
3033
3034     /* pcchBuf is NULL */
3035     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
3036     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3037
3038     /* lpValueBuf is NULL */
3039     sz = MAX_PATH;
3040     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3042     ok(sz == 4, "Expected 4, got %d\n", sz);
3043
3044     /* lpValueBuf is NULL, pcchValueBuf is too small */
3045     sz = 2;
3046     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3047     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3048     ok(sz == 4, "Expected 4, got %d\n", sz);
3049
3050     /* lpValueBuf is non-NULL, pcchValueBuf is too small */
3051     sz = 2;
3052     lstrcpyA(buf, "apple");
3053     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3054     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
3055     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3056     ok(sz == 4, "Expected 4, got %d\n", sz);
3057
3058     /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
3059     sz = 4;
3060     lstrcpyA(buf, "apple");
3061     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3062     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3063     ok(!lstrcmpA(buf, "apple"),
3064        "Expected buf to remain unchanged, got \"%s\"\n", buf);
3065     ok(sz == 4, "Expected 4, got %d\n", sz);
3066
3067     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
3068     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3069
3070     /* random property not supported by MSI, value exists */
3071     sz = MAX_PATH;
3072     lstrcpyA(buf, "apple");
3073     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
3074     ok(r == ERROR_UNKNOWN_PROPERTY,
3075        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3076     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3077     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3078
3079     RegDeleteValueA(propkey, "IMadeThis");
3080     RegDeleteValueA(propkey, "HelpLink");
3081     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3082     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3083     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3084     RegCloseKey(propkey);
3085     RegCloseKey(localkey);
3086     RegCloseKey(prodkey);
3087
3088     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3089     lstrcatA(keypath, prod_squashed);
3090
3091     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3093
3094     /* user product key exists */
3095     sz = MAX_PATH;
3096     lstrcpyA(buf, "apple");
3097     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3098     ok(r == ERROR_UNKNOWN_PROPERTY,
3099        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3100     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3101     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3102
3103     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3104     lstrcatA(keypath, usersid);
3105     lstrcatA(keypath, "\\Products\\");
3106     lstrcatA(keypath, prod_squashed);
3107
3108     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3110
3111     /* local user product key exists */
3112     sz = MAX_PATH;
3113     lstrcpyA(buf, "apple");
3114     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3115     ok(r == ERROR_UNKNOWN_PROPERTY,
3116        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3117     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3118     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3119
3120     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3121     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3122
3123     /* InstallProperties key exists */
3124     sz = MAX_PATH;
3125     lstrcpyA(buf, "apple");
3126     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3127     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3128     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3129     ok(sz == 0, "Expected 0, got %d\n", sz);
3130
3131     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3133
3134     /* HelpLink value exists */
3135     sz = MAX_PATH;
3136     lstrcpyA(buf, "apple");
3137     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3138     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3139     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3140     ok(sz == 4, "Expected 4, got %d\n", sz);
3141
3142     RegDeleteValueA(propkey, "HelpLink");
3143     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3144     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3145     RegDeleteKeyA(prodkey, "");
3146     RegCloseKey(propkey);
3147     RegCloseKey(localkey);
3148     RegCloseKey(prodkey);
3149
3150     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3151     lstrcatA(keypath, prod_squashed);
3152
3153     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3154     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3155
3156     /* classes product key exists */
3157     sz = MAX_PATH;
3158     lstrcpyA(buf, "apple");
3159     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3160     ok(r == ERROR_UNKNOWN_PROPERTY,
3161        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3162     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3163     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3164
3165     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3166     lstrcatA(keypath, usersid);
3167     lstrcatA(keypath, "\\Products\\");
3168     lstrcatA(keypath, prod_squashed);
3169
3170     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3171     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3172
3173     /* local user product key exists */
3174     sz = MAX_PATH;
3175     lstrcpyA(buf, "apple");
3176     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3177     ok(r == ERROR_UNKNOWN_PROPERTY,
3178        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3179     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3180     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3181
3182     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3183     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3184
3185     /* InstallProperties key exists */
3186     sz = MAX_PATH;
3187     lstrcpyA(buf, "apple");
3188     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3189     ok(r == ERROR_UNKNOWN_PROPERTY,
3190        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3191     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3192     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3193
3194     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3195     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3196     RegCloseKey(propkey);
3197     RegCloseKey(localkey);
3198
3199     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3200     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
3201     lstrcatA(keypath, prod_squashed);
3202
3203     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3205
3206     /* Local System product key exists */
3207     sz = MAX_PATH;
3208     lstrcpyA(buf, "apple");
3209     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3210     ok(r == ERROR_UNKNOWN_PROPERTY,
3211         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3212     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3213     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3214
3215     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3217
3218     /* InstallProperties key exists */
3219     sz = MAX_PATH;
3220     lstrcpyA(buf, "apple");
3221     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3223     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3224     ok(sz == 0, "Expected 0, got %d\n", sz);
3225
3226     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3228
3229     /* HelpLink value exists */
3230     sz = MAX_PATH;
3231     lstrcpyA(buf, "apple");
3232     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3234     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3235     ok(sz == 4, "Expected 4, got %d\n", sz);
3236
3237     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
3238                          (const BYTE *)&val, sizeof(DWORD));
3239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3240
3241     /* HelpLink type is REG_DWORD */
3242     sz = MAX_PATH;
3243     lstrcpyA(buf, "apple");
3244     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3246     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3247     ok(sz == 2, "Expected 2, got %d\n", sz);
3248
3249     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
3250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3251
3252     /* DisplayName value exists */
3253     sz = MAX_PATH;
3254     lstrcpyA(buf, "apple");
3255     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3257     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3258     ok(sz == 4, "Expected 4, got %d\n", sz);
3259
3260     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
3261                          (const BYTE *)&val, sizeof(DWORD));
3262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3263
3264     /* DisplayName type is REG_DWORD */
3265     sz = MAX_PATH;
3266     lstrcpyA(buf, "apple");
3267     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3268     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3269     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3270     ok(sz == 2, "Expected 2, got %d\n", sz);
3271
3272     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3274
3275     /* DisplayVersion value exists */
3276     sz = MAX_PATH;
3277     lstrcpyA(buf, "apple");
3278     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3280     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3281     ok(sz == 5, "Expected 5, got %d\n", sz);
3282
3283     res = RegSetValueExA(propkey, "DisplayVersion", 0,
3284                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3286
3287     /* DisplayVersion type is REG_DWORD */
3288     sz = MAX_PATH;
3289     lstrcpyA(buf, "apple");
3290     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3291     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3292     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3293     ok(sz == 2, "Expected 2, got %d\n", sz);
3294
3295     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3297
3298     /* HelpTelephone value exists */
3299     sz = MAX_PATH;
3300     lstrcpyA(buf, "apple");
3301     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3303     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3304     ok(sz == 4, "Expected 4, got %d\n", sz);
3305
3306     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3307                          (const BYTE *)&val, sizeof(DWORD));
3308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3309
3310     /* HelpTelephone type is REG_DWORD */
3311     sz = MAX_PATH;
3312     lstrcpyA(buf, "apple");
3313     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3315     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3316     ok(sz == 2, "Expected 2, got %d\n", sz);
3317
3318     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3320
3321     /* InstallLocation value exists */
3322     sz = MAX_PATH;
3323     lstrcpyA(buf, "apple");
3324     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3326     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3327     ok(sz == 3, "Expected 3, got %d\n", sz);
3328
3329     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3330                          (const BYTE *)&val, sizeof(DWORD));
3331     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3332
3333     /* InstallLocation type is REG_DWORD */
3334     sz = MAX_PATH;
3335     lstrcpyA(buf, "apple");
3336     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3338     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3339     ok(sz == 2, "Expected 2, got %d\n", sz);
3340
3341     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3343
3344     /* InstallSource value exists */
3345     sz = MAX_PATH;
3346     lstrcpyA(buf, "apple");
3347     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3349     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3350     ok(sz == 6, "Expected 6, got %d\n", sz);
3351
3352     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3353                          (const BYTE *)&val, sizeof(DWORD));
3354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3355
3356     /* InstallSource type is REG_DWORD */
3357     sz = MAX_PATH;
3358     lstrcpyA(buf, "apple");
3359     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3360     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3361     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3362     ok(sz == 2, "Expected 2, got %d\n", sz);
3363
3364     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3366
3367     /* InstallDate value exists */
3368     sz = MAX_PATH;
3369     lstrcpyA(buf, "apple");
3370     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3372     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3373     ok(sz == 4, "Expected 4, got %d\n", sz);
3374
3375     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3376                          (const BYTE *)&val, sizeof(DWORD));
3377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3378
3379     /* InstallDate type is REG_DWORD */
3380     sz = MAX_PATH;
3381     lstrcpyA(buf, "apple");
3382     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3384     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3385     ok(sz == 2, "Expected 2, got %d\n", sz);
3386
3387     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3389
3390     /* Publisher value exists */
3391     sz = MAX_PATH;
3392     lstrcpyA(buf, "apple");
3393     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3394     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3395     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3396     ok(sz == 3, "Expected 3, got %d\n", sz);
3397
3398     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3399                          (const BYTE *)&val, sizeof(DWORD));
3400     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3401
3402     /* Publisher type is REG_DWORD */
3403     sz = MAX_PATH;
3404     lstrcpyA(buf, "apple");
3405     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3406     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3407     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3408     ok(sz == 2, "Expected 2, got %d\n", sz);
3409
3410     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3412
3413     /* LocalPackage value exists */
3414     sz = MAX_PATH;
3415     lstrcpyA(buf, "apple");
3416     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3417     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3418     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3419     ok(sz == 4, "Expected 4, got %d\n", sz);
3420
3421     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3422                          (const BYTE *)&val, sizeof(DWORD));
3423     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3424
3425     /* LocalPackage type is REG_DWORD */
3426     sz = MAX_PATH;
3427     lstrcpyA(buf, "apple");
3428     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3429     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3430     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3431     ok(sz == 2, "Expected 2, got %d\n", sz);
3432
3433     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3435
3436     /* UrlInfoAbout value exists */
3437     sz = MAX_PATH;
3438     lstrcpyA(buf, "apple");
3439     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3441     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3442     ok(sz == 5, "Expected 5, got %d\n", sz);
3443
3444     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3445                          (const BYTE *)&val, sizeof(DWORD));
3446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3447
3448     /* UrlInfoAbout type is REG_DWORD */
3449     sz = MAX_PATH;
3450     lstrcpyA(buf, "apple");
3451     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3452     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3453     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3454     ok(sz == 2, "Expected 2, got %d\n", sz);
3455
3456     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3457     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3458
3459     /* UrlUpdateInfo value exists */
3460     sz = MAX_PATH;
3461     lstrcpyA(buf, "apple");
3462     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3464     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3465     ok(sz == 4, "Expected 4, got %d\n", sz);
3466
3467     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3468                          (const BYTE *)&val, sizeof(DWORD));
3469     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3470
3471     /* UrlUpdateInfo type is REG_DWORD */
3472     sz = MAX_PATH;
3473     lstrcpyA(buf, "apple");
3474     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3475     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3476     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3477     ok(sz == 2, "Expected 2, got %d\n", sz);
3478
3479     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3481
3482     /* VersionMinor value exists */
3483     sz = MAX_PATH;
3484     lstrcpyA(buf, "apple");
3485     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3486     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3487     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3488     ok(sz == 1, "Expected 1, got %d\n", sz);
3489
3490     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3491                          (const BYTE *)&val, sizeof(DWORD));
3492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3493
3494     /* VersionMinor type is REG_DWORD */
3495     sz = MAX_PATH;
3496     lstrcpyA(buf, "apple");
3497     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3498     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3499     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3500     ok(sz == 2, "Expected 2, got %d\n", sz);
3501
3502     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3504
3505     /* VersionMajor value exists */
3506     sz = MAX_PATH;
3507     lstrcpyA(buf, "apple");
3508     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3510     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3511     ok(sz == 1, "Expected 1, got %d\n", sz);
3512
3513     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3514                          (const BYTE *)&val, sizeof(DWORD));
3515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3516
3517     /* VersionMajor type is REG_DWORD */
3518     sz = MAX_PATH;
3519     lstrcpyA(buf, "apple");
3520     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3522     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3523     ok(sz == 2, "Expected 2, got %d\n", sz);
3524
3525     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3527
3528     /* ProductID value exists */
3529     sz = MAX_PATH;
3530     lstrcpyA(buf, "apple");
3531     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3532     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3533     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3534     ok(sz == 2, "Expected 2, got %d\n", sz);
3535
3536     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3537                          (const BYTE *)&val, sizeof(DWORD));
3538     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3539
3540     /* ProductID type is REG_DWORD */
3541     sz = MAX_PATH;
3542     lstrcpyA(buf, "apple");
3543     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3545     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3546     ok(sz == 2, "Expected 2, got %d\n", sz);
3547
3548     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3549     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3550
3551     /* RegCompany value exists */
3552     sz = MAX_PATH;
3553     lstrcpyA(buf, "apple");
3554     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3556     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3557     ok(sz == 4, "Expected 4, got %d\n", sz);
3558
3559     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3560                          (const BYTE *)&val, sizeof(DWORD));
3561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3562
3563     /* RegCompany type is REG_DWORD */
3564     sz = MAX_PATH;
3565     lstrcpyA(buf, "apple");
3566     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3567     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3568     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3569     ok(sz == 2, "Expected 2, got %d\n", sz);
3570
3571     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3572     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3573
3574     /* RegOwner value exists */
3575     sz = MAX_PATH;
3576     lstrcpyA(buf, "apple");
3577     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3578     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3579     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3580     ok(sz == 3, "Expected 3, got %d\n", sz);
3581
3582     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3583                          (const BYTE *)&val, sizeof(DWORD));
3584     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3585
3586     /* RegOwner type is REG_DWORD */
3587     sz = MAX_PATH;
3588     lstrcpyA(buf, "apple");
3589     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3590     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3591     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3592     ok(sz == 2, "Expected 2, got %d\n", sz);
3593
3594     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3595     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3596
3597     /* InstanceType value exists */
3598     sz = MAX_PATH;
3599     lstrcpyA(buf, "apple");
3600     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3601     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3602     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3603     ok(sz == 0, "Expected 0, got %d\n", sz);
3604
3605     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3606                          (const BYTE *)&val, sizeof(DWORD));
3607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3608
3609     /* InstanceType type is REG_DWORD */
3610     sz = MAX_PATH;
3611     lstrcpyA(buf, "apple");
3612     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3613     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3614     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3615     ok(sz == 0, "Expected 0, got %d\n", sz);
3616
3617     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3619
3620     /* InstanceType value exists */
3621     sz = MAX_PATH;
3622     lstrcpyA(buf, "apple");
3623     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3624     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3625     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3626     ok(sz == 4, "Expected 4, got %d\n", sz);
3627
3628     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3629                          (const BYTE *)&val, sizeof(DWORD));
3630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3631
3632     /* InstanceType type is REG_DWORD */
3633     sz = MAX_PATH;
3634     lstrcpyA(buf, "apple");
3635     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3636     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3637     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3638     ok(sz == 2, "Expected 2, got %d\n", sz);
3639
3640     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3642
3643     /* Transforms value exists */
3644     sz = MAX_PATH;
3645     lstrcpyA(buf, "apple");
3646     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3647     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3648     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3649     ok(sz == 0, "Expected 0, got %d\n", sz);
3650
3651     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3652                          (const BYTE *)&val, sizeof(DWORD));
3653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3654
3655     /* Transforms type is REG_DWORD */
3656     sz = MAX_PATH;
3657     lstrcpyA(buf, "apple");
3658     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3659     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3660     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3661     ok(sz == 0, "Expected 0, got %d\n", sz);
3662
3663     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3664     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3665
3666     /* Transforms value exists */
3667     sz = MAX_PATH;
3668     lstrcpyA(buf, "apple");
3669     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3670     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3671     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3672     ok(sz == 6, "Expected 6, got %d\n", sz);
3673
3674     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3675                          (const BYTE *)&val, sizeof(DWORD));
3676     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3677
3678     /* Transforms type is REG_DWORD */
3679     sz = MAX_PATH;
3680     lstrcpyA(buf, "apple");
3681     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3682     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3683     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3684     ok(sz == 2, "Expected 2, got %d\n", sz);
3685
3686     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3688
3689     /* Language value exists */
3690     sz = MAX_PATH;
3691     lstrcpyA(buf, "apple");
3692     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3693     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3694     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3695     ok(sz == 0, "Expected 0, got %d\n", sz);
3696
3697     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3698                          (const BYTE *)&val, sizeof(DWORD));
3699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3700
3701     /* Language type is REG_DWORD */
3702     sz = MAX_PATH;
3703     lstrcpyA(buf, "apple");
3704     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3705     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3706     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3707     ok(sz == 0, "Expected 0, got %d\n", sz);
3708
3709     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3711
3712     /* Language value exists */
3713     sz = MAX_PATH;
3714     lstrcpyA(buf, "apple");
3715     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3716     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3717     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3718     ok(sz == 4, "Expected 4, got %d\n", sz);
3719
3720     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3721                          (const BYTE *)&val, sizeof(DWORD));
3722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3723
3724     /* Language type is REG_DWORD */
3725     sz = MAX_PATH;
3726     lstrcpyA(buf, "apple");
3727     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3728     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3729     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3730     ok(sz == 2, "Expected 2, got %d\n", sz);
3731
3732     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3733     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3734
3735     /* ProductName value exists */
3736     sz = MAX_PATH;
3737     lstrcpyA(buf, "apple");
3738     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3739     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3740     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3741     ok(sz == 0, "Expected 0, got %d\n", sz);
3742
3743     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3744                          (const BYTE *)&val, sizeof(DWORD));
3745     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3746
3747     /* ProductName type is REG_DWORD */
3748     sz = MAX_PATH;
3749     lstrcpyA(buf, "apple");
3750     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3751     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3752     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3753     ok(sz == 0, "Expected 0, got %d\n", sz);
3754
3755     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3756     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3757
3758     /* ProductName value exists */
3759     sz = MAX_PATH;
3760     lstrcpyA(buf, "apple");
3761     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3762     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3763     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3764     ok(sz == 4, "Expected 4, got %d\n", sz);
3765
3766     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3767                          (const BYTE *)&val, sizeof(DWORD));
3768     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3769
3770     /* ProductName type is REG_DWORD */
3771     sz = MAX_PATH;
3772     lstrcpyA(buf, "apple");
3773     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3774     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3775     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3776     ok(sz == 2, "Expected 2, got %d\n", sz);
3777
3778     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3780
3781     /* Assignment value exists */
3782     sz = MAX_PATH;
3783     lstrcpyA(buf, "apple");
3784     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3786     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3787     ok(sz == 0, "Expected 0, got %d\n", sz);
3788
3789     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3790                          (const BYTE *)&val, sizeof(DWORD));
3791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3792
3793     /* Assignment type is REG_DWORD */
3794     sz = MAX_PATH;
3795     lstrcpyA(buf, "apple");
3796     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3797     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3798     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3799     ok(sz == 0, "Expected 0, got %d\n", sz);
3800
3801     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3803
3804     /* Assignment value exists */
3805     sz = MAX_PATH;
3806     lstrcpyA(buf, "apple");
3807     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3808     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3809     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3810     ok(sz == 2, "Expected 2, got %d\n", sz);
3811
3812     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3813                          (const BYTE *)&val, sizeof(DWORD));
3814     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3815
3816     /* Assignment type is REG_DWORD */
3817     sz = MAX_PATH;
3818     lstrcpyA(buf, "apple");
3819     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3821     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3822     ok(sz == 2, "Expected 2, got %d\n", sz);
3823
3824     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3825     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3826
3827     /* PackageCode value exists */
3828     sz = MAX_PATH;
3829     lstrcpyA(buf, "apple");
3830     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3831     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3832     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3833     ok(sz == 0, "Expected 0, got %d\n", sz);
3834
3835     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3836                          (const BYTE *)&val, sizeof(DWORD));
3837     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3838
3839     /* PackageCode type is REG_DWORD */
3840     sz = MAX_PATH;
3841     lstrcpyA(buf, "apple");
3842     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3843     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3844     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3845     ok(sz == 0, "Expected 0, got %d\n", sz);
3846
3847     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3848     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3849
3850     /* PackageCode value exists */
3851     sz = MAX_PATH;
3852     lstrcpyA(buf, "apple");
3853     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3854     ok(r == ERROR_BAD_CONFIGURATION,
3855        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3856     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3857     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3858
3859     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3860                          (const BYTE *)&val, sizeof(DWORD));
3861     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3862
3863     /* PackageCode type is REG_DWORD */
3864     sz = MAX_PATH;
3865     lstrcpyA(buf, "apple");
3866     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3867     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3868     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3869     ok(sz == 2, "Expected 2, got %d\n", sz);
3870
3871     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3872     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3873
3874     /* PackageCode value exists */
3875     sz = MAX_PATH;
3876     lstrcpyA(buf, "apple");
3877     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3878     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3879     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3880     ok(sz == 38, "Expected 38, got %d\n", sz);
3881
3882     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3883     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3884
3885     /* Version value exists */
3886     sz = MAX_PATH;
3887     lstrcpyA(buf, "apple");
3888     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3889     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3890     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3891     ok(sz == 0, "Expected 0, got %d\n", sz);
3892
3893     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3894                          (const BYTE *)&val, sizeof(DWORD));
3895     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3896
3897     /* Version type is REG_DWORD */
3898     sz = MAX_PATH;
3899     lstrcpyA(buf, "apple");
3900     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3901     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3902     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3903     ok(sz == 0, "Expected 0, got %d\n", sz);
3904
3905     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3907
3908     /* Version value exists */
3909     sz = MAX_PATH;
3910     lstrcpyA(buf, "apple");
3911     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3912     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3913     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3914     ok(sz == 3, "Expected 3, got %d\n", sz);
3915
3916     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3917                          (const BYTE *)&val, sizeof(DWORD));
3918     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3919
3920     /* Version type is REG_DWORD */
3921     sz = MAX_PATH;
3922     lstrcpyA(buf, "apple");
3923     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3924     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3925     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3926     ok(sz == 2, "Expected 2, got %d\n", sz);
3927
3928     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3930
3931     /* ProductIcon value exists */
3932     sz = MAX_PATH;
3933     lstrcpyA(buf, "apple");
3934     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3935     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3936     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3937     ok(sz == 0, "Expected 0, got %d\n", sz);
3938
3939     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3940                          (const BYTE *)&val, sizeof(DWORD));
3941     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3942
3943     /* ProductIcon type is REG_DWORD */
3944     sz = MAX_PATH;
3945     lstrcpyA(buf, "apple");
3946     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3947     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3948     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3949     ok(sz == 0, "Expected 0, got %d\n", sz);
3950
3951     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3952     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3953
3954     /* ProductIcon value exists */
3955     sz = MAX_PATH;
3956     lstrcpyA(buf, "apple");
3957     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3958     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3959     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3960     ok(sz == 3, "Expected 3, got %d\n", sz);
3961
3962     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3963                          (const BYTE *)&val, sizeof(DWORD));
3964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3965
3966     /* ProductIcon type is REG_DWORD */
3967     sz = MAX_PATH;
3968     lstrcpyA(buf, "apple");
3969     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3970     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3971     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3972     ok(sz == 2, "Expected 2, got %d\n", sz);
3973
3974     /* SourceList key does not exist */
3975     sz = MAX_PATH;
3976     lstrcpyA(buf, "apple");
3977     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3978     ok(r == ERROR_UNKNOWN_PRODUCT,
3979        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3980     ok(!lstrcmpA(buf, "apple"),
3981        "Expected buf to be unchanged, got \"%s\"\n", buf);
3982     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
3983
3984     res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
3985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3986
3987     /* SourceList key exists, but PackageName val does not exist */
3988     sz = MAX_PATH;
3989     lstrcpyA(buf, "apple");
3990     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3991     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3992     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3993     ok(sz == 0, "Expected 0, got %d\n", sz);
3994
3995     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3997
3998     /* PackageName val exists */
3999     sz = MAX_PATH;
4000     lstrcpyA(buf, "apple");
4001     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4002     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4003     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
4004     ok(sz == 8, "Expected 8, got %d\n", sz);
4005
4006     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
4007                          (const BYTE *)&val, sizeof(DWORD));
4008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4009
4010     /* PackageName type is REG_DWORD */
4011     sz = MAX_PATH;
4012     lstrcpyA(buf, "apple");
4013     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4014     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4015     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4016     ok(sz == 2, "Expected 2, got %d\n", sz);
4017
4018     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4020
4021     /* Authorized value exists */
4022     sz = MAX_PATH;
4023     lstrcpyA(buf, "apple");
4024     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4025     if (r != ERROR_UNKNOWN_PROPERTY)
4026     {
4027         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4028         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4029         ok(sz == 0, "Expected 0, got %d\n", sz);
4030     }
4031
4032     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
4033                          (const BYTE *)&val, sizeof(DWORD));
4034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4035
4036     /* AuthorizedLUAApp type is REG_DWORD */
4037     sz = MAX_PATH;
4038     lstrcpyA(buf, "apple");
4039     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4040     if (r != ERROR_UNKNOWN_PROPERTY)
4041     {
4042         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4043         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4044         ok(sz == 0, "Expected 0, got %d\n", sz);
4045     }
4046
4047     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4049
4050     /* Authorized value exists */
4051     sz = MAX_PATH;
4052     lstrcpyA(buf, "apple");
4053     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4054     if (r != ERROR_UNKNOWN_PROPERTY)
4055     {
4056         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4057         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4058         ok(sz == 4, "Expected 4, got %d\n", sz);
4059     }
4060
4061     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
4062                          (const BYTE *)&val, sizeof(DWORD));
4063     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4064
4065     /* AuthorizedLUAApp type is REG_DWORD */
4066     sz = MAX_PATH;
4067     lstrcpyA(buf, "apple");
4068     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4069     if (r != ERROR_UNKNOWN_PROPERTY)
4070     {
4071         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4072         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4073         ok(sz == 2, "Expected 2, got %d\n", sz);
4074     }
4075
4076     RegDeleteValueA(propkey, "HelpLink");
4077     RegDeleteValueA(propkey, "DisplayName");
4078     RegDeleteValueA(propkey, "DisplayVersion");
4079     RegDeleteValueA(propkey, "HelpTelephone");
4080     RegDeleteValueA(propkey, "InstallLocation");
4081     RegDeleteValueA(propkey, "InstallSource");
4082     RegDeleteValueA(propkey, "InstallDate");
4083     RegDeleteValueA(propkey, "Publisher");
4084     RegDeleteValueA(propkey, "LocalPackage");
4085     RegDeleteValueA(propkey, "UrlInfoAbout");
4086     RegDeleteValueA(propkey, "UrlUpdateInfo");
4087     RegDeleteValueA(propkey, "VersionMinor");
4088     RegDeleteValueA(propkey, "VersionMajor");
4089     RegDeleteValueA(propkey, "ProductID");
4090     RegDeleteValueA(propkey, "RegCompany");
4091     RegDeleteValueA(propkey, "RegOwner");
4092     RegDeleteValueA(propkey, "InstanceType");
4093     RegDeleteValueA(propkey, "Transforms");
4094     RegDeleteValueA(propkey, "Language");
4095     RegDeleteValueA(propkey, "ProductName");
4096     RegDeleteValueA(propkey, "Assignment");
4097     RegDeleteValueA(propkey, "PackageCode");
4098     RegDeleteValueA(propkey, "Version");
4099     RegDeleteValueA(propkey, "ProductIcon");
4100     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4101     delete_key(propkey, "", access & KEY_WOW64_64KEY);
4102     delete_key(localkey, "", access & KEY_WOW64_64KEY);
4103     RegDeleteValueA(prodkey, "InstanceType");
4104     RegDeleteValueA(prodkey, "Transforms");
4105     RegDeleteValueA(prodkey, "Language");
4106     RegDeleteValueA(prodkey, "ProductName");
4107     RegDeleteValueA(prodkey, "Assignment");
4108     RegDeleteValueA(prodkey, "PackageCode");
4109     RegDeleteValueA(prodkey, "Version");
4110     RegDeleteValueA(prodkey, "ProductIcon");
4111     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4112     RegDeleteValueA(source, "PackageName");
4113     delete_key(source, "", access & KEY_WOW64_64KEY);
4114     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4115     RegCloseKey(propkey);
4116     RegCloseKey(localkey);
4117     RegCloseKey(source);
4118     RegCloseKey(prodkey);
4119     LocalFree(usersid);
4120 }
4121
4122 static void test_MsiGetProductInfoEx(void)
4123 {
4124     UINT r;
4125     LONG res;
4126     HKEY propkey, userkey;
4127     HKEY prodkey, localkey;
4128     CHAR prodcode[MAX_PATH];
4129     CHAR prod_squashed[MAX_PATH];
4130     CHAR packcode[MAX_PATH];
4131     CHAR pack_squashed[MAX_PATH];
4132     CHAR buf[MAX_PATH];
4133     CHAR keypath[MAX_PATH];
4134     LPSTR usersid;
4135     DWORD sz;
4136     REGSAM access = KEY_ALL_ACCESS;
4137     BOOL wow64;
4138
4139     if (!pMsiGetProductInfoExA)
4140     {
4141         win_skip("MsiGetProductInfoExA is not available\n");
4142         return;
4143     }
4144
4145     create_test_guid(prodcode, prod_squashed);
4146     create_test_guid(packcode, pack_squashed);
4147     get_user_sid(&usersid);
4148
4149     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
4150         access |= KEY_WOW64_64KEY;
4151
4152     /* NULL szProductCode */
4153     sz = MAX_PATH;
4154     lstrcpyA(buf, "apple");
4155     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4156                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4157     ok(r == ERROR_INVALID_PARAMETER,
4158        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4159     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4160     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4161
4162     /* empty szProductCode */
4163     sz = MAX_PATH;
4164     lstrcpyA(buf, "apple");
4165     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4166                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4167     ok(r == ERROR_INVALID_PARAMETER,
4168        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4169     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4170     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4171
4172     /* garbage szProductCode */
4173     sz = MAX_PATH;
4174     lstrcpyA(buf, "apple");
4175     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4176                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4177     ok(r == ERROR_INVALID_PARAMETER,
4178        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4179     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4180     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4181
4182     /* guid without brackets */
4183     sz = MAX_PATH;
4184     lstrcpyA(buf, "apple");
4185     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
4186                               MSIINSTALLCONTEXT_USERUNMANAGED,
4187                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4188     ok(r == ERROR_INVALID_PARAMETER,
4189        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4190     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4191     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4192
4193     /* guid with brackets */
4194     sz = MAX_PATH;
4195     lstrcpyA(buf, "apple");
4196     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
4197                               MSIINSTALLCONTEXT_USERUNMANAGED,
4198                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4199     ok(r == ERROR_UNKNOWN_PRODUCT,
4200        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4201     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4202     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4203
4204     /* szValue is non-NULL while pcchValue is NULL */
4205     lstrcpyA(buf, "apple");
4206     r = pMsiGetProductInfoExA(prodcode, usersid,
4207                               MSIINSTALLCONTEXT_USERUNMANAGED,
4208                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
4209     ok(r == ERROR_INVALID_PARAMETER,
4210        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4211     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4212
4213     /* dwContext is out of range */
4214     sz = MAX_PATH;
4215     lstrcpyA(buf, "apple");
4216     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
4217                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4218     ok(r == ERROR_INVALID_PARAMETER,
4219        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4220     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4221     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4222
4223     /* szProperty is NULL */
4224     sz = MAX_PATH;
4225     lstrcpyA(buf, "apple");
4226     r = pMsiGetProductInfoExA(prodcode, usersid,
4227                               MSIINSTALLCONTEXT_USERUNMANAGED,
4228                               NULL, buf, &sz);
4229     ok(r == ERROR_INVALID_PARAMETER,
4230        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4231     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4232     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4233
4234     /* szProperty is empty */
4235     sz = MAX_PATH;
4236     lstrcpyA(buf, "apple");
4237     r = pMsiGetProductInfoExA(prodcode, usersid,
4238                               MSIINSTALLCONTEXT_USERUNMANAGED,
4239                               "", buf, &sz);
4240     ok(r == ERROR_INVALID_PARAMETER,
4241        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4242     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4243     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4244
4245     /* szProperty is not a valid property */
4246     sz = MAX_PATH;
4247     lstrcpyA(buf, "apple");
4248     r = pMsiGetProductInfoExA(prodcode, usersid,
4249                               MSIINSTALLCONTEXT_USERUNMANAGED,
4250                               "notvalid", buf, &sz);
4251     ok(r == ERROR_UNKNOWN_PRODUCT,
4252        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4253     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4254     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4255
4256     /* same length as guid, but random */
4257     sz = MAX_PATH;
4258     lstrcpyA(buf, "apple");
4259     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
4260                               MSIINSTALLCONTEXT_USERUNMANAGED,
4261                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4262     ok(r == ERROR_INVALID_PARAMETER,
4263        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4264     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4265     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4266
4267     /* MSIINSTALLCONTEXT_USERUNMANAGED */
4268
4269     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4270     lstrcatA(keypath, usersid);
4271     lstrcatA(keypath, "\\Products\\");
4272     lstrcatA(keypath, prod_squashed);
4273
4274     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4275     if (res == ERROR_ACCESS_DENIED)
4276     {
4277         skip("Not enough rights to perform tests\n");
4278         LocalFree(usersid);
4279         return;
4280     }
4281     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4282
4283     /* local user product key exists */
4284     sz = MAX_PATH;
4285     lstrcpyA(buf, "apple");
4286     r = pMsiGetProductInfoExA(prodcode, usersid,
4287                               MSIINSTALLCONTEXT_USERUNMANAGED,
4288                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4289     ok(r == ERROR_UNKNOWN_PRODUCT,
4290        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4291     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4292     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4293
4294     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4295     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4296
4297     /* InstallProperties key exists */
4298     sz = MAX_PATH;
4299     lstrcpyA(buf, "apple");
4300     r = pMsiGetProductInfoExA(prodcode, usersid,
4301                               MSIINSTALLCONTEXT_USERUNMANAGED,
4302                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4303     ok(r == ERROR_UNKNOWN_PRODUCT,
4304        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4305     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4306     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4307
4308     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4309     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4310
4311     /* LocalPackage value exists */
4312     sz = MAX_PATH;
4313     lstrcpyA(buf, "apple");
4314     r = pMsiGetProductInfoExA(prodcode, usersid,
4315                               MSIINSTALLCONTEXT_USERUNMANAGED,
4316                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4317     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4318     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4319     ok(sz == 1, "Expected 1, got %d\n", sz);
4320
4321     RegDeleteValueA(propkey, "LocalPackage");
4322
4323     /* LocalPackage value must exist */
4324     sz = MAX_PATH;
4325     lstrcpyA(buf, "apple");
4326     r = pMsiGetProductInfoExA(prodcode, usersid,
4327                               MSIINSTALLCONTEXT_USERUNMANAGED,
4328                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4329     ok(r == ERROR_UNKNOWN_PRODUCT,
4330        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4331     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4332     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4333
4334     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4335     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4336
4337     /* LocalPackage exists, but HelpLink does not exist */
4338     sz = MAX_PATH;
4339     lstrcpyA(buf, "apple");
4340     r = pMsiGetProductInfoExA(prodcode, usersid,
4341                               MSIINSTALLCONTEXT_USERUNMANAGED,
4342                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4344     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4345     ok(sz == 0, "Expected 0, got %d\n", sz);
4346
4347     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4349
4350     /* HelpLink value exists */
4351     sz = MAX_PATH;
4352     lstrcpyA(buf, "apple");
4353     r = pMsiGetProductInfoExA(prodcode, usersid,
4354                               MSIINSTALLCONTEXT_USERUNMANAGED,
4355                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4357     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4358     ok(sz == 4, "Expected 4, got %d\n", sz);
4359
4360     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4362
4363     /* HelpTelephone value exists */
4364     sz = MAX_PATH;
4365     lstrcpyA(buf, "apple");
4366     r = pMsiGetProductInfoExA(prodcode, usersid,
4367                               MSIINSTALLCONTEXT_USERUNMANAGED,
4368                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4369     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4370     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4371     ok(sz == 5, "Expected 5, got %d\n", sz);
4372
4373     /* szValue and pcchValue are NULL */
4374     r = pMsiGetProductInfoExA(prodcode, usersid,
4375                               MSIINSTALLCONTEXT_USERUNMANAGED,
4376                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4377     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4378
4379     /* pcchValue is exactly 5 */
4380     sz = 5;
4381     lstrcpyA(buf, "apple");
4382     r = pMsiGetProductInfoExA(prodcode, usersid,
4383                               MSIINSTALLCONTEXT_USERUNMANAGED,
4384                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4385     ok(r == ERROR_MORE_DATA,
4386        "Expected ERROR_MORE_DATA, got %d\n", r);
4387     ok(sz == 10, "Expected 10, got %d\n", sz);
4388
4389     /* szValue is NULL, pcchValue is exactly 5 */
4390     sz = 5;
4391     r = pMsiGetProductInfoExA(prodcode, usersid,
4392                               MSIINSTALLCONTEXT_USERUNMANAGED,
4393                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4394     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4395     ok(sz == 10, "Expected 10, got %d\n", sz);
4396
4397     /* szValue is NULL, pcchValue is MAX_PATH */
4398     sz = MAX_PATH;
4399     r = pMsiGetProductInfoExA(prodcode, usersid,
4400                               MSIINSTALLCONTEXT_USERUNMANAGED,
4401                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4402     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4403     ok(sz == 10, "Expected 10, got %d\n", sz);
4404
4405     /* pcchValue is exactly 0 */
4406     sz = 0;
4407     lstrcpyA(buf, "apple");
4408     r = pMsiGetProductInfoExA(prodcode, usersid,
4409                               MSIINSTALLCONTEXT_USERUNMANAGED,
4410                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4411     ok(r == ERROR_MORE_DATA,
4412        "Expected ERROR_MORE_DATA, got %d\n", r);
4413     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4414     ok(sz == 10, "Expected 10, got %d\n", sz);
4415
4416     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4418
4419     /* szProperty is not a valid property */
4420     sz = MAX_PATH;
4421     lstrcpyA(buf, "apple");
4422     r = pMsiGetProductInfoExA(prodcode, usersid,
4423                               MSIINSTALLCONTEXT_USERUNMANAGED,
4424                               "notvalid", buf, &sz);
4425     ok(r == ERROR_UNKNOWN_PROPERTY,
4426        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4427     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4428     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4429
4430     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4431     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4432
4433     /* InstallDate value exists */
4434     sz = MAX_PATH;
4435     lstrcpyA(buf, "apple");
4436     r = pMsiGetProductInfoExA(prodcode, usersid,
4437                               MSIINSTALLCONTEXT_USERUNMANAGED,
4438                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4439     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4440     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4441     ok(sz == 4, "Expected 4, got %d\n", sz);
4442
4443     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4445
4446     /* DisplayName value exists */
4447     sz = MAX_PATH;
4448     lstrcpyA(buf, "apple");
4449     r = pMsiGetProductInfoExA(prodcode, usersid,
4450                               MSIINSTALLCONTEXT_USERUNMANAGED,
4451                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4452     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4453     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4454     ok(sz == 4, "Expected 4, got %d\n", sz);
4455
4456     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4457     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4458
4459     /* InstallLocation value exists */
4460     sz = MAX_PATH;
4461     lstrcpyA(buf, "apple");
4462     r = pMsiGetProductInfoExA(prodcode, usersid,
4463                               MSIINSTALLCONTEXT_USERUNMANAGED,
4464                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4465     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4466     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4467     ok(sz == 3, "Expected 3, got %d\n", sz);
4468
4469     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4470     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4471
4472     /* InstallSource value exists */
4473     sz = MAX_PATH;
4474     lstrcpyA(buf, "apple");
4475     r = pMsiGetProductInfoExA(prodcode, usersid,
4476                               MSIINSTALLCONTEXT_USERUNMANAGED,
4477                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4478     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4479     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4480     ok(sz == 6, "Expected 6, got %d\n", sz);
4481
4482     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4483     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4484
4485     /* LocalPackage value exists */
4486     sz = MAX_PATH;
4487     lstrcpyA(buf, "apple");
4488     r = pMsiGetProductInfoExA(prodcode, usersid,
4489                               MSIINSTALLCONTEXT_USERUNMANAGED,
4490                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4491     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4492     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4493     ok(sz == 5, "Expected 5, got %d\n", sz);
4494
4495     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4496     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4497
4498     /* Publisher value exists */
4499     sz = MAX_PATH;
4500     lstrcpyA(buf, "apple");
4501     r = pMsiGetProductInfoExA(prodcode, usersid,
4502                               MSIINSTALLCONTEXT_USERUNMANAGED,
4503                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4504     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4505     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4506     ok(sz == 3, "Expected 3, got %d\n", sz);
4507
4508     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4510
4511     /* URLInfoAbout value exists */
4512     sz = MAX_PATH;
4513     lstrcpyA(buf, "apple");
4514     r = pMsiGetProductInfoExA(prodcode, usersid,
4515                               MSIINSTALLCONTEXT_USERUNMANAGED,
4516                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4517     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4518     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4519     ok(sz == 5, "Expected 5, got %d\n", sz);
4520
4521     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4522     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4523
4524     /* URLUpdateInfo value exists */
4525     sz = MAX_PATH;
4526     lstrcpyA(buf, "apple");
4527     r = pMsiGetProductInfoExA(prodcode, usersid,
4528                               MSIINSTALLCONTEXT_USERUNMANAGED,
4529                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4530     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4531     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4532     ok(sz == 6, "Expected 6, got %d\n", sz);
4533
4534     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4535     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4536
4537     /* VersionMinor value exists */
4538     sz = MAX_PATH;
4539     lstrcpyA(buf, "apple");
4540     r = pMsiGetProductInfoExA(prodcode, usersid,
4541                               MSIINSTALLCONTEXT_USERUNMANAGED,
4542                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4543     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4544     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4545     ok(sz == 1, "Expected 1, got %d\n", sz);
4546
4547     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4549
4550     /* VersionMajor value exists */
4551     sz = MAX_PATH;
4552     lstrcpyA(buf, "apple");
4553     r = pMsiGetProductInfoExA(prodcode, usersid,
4554                               MSIINSTALLCONTEXT_USERUNMANAGED,
4555                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4556     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4557     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4558     ok(sz == 1, "Expected 1, got %d\n", sz);
4559
4560     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4562
4563     /* DisplayVersion value exists */
4564     sz = MAX_PATH;
4565     lstrcpyA(buf, "apple");
4566     r = pMsiGetProductInfoExA(prodcode, usersid,
4567                               MSIINSTALLCONTEXT_USERUNMANAGED,
4568                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4569     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4570     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4571     ok(sz == 5, "Expected 5, got %d\n", sz);
4572
4573     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4574     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4575
4576     /* ProductID value exists */
4577     sz = MAX_PATH;
4578     lstrcpyA(buf, "apple");
4579     r = pMsiGetProductInfoExA(prodcode, usersid,
4580                               MSIINSTALLCONTEXT_USERUNMANAGED,
4581                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4582     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4583     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4584     ok(sz == 2, "Expected 2, got %d\n", sz);
4585
4586     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4587     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4588
4589     /* RegCompany value exists */
4590     sz = MAX_PATH;
4591     lstrcpyA(buf, "apple");
4592     r = pMsiGetProductInfoExA(prodcode, usersid,
4593                               MSIINSTALLCONTEXT_USERUNMANAGED,
4594                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4595     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4596     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4597     ok(sz == 4, "Expected 4, got %d\n", sz);
4598
4599     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4600     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4601
4602     /* RegOwner value exists */
4603     sz = MAX_PATH;
4604     lstrcpyA(buf, "apple");
4605     r = pMsiGetProductInfoExA(prodcode, usersid,
4606                               MSIINSTALLCONTEXT_USERUNMANAGED,
4607                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4608     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4609     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4610     ok(sz == 5, "Expected 5, got %d\n", sz);
4611
4612     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4614
4615     /* Transforms value exists */
4616     sz = MAX_PATH;
4617     lstrcpyA(buf, "apple");
4618     r = pMsiGetProductInfoExA(prodcode, usersid,
4619                               MSIINSTALLCONTEXT_USERUNMANAGED,
4620                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4621     ok(r == ERROR_UNKNOWN_PRODUCT,
4622        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4623     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4624     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4625
4626     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4628
4629     /* Language value exists */
4630     sz = MAX_PATH;
4631     lstrcpyA(buf, "apple");
4632     r = pMsiGetProductInfoExA(prodcode, usersid,
4633                               MSIINSTALLCONTEXT_USERUNMANAGED,
4634                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4635     ok(r == ERROR_UNKNOWN_PRODUCT,
4636        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4637     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4638     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4639
4640     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4642
4643     /* ProductName value exists */
4644     sz = MAX_PATH;
4645     lstrcpyA(buf, "apple");
4646     r = pMsiGetProductInfoExA(prodcode, usersid,
4647                               MSIINSTALLCONTEXT_USERUNMANAGED,
4648                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4649     ok(r == ERROR_UNKNOWN_PRODUCT,
4650        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4651     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4652     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4653
4654     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4655     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4656
4657     /* FIXME */
4658
4659     /* AssignmentType value exists */
4660     sz = MAX_PATH;
4661     lstrcpyA(buf, "apple");
4662     r = pMsiGetProductInfoExA(prodcode, usersid,
4663                               MSIINSTALLCONTEXT_USERUNMANAGED,
4664                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4665     ok(r == ERROR_UNKNOWN_PRODUCT,
4666        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4667     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4668     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4669
4670     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4671     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4672
4673     /* PackageCode value exists */
4674     sz = MAX_PATH;
4675     lstrcpyA(buf, "apple");
4676     r = pMsiGetProductInfoExA(prodcode, usersid,
4677                               MSIINSTALLCONTEXT_USERUNMANAGED,
4678                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4679     ok(r == ERROR_UNKNOWN_PRODUCT,
4680        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4681     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4682     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4683
4684     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4685     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4686
4687     /* Version value exists */
4688     sz = MAX_PATH;
4689     lstrcpyA(buf, "apple");
4690     r = pMsiGetProductInfoExA(prodcode, usersid,
4691                               MSIINSTALLCONTEXT_USERUNMANAGED,
4692                               INSTALLPROPERTY_VERSION, buf, &sz);
4693     ok(r == ERROR_UNKNOWN_PRODUCT,
4694        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4695     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4696     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4697
4698     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4700
4701     /* ProductIcon value exists */
4702     sz = MAX_PATH;
4703     lstrcpyA(buf, "apple");
4704     r = pMsiGetProductInfoExA(prodcode, usersid,
4705                               MSIINSTALLCONTEXT_USERUNMANAGED,
4706                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4707     ok(r == ERROR_UNKNOWN_PRODUCT,
4708        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4709     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4710     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4711
4712     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4714
4715     /* PackageName value exists */
4716     sz = MAX_PATH;
4717     lstrcpyA(buf, "apple");
4718     r = pMsiGetProductInfoExA(prodcode, usersid,
4719                               MSIINSTALLCONTEXT_USERUNMANAGED,
4720                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4721     ok(r == ERROR_UNKNOWN_PRODUCT,
4722        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4723     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4724     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4725
4726     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4728
4729     /* AuthorizedLUAApp value exists */
4730     sz = MAX_PATH;
4731     lstrcpyA(buf, "apple");
4732     r = pMsiGetProductInfoExA(prodcode, usersid,
4733                               MSIINSTALLCONTEXT_USERUNMANAGED,
4734                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4735     ok(r == ERROR_UNKNOWN_PRODUCT,
4736        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4737     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4738     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4739
4740     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4741     RegDeleteValueA(propkey, "PackageName");
4742     RegDeleteValueA(propkey, "ProductIcon");
4743     RegDeleteValueA(propkey, "Version");
4744     RegDeleteValueA(propkey, "PackageCode");
4745     RegDeleteValueA(propkey, "AssignmentType");
4746     RegDeleteValueA(propkey, "ProductName");
4747     RegDeleteValueA(propkey, "Language");
4748     RegDeleteValueA(propkey, "Transforms");
4749     RegDeleteValueA(propkey, "RegOwner");
4750     RegDeleteValueA(propkey, "RegCompany");
4751     RegDeleteValueA(propkey, "ProductID");
4752     RegDeleteValueA(propkey, "DisplayVersion");
4753     RegDeleteValueA(propkey, "VersionMajor");
4754     RegDeleteValueA(propkey, "VersionMinor");
4755     RegDeleteValueA(propkey, "URLUpdateInfo");
4756     RegDeleteValueA(propkey, "URLInfoAbout");
4757     RegDeleteValueA(propkey, "Publisher");
4758     RegDeleteValueA(propkey, "LocalPackage");
4759     RegDeleteValueA(propkey, "InstallSource");
4760     RegDeleteValueA(propkey, "InstallLocation");
4761     RegDeleteValueA(propkey, "DisplayName");
4762     RegDeleteValueA(propkey, "InstallDate");
4763     RegDeleteValueA(propkey, "HelpTelephone");
4764     RegDeleteValueA(propkey, "HelpLink");
4765     RegDeleteValueA(propkey, "LocalPackage");
4766     RegDeleteKeyA(propkey, "");
4767     RegCloseKey(propkey);
4768     RegDeleteKeyA(localkey, "");
4769     RegCloseKey(localkey);
4770
4771     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4772     lstrcatA(keypath, usersid);
4773     lstrcatA(keypath, "\\Installer\\Products\\");
4774     lstrcatA(keypath, prod_squashed);
4775
4776     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
4777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4778
4779     /* user product key exists */
4780     sz = MAX_PATH;
4781     lstrcpyA(buf, "apple");
4782     r = pMsiGetProductInfoExA(prodcode, usersid,
4783                               MSIINSTALLCONTEXT_USERUNMANAGED,
4784                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4785     ok(r == ERROR_UNKNOWN_PRODUCT,
4786        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4787     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4788     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4789
4790     RegDeleteKeyA(userkey, "");
4791     RegCloseKey(userkey);
4792
4793     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4794     lstrcatA(keypath, prod_squashed);
4795
4796     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4798
4799     sz = MAX_PATH;
4800     lstrcpyA(buf, "apple");
4801     r = pMsiGetProductInfoExA(prodcode, usersid,
4802                               MSIINSTALLCONTEXT_USERUNMANAGED,
4803                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4805     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4806     ok(sz == 1, "Expected 1, got %d\n", sz);
4807
4808     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4809     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4810
4811     /* HelpLink value exists */
4812     sz = MAX_PATH;
4813     lstrcpyA(buf, "apple");
4814     r = pMsiGetProductInfoExA(prodcode, usersid,
4815                               MSIINSTALLCONTEXT_USERUNMANAGED,
4816                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4817     ok(r == ERROR_UNKNOWN_PROPERTY,
4818        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4819     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4820     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4821
4822     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4823     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4824
4825     /* HelpTelephone value exists */
4826     sz = MAX_PATH;
4827     lstrcpyA(buf, "apple");
4828     r = pMsiGetProductInfoExA(prodcode, usersid,
4829                               MSIINSTALLCONTEXT_USERUNMANAGED,
4830                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4831     ok(r == ERROR_UNKNOWN_PROPERTY,
4832        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4833     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4834     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4835
4836     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4837     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4838
4839     /* InstallDate value exists */
4840     sz = MAX_PATH;
4841     lstrcpyA(buf, "apple");
4842     r = pMsiGetProductInfoExA(prodcode, usersid,
4843                               MSIINSTALLCONTEXT_USERUNMANAGED,
4844                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4845     ok(r == ERROR_UNKNOWN_PROPERTY,
4846        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4847     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4848     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4849
4850     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4851     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4852
4853     /* DisplayName value exists */
4854     sz = MAX_PATH;
4855     lstrcpyA(buf, "apple");
4856     r = pMsiGetProductInfoExA(prodcode, usersid,
4857                               MSIINSTALLCONTEXT_USERUNMANAGED,
4858                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4859     ok(r == ERROR_UNKNOWN_PROPERTY,
4860        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4861     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4862     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4863
4864     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4865     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4866
4867     /* InstallLocation value exists */
4868     sz = MAX_PATH;
4869     lstrcpyA(buf, "apple");
4870     r = pMsiGetProductInfoExA(prodcode, usersid,
4871                               MSIINSTALLCONTEXT_USERUNMANAGED,
4872                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4873     ok(r == ERROR_UNKNOWN_PROPERTY,
4874        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4875     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4876     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4877
4878     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4880
4881     /* InstallSource value exists */
4882     sz = MAX_PATH;
4883     lstrcpyA(buf, "apple");
4884     r = pMsiGetProductInfoExA(prodcode, usersid,
4885                               MSIINSTALLCONTEXT_USERUNMANAGED,
4886                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4887     ok(r == ERROR_UNKNOWN_PROPERTY,
4888        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4889     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4890     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4891
4892     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4893     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4894
4895     /* LocalPackage value exists */
4896     sz = MAX_PATH;
4897     lstrcpyA(buf, "apple");
4898     r = pMsiGetProductInfoExA(prodcode, usersid,
4899                               MSIINSTALLCONTEXT_USERUNMANAGED,
4900                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4901     ok(r == ERROR_UNKNOWN_PROPERTY,
4902        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4903     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4904     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4905
4906     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4907     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4908
4909     /* Publisher value exists */
4910     sz = MAX_PATH;
4911     lstrcpyA(buf, "apple");
4912     r = pMsiGetProductInfoExA(prodcode, usersid,
4913                               MSIINSTALLCONTEXT_USERUNMANAGED,
4914                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4915     ok(r == ERROR_UNKNOWN_PROPERTY,
4916        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4917     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4918     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4919
4920     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4921     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4922
4923     /* URLInfoAbout value exists */
4924     sz = MAX_PATH;
4925     lstrcpyA(buf, "apple");
4926     r = pMsiGetProductInfoExA(prodcode, usersid,
4927                               MSIINSTALLCONTEXT_USERUNMANAGED,
4928                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4929     ok(r == ERROR_UNKNOWN_PROPERTY,
4930        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4931     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4932     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4933
4934     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4936
4937     /* URLUpdateInfo value exists */
4938     sz = MAX_PATH;
4939     lstrcpyA(buf, "apple");
4940     r = pMsiGetProductInfoExA(prodcode, usersid,
4941                               MSIINSTALLCONTEXT_USERUNMANAGED,
4942                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4943     ok(r == ERROR_UNKNOWN_PROPERTY,
4944        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4945     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4946     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4947
4948     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4949     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4950
4951     /* VersionMinor value exists */
4952     sz = MAX_PATH;
4953     lstrcpyA(buf, "apple");
4954     r = pMsiGetProductInfoExA(prodcode, usersid,
4955                               MSIINSTALLCONTEXT_USERUNMANAGED,
4956                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4957     ok(r == ERROR_UNKNOWN_PROPERTY,
4958        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4959     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4960     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4961
4962     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4964
4965     /* VersionMajor value exists */
4966     sz = MAX_PATH;
4967     lstrcpyA(buf, "apple");
4968     r = pMsiGetProductInfoExA(prodcode, usersid,
4969                               MSIINSTALLCONTEXT_USERUNMANAGED,
4970                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4971     ok(r == ERROR_UNKNOWN_PROPERTY,
4972        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4973     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4974     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4975
4976     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4978
4979     /* DisplayVersion value exists */
4980     sz = MAX_PATH;
4981     lstrcpyA(buf, "apple");
4982     r = pMsiGetProductInfoExA(prodcode, usersid,
4983                               MSIINSTALLCONTEXT_USERUNMANAGED,
4984                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4985     ok(r == ERROR_UNKNOWN_PROPERTY,
4986        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4987     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4988     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4989
4990     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4992
4993     /* ProductID value exists */
4994     sz = MAX_PATH;
4995     lstrcpyA(buf, "apple");
4996     r = pMsiGetProductInfoExA(prodcode, usersid,
4997                               MSIINSTALLCONTEXT_USERUNMANAGED,
4998                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4999     ok(r == ERROR_UNKNOWN_PROPERTY,
5000        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5001     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5002     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5003
5004     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5006
5007     /* RegCompany value exists */
5008     sz = MAX_PATH;
5009     lstrcpyA(buf, "apple");
5010     r = pMsiGetProductInfoExA(prodcode, usersid,
5011                               MSIINSTALLCONTEXT_USERUNMANAGED,
5012                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5013     ok(r == ERROR_UNKNOWN_PROPERTY,
5014        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5015     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5016     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5017
5018     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5020
5021     /* RegOwner value exists */
5022     sz = MAX_PATH;
5023     lstrcpyA(buf, "apple");
5024     r = pMsiGetProductInfoExA(prodcode, usersid,
5025                               MSIINSTALLCONTEXT_USERUNMANAGED,
5026                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5027     ok(r == ERROR_UNKNOWN_PROPERTY,
5028        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5029     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5030     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5031
5032     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5033     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5034
5035     /* Transforms value exists */
5036     sz = MAX_PATH;
5037     lstrcpyA(buf, "apple");
5038     r = pMsiGetProductInfoExA(prodcode, usersid,
5039                               MSIINSTALLCONTEXT_USERUNMANAGED,
5040                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5042     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5043     ok(sz == 5, "Expected 5, got %d\n", sz);
5044
5045     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5046     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5047
5048     /* Language value exists */
5049     sz = MAX_PATH;
5050     lstrcpyA(buf, "apple");
5051     r = pMsiGetProductInfoExA(prodcode, usersid,
5052                               MSIINSTALLCONTEXT_USERUNMANAGED,
5053                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5054     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5055     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5056     ok(sz == 4, "Expected 4, got %d\n", sz);
5057
5058     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5059     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5060
5061     /* ProductName value exists */
5062     sz = MAX_PATH;
5063     lstrcpyA(buf, "apple");
5064     r = pMsiGetProductInfoExA(prodcode, usersid,
5065                               MSIINSTALLCONTEXT_USERUNMANAGED,
5066                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5067     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5068     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5069     ok(sz == 4, "Expected 4, got %d\n", sz);
5070
5071     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5073
5074     /* FIXME */
5075
5076     /* AssignmentType value exists */
5077     sz = MAX_PATH;
5078     lstrcpyA(buf, "apple");
5079     r = pMsiGetProductInfoExA(prodcode, usersid,
5080                               MSIINSTALLCONTEXT_USERUNMANAGED,
5081                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5082     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5083     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5084     ok(sz == 0, "Expected 0, got %d\n", sz);
5085
5086     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5088
5089     /* FIXME */
5090
5091     /* PackageCode value exists */
5092     sz = MAX_PATH;
5093     lstrcpyA(buf, "apple");
5094     r = pMsiGetProductInfoExA(prodcode, usersid,
5095                               MSIINSTALLCONTEXT_USERUNMANAGED,
5096                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5097     todo_wine
5098     {
5099         ok(r == ERROR_BAD_CONFIGURATION,
5100            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5101         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5102         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5103     }
5104
5105     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5107
5108     /* Version value exists */
5109     sz = MAX_PATH;
5110     lstrcpyA(buf, "apple");
5111     r = pMsiGetProductInfoExA(prodcode, usersid,
5112                               MSIINSTALLCONTEXT_USERUNMANAGED,
5113                               INSTALLPROPERTY_VERSION, buf, &sz);
5114     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5115     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5116     ok(sz == 3, "Expected 3, got %d\n", sz);
5117
5118     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5119     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5120
5121     /* ProductIcon value exists */
5122     sz = MAX_PATH;
5123     lstrcpyA(buf, "apple");
5124     r = pMsiGetProductInfoExA(prodcode, usersid,
5125                               MSIINSTALLCONTEXT_USERUNMANAGED,
5126                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5127     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5128     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5129     ok(sz == 4, "Expected 4, got %d\n", sz);
5130
5131     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5133
5134     /* PackageName value exists */
5135     sz = MAX_PATH;
5136     lstrcpyA(buf, "apple");
5137     r = pMsiGetProductInfoExA(prodcode, usersid,
5138                               MSIINSTALLCONTEXT_USERUNMANAGED,
5139                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5140     todo_wine
5141     {
5142         ok(r == ERROR_UNKNOWN_PRODUCT,
5143            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5144         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5145         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5146     }
5147
5148     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5149     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5150
5151     /* AuthorizedLUAApp value exists */
5152     sz = MAX_PATH;
5153     lstrcpyA(buf, "apple");
5154     r = pMsiGetProductInfoExA(prodcode, usersid,
5155                               MSIINSTALLCONTEXT_USERUNMANAGED,
5156                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5157     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5158     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5159     ok(sz == 4, "Expected 4, got %d\n", sz);
5160
5161     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5162     RegDeleteValueA(prodkey, "PackageName");
5163     RegDeleteValueA(prodkey, "ProductIcon");
5164     RegDeleteValueA(prodkey, "Version");
5165     RegDeleteValueA(prodkey, "PackageCode");
5166     RegDeleteValueA(prodkey, "AssignmentType");
5167     RegDeleteValueA(prodkey, "ProductName");
5168     RegDeleteValueA(prodkey, "Language");
5169     RegDeleteValueA(prodkey, "Transforms");
5170     RegDeleteValueA(prodkey, "RegOwner");
5171     RegDeleteValueA(prodkey, "RegCompany");
5172     RegDeleteValueA(prodkey, "ProductID");
5173     RegDeleteValueA(prodkey, "DisplayVersion");
5174     RegDeleteValueA(prodkey, "VersionMajor");
5175     RegDeleteValueA(prodkey, "VersionMinor");
5176     RegDeleteValueA(prodkey, "URLUpdateInfo");
5177     RegDeleteValueA(prodkey, "URLInfoAbout");
5178     RegDeleteValueA(prodkey, "Publisher");
5179     RegDeleteValueA(prodkey, "LocalPackage");
5180     RegDeleteValueA(prodkey, "InstallSource");
5181     RegDeleteValueA(prodkey, "InstallLocation");
5182     RegDeleteValueA(prodkey, "DisplayName");
5183     RegDeleteValueA(prodkey, "InstallDate");
5184     RegDeleteValueA(prodkey, "HelpTelephone");
5185     RegDeleteValueA(prodkey, "HelpLink");
5186     RegDeleteValueA(prodkey, "LocalPackage");
5187     RegDeleteKeyA(prodkey, "");
5188     RegCloseKey(prodkey);
5189
5190     /* MSIINSTALLCONTEXT_USERMANAGED */
5191
5192     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5193     lstrcatA(keypath, usersid);
5194     lstrcatA(keypath, "\\Products\\");
5195     lstrcatA(keypath, prod_squashed);
5196
5197     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5199
5200     /* local user product key exists */
5201     sz = MAX_PATH;
5202     lstrcpyA(buf, "apple");
5203     r = pMsiGetProductInfoExA(prodcode, usersid,
5204                               MSIINSTALLCONTEXT_USERMANAGED,
5205                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5206     ok(r == ERROR_UNKNOWN_PRODUCT,
5207        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5208     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5209     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5210
5211     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5213
5214     /* InstallProperties key exists */
5215     sz = MAX_PATH;
5216     lstrcpyA(buf, "apple");
5217     r = pMsiGetProductInfoExA(prodcode, usersid,
5218                               MSIINSTALLCONTEXT_USERMANAGED,
5219                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5220     ok(r == ERROR_UNKNOWN_PRODUCT,
5221        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5222     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5223     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5224
5225     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5227
5228     /* ManagedLocalPackage value exists */
5229     sz = MAX_PATH;
5230     lstrcpyA(buf, "apple");
5231     r = pMsiGetProductInfoExA(prodcode, usersid,
5232                               MSIINSTALLCONTEXT_USERMANAGED,
5233                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5235     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5236     ok(sz == 1, "Expected 1, got %d\n", sz);
5237
5238     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5240
5241     /* HelpLink value exists */
5242     sz = MAX_PATH;
5243     lstrcpyA(buf, "apple");
5244     r = pMsiGetProductInfoExA(prodcode, usersid,
5245                               MSIINSTALLCONTEXT_USERMANAGED,
5246                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5247     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5248     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5249     ok(sz == 4, "Expected 4, got %d\n", sz);
5250
5251     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5252     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5253
5254     /* HelpTelephone value exists */
5255     sz = MAX_PATH;
5256     lstrcpyA(buf, "apple");
5257     r = pMsiGetProductInfoExA(prodcode, usersid,
5258                               MSIINSTALLCONTEXT_USERMANAGED,
5259                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5260     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5261     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5262     ok(sz == 5, "Expected 5, got %d\n", sz);
5263
5264     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5266
5267     /* InstallDate value exists */
5268     sz = MAX_PATH;
5269     lstrcpyA(buf, "apple");
5270     r = pMsiGetProductInfoExA(prodcode, usersid,
5271                               MSIINSTALLCONTEXT_USERMANAGED,
5272                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5274     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5275     ok(sz == 4, "Expected 4, got %d\n", sz);
5276
5277     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5279
5280     /* DisplayName value exists */
5281     sz = MAX_PATH;
5282     lstrcpyA(buf, "apple");
5283     r = pMsiGetProductInfoExA(prodcode, usersid,
5284                               MSIINSTALLCONTEXT_USERMANAGED,
5285                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5287     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5288     ok(sz == 4, "Expected 4, got %d\n", sz);
5289
5290     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5292
5293     /* InstallLocation value exists */
5294     sz = MAX_PATH;
5295     lstrcpyA(buf, "apple");
5296     r = pMsiGetProductInfoExA(prodcode, usersid,
5297                               MSIINSTALLCONTEXT_USERMANAGED,
5298                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5299     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5300     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5301     ok(sz == 3, "Expected 3, got %d\n", sz);
5302
5303     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5305
5306     /* InstallSource value exists */
5307     sz = MAX_PATH;
5308     lstrcpyA(buf, "apple");
5309     r = pMsiGetProductInfoExA(prodcode, usersid,
5310                               MSIINSTALLCONTEXT_USERMANAGED,
5311                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5312     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5313     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5314     ok(sz == 6, "Expected 6, got %d\n", sz);
5315
5316     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5317     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5318
5319     /* LocalPackage value exists */
5320     sz = MAX_PATH;
5321     lstrcpyA(buf, "apple");
5322     r = pMsiGetProductInfoExA(prodcode, usersid,
5323                               MSIINSTALLCONTEXT_USERMANAGED,
5324                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5326     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5327     ok(sz == 5, "Expected 5, got %d\n", sz);
5328
5329     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5330     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5331
5332     /* Publisher value exists */
5333     sz = MAX_PATH;
5334     lstrcpyA(buf, "apple");
5335     r = pMsiGetProductInfoExA(prodcode, usersid,
5336                               MSIINSTALLCONTEXT_USERMANAGED,
5337                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5338     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5339     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5340     ok(sz == 3, "Expected 3, got %d\n", sz);
5341
5342     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5343     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5344
5345     /* URLInfoAbout value exists */
5346     sz = MAX_PATH;
5347     lstrcpyA(buf, "apple");
5348     r = pMsiGetProductInfoExA(prodcode, usersid,
5349                               MSIINSTALLCONTEXT_USERMANAGED,
5350                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5351     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5352     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5353     ok(sz == 5, "Expected 5, got %d\n", sz);
5354
5355     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5356     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5357
5358     /* URLUpdateInfo value exists */
5359     sz = MAX_PATH;
5360     lstrcpyA(buf, "apple");
5361     r = pMsiGetProductInfoExA(prodcode, usersid,
5362                               MSIINSTALLCONTEXT_USERMANAGED,
5363                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5364     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5365     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5366     ok(sz == 6, "Expected 6, got %d\n", sz);
5367
5368     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5369     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5370
5371     /* VersionMinor value exists */
5372     sz = MAX_PATH;
5373     lstrcpyA(buf, "apple");
5374     r = pMsiGetProductInfoExA(prodcode, usersid,
5375                               MSIINSTALLCONTEXT_USERMANAGED,
5376                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5377     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5378     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5379     ok(sz == 1, "Expected 1, got %d\n", sz);
5380
5381     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5382     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5383
5384     /* VersionMajor value exists */
5385     sz = MAX_PATH;
5386     lstrcpyA(buf, "apple");
5387     r = pMsiGetProductInfoExA(prodcode, usersid,
5388                               MSIINSTALLCONTEXT_USERMANAGED,
5389                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5390     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5391     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5392     ok(sz == 1, "Expected 1, got %d\n", sz);
5393
5394     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5395     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5396
5397     /* DisplayVersion value exists */
5398     sz = MAX_PATH;
5399     lstrcpyA(buf, "apple");
5400     r = pMsiGetProductInfoExA(prodcode, usersid,
5401                               MSIINSTALLCONTEXT_USERMANAGED,
5402                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5403     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5404     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5405     ok(sz == 5, "Expected 5, got %d\n", sz);
5406
5407     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5409
5410     /* ProductID value exists */
5411     sz = MAX_PATH;
5412     lstrcpyA(buf, "apple");
5413     r = pMsiGetProductInfoExA(prodcode, usersid,
5414                               MSIINSTALLCONTEXT_USERMANAGED,
5415                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5416     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5417     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5418     ok(sz == 2, "Expected 2, got %d\n", sz);
5419
5420     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5421     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5422
5423     /* RegCompany value exists */
5424     sz = MAX_PATH;
5425     lstrcpyA(buf, "apple");
5426     r = pMsiGetProductInfoExA(prodcode, usersid,
5427                               MSIINSTALLCONTEXT_USERMANAGED,
5428                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5429     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5430     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5431     ok(sz == 4, "Expected 4, got %d\n", sz);
5432
5433     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5435
5436     /* RegOwner value exists */
5437     sz = MAX_PATH;
5438     lstrcpyA(buf, "apple");
5439     r = pMsiGetProductInfoExA(prodcode, usersid,
5440                               MSIINSTALLCONTEXT_USERMANAGED,
5441                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5442     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5443     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5444     ok(sz == 5, "Expected 5, got %d\n", sz);
5445
5446     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5447     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5448
5449     /* Transforms value exists */
5450     sz = MAX_PATH;
5451     lstrcpyA(buf, "apple");
5452     r = pMsiGetProductInfoExA(prodcode, usersid,
5453                               MSIINSTALLCONTEXT_USERMANAGED,
5454                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5455     ok(r == ERROR_UNKNOWN_PRODUCT,
5456        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5457     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5458     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5459
5460     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5461     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5462
5463     /* Language value exists */
5464     sz = MAX_PATH;
5465     lstrcpyA(buf, "apple");
5466     r = pMsiGetProductInfoExA(prodcode, usersid,
5467                               MSIINSTALLCONTEXT_USERMANAGED,
5468                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5469     ok(r == ERROR_UNKNOWN_PRODUCT,
5470        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5471     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5472     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5473
5474     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5475     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5476
5477     /* ProductName value exists */
5478     sz = MAX_PATH;
5479     lstrcpyA(buf, "apple");
5480     r = pMsiGetProductInfoExA(prodcode, usersid,
5481                               MSIINSTALLCONTEXT_USERMANAGED,
5482                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5483     ok(r == ERROR_UNKNOWN_PRODUCT,
5484        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5485     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5486     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5487
5488     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5489     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5490
5491     /* FIXME */
5492
5493     /* AssignmentType value exists */
5494     sz = MAX_PATH;
5495     lstrcpyA(buf, "apple");
5496     r = pMsiGetProductInfoExA(prodcode, usersid,
5497                               MSIINSTALLCONTEXT_USERMANAGED,
5498                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5499     ok(r == ERROR_UNKNOWN_PRODUCT,
5500        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5501     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5502     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5503
5504     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5505     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5506
5507     /* PackageCode value exists */
5508     sz = MAX_PATH;
5509     lstrcpyA(buf, "apple");
5510     r = pMsiGetProductInfoExA(prodcode, usersid,
5511                               MSIINSTALLCONTEXT_USERMANAGED,
5512                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5513     ok(r == ERROR_UNKNOWN_PRODUCT,
5514        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5515     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5516     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5517
5518     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5519     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5520
5521     /* Version value exists */
5522     sz = MAX_PATH;
5523     lstrcpyA(buf, "apple");
5524     r = pMsiGetProductInfoExA(prodcode, usersid,
5525                               MSIINSTALLCONTEXT_USERMANAGED,
5526                               INSTALLPROPERTY_VERSION, buf, &sz);
5527     ok(r == ERROR_UNKNOWN_PRODUCT,
5528        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5529     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5530     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5531
5532     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5534
5535     /* ProductIcon value exists */
5536     sz = MAX_PATH;
5537     lstrcpyA(buf, "apple");
5538     r = pMsiGetProductInfoExA(prodcode, usersid,
5539                               MSIINSTALLCONTEXT_USERMANAGED,
5540                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5541     ok(r == ERROR_UNKNOWN_PRODUCT,
5542        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5543     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5544     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5545
5546     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5547     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5548
5549     /* PackageName value exists */
5550     sz = MAX_PATH;
5551     lstrcpyA(buf, "apple");
5552     r = pMsiGetProductInfoExA(prodcode, usersid,
5553                               MSIINSTALLCONTEXT_USERMANAGED,
5554                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5555     ok(r == ERROR_UNKNOWN_PRODUCT,
5556        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5557     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5558     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5559
5560     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5562
5563     /* AuthorizedLUAApp value exists */
5564     sz = MAX_PATH;
5565     lstrcpyA(buf, "apple");
5566     r = pMsiGetProductInfoExA(prodcode, usersid,
5567                               MSIINSTALLCONTEXT_USERMANAGED,
5568                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5569     ok(r == ERROR_UNKNOWN_PRODUCT,
5570        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5571     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5572     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5573
5574     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5575     RegDeleteValueA(propkey, "PackageName");
5576     RegDeleteValueA(propkey, "ProductIcon");
5577     RegDeleteValueA(propkey, "Version");
5578     RegDeleteValueA(propkey, "PackageCode");
5579     RegDeleteValueA(propkey, "AssignmentType");
5580     RegDeleteValueA(propkey, "ProductName");
5581     RegDeleteValueA(propkey, "Language");
5582     RegDeleteValueA(propkey, "Transforms");
5583     RegDeleteValueA(propkey, "RegOwner");
5584     RegDeleteValueA(propkey, "RegCompany");
5585     RegDeleteValueA(propkey, "ProductID");
5586     RegDeleteValueA(propkey, "DisplayVersion");
5587     RegDeleteValueA(propkey, "VersionMajor");
5588     RegDeleteValueA(propkey, "VersionMinor");
5589     RegDeleteValueA(propkey, "URLUpdateInfo");
5590     RegDeleteValueA(propkey, "URLInfoAbout");
5591     RegDeleteValueA(propkey, "Publisher");
5592     RegDeleteValueA(propkey, "LocalPackage");
5593     RegDeleteValueA(propkey, "InstallSource");
5594     RegDeleteValueA(propkey, "InstallLocation");
5595     RegDeleteValueA(propkey, "DisplayName");
5596     RegDeleteValueA(propkey, "InstallDate");
5597     RegDeleteValueA(propkey, "HelpTelephone");
5598     RegDeleteValueA(propkey, "HelpLink");
5599     RegDeleteValueA(propkey, "ManagedLocalPackage");
5600     RegDeleteKeyA(propkey, "");
5601     RegCloseKey(propkey);
5602     RegDeleteKeyA(localkey, "");
5603     RegCloseKey(localkey);
5604
5605     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5606     lstrcatA(keypath, usersid);
5607     lstrcatA(keypath, "\\Installer\\Products\\");
5608     lstrcatA(keypath, prod_squashed);
5609
5610     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5612
5613     /* user product key exists */
5614     sz = MAX_PATH;
5615     lstrcpyA(buf, "apple");
5616     r = pMsiGetProductInfoExA(prodcode, usersid,
5617                               MSIINSTALLCONTEXT_USERMANAGED,
5618                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5619     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5620     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5621     ok(sz == 1, "Expected 1, got %d\n", sz);
5622
5623     delete_key(userkey, "", access & KEY_WOW64_64KEY);
5624     RegCloseKey(userkey);
5625
5626     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5627     lstrcatA(keypath, prod_squashed);
5628
5629     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5631
5632     /* current user product key exists */
5633     sz = MAX_PATH;
5634     lstrcpyA(buf, "apple");
5635     r = pMsiGetProductInfoExA(prodcode, usersid,
5636                               MSIINSTALLCONTEXT_USERMANAGED,
5637                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5638     ok(r == ERROR_UNKNOWN_PRODUCT,
5639        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5640     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5641     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5642
5643     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5645
5646     /* HelpLink value exists, user product key does not exist */
5647     sz = MAX_PATH;
5648     lstrcpyA(buf, "apple");
5649     r = pMsiGetProductInfoExA(prodcode, usersid,
5650                               MSIINSTALLCONTEXT_USERMANAGED,
5651                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5652     ok(r == ERROR_UNKNOWN_PRODUCT,
5653        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5654     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5655     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5656
5657     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5658     lstrcatA(keypath, usersid);
5659     lstrcatA(keypath, "\\Installer\\Products\\");
5660     lstrcatA(keypath, prod_squashed);
5661
5662     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5663     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5664
5665     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5667
5668     /* HelpLink value exists, user product key does exist */
5669     sz = MAX_PATH;
5670     lstrcpyA(buf, "apple");
5671     r = pMsiGetProductInfoExA(prodcode, usersid,
5672                               MSIINSTALLCONTEXT_USERMANAGED,
5673                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5674     ok(r == ERROR_UNKNOWN_PROPERTY,
5675        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5676     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5677     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5678
5679     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5681
5682     /* HelpTelephone value exists */
5683     sz = MAX_PATH;
5684     lstrcpyA(buf, "apple");
5685     r = pMsiGetProductInfoExA(prodcode, usersid,
5686                               MSIINSTALLCONTEXT_USERMANAGED,
5687                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5688     ok(r == ERROR_UNKNOWN_PROPERTY,
5689        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5690     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5691     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5692
5693     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5694     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5695
5696     /* InstallDate value exists */
5697     sz = MAX_PATH;
5698     lstrcpyA(buf, "apple");
5699     r = pMsiGetProductInfoExA(prodcode, usersid,
5700                               MSIINSTALLCONTEXT_USERMANAGED,
5701                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5702     ok(r == ERROR_UNKNOWN_PROPERTY,
5703        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5704     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5705     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5706
5707     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5709
5710     /* DisplayName value exists */
5711     sz = MAX_PATH;
5712     lstrcpyA(buf, "apple");
5713     r = pMsiGetProductInfoExA(prodcode, usersid,
5714                               MSIINSTALLCONTEXT_USERMANAGED,
5715                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5716     ok(r == ERROR_UNKNOWN_PROPERTY,
5717        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5718     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5719     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5720
5721     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5723
5724     /* InstallLocation value exists */
5725     sz = MAX_PATH;
5726     lstrcpyA(buf, "apple");
5727     r = pMsiGetProductInfoExA(prodcode, usersid,
5728                               MSIINSTALLCONTEXT_USERMANAGED,
5729                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5730     ok(r == ERROR_UNKNOWN_PROPERTY,
5731        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5732     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5733     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5734
5735     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5737
5738     /* InstallSource value exists */
5739     sz = MAX_PATH;
5740     lstrcpyA(buf, "apple");
5741     r = pMsiGetProductInfoExA(prodcode, usersid,
5742                               MSIINSTALLCONTEXT_USERMANAGED,
5743                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5744     ok(r == ERROR_UNKNOWN_PROPERTY,
5745        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5746     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5747     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5748
5749     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5750     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5751
5752     /* LocalPackage value exists */
5753     sz = MAX_PATH;
5754     lstrcpyA(buf, "apple");
5755     r = pMsiGetProductInfoExA(prodcode, usersid,
5756                               MSIINSTALLCONTEXT_USERMANAGED,
5757                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5758     ok(r == ERROR_UNKNOWN_PROPERTY,
5759        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5760     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5761     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5762
5763     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5764     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5765
5766     /* Publisher value exists */
5767     sz = MAX_PATH;
5768     lstrcpyA(buf, "apple");
5769     r = pMsiGetProductInfoExA(prodcode, usersid,
5770                               MSIINSTALLCONTEXT_USERMANAGED,
5771                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5772     ok(r == ERROR_UNKNOWN_PROPERTY,
5773        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5774     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5775     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5776
5777     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5779
5780     /* URLInfoAbout value exists */
5781     sz = MAX_PATH;
5782     lstrcpyA(buf, "apple");
5783     r = pMsiGetProductInfoExA(prodcode, usersid,
5784                               MSIINSTALLCONTEXT_USERMANAGED,
5785                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5786     ok(r == ERROR_UNKNOWN_PROPERTY,
5787        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5788     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5789     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5790
5791     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5792     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5793
5794     /* URLUpdateInfo value exists */
5795     sz = MAX_PATH;
5796     lstrcpyA(buf, "apple");
5797     r = pMsiGetProductInfoExA(prodcode, usersid,
5798                               MSIINSTALLCONTEXT_USERMANAGED,
5799                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5800     ok(r == ERROR_UNKNOWN_PROPERTY,
5801        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5802     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5803     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5804
5805     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5806     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5807
5808     /* VersionMinor value exists */
5809     sz = MAX_PATH;
5810     lstrcpyA(buf, "apple");
5811     r = pMsiGetProductInfoExA(prodcode, usersid,
5812                               MSIINSTALLCONTEXT_USERMANAGED,
5813                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5814     ok(r == ERROR_UNKNOWN_PROPERTY,
5815        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5816     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5817     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5818
5819     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5820     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5821
5822     /* VersionMajor value exists */
5823     sz = MAX_PATH;
5824     lstrcpyA(buf, "apple");
5825     r = pMsiGetProductInfoExA(prodcode, usersid,
5826                               MSIINSTALLCONTEXT_USERMANAGED,
5827                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5828     ok(r == ERROR_UNKNOWN_PROPERTY,
5829        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5830     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5831     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5832
5833     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5834     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5835
5836     /* DisplayVersion value exists */
5837     sz = MAX_PATH;
5838     lstrcpyA(buf, "apple");
5839     r = pMsiGetProductInfoExA(prodcode, usersid,
5840                               MSIINSTALLCONTEXT_USERMANAGED,
5841                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5842     ok(r == ERROR_UNKNOWN_PROPERTY,
5843        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5844     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5845     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5846
5847     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5848     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5849
5850     /* ProductID value exists */
5851     sz = MAX_PATH;
5852     lstrcpyA(buf, "apple");
5853     r = pMsiGetProductInfoExA(prodcode, usersid,
5854                               MSIINSTALLCONTEXT_USERMANAGED,
5855                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5856     ok(r == ERROR_UNKNOWN_PROPERTY,
5857        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5858     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5859     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5860
5861     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5863
5864     /* RegCompany value exists */
5865     sz = MAX_PATH;
5866     lstrcpyA(buf, "apple");
5867     r = pMsiGetProductInfoExA(prodcode, usersid,
5868                               MSIINSTALLCONTEXT_USERMANAGED,
5869                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5870     ok(r == ERROR_UNKNOWN_PROPERTY,
5871        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5872     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5873     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5874
5875     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5876     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5877
5878     /* RegOwner value exists */
5879     sz = MAX_PATH;
5880     lstrcpyA(buf, "apple");
5881     r = pMsiGetProductInfoExA(prodcode, usersid,
5882                               MSIINSTALLCONTEXT_USERMANAGED,
5883                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5884     ok(r == ERROR_UNKNOWN_PROPERTY,
5885        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5886     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5887     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5888
5889     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5891
5892     /* Transforms value exists */
5893     sz = MAX_PATH;
5894     lstrcpyA(buf, "apple");
5895     r = pMsiGetProductInfoExA(prodcode, usersid,
5896                               MSIINSTALLCONTEXT_USERMANAGED,
5897                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5898     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5899     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5900     ok(sz == 5, "Expected 5, got %d\n", sz);
5901
5902     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5903     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5904
5905     /* Language value exists */
5906     sz = MAX_PATH;
5907     lstrcpyA(buf, "apple");
5908     r = pMsiGetProductInfoExA(prodcode, usersid,
5909                               MSIINSTALLCONTEXT_USERMANAGED,
5910                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5911     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5912     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5913     ok(sz == 4, "Expected 4, got %d\n", sz);
5914
5915     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5917
5918     /* ProductName value exists */
5919     sz = MAX_PATH;
5920     lstrcpyA(buf, "apple");
5921     r = pMsiGetProductInfoExA(prodcode, usersid,
5922                               MSIINSTALLCONTEXT_USERMANAGED,
5923                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5924     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5925     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5926     ok(sz == 4, "Expected 4, got %d\n", sz);
5927
5928     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5930
5931     /* FIXME */
5932
5933     /* AssignmentType value exists */
5934     sz = MAX_PATH;
5935     lstrcpyA(buf, "apple");
5936     r = pMsiGetProductInfoExA(prodcode, usersid,
5937                               MSIINSTALLCONTEXT_USERMANAGED,
5938                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5939     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5940     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5941     ok(sz == 0, "Expected 0, got %d\n", sz);
5942
5943     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5945
5946     /* FIXME */
5947
5948     /* PackageCode value exists */
5949     sz = MAX_PATH;
5950     lstrcpyA(buf, "apple");
5951     r = pMsiGetProductInfoExA(prodcode, usersid,
5952                               MSIINSTALLCONTEXT_USERMANAGED,
5953                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5954     todo_wine
5955     {
5956         ok(r == ERROR_BAD_CONFIGURATION,
5957            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5958         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5959         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5960     }
5961
5962     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5964
5965     /* Version value exists */
5966     sz = MAX_PATH;
5967     lstrcpyA(buf, "apple");
5968     r = pMsiGetProductInfoExA(prodcode, usersid,
5969                               MSIINSTALLCONTEXT_USERMANAGED,
5970                               INSTALLPROPERTY_VERSION, buf, &sz);
5971     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5972     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5973     ok(sz == 3, "Expected 3, got %d\n", sz);
5974
5975     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5976     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5977
5978     /* ProductIcon value exists */
5979     sz = MAX_PATH;
5980     lstrcpyA(buf, "apple");
5981     r = pMsiGetProductInfoExA(prodcode, usersid,
5982                               MSIINSTALLCONTEXT_USERMANAGED,
5983                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5984     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5985     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5986     ok(sz == 4, "Expected 4, got %d\n", sz);
5987
5988     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5989     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5990
5991     /* PackageName value exists */
5992     sz = MAX_PATH;
5993     lstrcpyA(buf, "apple");
5994     r = pMsiGetProductInfoExA(prodcode, usersid,
5995                               MSIINSTALLCONTEXT_USERMANAGED,
5996                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5997     todo_wine
5998     {
5999         ok(r == ERROR_UNKNOWN_PRODUCT,
6000            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6001         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6002         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6003     }
6004
6005     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6006     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6007
6008     /* AuthorizedLUAApp value exists */
6009     sz = MAX_PATH;
6010     lstrcpyA(buf, "apple");
6011     r = pMsiGetProductInfoExA(prodcode, usersid,
6012                               MSIINSTALLCONTEXT_USERMANAGED,
6013                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6014     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6015     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6016     ok(sz == 4, "Expected 4, got %d\n", sz);
6017
6018     RegDeleteValueA(userkey, "AuthorizedLUAApp");
6019     RegDeleteValueA(userkey, "PackageName");
6020     RegDeleteValueA(userkey, "ProductIcon");
6021     RegDeleteValueA(userkey, "Version");
6022     RegDeleteValueA(userkey, "PackageCode");
6023     RegDeleteValueA(userkey, "AssignmentType");
6024     RegDeleteValueA(userkey, "ProductName");
6025     RegDeleteValueA(userkey, "Language");
6026     RegDeleteValueA(userkey, "Transforms");
6027     RegDeleteValueA(userkey, "RegOwner");
6028     RegDeleteValueA(userkey, "RegCompany");
6029     RegDeleteValueA(userkey, "ProductID");
6030     RegDeleteValueA(userkey, "DisplayVersion");
6031     RegDeleteValueA(userkey, "VersionMajor");
6032     RegDeleteValueA(userkey, "VersionMinor");
6033     RegDeleteValueA(userkey, "URLUpdateInfo");
6034     RegDeleteValueA(userkey, "URLInfoAbout");
6035     RegDeleteValueA(userkey, "Publisher");
6036     RegDeleteValueA(userkey, "LocalPackage");
6037     RegDeleteValueA(userkey, "InstallSource");
6038     RegDeleteValueA(userkey, "InstallLocation");
6039     RegDeleteValueA(userkey, "DisplayName");
6040     RegDeleteValueA(userkey, "InstallDate");
6041     RegDeleteValueA(userkey, "HelpTelephone");
6042     RegDeleteValueA(userkey, "HelpLink");
6043     delete_key(userkey, "", access & KEY_WOW64_64KEY);
6044     RegCloseKey(userkey);
6045     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6046     RegCloseKey(prodkey);
6047
6048     /* MSIINSTALLCONTEXT_MACHINE */
6049
6050     /* szUserSid is non-NULL */
6051     sz = MAX_PATH;
6052     lstrcpyA(buf, "apple");
6053     r = pMsiGetProductInfoExA(prodcode, usersid,
6054                               MSIINSTALLCONTEXT_MACHINE,
6055                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6056     ok(r == ERROR_INVALID_PARAMETER,
6057        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6058     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6059     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6060
6061     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
6062     lstrcatA(keypath, prod_squashed);
6063
6064     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6065     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6066
6067     /* local system product key exists */
6068     sz = MAX_PATH;
6069     lstrcpyA(buf, "apple");
6070     r = pMsiGetProductInfoExA(prodcode, NULL,
6071                               MSIINSTALLCONTEXT_MACHINE,
6072                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6073     ok(r == ERROR_UNKNOWN_PRODUCT,
6074        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6075     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6076     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6077
6078     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6080
6081     /* InstallProperties key exists */
6082     sz = MAX_PATH;
6083     lstrcpyA(buf, "apple");
6084     r = pMsiGetProductInfoExA(prodcode, NULL,
6085                               MSIINSTALLCONTEXT_MACHINE,
6086                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6087     ok(r == ERROR_UNKNOWN_PRODUCT,
6088        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6089     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6090     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6091
6092     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6094
6095     /* LocalPackage value exists */
6096     sz = MAX_PATH;
6097     lstrcpyA(buf, "apple");
6098     r = pMsiGetProductInfoExA(prodcode, NULL,
6099                               MSIINSTALLCONTEXT_MACHINE,
6100                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6101     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6102     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6103     ok(sz == 1, "Expected 1, got %d\n", sz);
6104
6105     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6107
6108     /* HelpLink value exists */
6109     sz = MAX_PATH;
6110     lstrcpyA(buf, "apple");
6111     r = pMsiGetProductInfoExA(prodcode, NULL,
6112                               MSIINSTALLCONTEXT_MACHINE,
6113                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6114     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6115     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6116     ok(sz == 4, "Expected 4, got %d\n", sz);
6117
6118     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6119     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6120
6121     /* HelpTelephone value exists */
6122     sz = MAX_PATH;
6123     lstrcpyA(buf, "apple");
6124     r = pMsiGetProductInfoExA(prodcode, NULL,
6125                               MSIINSTALLCONTEXT_MACHINE,
6126                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6127     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6128     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6129     ok(sz == 5, "Expected 5, got %d\n", sz);
6130
6131     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6133
6134     /* InstallDate value exists */
6135     sz = MAX_PATH;
6136     lstrcpyA(buf, "apple");
6137     r = pMsiGetProductInfoExA(prodcode, NULL,
6138                               MSIINSTALLCONTEXT_MACHINE,
6139                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6140     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6141     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6142     ok(sz == 4, "Expected 4, got %d\n", sz);
6143
6144     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6145     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6146
6147     /* DisplayName value exists */
6148     sz = MAX_PATH;
6149     lstrcpyA(buf, "apple");
6150     r = pMsiGetProductInfoExA(prodcode, NULL,
6151                               MSIINSTALLCONTEXT_MACHINE,
6152                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6153     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6154     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6155     ok(sz == 4, "Expected 4, got %d\n", sz);
6156
6157     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6159
6160     /* InstallLocation value exists */
6161     sz = MAX_PATH;
6162     lstrcpyA(buf, "apple");
6163     r = pMsiGetProductInfoExA(prodcode, NULL,
6164                               MSIINSTALLCONTEXT_MACHINE,
6165                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6166     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6167     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6168     ok(sz == 3, "Expected 3, got %d\n", sz);
6169
6170     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6171     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6172
6173     /* InstallSource value exists */
6174     sz = MAX_PATH;
6175     lstrcpyA(buf, "apple");
6176     r = pMsiGetProductInfoExA(prodcode, NULL,
6177                               MSIINSTALLCONTEXT_MACHINE,
6178                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6179     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6180     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6181     ok(sz == 6, "Expected 6, got %d\n", sz);
6182
6183     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6184     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6185
6186     /* LocalPackage value exists */
6187     sz = MAX_PATH;
6188     lstrcpyA(buf, "apple");
6189     r = pMsiGetProductInfoExA(prodcode, NULL,
6190                               MSIINSTALLCONTEXT_MACHINE,
6191                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6192     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6193     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6194     ok(sz == 5, "Expected 5, got %d\n", sz);
6195
6196     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6198
6199     /* Publisher value exists */
6200     sz = MAX_PATH;
6201     lstrcpyA(buf, "apple");
6202     r = pMsiGetProductInfoExA(prodcode, NULL,
6203                               MSIINSTALLCONTEXT_MACHINE,
6204                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6205     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6206     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6207     ok(sz == 3, "Expected 3, got %d\n", sz);
6208
6209     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6211
6212     /* URLInfoAbout value exists */
6213     sz = MAX_PATH;
6214     lstrcpyA(buf, "apple");
6215     r = pMsiGetProductInfoExA(prodcode, NULL,
6216                               MSIINSTALLCONTEXT_MACHINE,
6217                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6218     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6219     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6220     ok(sz == 5, "Expected 5, got %d\n", sz);
6221
6222     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6223     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6224
6225     /* URLUpdateInfo value exists */
6226     sz = MAX_PATH;
6227     lstrcpyA(buf, "apple");
6228     r = pMsiGetProductInfoExA(prodcode, NULL,
6229                               MSIINSTALLCONTEXT_MACHINE,
6230                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6231     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6232     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6233     ok(sz == 6, "Expected 6, got %d\n", sz);
6234
6235     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6236     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6237
6238     /* VersionMinor value exists */
6239     sz = MAX_PATH;
6240     lstrcpyA(buf, "apple");
6241     r = pMsiGetProductInfoExA(prodcode, NULL,
6242                               MSIINSTALLCONTEXT_MACHINE,
6243                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6244     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6245     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6246     ok(sz == 1, "Expected 1, got %d\n", sz);
6247
6248     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6249     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6250
6251     /* VersionMajor value exists */
6252     sz = MAX_PATH;
6253     lstrcpyA(buf, "apple");
6254     r = pMsiGetProductInfoExA(prodcode, NULL,
6255                               MSIINSTALLCONTEXT_MACHINE,
6256                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6257     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6258     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6259     ok(sz == 1, "Expected 1, got %d\n", sz);
6260
6261     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6263
6264     /* DisplayVersion value exists */
6265     sz = MAX_PATH;
6266     lstrcpyA(buf, "apple");
6267     r = pMsiGetProductInfoExA(prodcode, NULL,
6268                               MSIINSTALLCONTEXT_MACHINE,
6269                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6270     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6271     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6272     ok(sz == 5, "Expected 5, got %d\n", sz);
6273
6274     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6275     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6276
6277     /* ProductID value exists */
6278     sz = MAX_PATH;
6279     lstrcpyA(buf, "apple");
6280     r = pMsiGetProductInfoExA(prodcode, NULL,
6281                               MSIINSTALLCONTEXT_MACHINE,
6282                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6283     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6284     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6285     ok(sz == 2, "Expected 2, got %d\n", sz);
6286
6287     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6289
6290     /* RegCompany value exists */
6291     sz = MAX_PATH;
6292     lstrcpyA(buf, "apple");
6293     r = pMsiGetProductInfoExA(prodcode, NULL,
6294                               MSIINSTALLCONTEXT_MACHINE,
6295                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6296     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6297     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6298     ok(sz == 4, "Expected 4, got %d\n", sz);
6299
6300     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6301     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6302
6303     /* RegOwner value exists */
6304     sz = MAX_PATH;
6305     lstrcpyA(buf, "apple");
6306     r = pMsiGetProductInfoExA(prodcode, NULL,
6307                               MSIINSTALLCONTEXT_MACHINE,
6308                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6309     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6310     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6311     ok(sz == 5, "Expected 5, got %d\n", sz);
6312
6313     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6314     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6315
6316     /* Transforms value exists */
6317     sz = MAX_PATH;
6318     lstrcpyA(buf, "apple");
6319     r = pMsiGetProductInfoExA(prodcode, NULL,
6320                               MSIINSTALLCONTEXT_MACHINE,
6321                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6322     ok(r == ERROR_UNKNOWN_PRODUCT,
6323        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6324     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6325     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6326
6327     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6328     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6329
6330     /* Language value exists */
6331     sz = MAX_PATH;
6332     lstrcpyA(buf, "apple");
6333     r = pMsiGetProductInfoExA(prodcode, NULL,
6334                               MSIINSTALLCONTEXT_MACHINE,
6335                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6336     ok(r == ERROR_UNKNOWN_PRODUCT,
6337        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6338     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6339     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6340
6341     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6343
6344     /* ProductName value exists */
6345     sz = MAX_PATH;
6346     lstrcpyA(buf, "apple");
6347     r = pMsiGetProductInfoExA(prodcode, NULL,
6348                               MSIINSTALLCONTEXT_MACHINE,
6349                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6350     ok(r == ERROR_UNKNOWN_PRODUCT,
6351        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6352     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6353     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6354
6355     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6356     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6357
6358     /* FIXME */
6359
6360     /* AssignmentType value exists */
6361     sz = MAX_PATH;
6362     lstrcpyA(buf, "apple");
6363     r = pMsiGetProductInfoExA(prodcode, NULL,
6364                               MSIINSTALLCONTEXT_MACHINE,
6365                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6366     ok(r == ERROR_UNKNOWN_PRODUCT,
6367        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6368     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6369     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6370
6371     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6372     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6373
6374     /* PackageCode value exists */
6375     sz = MAX_PATH;
6376     lstrcpyA(buf, "apple");
6377     r = pMsiGetProductInfoExA(prodcode, NULL,
6378                               MSIINSTALLCONTEXT_MACHINE,
6379                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6380     ok(r == ERROR_UNKNOWN_PRODUCT,
6381        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6382     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6383     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6384
6385     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6386     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6387
6388     /* Version value exists */
6389     sz = MAX_PATH;
6390     lstrcpyA(buf, "apple");
6391     r = pMsiGetProductInfoExA(prodcode, NULL,
6392                               MSIINSTALLCONTEXT_MACHINE,
6393                               INSTALLPROPERTY_VERSION, buf, &sz);
6394     ok(r == ERROR_UNKNOWN_PRODUCT,
6395        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6396     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6397     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6398
6399     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6400     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6401
6402     /* ProductIcon value exists */
6403     sz = MAX_PATH;
6404     lstrcpyA(buf, "apple");
6405     r = pMsiGetProductInfoExA(prodcode, NULL,
6406                               MSIINSTALLCONTEXT_MACHINE,
6407                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6408     ok(r == ERROR_UNKNOWN_PRODUCT,
6409        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6410     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6411     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6412
6413     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6414     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6415
6416     /* PackageName value exists */
6417     sz = MAX_PATH;
6418     lstrcpyA(buf, "apple");
6419     r = pMsiGetProductInfoExA(prodcode, NULL,
6420                               MSIINSTALLCONTEXT_MACHINE,
6421                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6422     ok(r == ERROR_UNKNOWN_PRODUCT,
6423        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6424     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6425     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6426
6427     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6428     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6429
6430     /* AuthorizedLUAApp value exists */
6431     sz = MAX_PATH;
6432     lstrcpyA(buf, "apple");
6433     r = pMsiGetProductInfoExA(prodcode, NULL,
6434                               MSIINSTALLCONTEXT_MACHINE,
6435                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6436     ok(r == ERROR_UNKNOWN_PRODUCT,
6437        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6438     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6439     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6440
6441     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6442     RegDeleteValueA(propkey, "PackageName");
6443     RegDeleteValueA(propkey, "ProductIcon");
6444     RegDeleteValueA(propkey, "Version");
6445     RegDeleteValueA(propkey, "PackageCode");
6446     RegDeleteValueA(propkey, "AssignmentType");
6447     RegDeleteValueA(propkey, "ProductName");
6448     RegDeleteValueA(propkey, "Language");
6449     RegDeleteValueA(propkey, "Transforms");
6450     RegDeleteValueA(propkey, "RegOwner");
6451     RegDeleteValueA(propkey, "RegCompany");
6452     RegDeleteValueA(propkey, "ProductID");
6453     RegDeleteValueA(propkey, "DisplayVersion");
6454     RegDeleteValueA(propkey, "VersionMajor");
6455     RegDeleteValueA(propkey, "VersionMinor");
6456     RegDeleteValueA(propkey, "URLUpdateInfo");
6457     RegDeleteValueA(propkey, "URLInfoAbout");
6458     RegDeleteValueA(propkey, "Publisher");
6459     RegDeleteValueA(propkey, "LocalPackage");
6460     RegDeleteValueA(propkey, "InstallSource");
6461     RegDeleteValueA(propkey, "InstallLocation");
6462     RegDeleteValueA(propkey, "DisplayName");
6463     RegDeleteValueA(propkey, "InstallDate");
6464     RegDeleteValueA(propkey, "HelpTelephone");
6465     RegDeleteValueA(propkey, "HelpLink");
6466     RegDeleteValueA(propkey, "LocalPackage");
6467     delete_key(propkey, "", access & KEY_WOW64_64KEY);
6468     RegCloseKey(propkey);
6469     delete_key(localkey, "", access & KEY_WOW64_64KEY);
6470     RegCloseKey(localkey);
6471
6472     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6473     lstrcatA(keypath, prod_squashed);
6474
6475     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6476     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6477
6478     /* local classes product key exists */
6479     sz = MAX_PATH;
6480     lstrcpyA(buf, "apple");
6481     r = pMsiGetProductInfoExA(prodcode, NULL,
6482                               MSIINSTALLCONTEXT_MACHINE,
6483                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6484     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6485     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6486     ok(sz == 1, "Expected 1, got %d\n", sz);
6487
6488     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6489     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6490
6491     /* HelpLink value exists */
6492     sz = MAX_PATH;
6493     lstrcpyA(buf, "apple");
6494     r = pMsiGetProductInfoExA(prodcode, NULL,
6495                               MSIINSTALLCONTEXT_MACHINE,
6496                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6497     ok(r == ERROR_UNKNOWN_PROPERTY,
6498        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6499     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6500     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6501
6502     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6504
6505     /* HelpTelephone value exists */
6506     sz = MAX_PATH;
6507     lstrcpyA(buf, "apple");
6508     r = pMsiGetProductInfoExA(prodcode, NULL,
6509                               MSIINSTALLCONTEXT_MACHINE,
6510                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6511     ok(r == ERROR_UNKNOWN_PROPERTY,
6512        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6513     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6514     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6515
6516     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6517     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6518
6519     /* InstallDate value exists */
6520     sz = MAX_PATH;
6521     lstrcpyA(buf, "apple");
6522     r = pMsiGetProductInfoExA(prodcode, NULL,
6523                               MSIINSTALLCONTEXT_MACHINE,
6524                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6525     ok(r == ERROR_UNKNOWN_PROPERTY,
6526        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6527     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6528     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6529
6530     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6531     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6532
6533     /* DisplayName value exists */
6534     sz = MAX_PATH;
6535     lstrcpyA(buf, "apple");
6536     r = pMsiGetProductInfoExA(prodcode, NULL,
6537                               MSIINSTALLCONTEXT_MACHINE,
6538                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6539     ok(r == ERROR_UNKNOWN_PROPERTY,
6540        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6541     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6542     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6543
6544     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6545     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6546
6547     /* InstallLocation value exists */
6548     sz = MAX_PATH;
6549     lstrcpyA(buf, "apple");
6550     r = pMsiGetProductInfoExA(prodcode, NULL,
6551                               MSIINSTALLCONTEXT_MACHINE,
6552                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6553     ok(r == ERROR_UNKNOWN_PROPERTY,
6554        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6555     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6556     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6557
6558     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6559     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6560
6561     /* InstallSource value exists */
6562     sz = MAX_PATH;
6563     lstrcpyA(buf, "apple");
6564     r = pMsiGetProductInfoExA(prodcode, NULL,
6565                               MSIINSTALLCONTEXT_MACHINE,
6566                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6567     ok(r == ERROR_UNKNOWN_PROPERTY,
6568        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6569     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6570     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6571
6572     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6574
6575     /* LocalPackage value exists */
6576     sz = MAX_PATH;
6577     lstrcpyA(buf, "apple");
6578     r = pMsiGetProductInfoExA(prodcode, NULL,
6579                               MSIINSTALLCONTEXT_MACHINE,
6580                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6581     ok(r == ERROR_UNKNOWN_PROPERTY,
6582        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6583     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6584     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6585
6586     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6587     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6588
6589     /* Publisher value exists */
6590     sz = MAX_PATH;
6591     lstrcpyA(buf, "apple");
6592     r = pMsiGetProductInfoExA(prodcode, NULL,
6593                               MSIINSTALLCONTEXT_MACHINE,
6594                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6595     ok(r == ERROR_UNKNOWN_PROPERTY,
6596        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6597     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6598     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6599
6600     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6602
6603     /* URLInfoAbout value exists */
6604     sz = MAX_PATH;
6605     lstrcpyA(buf, "apple");
6606     r = pMsiGetProductInfoExA(prodcode, NULL,
6607                               MSIINSTALLCONTEXT_MACHINE,
6608                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6609     ok(r == ERROR_UNKNOWN_PROPERTY,
6610        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6611     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6612     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6613
6614     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6615     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6616
6617     /* URLUpdateInfo value exists */
6618     sz = MAX_PATH;
6619     lstrcpyA(buf, "apple");
6620     r = pMsiGetProductInfoExA(prodcode, NULL,
6621                               MSIINSTALLCONTEXT_MACHINE,
6622                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6623     ok(r == ERROR_UNKNOWN_PROPERTY,
6624        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6625     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6626     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6627
6628     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6629     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6630
6631     /* VersionMinor value exists */
6632     sz = MAX_PATH;
6633     lstrcpyA(buf, "apple");
6634     r = pMsiGetProductInfoExA(prodcode, NULL,
6635                               MSIINSTALLCONTEXT_MACHINE,
6636                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6637     ok(r == ERROR_UNKNOWN_PROPERTY,
6638        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6639     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6640     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6641
6642     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6643     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6644
6645     /* VersionMajor value exists */
6646     sz = MAX_PATH;
6647     lstrcpyA(buf, "apple");
6648     r = pMsiGetProductInfoExA(prodcode, NULL,
6649                               MSIINSTALLCONTEXT_MACHINE,
6650                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6651     ok(r == ERROR_UNKNOWN_PROPERTY,
6652        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6653     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6654     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6655
6656     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6657     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6658
6659     /* DisplayVersion value exists */
6660     sz = MAX_PATH;
6661     lstrcpyA(buf, "apple");
6662     r = pMsiGetProductInfoExA(prodcode, NULL,
6663                               MSIINSTALLCONTEXT_MACHINE,
6664                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6665     ok(r == ERROR_UNKNOWN_PROPERTY,
6666        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6667     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6668     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6669
6670     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6671     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6672
6673     /* ProductID value exists */
6674     sz = MAX_PATH;
6675     lstrcpyA(buf, "apple");
6676     r = pMsiGetProductInfoExA(prodcode, NULL,
6677                               MSIINSTALLCONTEXT_MACHINE,
6678                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6679     ok(r == ERROR_UNKNOWN_PROPERTY,
6680        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6681     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6682     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6683
6684     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6685     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6686
6687     /* RegCompany value exists */
6688     sz = MAX_PATH;
6689     lstrcpyA(buf, "apple");
6690     r = pMsiGetProductInfoExA(prodcode, NULL,
6691                               MSIINSTALLCONTEXT_MACHINE,
6692                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6693     ok(r == ERROR_UNKNOWN_PROPERTY,
6694        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6695     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6696     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6697
6698     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6700
6701     /* RegOwner value exists */
6702     sz = MAX_PATH;
6703     lstrcpyA(buf, "apple");
6704     r = pMsiGetProductInfoExA(prodcode, NULL,
6705                               MSIINSTALLCONTEXT_MACHINE,
6706                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6707     ok(r == ERROR_UNKNOWN_PROPERTY,
6708        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6709     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6710     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6711
6712     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6714
6715     /* Transforms value exists */
6716     sz = MAX_PATH;
6717     lstrcpyA(buf, "apple");
6718     r = pMsiGetProductInfoExA(prodcode, NULL,
6719                               MSIINSTALLCONTEXT_MACHINE,
6720                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6721     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6722     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6723     ok(sz == 5, "Expected 5, got %d\n", sz);
6724
6725     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6727
6728     /* Language value exists */
6729     sz = MAX_PATH;
6730     lstrcpyA(buf, "apple");
6731     r = pMsiGetProductInfoExA(prodcode, NULL,
6732                               MSIINSTALLCONTEXT_MACHINE,
6733                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6734     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6735     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6736     ok(sz == 4, "Expected 4, got %d\n", sz);
6737
6738     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6739     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6740
6741     /* ProductName value exists */
6742     sz = MAX_PATH;
6743     lstrcpyA(buf, "apple");
6744     r = pMsiGetProductInfoExA(prodcode, NULL,
6745                               MSIINSTALLCONTEXT_MACHINE,
6746                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6747     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6748     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6749     ok(sz == 4, "Expected 4, got %d\n", sz);
6750
6751     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6752     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6753
6754     /* FIXME */
6755
6756     /* AssignmentType value exists */
6757     sz = MAX_PATH;
6758     lstrcpyA(buf, "apple");
6759     r = pMsiGetProductInfoExA(prodcode, NULL,
6760                               MSIINSTALLCONTEXT_MACHINE,
6761                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6762     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6763     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6764     ok(sz == 0, "Expected 0, got %d\n", sz);
6765
6766     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6767     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6768
6769     /* FIXME */
6770
6771     /* PackageCode value exists */
6772     sz = MAX_PATH;
6773     lstrcpyA(buf, "apple");
6774     r = pMsiGetProductInfoExA(prodcode, NULL,
6775                               MSIINSTALLCONTEXT_MACHINE,
6776                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6777     todo_wine
6778     {
6779         ok(r == ERROR_BAD_CONFIGURATION,
6780            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6781         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6782         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6783     }
6784
6785     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6786     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6787
6788     /* Version value exists */
6789     sz = MAX_PATH;
6790     lstrcpyA(buf, "apple");
6791     r = pMsiGetProductInfoExA(prodcode, NULL,
6792                               MSIINSTALLCONTEXT_MACHINE,
6793                               INSTALLPROPERTY_VERSION, buf, &sz);
6794     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6795     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6796     ok(sz == 3, "Expected 3, got %d\n", sz);
6797
6798     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6799     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6800
6801     /* ProductIcon value exists */
6802     sz = MAX_PATH;
6803     lstrcpyA(buf, "apple");
6804     r = pMsiGetProductInfoExA(prodcode, NULL,
6805                               MSIINSTALLCONTEXT_MACHINE,
6806                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6807     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6808     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6809     ok(sz == 4, "Expected 4, got %d\n", sz);
6810
6811     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6812     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6813
6814     /* PackageName value exists */
6815     sz = MAX_PATH;
6816     lstrcpyA(buf, "apple");
6817     r = pMsiGetProductInfoExA(prodcode, NULL,
6818                               MSIINSTALLCONTEXT_MACHINE,
6819                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6820     todo_wine
6821     {
6822         ok(r == ERROR_UNKNOWN_PRODUCT,
6823            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6824         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6825         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6826     }
6827
6828     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6829     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6830
6831     /* AuthorizedLUAApp value exists */
6832     sz = MAX_PATH;
6833     lstrcpyA(buf, "apple");
6834     r = pMsiGetProductInfoExA(prodcode, NULL,
6835                               MSIINSTALLCONTEXT_MACHINE,
6836                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6837     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6838     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6839     ok(sz == 4, "Expected 4, got %d\n", sz);
6840
6841     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6842     RegDeleteValueA(prodkey, "PackageName");
6843     RegDeleteValueA(prodkey, "ProductIcon");
6844     RegDeleteValueA(prodkey, "Version");
6845     RegDeleteValueA(prodkey, "PackageCode");
6846     RegDeleteValueA(prodkey, "AssignmentType");
6847     RegDeleteValueA(prodkey, "ProductName");
6848     RegDeleteValueA(prodkey, "Language");
6849     RegDeleteValueA(prodkey, "Transforms");
6850     RegDeleteValueA(prodkey, "RegOwner");
6851     RegDeleteValueA(prodkey, "RegCompany");
6852     RegDeleteValueA(prodkey, "ProductID");
6853     RegDeleteValueA(prodkey, "DisplayVersion");
6854     RegDeleteValueA(prodkey, "VersionMajor");
6855     RegDeleteValueA(prodkey, "VersionMinor");
6856     RegDeleteValueA(prodkey, "URLUpdateInfo");
6857     RegDeleteValueA(prodkey, "URLInfoAbout");
6858     RegDeleteValueA(prodkey, "Publisher");
6859     RegDeleteValueA(prodkey, "LocalPackage");
6860     RegDeleteValueA(prodkey, "InstallSource");
6861     RegDeleteValueA(prodkey, "InstallLocation");
6862     RegDeleteValueA(prodkey, "DisplayName");
6863     RegDeleteValueA(prodkey, "InstallDate");
6864     RegDeleteValueA(prodkey, "HelpTelephone");
6865     RegDeleteValueA(prodkey, "HelpLink");
6866     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6867     RegCloseKey(prodkey);
6868     LocalFree(usersid);
6869 }
6870
6871 #define INIT_USERINFO() \
6872     lstrcpyA(user, "apple"); \
6873     lstrcpyA(org, "orange"); \
6874     lstrcpyA(serial, "banana"); \
6875     usersz = orgsz = serialsz = MAX_PATH;
6876
6877 static void test_MsiGetUserInfo(void)
6878 {
6879     USERINFOSTATE state;
6880     CHAR user[MAX_PATH];
6881     CHAR org[MAX_PATH];
6882     CHAR serial[MAX_PATH];
6883     DWORD usersz, orgsz, serialsz;
6884     CHAR keypath[MAX_PATH * 2];
6885     CHAR prodcode[MAX_PATH];
6886     CHAR prod_squashed[MAX_PATH];
6887     HKEY prodkey, userprod, props;
6888     LPSTR usersid;
6889     LONG res;
6890     REGSAM access = KEY_ALL_ACCESS;
6891     BOOL wow64;
6892
6893     create_test_guid(prodcode, prod_squashed);
6894     get_user_sid(&usersid);
6895
6896     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
6897         access |= KEY_WOW64_64KEY;
6898
6899     /* NULL szProduct */
6900     INIT_USERINFO();
6901     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6902     ok(state == USERINFOSTATE_INVALIDARG,
6903        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6904     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6905     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6906     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6907     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6908     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6909     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6910
6911     /* empty szProductCode */
6912     INIT_USERINFO();
6913     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6914     ok(state == USERINFOSTATE_INVALIDARG,
6915        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6916     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6917     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6918     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6919     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6920     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6921     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6922
6923     /* garbage szProductCode */
6924     INIT_USERINFO();
6925     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6926     ok(state == USERINFOSTATE_INVALIDARG,
6927        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6928     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6929     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6930     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6931     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6932     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6933     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6934
6935     /* guid without brackets */
6936     INIT_USERINFO();
6937     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6938                             user, &usersz, org, &orgsz, serial, &serialsz);
6939     ok(state == USERINFOSTATE_INVALIDARG,
6940        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6941     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6942     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6943     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6944     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6945     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6946     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6947
6948     /* guid with brackets */
6949     INIT_USERINFO();
6950     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6951                             user, &usersz, org, &orgsz, serial, &serialsz);
6952     ok(state == USERINFOSTATE_UNKNOWN,
6953        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6954     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6955     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6956     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6957     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6958     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6959     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6960
6961     /* NULL lpUserNameBuf */
6962     INIT_USERINFO();
6963     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6964     ok(state == USERINFOSTATE_UNKNOWN,
6965        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6966     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6967     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6968     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6969     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6970     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6971
6972     /* NULL pcchUserNameBuf */
6973     INIT_USERINFO();
6974     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6975     ok(state == USERINFOSTATE_INVALIDARG,
6976        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6977     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6978     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6979     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6980     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6981     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6982
6983     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6984     INIT_USERINFO();
6985     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6986     ok(state == USERINFOSTATE_UNKNOWN,
6987        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6988     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6989     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6990     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6991     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6992
6993     /* NULL lpOrgNameBuf */
6994     INIT_USERINFO();
6995     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6996     ok(state == USERINFOSTATE_UNKNOWN,
6997        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6998     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6999     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7000     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7001     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7002     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7003
7004     /* NULL pcchOrgNameBuf */
7005     INIT_USERINFO();
7006     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
7007     ok(state == USERINFOSTATE_INVALIDARG,
7008        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7009     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7010     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7011     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7012     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7013     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7014
7015     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
7016     INIT_USERINFO();
7017     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
7018     ok(state == USERINFOSTATE_UNKNOWN,
7019        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7020     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7021     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7022     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7023     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7024
7025     /* NULL lpSerialBuf */
7026     INIT_USERINFO();
7027     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
7028     ok(state == USERINFOSTATE_UNKNOWN,
7029        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7030     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7031     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7032     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7033     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7034     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7035
7036     /* NULL pcchSerialBuf */
7037     INIT_USERINFO();
7038     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
7039     ok(state == USERINFOSTATE_INVALIDARG,
7040        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7041     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7042     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7043     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7044     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7045     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7046
7047     /* both lpSerialBuf and pcchSerialBuf NULL */
7048     INIT_USERINFO();
7049     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
7050     ok(state == USERINFOSTATE_UNKNOWN,
7051        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7052     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7053     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7054     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7055     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7056
7057     /* MSIINSTALLCONTEXT_USERMANAGED */
7058
7059     /* create local system product key */
7060     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7061     lstrcatA(keypath, usersid);
7062     lstrcatA(keypath, "\\Installer\\Products\\");
7063     lstrcatA(keypath, prod_squashed);
7064
7065     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7066     if (res == ERROR_ACCESS_DENIED)
7067     {
7068         skip("Not enough rights to perform tests\n");
7069         LocalFree(usersid);
7070         return;
7071     }
7072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7073
7074     /* managed product key exists */
7075     INIT_USERINFO();
7076     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7077     ok(state == USERINFOSTATE_ABSENT,
7078        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7079     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7080     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7081     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7082     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7083     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7084     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7085
7086     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7087     lstrcatA(keypath, "Installer\\UserData\\");
7088     lstrcatA(keypath, usersid);
7089     lstrcatA(keypath, "\\Products\\");
7090     lstrcatA(keypath, prod_squashed);
7091
7092     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7094
7095     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7096     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7097
7098     /* InstallProperties key exists */
7099     INIT_USERINFO();
7100     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7101     ok(state == USERINFOSTATE_ABSENT,
7102        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7103     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7104     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7105     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7106     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7107     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7108     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7109
7110     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7111     INIT_USERINFO();
7112     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7113     ok(state == USERINFOSTATE_ABSENT,
7114        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7115     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7116     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7117     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7118     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7119
7120     /* RegOwner, RegCompany don't exist, out params are NULL */
7121     INIT_USERINFO();
7122     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7123     ok(state == USERINFOSTATE_ABSENT,
7124        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7125     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7126     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7127
7128     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7130
7131     /* RegOwner value exists */
7132     INIT_USERINFO();
7133     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7134     ok(state == USERINFOSTATE_ABSENT,
7135        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7136     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7137     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7138     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7139     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7140     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7141     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7142
7143     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7144     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7145
7146     /* RegCompany value exists */
7147     INIT_USERINFO();
7148     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7149     ok(state == USERINFOSTATE_ABSENT,
7150        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7151     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7152     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7153     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7154     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7155     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7156     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7157
7158     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7159     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7160
7161     /* ProductID value exists */
7162     INIT_USERINFO();
7163     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7164     ok(state == USERINFOSTATE_PRESENT,
7165        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7166     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7167     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7168     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7169     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7170     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7171     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7172
7173     /* pcchUserNameBuf is too small */
7174     INIT_USERINFO();
7175     usersz = 0;
7176     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7177     ok(state == USERINFOSTATE_MOREDATA,
7178        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7179     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7180     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7181     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7182     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7183     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7184     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7185
7186     /* pcchUserNameBuf has no room for NULL terminator */
7187     INIT_USERINFO();
7188     usersz = 5;
7189     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7190     ok(state == USERINFOSTATE_MOREDATA,
7191        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7192     todo_wine
7193     {
7194         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7195     }
7196     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7197     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7198     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7199     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7200     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7201
7202     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
7203     INIT_USERINFO();
7204     usersz = 0;
7205     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7206     ok(state == USERINFOSTATE_PRESENT,
7207        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7208     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7209     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7210     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7211     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7212     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7213     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7214
7215     RegDeleteValueA(props, "ProductID");
7216     RegDeleteValueA(props, "RegCompany");
7217     RegDeleteValueA(props, "RegOwner");
7218     delete_key(props, "", access & KEY_WOW64_64KEY);
7219     RegCloseKey(props);
7220     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7221     RegCloseKey(userprod);
7222     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7223     RegCloseKey(prodkey);
7224
7225     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7226
7227     /* create local system product key */
7228     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7229     lstrcatA(keypath, prod_squashed);
7230
7231     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7232     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7233
7234     /* product key exists */
7235     INIT_USERINFO();
7236     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7237     ok(state == USERINFOSTATE_ABSENT,
7238        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7239     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7240     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7241     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7242     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7243     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7244     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7245
7246     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7247     lstrcatA(keypath, "Installer\\UserData\\");
7248     lstrcatA(keypath, usersid);
7249     lstrcatA(keypath, "\\Products\\");
7250     lstrcatA(keypath, prod_squashed);
7251
7252     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7253     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7254
7255     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7257
7258     /* InstallProperties key exists */
7259     INIT_USERINFO();
7260     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7261     ok(state == USERINFOSTATE_ABSENT,
7262        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7263     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7264     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7265     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7266     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7267     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7268     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7269
7270     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7271     INIT_USERINFO();
7272     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7273     ok(state == USERINFOSTATE_ABSENT,
7274        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7275     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7276     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7277     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7278     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7279
7280     /* RegOwner, RegCompany don't exist, out params are NULL */
7281     INIT_USERINFO();
7282     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7283     ok(state == USERINFOSTATE_ABSENT,
7284        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7285     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7286     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7287
7288     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7289     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7290
7291     /* RegOwner value exists */
7292     INIT_USERINFO();
7293     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7294     ok(state == USERINFOSTATE_ABSENT,
7295        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7296     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7297     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7298     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7299     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7300     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7301     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7302
7303     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7305
7306     /* RegCompany value exists */
7307     INIT_USERINFO();
7308     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7309     ok(state == USERINFOSTATE_ABSENT,
7310        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7311     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7312     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7313     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7314     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7315     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7316     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7317
7318     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7320
7321     /* ProductID value exists */
7322     INIT_USERINFO();
7323     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7324     ok(state == USERINFOSTATE_PRESENT,
7325        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7326     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7327     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7328     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7329     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7330     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7331     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7332
7333     RegDeleteValueA(props, "ProductID");
7334     RegDeleteValueA(props, "RegCompany");
7335     RegDeleteValueA(props, "RegOwner");
7336     delete_key(props, "", access & KEY_WOW64_64KEY);
7337     RegCloseKey(props);
7338     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7339     RegCloseKey(userprod);
7340     RegDeleteKeyA(prodkey, "");
7341     RegCloseKey(prodkey);
7342
7343     /* MSIINSTALLCONTEXT_MACHINE */
7344
7345     /* create local system product key */
7346     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7347     lstrcatA(keypath, prod_squashed);
7348
7349     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7351
7352     /* product key exists */
7353     INIT_USERINFO();
7354     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7355     ok(state == USERINFOSTATE_ABSENT,
7356        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7357     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7358     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7359     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7360     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7361     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7362     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7363
7364     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7365     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7366     lstrcatA(keypath, "\\Products\\");
7367     lstrcatA(keypath, prod_squashed);
7368
7369     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7371
7372     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7373     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7374
7375     /* InstallProperties key exists */
7376     INIT_USERINFO();
7377     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7378     ok(state == USERINFOSTATE_ABSENT,
7379        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7380     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7381     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7382     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7383     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7384     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7385     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7386
7387     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7388     INIT_USERINFO();
7389     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7390     ok(state == USERINFOSTATE_ABSENT,
7391        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7392     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7393     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7394     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7395     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7396
7397     /* RegOwner, RegCompany don't exist, out params are NULL */
7398     INIT_USERINFO();
7399     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7400     ok(state == USERINFOSTATE_ABSENT,
7401        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7402     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7403     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7404
7405     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7406     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7407
7408     /* RegOwner value exists */
7409     INIT_USERINFO();
7410     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7411     ok(state == USERINFOSTATE_ABSENT,
7412        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7413     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7414     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7415     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7416     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7417     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7418     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7419
7420     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7421     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7422
7423     /* RegCompany value exists */
7424     INIT_USERINFO();
7425     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7426     ok(state == USERINFOSTATE_ABSENT,
7427        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7428     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7429     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7430     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7431     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7432     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7433     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7434
7435     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7436     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7437
7438     /* ProductID value exists */
7439     INIT_USERINFO();
7440     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7441     ok(state == USERINFOSTATE_PRESENT,
7442        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7443     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7444     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7445     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7446     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7447     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7448     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7449
7450     RegDeleteValueA(props, "ProductID");
7451     RegDeleteValueA(props, "RegCompany");
7452     RegDeleteValueA(props, "RegOwner");
7453     delete_key(props, "", access & KEY_WOW64_64KEY);
7454     RegCloseKey(props);
7455     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7456     RegCloseKey(userprod);
7457     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7458     RegCloseKey(prodkey);
7459     LocalFree(usersid);
7460 }
7461
7462 static void test_MsiOpenProduct(void)
7463 {
7464     MSIHANDLE hprod, hdb;
7465     CHAR val[MAX_PATH];
7466     CHAR path[MAX_PATH];
7467     CHAR keypath[MAX_PATH*2];
7468     CHAR prodcode[MAX_PATH];
7469     CHAR prod_squashed[MAX_PATH];
7470     HKEY prodkey, userkey, props;
7471     LPSTR usersid;
7472     DWORD size;
7473     LONG res;
7474     UINT r;
7475     REGSAM access = KEY_ALL_ACCESS;
7476     BOOL wow64;
7477
7478     GetCurrentDirectoryA(MAX_PATH, path);
7479     lstrcatA(path, "\\");
7480
7481     create_test_guid(prodcode, prod_squashed);
7482     get_user_sid(&usersid);
7483
7484     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
7485         access |= KEY_WOW64_64KEY;
7486
7487     hdb = create_package_db(prodcode);
7488     MsiCloseHandle(hdb);
7489
7490     /* NULL szProduct */
7491     hprod = 0xdeadbeef;
7492     r = MsiOpenProductA(NULL, &hprod);
7493     ok(r == ERROR_INVALID_PARAMETER,
7494        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7495     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7496
7497     /* empty szProduct */
7498     hprod = 0xdeadbeef;
7499     r = MsiOpenProductA("", &hprod);
7500     ok(r == ERROR_INVALID_PARAMETER,
7501        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7502     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7503
7504     /* garbage szProduct */
7505     hprod = 0xdeadbeef;
7506     r = MsiOpenProductA("garbage", &hprod);
7507     ok(r == ERROR_INVALID_PARAMETER,
7508        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7509     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7510
7511     /* guid without brackets */
7512     hprod = 0xdeadbeef;
7513     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7514     ok(r == ERROR_INVALID_PARAMETER,
7515        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7516     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7517
7518     /* guid with brackets */
7519     hprod = 0xdeadbeef;
7520     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7521     ok(r == ERROR_UNKNOWN_PRODUCT,
7522        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7523     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7524
7525     /* same length as guid, but random */
7526     hprod = 0xdeadbeef;
7527     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7528     ok(r == ERROR_INVALID_PARAMETER,
7529        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7530     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7531
7532     /* hProduct is NULL */
7533     hprod = 0xdeadbeef;
7534     r = MsiOpenProductA(prodcode, NULL);
7535     ok(r == ERROR_INVALID_PARAMETER,
7536        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7537     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7538
7539     /* MSIINSTALLCONTEXT_USERMANAGED */
7540
7541     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7542     lstrcatA(keypath, "Installer\\Managed\\");
7543     lstrcatA(keypath, usersid);
7544     lstrcatA(keypath, "\\Installer\\Products\\");
7545     lstrcatA(keypath, prod_squashed);
7546
7547     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7548     if (res == ERROR_ACCESS_DENIED)
7549     {
7550         skip("Not enough rights to perform tests\n");
7551         LocalFree(usersid);
7552         return;
7553     }
7554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7555
7556     /* managed product key exists */
7557     hprod = 0xdeadbeef;
7558     r = MsiOpenProductA(prodcode, &hprod);
7559     ok(r == ERROR_UNKNOWN_PRODUCT,
7560        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7561     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7562
7563     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7564     lstrcatA(keypath, "Installer\\UserData\\");
7565     lstrcatA(keypath, usersid);
7566     lstrcatA(keypath, "\\Products\\");
7567     lstrcatA(keypath, prod_squashed);
7568
7569     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7570     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7571
7572     /* user product key exists */
7573     hprod = 0xdeadbeef;
7574     r = MsiOpenProductA(prodcode, &hprod);
7575     ok(r == ERROR_UNKNOWN_PRODUCT,
7576        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7577     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7578
7579     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7580     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7581
7582     /* InstallProperties key exists */
7583     hprod = 0xdeadbeef;
7584     r = MsiOpenProductA(prodcode, &hprod);
7585     ok(r == ERROR_UNKNOWN_PRODUCT,
7586        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7587     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7588
7589     lstrcpyA(val, path);
7590     lstrcatA(val, "\\winetest.msi");
7591     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7592                          (const BYTE *)val, lstrlenA(val) + 1);
7593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7594
7595     /* ManagedLocalPackage value exists */
7596     hprod = 0xdeadbeef;
7597     r = MsiOpenProductA(prodcode, &hprod);
7598     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7599     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7600
7601     size = MAX_PATH;
7602     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7603     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7604     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7605     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7606
7607     MsiCloseHandle(hprod);
7608
7609     RegDeleteValueA(props, "ManagedLocalPackage");
7610     delete_key(props, "", access & KEY_WOW64_64KEY);
7611     RegCloseKey(props);
7612     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7613     RegCloseKey(userkey);
7614     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7615     RegCloseKey(prodkey);
7616
7617     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7618
7619     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7620     lstrcatA(keypath, prod_squashed);
7621
7622     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7624
7625     /* unmanaged product key exists */
7626     hprod = 0xdeadbeef;
7627     r = MsiOpenProductA(prodcode, &hprod);
7628     ok(r == ERROR_UNKNOWN_PRODUCT,
7629        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7630     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7631
7632     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7633     lstrcatA(keypath, "Installer\\UserData\\");
7634     lstrcatA(keypath, usersid);
7635     lstrcatA(keypath, "\\Products\\");
7636     lstrcatA(keypath, prod_squashed);
7637
7638     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7639     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7640
7641     /* user product key exists */
7642     hprod = 0xdeadbeef;
7643     r = MsiOpenProductA(prodcode, &hprod);
7644     ok(r == ERROR_UNKNOWN_PRODUCT,
7645        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7646     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7647
7648     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7649     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7650
7651     /* InstallProperties key exists */
7652     hprod = 0xdeadbeef;
7653     r = MsiOpenProductA(prodcode, &hprod);
7654     ok(r == ERROR_UNKNOWN_PRODUCT,
7655        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7656     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7657
7658     lstrcpyA(val, path);
7659     lstrcatA(val, "\\winetest.msi");
7660     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7661                          (const BYTE *)val, lstrlenA(val) + 1);
7662     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7663
7664     /* LocalPackage value exists */
7665     hprod = 0xdeadbeef;
7666     r = MsiOpenProductA(prodcode, &hprod);
7667     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7668     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7669
7670     size = MAX_PATH;
7671     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7672     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7673     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7674     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7675
7676     MsiCloseHandle(hprod);
7677
7678     RegDeleteValueA(props, "LocalPackage");
7679     delete_key(props, "", access & KEY_WOW64_64KEY);
7680     RegCloseKey(props);
7681     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7682     RegCloseKey(userkey);
7683     RegDeleteKeyA(prodkey, "");
7684     RegCloseKey(prodkey);
7685
7686     /* MSIINSTALLCONTEXT_MACHINE */
7687
7688     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7689     lstrcatA(keypath, prod_squashed);
7690
7691     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7692     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7693
7694     /* managed product key exists */
7695     hprod = 0xdeadbeef;
7696     r = MsiOpenProductA(prodcode, &hprod);
7697     ok(r == ERROR_UNKNOWN_PRODUCT,
7698        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7699     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7700
7701     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7702     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7703     lstrcatA(keypath, prod_squashed);
7704
7705     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7706     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7707
7708     /* user product key exists */
7709     hprod = 0xdeadbeef;
7710     r = MsiOpenProductA(prodcode, &hprod);
7711     ok(r == ERROR_UNKNOWN_PRODUCT,
7712        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7713     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7714
7715     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7717
7718     /* InstallProperties key exists */
7719     hprod = 0xdeadbeef;
7720     r = MsiOpenProductA(prodcode, &hprod);
7721     ok(r == ERROR_UNKNOWN_PRODUCT,
7722        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7723     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7724
7725     lstrcpyA(val, path);
7726     lstrcatA(val, "\\winetest.msi");
7727     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7728                          (const BYTE *)val, lstrlenA(val) + 1);
7729     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7730
7731     /* LocalPackage value exists */
7732     hprod = 0xdeadbeef;
7733     r = MsiOpenProductA(prodcode, &hprod);
7734     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7735     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7736
7737     size = MAX_PATH;
7738     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7739     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7740     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7741     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7742
7743     MsiCloseHandle(hprod);
7744
7745     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7746                          (const BYTE *)"winetest.msi", 13);
7747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7748
7749     /* LocalPackage has just the package name */
7750     hprod = 0xdeadbeef;
7751     r = MsiOpenProductA(prodcode, &hprod);
7752     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7753        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7754     if (r == ERROR_SUCCESS)
7755         MsiCloseHandle(hprod);
7756     else
7757         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7758
7759     lstrcpyA(val, path);
7760     lstrcatA(val, "\\winetest.msi");
7761     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7762                          (const BYTE *)val, lstrlenA(val) + 1);
7763     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7764
7765     DeleteFileA(msifile);
7766
7767     /* local package does not exist */
7768     hprod = 0xdeadbeef;
7769     r = MsiOpenProductA(prodcode, &hprod);
7770     ok(r == ERROR_UNKNOWN_PRODUCT,
7771        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7772     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7773
7774     RegDeleteValueA(props, "LocalPackage");
7775     delete_key(props, "", access & KEY_WOW64_64KEY);
7776     RegCloseKey(props);
7777     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7778     RegCloseKey(userkey);
7779     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7780     RegCloseKey(prodkey);
7781
7782     DeleteFileA(msifile);
7783     LocalFree(usersid);
7784 }
7785
7786 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7787 {
7788     MSIINSTALLCONTEXT context;
7789     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7790     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7791     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7792     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7793     HKEY prodkey, patches, udprod, udpatch, hpatch;
7794     DWORD size, data;
7795     LONG res;
7796     UINT r;
7797     REGSAM access = KEY_ALL_ACCESS;
7798     BOOL wow64;
7799
7800     create_test_guid(prodcode, prod_squashed);
7801     create_test_guid(patch, patch_squashed);
7802
7803     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
7804         access |= KEY_WOW64_64KEY;
7805
7806     /* MSIPATCHSTATE_APPLIED */
7807
7808     lstrcpyA(patchcode, "apple");
7809     lstrcpyA(targetprod, "banana");
7810     context = 0xdeadbeef;
7811     lstrcpyA(targetsid, "kiwi");
7812     size = MAX_PATH;
7813     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7814                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7815                            &context, targetsid, &size);
7816     if (r == ERROR_ACCESS_DENIED)
7817     {
7818         skip("Not enough rights to perform tests\n");
7819         return;
7820     }
7821     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7822     ok(!lstrcmpA(patchcode, "apple"),
7823        "Expected patchcode to be unchanged, got %s\n", patchcode);
7824     ok(!lstrcmpA(targetprod, "banana"),
7825        "Expected targetprod to be unchanged, got %s\n", targetprod);
7826     ok(context == 0xdeadbeef,
7827        "Expected context to be unchanged, got %d\n", context);
7828     ok(!lstrcmpA(targetsid, "kiwi"),
7829        "Expected targetsid to be unchanged, got %s\n", targetsid);
7830     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7831
7832     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7833     lstrcatA(keypath, expectedsid);
7834     lstrcatA(keypath, "\\Installer\\Products\\");
7835     lstrcatA(keypath, prod_squashed);
7836
7837     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7838     if (res == ERROR_ACCESS_DENIED)
7839     {
7840         skip("Not enough rights to perform tests\n");
7841         return;
7842     }
7843     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7844
7845     /* managed product key exists */
7846     lstrcpyA(patchcode, "apple");
7847     lstrcpyA(targetprod, "banana");
7848     context = 0xdeadbeef;
7849     lstrcpyA(targetsid, "kiwi");
7850     size = MAX_PATH;
7851     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7852                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7853                            &context, targetsid, &size);
7854     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7855     ok(!lstrcmpA(patchcode, "apple"),
7856        "Expected patchcode to be unchanged, got %s\n", patchcode);
7857     ok(!lstrcmpA(targetprod, "banana"),
7858        "Expected targetprod to be unchanged, got %s\n", targetprod);
7859     ok(context == 0xdeadbeef,
7860        "Expected context to be unchanged, got %d\n", context);
7861     ok(!lstrcmpA(targetsid, "kiwi"),
7862        "Expected targetsid to be unchanged, got %s\n", targetsid);
7863     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7864
7865     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
7866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7867
7868     /* patches key exists */
7869     lstrcpyA(patchcode, "apple");
7870     lstrcpyA(targetprod, "banana");
7871     context = 0xdeadbeef;
7872     lstrcpyA(targetsid, "kiwi");
7873     size = MAX_PATH;
7874     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7875                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7876                            &context, targetsid, &size);
7877     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7878     ok(!lstrcmpA(patchcode, "apple"),
7879        "Expected patchcode to be unchanged, got %s\n", patchcode);
7880     ok(!lstrcmpA(targetprod, "banana"),
7881        "Expected targetprod to be unchanged, got %s\n", targetprod);
7882     ok(context == 0xdeadbeef,
7883        "Expected context to be unchanged, got %d\n", context);
7884     ok(!lstrcmpA(targetsid, "kiwi"),
7885        "Expected targetsid to be unchanged, got %s\n", targetsid);
7886     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7887
7888     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7889                          (const BYTE *)patch_squashed,
7890                          lstrlenA(patch_squashed) + 1);
7891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7892
7893     /* Patches value exists, is not REG_MULTI_SZ */
7894     lstrcpyA(patchcode, "apple");
7895     lstrcpyA(targetprod, "banana");
7896     context = 0xdeadbeef;
7897     lstrcpyA(targetsid, "kiwi");
7898     size = MAX_PATH;
7899     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7900                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7901                            &context, targetsid, &size);
7902     ok(r == ERROR_BAD_CONFIGURATION,
7903        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7904     ok(!lstrcmpA(patchcode, "apple"),
7905        "Expected patchcode to be unchanged, got %s\n", patchcode);
7906     ok(!lstrcmpA(targetprod, "banana"),
7907        "Expected targetprod to be unchanged, got %s\n", targetprod);
7908     ok(context == 0xdeadbeef,
7909        "Expected context to be unchanged, got %d\n", context);
7910     ok(!lstrcmpA(targetsid, "kiwi"),
7911        "Expected targetsid to be unchanged, got %s\n", targetsid);
7912     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7913
7914     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7915                          (const BYTE *)"a\0b\0c\0\0", 7);
7916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7917
7918     /* Patches value exists, is not a squashed guid */
7919     lstrcpyA(patchcode, "apple");
7920     lstrcpyA(targetprod, "banana");
7921     context = 0xdeadbeef;
7922     lstrcpyA(targetsid, "kiwi");
7923     size = MAX_PATH;
7924     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7925                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7926                            &context, targetsid, &size);
7927     ok(r == ERROR_BAD_CONFIGURATION,
7928        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7929     ok(!lstrcmpA(patchcode, "apple"),
7930        "Expected patchcode to be unchanged, got %s\n", patchcode);
7931     ok(!lstrcmpA(targetprod, "banana"),
7932        "Expected targetprod to be unchanged, got %s\n", targetprod);
7933     ok(context == 0xdeadbeef,
7934        "Expected context to be unchanged, got %d\n", context);
7935     ok(!lstrcmpA(targetsid, "kiwi"),
7936        "Expected targetsid to be unchanged, got %s\n", targetsid);
7937     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7938
7939     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
7940     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7941                          (const BYTE *)patch_squashed,
7942                          lstrlenA(patch_squashed) + 2);
7943     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7944
7945     /* Patches value exists */
7946     lstrcpyA(patchcode, "apple");
7947     lstrcpyA(targetprod, "banana");
7948     context = 0xdeadbeef;
7949     lstrcpyA(targetsid, "kiwi");
7950     size = MAX_PATH;
7951     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7952                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7953                            &context, targetsid, &size);
7954     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7955     ok(!lstrcmpA(patchcode, "apple"),
7956        "Expected patchcode to be unchanged, got %s\n", patchcode);
7957     ok(!lstrcmpA(targetprod, "banana"),
7958        "Expected targetprod to be unchanged, got %s\n", targetprod);
7959     ok(context == 0xdeadbeef,
7960        "Expected context to be unchanged, got %d\n", context);
7961     ok(!lstrcmpA(targetsid, "kiwi"),
7962        "Expected targetsid to be unchanged, got %s\n", targetsid);
7963     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7964
7965     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7966                          (const BYTE *)"whatever", 9);
7967     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7968
7969     /* patch squashed value exists */
7970     lstrcpyA(patchcode, "apple");
7971     lstrcpyA(targetprod, "banana");
7972     context = 0xdeadbeef;
7973     lstrcpyA(targetsid, "kiwi");
7974     size = MAX_PATH;
7975     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7976                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7977                            &context, targetsid, &size);
7978     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7979     ok(!lstrcmpA(patchcode, patch),
7980        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7981     ok(!lstrcmpA(targetprod, prodcode),
7982        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7983     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7984        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7985     ok(!lstrcmpA(targetsid, expectedsid),
7986        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7987     ok(size == lstrlenA(expectedsid),
7988        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7989
7990     /* increase the index */
7991     lstrcpyA(patchcode, "apple");
7992     lstrcpyA(targetprod, "banana");
7993     context = 0xdeadbeef;
7994     lstrcpyA(targetsid, "kiwi");
7995     size = MAX_PATH;
7996     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7997                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7998                            &context, targetsid, &size);
7999     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8000     ok(!lstrcmpA(patchcode, "apple"),
8001        "Expected patchcode to be unchanged, got %s\n", patchcode);
8002     ok(!lstrcmpA(targetprod, "banana"),
8003        "Expected targetprod to be unchanged, got %s\n", targetprod);
8004     ok(context == 0xdeadbeef,
8005        "Expected context to be unchanged, got %d\n", context);
8006     ok(!lstrcmpA(targetsid, "kiwi"),
8007        "Expected targetsid to be unchanged, got %s\n", targetsid);
8008     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8009
8010     /* increase again */
8011     lstrcpyA(patchcode, "apple");
8012     lstrcpyA(targetprod, "banana");
8013     context = 0xdeadbeef;
8014     lstrcpyA(targetsid, "kiwi");
8015     size = MAX_PATH;
8016     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8017                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
8018                            &context, targetsid, &size);
8019     ok(r == ERROR_INVALID_PARAMETER,
8020        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8021     ok(!lstrcmpA(patchcode, "apple"),
8022        "Expected patchcode to be unchanged, got %s\n", patchcode);
8023     ok(!lstrcmpA(targetprod, "banana"),
8024        "Expected targetprod to be unchanged, got %s\n", targetprod);
8025     ok(context == 0xdeadbeef,
8026        "Expected context to be unchanged, got %d\n", context);
8027     ok(!lstrcmpA(targetsid, "kiwi"),
8028        "Expected targetsid to be unchanged, got %s\n", targetsid);
8029     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8030
8031     /* szPatchCode is NULL */
8032     lstrcpyA(targetprod, "banana");
8033     context = 0xdeadbeef;
8034     lstrcpyA(targetsid, "kiwi");
8035     size = MAX_PATH;
8036     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8037                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
8038                            &context, targetsid, &size);
8039     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8040     ok(!lstrcmpA(targetprod, prodcode),
8041        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8042     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8043        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8044     ok(!lstrcmpA(targetsid, expectedsid),
8045        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8046     ok(size == lstrlenA(expectedsid),
8047        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8048
8049     /* szTargetProductCode is NULL */
8050     lstrcpyA(patchcode, "apple");
8051     context = 0xdeadbeef;
8052     lstrcpyA(targetsid, "kiwi");
8053     size = MAX_PATH;
8054     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8055                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
8056                            &context, targetsid, &size);
8057     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8058     ok(!lstrcmpA(patchcode, patch),
8059        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8060     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8061        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8062     ok(!lstrcmpA(targetsid, expectedsid),
8063        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8064     ok(size == lstrlenA(expectedsid),
8065        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8066
8067     /* pdwTargetProductContext is NULL */
8068     lstrcpyA(patchcode, "apple");
8069     lstrcpyA(targetprod, "banana");
8070     lstrcpyA(targetsid, "kiwi");
8071     size = MAX_PATH;
8072     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8073                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8074                            NULL, targetsid, &size);
8075     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8076     ok(!lstrcmpA(patchcode, patch),
8077        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8078     ok(!lstrcmpA(targetprod, prodcode),
8079        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8080     ok(!lstrcmpA(targetsid, expectedsid),
8081        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8082     ok(size == lstrlenA(expectedsid),
8083        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8084
8085     /* szTargetUserSid is NULL */
8086     lstrcpyA(patchcode, "apple");
8087     lstrcpyA(targetprod, "banana");
8088     context = 0xdeadbeef;
8089     size = MAX_PATH;
8090     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8091                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8092                            &context, NULL, &size);
8093     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8094     ok(!lstrcmpA(patchcode, patch),
8095        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8096     ok(!lstrcmpA(targetprod, prodcode),
8097        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8098     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8099        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8100     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8101        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8102
8103     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
8104     lstrcpyA(patchcode, "apple");
8105     lstrcpyA(targetprod, "banana");
8106     context = 0xdeadbeef;
8107     lstrcpyA(targetsid, "kiwi");
8108     size = lstrlenA(expectedsid);
8109     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8110                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8111                            &context, targetsid, &size);
8112     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8113     ok(!lstrcmpA(patchcode, patch),
8114        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8115     ok(!lstrcmpA(targetprod, prodcode),
8116        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8117     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8118        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8119     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
8120        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8121     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8122        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8123
8124     /* pcchTargetUserSid has enough room for NULL terminator */
8125     lstrcpyA(patchcode, "apple");
8126     lstrcpyA(targetprod, "banana");
8127     context = 0xdeadbeef;
8128     lstrcpyA(targetsid, "kiwi");
8129     size = lstrlenA(expectedsid) + 1;
8130     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8131                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8132                            &context, targetsid, &size);
8133     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8134     ok(!lstrcmpA(patchcode, patch),
8135        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8136     ok(!lstrcmpA(targetprod, prodcode),
8137        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8138     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8139        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8140     ok(!lstrcmpA(targetsid, expectedsid),
8141        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8142     ok(size == lstrlenA(expectedsid),
8143        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8144
8145     /* both szTargetuserSid and pcchTargetUserSid are NULL */
8146     lstrcpyA(patchcode, "apple");
8147     lstrcpyA(targetprod, "banana");
8148     context = 0xdeadbeef;
8149     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8150                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8151                            &context, NULL, NULL);
8152     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8153     ok(!lstrcmpA(patchcode, patch),
8154        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8155     ok(!lstrcmpA(targetprod, prodcode),
8156        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8157     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8158        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8159
8160     /* MSIPATCHSTATE_SUPERSEDED */
8161
8162     lstrcpyA(patchcode, "apple");
8163     lstrcpyA(targetprod, "banana");
8164     context = 0xdeadbeef;
8165     lstrcpyA(targetsid, "kiwi");
8166     size = MAX_PATH;
8167     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8168                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8169                            &context, targetsid, &size);
8170     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8171     ok(!lstrcmpA(patchcode, "apple"),
8172        "Expected patchcode to be unchanged, got %s\n", patchcode);
8173     ok(!lstrcmpA(targetprod, "banana"),
8174        "Expected targetprod to be unchanged, got %s\n", targetprod);
8175     ok(context == 0xdeadbeef,
8176        "Expected context to be unchanged, got %d\n", context);
8177     ok(!lstrcmpA(targetsid, "kiwi"),
8178        "Expected targetsid to be unchanged, got %s\n", targetsid);
8179     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8180
8181     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8182     lstrcatA(keypath, expectedsid);
8183     lstrcatA(keypath, "\\Products\\");
8184     lstrcatA(keypath, prod_squashed);
8185
8186     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8188
8189     /* UserData product key exists */
8190     lstrcpyA(patchcode, "apple");
8191     lstrcpyA(targetprod, "banana");
8192     context = 0xdeadbeef;
8193     lstrcpyA(targetsid, "kiwi");
8194     size = MAX_PATH;
8195     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8196                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8197                            &context, targetsid, &size);
8198     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8199     ok(!lstrcmpA(patchcode, "apple"),
8200        "Expected patchcode to be unchanged, got %s\n", patchcode);
8201     ok(!lstrcmpA(targetprod, "banana"),
8202        "Expected targetprod to be unchanged, got %s\n", targetprod);
8203     ok(context == 0xdeadbeef,
8204        "Expected context to be unchanged, got %d\n", context);
8205     ok(!lstrcmpA(targetsid, "kiwi"),
8206        "Expected targetsid to be unchanged, got %s\n", targetsid);
8207     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8208
8209     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8211
8212     /* UserData patches key exists */
8213     lstrcpyA(patchcode, "apple");
8214     lstrcpyA(targetprod, "banana");
8215     context = 0xdeadbeef;
8216     lstrcpyA(targetsid, "kiwi");
8217     size = MAX_PATH;
8218     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8219                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8220                            &context, targetsid, &size);
8221     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8222     ok(!lstrcmpA(patchcode, "apple"),
8223        "Expected patchcode to be unchanged, got %s\n", patchcode);
8224     ok(!lstrcmpA(targetprod, "banana"),
8225        "Expected targetprod to be unchanged, got %s\n", targetprod);
8226     ok(context == 0xdeadbeef,
8227        "Expected context to be unchanged, got %d\n", context);
8228     ok(!lstrcmpA(targetsid, "kiwi"),
8229        "Expected targetsid to be unchanged, got %s\n", targetsid);
8230     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8231
8232     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8233     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8234
8235     /* specific UserData patch key exists */
8236     lstrcpyA(patchcode, "apple");
8237     lstrcpyA(targetprod, "banana");
8238     context = 0xdeadbeef;
8239     lstrcpyA(targetsid, "kiwi");
8240     size = MAX_PATH;
8241     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8242                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8243                            &context, targetsid, &size);
8244     ok(r == ERROR_BAD_CONFIGURATION,
8245        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8246     ok(!lstrcmpA(patchcode, "apple"),
8247        "Expected patchcode to be unchanged, got %s\n", patchcode);
8248     ok(!lstrcmpA(targetprod, "banana"),
8249        "Expected targetprod to be unchanged, got %s\n", targetprod);
8250     ok(context == 0xdeadbeef,
8251        "Expected context to be unchanged, got %d\n", context);
8252     ok(!lstrcmpA(targetsid, "kiwi"),
8253        "Expected targetsid to be unchanged, got %s\n", targetsid);
8254     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8255
8256     data = MSIPATCHSTATE_SUPERSEDED;
8257     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8258                          (const BYTE *)&data, sizeof(DWORD));
8259     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8260
8261     /* State value exists */
8262     lstrcpyA(patchcode, "apple");
8263     lstrcpyA(targetprod, "banana");
8264     context = 0xdeadbeef;
8265     lstrcpyA(targetsid, "kiwi");
8266     size = MAX_PATH;
8267     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8268                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8269                            &context, targetsid, &size);
8270     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8271     ok(!lstrcmpA(patchcode, patch),
8272        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8273     ok(!lstrcmpA(targetprod, prodcode),
8274        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8275     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8276        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8277     ok(!lstrcmpA(targetsid, expectedsid),
8278        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8279     ok(size == lstrlenA(expectedsid),
8280        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8281
8282     /* MSIPATCHSTATE_OBSOLETED */
8283
8284     lstrcpyA(patchcode, "apple");
8285     lstrcpyA(targetprod, "banana");
8286     context = 0xdeadbeef;
8287     lstrcpyA(targetsid, "kiwi");
8288     size = MAX_PATH;
8289     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8290                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8291                            &context, targetsid, &size);
8292     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8293     ok(!lstrcmpA(patchcode, "apple"),
8294        "Expected patchcode to be unchanged, got %s\n", patchcode);
8295     ok(!lstrcmpA(targetprod, "banana"),
8296        "Expected targetprod to be unchanged, got %s\n", targetprod);
8297     ok(context == 0xdeadbeef,
8298        "Expected context to be unchanged, got %d\n", context);
8299     ok(!lstrcmpA(targetsid, "kiwi"),
8300        "Expected targetsid to be unchanged, got %s\n", targetsid);
8301     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8302
8303     data = MSIPATCHSTATE_OBSOLETED;
8304     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8305                          (const BYTE *)&data, sizeof(DWORD));
8306     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8307
8308     /* State value is obsoleted */
8309     lstrcpyA(patchcode, "apple");
8310     lstrcpyA(targetprod, "banana");
8311     context = 0xdeadbeef;
8312     lstrcpyA(targetsid, "kiwi");
8313     size = MAX_PATH;
8314     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8315                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8316                            &context, targetsid, &size);
8317     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8318     ok(!lstrcmpA(patchcode, patch),
8319        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8320     ok(!lstrcmpA(targetprod, prodcode),
8321        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8322     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8323        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8324     ok(!lstrcmpA(targetsid, expectedsid),
8325        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8326     ok(size == lstrlenA(expectedsid),
8327        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8328
8329     /* MSIPATCHSTATE_REGISTERED */
8330     /* FIXME */
8331
8332     /* MSIPATCHSTATE_ALL */
8333
8334     /* 1st */
8335     lstrcpyA(patchcode, "apple");
8336     lstrcpyA(targetprod, "banana");
8337     context = 0xdeadbeef;
8338     lstrcpyA(targetsid, "kiwi");
8339     size = MAX_PATH;
8340     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8341                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8342                            &context, targetsid, &size);
8343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8344     ok(!lstrcmpA(patchcode, patch),
8345        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8346     ok(!lstrcmpA(targetprod, prodcode),
8347        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8348     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8349        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8350     ok(!lstrcmpA(targetsid, expectedsid),
8351        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8352     ok(size == lstrlenA(expectedsid),
8353        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8354
8355     /* same patch in multiple places, only one is enumerated */
8356     lstrcpyA(patchcode, "apple");
8357     lstrcpyA(targetprod, "banana");
8358     context = 0xdeadbeef;
8359     lstrcpyA(targetsid, "kiwi");
8360     size = MAX_PATH;
8361     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8362                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8363                            &context, targetsid, &size);
8364     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8365     ok(!lstrcmpA(patchcode, "apple"),
8366        "Expected patchcode to be unchanged, got %s\n", patchcode);
8367     ok(!lstrcmpA(targetprod, "banana"),
8368        "Expected targetprod to be unchanged, got %s\n", targetprod);
8369     ok(context == 0xdeadbeef,
8370        "Expected context to be unchanged, got %d\n", context);
8371     ok(!lstrcmpA(targetsid, "kiwi"),
8372        "Expected targetsid to be unchanged, got %s\n", targetsid);
8373     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8374
8375     RegDeleteValueA(hpatch, "State");
8376     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8377     RegCloseKey(hpatch);
8378     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8379     RegCloseKey(udpatch);
8380     delete_key(udprod, "", access & KEY_WOW64_64KEY);
8381     RegCloseKey(udprod);
8382     RegDeleteValueA(patches, "Patches");
8383     delete_key(patches, "", access & KEY_WOW64_64KEY);
8384     RegCloseKey(patches);
8385     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8386     RegCloseKey(prodkey);
8387 }
8388
8389 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8390 {
8391     MSIINSTALLCONTEXT context;
8392     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8393     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8394     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8395     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8396     HKEY prodkey, patches, udprod, udpatch;
8397     HKEY userkey, hpatch;
8398     DWORD size, data;
8399     LONG res;
8400     UINT r;
8401     REGSAM access = KEY_ALL_ACCESS;
8402     BOOL wow64;
8403
8404     create_test_guid(prodcode, prod_squashed);
8405     create_test_guid(patch, patch_squashed);
8406
8407     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
8408         access |= KEY_WOW64_64KEY;
8409
8410     /* MSIPATCHSTATE_APPLIED */
8411
8412     lstrcpyA(patchcode, "apple");
8413     lstrcpyA(targetprod, "banana");
8414     context = 0xdeadbeef;
8415     lstrcpyA(targetsid, "kiwi");
8416     size = MAX_PATH;
8417     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8418                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8419                            &context, targetsid, &size);
8420     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8421     ok(!lstrcmpA(patchcode, "apple"),
8422        "Expected patchcode to be unchanged, got %s\n", patchcode);
8423     ok(!lstrcmpA(targetprod, "banana"),
8424        "Expected targetprod to be unchanged, got %s\n", targetprod);
8425     ok(context == 0xdeadbeef,
8426        "Expected context to be unchanged, got %d\n", context);
8427     ok(!lstrcmpA(targetsid, "kiwi"),
8428        "Expected targetsid to be unchanged, got %s\n", targetsid);
8429     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8430
8431     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8432     lstrcatA(keypath, prod_squashed);
8433
8434     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8435     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8436
8437     /* current user product key exists */
8438     lstrcpyA(patchcode, "apple");
8439     lstrcpyA(targetprod, "banana");
8440     context = 0xdeadbeef;
8441     lstrcpyA(targetsid, "kiwi");
8442     size = MAX_PATH;
8443     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8444                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8445                            &context, targetsid, &size);
8446     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8447     ok(!lstrcmpA(patchcode, "apple"),
8448        "Expected patchcode to be unchanged, got %s\n", patchcode);
8449     ok(!lstrcmpA(targetprod, "banana"),
8450        "Expected targetprod to be unchanged, got %s\n", targetprod);
8451     ok(context == 0xdeadbeef,
8452        "Expected context to be unchanged, got %d\n", context);
8453     ok(!lstrcmpA(targetsid, "kiwi"),
8454        "Expected targetsid to be unchanged, got %s\n", targetsid);
8455     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8456
8457     res = RegCreateKeyA(prodkey, "Patches", &patches);
8458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8459
8460     /* Patches key exists */
8461     lstrcpyA(patchcode, "apple");
8462     lstrcpyA(targetprod, "banana");
8463     context = 0xdeadbeef;
8464     lstrcpyA(targetsid, "kiwi");
8465     size = MAX_PATH;
8466     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8467                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8468                            &context, targetsid, &size);
8469     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8470     ok(!lstrcmpA(patchcode, "apple"),
8471        "Expected patchcode to be unchanged, got %s\n", patchcode);
8472     ok(!lstrcmpA(targetprod, "banana"),
8473        "Expected targetprod to be unchanged, got %s\n", targetprod);
8474     ok(context == 0xdeadbeef,
8475        "Expected context to be unchanged, got %d\n", context);
8476     ok(!lstrcmpA(targetsid, "kiwi"),
8477        "Expected targetsid to be unchanged, got %s\n", targetsid);
8478     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8479
8480     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8481                          (const BYTE *)patch_squashed,
8482                          lstrlenA(patch_squashed) + 1);
8483     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8484
8485     /* Patches value exists, is not REG_MULTI_SZ */
8486     lstrcpyA(patchcode, "apple");
8487     lstrcpyA(targetprod, "banana");
8488     context = 0xdeadbeef;
8489     lstrcpyA(targetsid, "kiwi");
8490     size = MAX_PATH;
8491     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8492                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8493                            &context, targetsid, &size);
8494     ok(r == ERROR_BAD_CONFIGURATION,
8495        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8496     ok(!lstrcmpA(patchcode, "apple"),
8497        "Expected patchcode to be unchanged, got %s\n", patchcode);
8498     ok(!lstrcmpA(targetprod, "banana"),
8499        "Expected targetprod to be unchanged, got %s\n", targetprod);
8500     ok(context == 0xdeadbeef,
8501        "Expected context to be unchanged, got %d\n", context);
8502     ok(!lstrcmpA(targetsid, "kiwi"),
8503        "Expected targetsid to be unchanged, got %s\n", targetsid);
8504     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8505
8506     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8507                          (const BYTE *)"a\0b\0c\0\0", 7);
8508     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8509
8510     /* Patches value exists, is not a squashed guid */
8511     lstrcpyA(patchcode, "apple");
8512     lstrcpyA(targetprod, "banana");
8513     context = 0xdeadbeef;
8514     lstrcpyA(targetsid, "kiwi");
8515     size = MAX_PATH;
8516     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8517                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8518                            &context, targetsid, &size);
8519     ok(r == ERROR_BAD_CONFIGURATION,
8520        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8521     ok(!lstrcmpA(patchcode, "apple"),
8522        "Expected patchcode to be unchanged, got %s\n", patchcode);
8523     ok(!lstrcmpA(targetprod, "banana"),
8524        "Expected targetprod to be unchanged, got %s\n", targetprod);
8525     ok(context == 0xdeadbeef,
8526        "Expected context to be unchanged, got %d\n", context);
8527     ok(!lstrcmpA(targetsid, "kiwi"),
8528        "Expected targetsid to be unchanged, got %s\n", targetsid);
8529     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8530
8531     patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
8532     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8533                          (const BYTE *)patch_squashed,
8534                          lstrlenA(patch_squashed) + 2);
8535     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8536
8537     /* Patches value exists */
8538     lstrcpyA(patchcode, "apple");
8539     lstrcpyA(targetprod, "banana");
8540     context = 0xdeadbeef;
8541     lstrcpyA(targetsid, "kiwi");
8542     size = MAX_PATH;
8543     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8544                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8545                            &context, targetsid, &size);
8546     ok(r == ERROR_NO_MORE_ITEMS ||
8547        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8548        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8549     ok(!lstrcmpA(patchcode, "apple"),
8550        "Expected patchcode to be unchanged, got %s\n", patchcode);
8551     ok(!lstrcmpA(targetprod, "banana"),
8552        "Expected targetprod to be unchanged, got %s\n", targetprod);
8553     ok(context == 0xdeadbeef,
8554        "Expected context to be unchanged, got %d\n", context);
8555     ok(!lstrcmpA(targetsid, "kiwi"),
8556        "Expected targetsid to be unchanged, got %s\n", targetsid);
8557     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8558
8559     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8560                          (const BYTE *)"whatever", 9);
8561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8562
8563     /* patch code value exists */
8564     lstrcpyA(patchcode, "apple");
8565     lstrcpyA(targetprod, "banana");
8566     context = 0xdeadbeef;
8567     lstrcpyA(targetsid, "kiwi");
8568     size = MAX_PATH;
8569     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8570                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8571                            &context, targetsid, &size);
8572     ok(r == ERROR_NO_MORE_ITEMS ||
8573        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8574        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8575     ok(!lstrcmpA(patchcode, "apple"),
8576        "Expected patchcode to be unchanged, got %s\n", patchcode);
8577     ok(!lstrcmpA(targetprod, "banana"),
8578        "Expected targetprod to be unchanged, got %s\n", targetprod);
8579     ok(context == 0xdeadbeef,
8580        "Expected context to be unchanged, got %d\n", context);
8581     ok(!lstrcmpA(targetsid, "kiwi"),
8582        "Expected targetsid to be unchanged, got %s\n", targetsid);
8583     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8584
8585     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8586     lstrcatA(keypath, expectedsid);
8587     lstrcatA(keypath, "\\Patches\\");
8588     lstrcatA(keypath, patch_squashed);
8589
8590     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8591     if (res == ERROR_ACCESS_DENIED)
8592     {
8593         skip("Not enough rights to perform tests\n");
8594         goto error;
8595     }
8596     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8597
8598     /* userdata patch key exists */
8599     lstrcpyA(patchcode, "apple");
8600     lstrcpyA(targetprod, "banana");
8601     context = 0xdeadbeef;
8602     lstrcpyA(targetsid, "kiwi");
8603     size = MAX_PATH;
8604     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8605                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8606                            &context, targetsid, &size);
8607     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8608     ok(!lstrcmpA(patchcode, patch),
8609        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8610     ok(!lstrcmpA(targetprod, prodcode),
8611        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8612     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8613        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8614     ok(!lstrcmpA(targetsid, expectedsid),
8615        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8616     ok(size == lstrlenA(expectedsid),
8617        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8618
8619     /* MSIPATCHSTATE_SUPERSEDED */
8620
8621     lstrcpyA(patchcode, "apple");
8622     lstrcpyA(targetprod, "banana");
8623     context = 0xdeadbeef;
8624     lstrcpyA(targetsid, "kiwi");
8625     size = MAX_PATH;
8626     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8627                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8628                            &context, targetsid, &size);
8629     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8630     ok(!lstrcmpA(patchcode, "apple"),
8631        "Expected patchcode to be unchanged, got %s\n", patchcode);
8632     ok(!lstrcmpA(targetprod, "banana"),
8633        "Expected targetprod to be unchanged, got %s\n", targetprod);
8634     ok(context == 0xdeadbeef,
8635        "Expected context to be unchanged, got %d\n", context);
8636     ok(!lstrcmpA(targetsid, "kiwi"),
8637        "Expected targetsid to be unchanged, got %s\n", targetsid);
8638     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8639
8640     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8641     lstrcatA(keypath, expectedsid);
8642     lstrcatA(keypath, "\\Products\\");
8643     lstrcatA(keypath, prod_squashed);
8644
8645     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8646     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8647
8648     /* UserData product key exists */
8649     lstrcpyA(patchcode, "apple");
8650     lstrcpyA(targetprod, "banana");
8651     context = 0xdeadbeef;
8652     lstrcpyA(targetsid, "kiwi");
8653     size = MAX_PATH;
8654     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8655                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8656                            &context, targetsid, &size);
8657     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8658     ok(!lstrcmpA(patchcode, "apple"),
8659        "Expected patchcode to be unchanged, got %s\n", patchcode);
8660     ok(!lstrcmpA(targetprod, "banana"),
8661        "Expected targetprod to be unchanged, got %s\n", targetprod);
8662     ok(context == 0xdeadbeef,
8663        "Expected context to be unchanged, got %d\n", context);
8664     ok(!lstrcmpA(targetsid, "kiwi"),
8665        "Expected targetsid to be unchanged, got %s\n", targetsid);
8666     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8667
8668     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8669     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8670
8671     /* UserData patches key exists */
8672     lstrcpyA(patchcode, "apple");
8673     lstrcpyA(targetprod, "banana");
8674     context = 0xdeadbeef;
8675     lstrcpyA(targetsid, "kiwi");
8676     size = MAX_PATH;
8677     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8678                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8679                            &context, targetsid, &size);
8680     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8681     ok(!lstrcmpA(patchcode, "apple"),
8682        "Expected patchcode to be unchanged, got %s\n", patchcode);
8683     ok(!lstrcmpA(targetprod, "banana"),
8684        "Expected targetprod to be unchanged, got %s\n", targetprod);
8685     ok(context == 0xdeadbeef,
8686        "Expected context to be unchanged, got %d\n", context);
8687     ok(!lstrcmpA(targetsid, "kiwi"),
8688        "Expected targetsid to be unchanged, got %s\n", targetsid);
8689     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8690
8691     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8692     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8693
8694     /* specific UserData patch key exists */
8695     lstrcpyA(patchcode, "apple");
8696     lstrcpyA(targetprod, "banana");
8697     context = 0xdeadbeef;
8698     lstrcpyA(targetsid, "kiwi");
8699     size = MAX_PATH;
8700     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8701                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8702                            &context, targetsid, &size);
8703     ok(r == ERROR_BAD_CONFIGURATION,
8704        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8705     ok(!lstrcmpA(patchcode, "apple"),
8706        "Expected patchcode to be unchanged, got %s\n", patchcode);
8707     ok(!lstrcmpA(targetprod, "banana"),
8708        "Expected targetprod to be unchanged, got %s\n", targetprod);
8709     ok(context == 0xdeadbeef,
8710        "Expected context to be unchanged, got %d\n", context);
8711     ok(!lstrcmpA(targetsid, "kiwi"),
8712        "Expected targetsid to be unchanged, got %s\n", targetsid);
8713     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8714
8715     data = MSIPATCHSTATE_SUPERSEDED;
8716     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8717                          (const BYTE *)&data, sizeof(DWORD));
8718     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8719
8720     /* State value exists */
8721     lstrcpyA(patchcode, "apple");
8722     lstrcpyA(targetprod, "banana");
8723     context = 0xdeadbeef;
8724     lstrcpyA(targetsid, "kiwi");
8725     size = MAX_PATH;
8726     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8727                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8728                            &context, targetsid, &size);
8729     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8730     ok(!lstrcmpA(patchcode, patch),
8731        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8732     ok(!lstrcmpA(targetprod, prodcode),
8733        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8734     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8735        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8736     ok(!lstrcmpA(targetsid, expectedsid),
8737        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8738     ok(size == lstrlenA(expectedsid),
8739        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8740
8741     /* MSIPATCHSTATE_OBSOLETED */
8742
8743     lstrcpyA(patchcode, "apple");
8744     lstrcpyA(targetprod, "banana");
8745     context = 0xdeadbeef;
8746     lstrcpyA(targetsid, "kiwi");
8747     size = MAX_PATH;
8748     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8749                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8750                            &context, targetsid, &size);
8751     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8752     ok(!lstrcmpA(patchcode, "apple"),
8753        "Expected patchcode to be unchanged, got %s\n", patchcode);
8754     ok(!lstrcmpA(targetprod, "banana"),
8755        "Expected targetprod to be unchanged, got %s\n", targetprod);
8756     ok(context == 0xdeadbeef,
8757        "Expected context to be unchanged, got %d\n", context);
8758     ok(!lstrcmpA(targetsid, "kiwi"),
8759        "Expected targetsid to be unchanged, got %s\n", targetsid);
8760     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8761
8762     data = MSIPATCHSTATE_OBSOLETED;
8763     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8764                          (const BYTE *)&data, sizeof(DWORD));
8765     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8766
8767     /* State value is obsoleted */
8768     lstrcpyA(patchcode, "apple");
8769     lstrcpyA(targetprod, "banana");
8770     context = 0xdeadbeef;
8771     lstrcpyA(targetsid, "kiwi");
8772     size = MAX_PATH;
8773     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8774                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8775                            &context, targetsid, &size);
8776     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8777     ok(!lstrcmpA(patchcode, patch),
8778        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8779     ok(!lstrcmpA(targetprod, prodcode),
8780        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8781     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8782        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8783     ok(!lstrcmpA(targetsid, expectedsid),
8784        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8785     ok(size == lstrlenA(expectedsid),
8786        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8787
8788     /* MSIPATCHSTATE_REGISTERED */
8789     /* FIXME */
8790
8791     /* MSIPATCHSTATE_ALL */
8792
8793     /* 1st */
8794     lstrcpyA(patchcode, "apple");
8795     lstrcpyA(targetprod, "banana");
8796     context = 0xdeadbeef;
8797     lstrcpyA(targetsid, "kiwi");
8798     size = MAX_PATH;
8799     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8800                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8801                            &context, targetsid, &size);
8802     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8803     ok(!lstrcmpA(patchcode, patch),
8804        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8805     ok(!lstrcmpA(targetprod, prodcode),
8806        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8807     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8808        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8809     ok(!lstrcmpA(targetsid, expectedsid),
8810        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8811     ok(size == lstrlenA(expectedsid),
8812        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8813
8814     /* same patch in multiple places, only one is enumerated */
8815     lstrcpyA(patchcode, "apple");
8816     lstrcpyA(targetprod, "banana");
8817     context = 0xdeadbeef;
8818     lstrcpyA(targetsid, "kiwi");
8819     size = MAX_PATH;
8820     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8821                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8822                            &context, targetsid, &size);
8823     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8824     ok(!lstrcmpA(patchcode, "apple"),
8825        "Expected patchcode to be unchanged, got %s\n", patchcode);
8826     ok(!lstrcmpA(targetprod, "banana"),
8827        "Expected targetprod to be unchanged, got %s\n", targetprod);
8828     ok(context == 0xdeadbeef,
8829        "Expected context to be unchanged, got %d\n", context);
8830     ok(!lstrcmpA(targetsid, "kiwi"),
8831        "Expected targetsid to be unchanged, got %s\n", targetsid);
8832     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8833
8834     RegDeleteValueA(hpatch, "State");
8835     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8836     RegCloseKey(hpatch);
8837     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8838     RegCloseKey(udpatch);
8839     delete_key(udprod, "", access & KEY_WOW64_64KEY);
8840     RegCloseKey(udprod);
8841     delete_key(userkey, "", access & KEY_WOW64_64KEY);
8842     RegCloseKey(userkey);
8843     RegDeleteValueA(patches, patch_squashed);
8844     RegDeleteValueA(patches, "Patches");
8845
8846 error:
8847     RegDeleteKeyA(patches, "");
8848     RegCloseKey(patches);
8849     RegDeleteKeyA(prodkey, "");
8850     RegCloseKey(prodkey);
8851 }
8852
8853 static void test_MsiEnumPatchesEx_machine(void)
8854 {
8855     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8856     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8857     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8858     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8859     HKEY prodkey, patches, udprod, udpatch;
8860     HKEY hpatch;
8861     MSIINSTALLCONTEXT context;
8862     DWORD size, data;
8863     LONG res;
8864     UINT r;
8865     REGSAM access = KEY_ALL_ACCESS;
8866     BOOL wow64;
8867
8868     create_test_guid(prodcode, prod_squashed);
8869     create_test_guid(patch, patch_squashed);
8870
8871     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
8872         access |= KEY_WOW64_64KEY;
8873
8874     /* MSIPATCHSTATE_APPLIED */
8875
8876     lstrcpyA(patchcode, "apple");
8877     lstrcpyA(targetprod, "banana");
8878     context = 0xdeadbeef;
8879     lstrcpyA(targetsid, "kiwi");
8880     size = MAX_PATH;
8881     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8882                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8883                            &context, targetsid, &size);
8884     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8885     ok(!lstrcmpA(patchcode, "apple"),
8886        "Expected patchcode to be unchanged, got %s\n", patchcode);
8887     ok(!lstrcmpA(targetprod, "banana"),
8888        "Expected targetprod to be unchanged, got %s\n", targetprod);
8889     ok(context == 0xdeadbeef,
8890        "Expected context to be unchanged, got %d\n", context);
8891     ok(!lstrcmpA(targetsid, "kiwi"),
8892        "Expected targetsid to be unchanged, got %s\n", targetsid);
8893     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8894
8895     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8896     lstrcatA(keypath, prod_squashed);
8897
8898     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8899     if (res == ERROR_ACCESS_DENIED)
8900     {
8901         skip("Not enough rights to perform tests\n");
8902         return;
8903     }
8904     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8905
8906     /* local product key exists */
8907     lstrcpyA(patchcode, "apple");
8908     lstrcpyA(targetprod, "banana");
8909     context = 0xdeadbeef;
8910     lstrcpyA(targetsid, "kiwi");
8911     size = MAX_PATH;
8912     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8913                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8914                            &context, targetsid, &size);
8915     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8916     ok(!lstrcmpA(patchcode, "apple"),
8917        "Expected patchcode to be unchanged, got %s\n", patchcode);
8918     ok(!lstrcmpA(targetprod, "banana"),
8919        "Expected targetprod to be unchanged, got %s\n", targetprod);
8920     ok(context == 0xdeadbeef,
8921        "Expected context to be unchanged, got %d\n", context);
8922     ok(!lstrcmpA(targetsid, "kiwi"),
8923        "Expected targetsid to be unchanged, got %s\n", targetsid);
8924     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8925
8926     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
8927     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8928
8929     /* Patches key exists */
8930     lstrcpyA(patchcode, "apple");
8931     lstrcpyA(targetprod, "banana");
8932     context = 0xdeadbeef;
8933     lstrcpyA(targetsid, "kiwi");
8934     size = MAX_PATH;
8935     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8936                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8937                            &context, targetsid, &size);
8938     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8939     ok(!lstrcmpA(patchcode, "apple"),
8940        "Expected patchcode to be unchanged, got %s\n", patchcode);
8941     ok(!lstrcmpA(targetprod, "banana"),
8942        "Expected targetprod to be unchanged, got %s\n", targetprod);
8943     ok(context == 0xdeadbeef,
8944        "Expected context to be unchanged, got %d\n", context);
8945     ok(!lstrcmpA(targetsid, "kiwi"),
8946        "Expected targetsid to be unchanged, got %s\n", targetsid);
8947     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8948
8949     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8950                          (const BYTE *)patch_squashed,
8951                          lstrlenA(patch_squashed) + 1);
8952     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8953
8954     /* Patches value exists, is not REG_MULTI_SZ */
8955     lstrcpyA(patchcode, "apple");
8956     lstrcpyA(targetprod, "banana");
8957     context = 0xdeadbeef;
8958     lstrcpyA(targetsid, "kiwi");
8959     size = MAX_PATH;
8960     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8961                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8962                            &context, targetsid, &size);
8963     ok(r == ERROR_BAD_CONFIGURATION,
8964        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8965     ok(!lstrcmpA(patchcode, "apple"),
8966        "Expected patchcode to be unchanged, got %s\n", patchcode);
8967     ok(!lstrcmpA(targetprod, "banana"),
8968        "Expected targetprod to be unchanged, got %s\n", targetprod);
8969     ok(context == 0xdeadbeef,
8970        "Expected context to be unchanged, got %d\n", context);
8971     ok(!lstrcmpA(targetsid, "kiwi"),
8972        "Expected targetsid to be unchanged, got %s\n", targetsid);
8973     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8974
8975     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8976                          (const BYTE *)"a\0b\0c\0\0", 7);
8977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8978
8979     /* Patches value exists, is not a squashed guid */
8980     lstrcpyA(patchcode, "apple");
8981     lstrcpyA(targetprod, "banana");
8982     context = 0xdeadbeef;
8983     lstrcpyA(targetsid, "kiwi");
8984     size = MAX_PATH;
8985     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8986                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8987                            &context, targetsid, &size);
8988     ok(r == ERROR_BAD_CONFIGURATION,
8989        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8990     ok(!lstrcmpA(patchcode, "apple"),
8991        "Expected patchcode to be unchanged, got %s\n", patchcode);
8992     ok(!lstrcmpA(targetprod, "banana"),
8993        "Expected targetprod to be unchanged, got %s\n", targetprod);
8994     ok(context == 0xdeadbeef,
8995        "Expected context to be unchanged, got %d\n", context);
8996     ok(!lstrcmpA(targetsid, "kiwi"),
8997        "Expected targetsid to be unchanged, got %s\n", targetsid);
8998     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8999
9000     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9001     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9002                          (const BYTE *)patch_squashed,
9003                          lstrlenA(patch_squashed) + 2);
9004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9005
9006     /* Patches value exists */
9007     lstrcpyA(patchcode, "apple");
9008     lstrcpyA(targetprod, "banana");
9009     context = 0xdeadbeef;
9010     lstrcpyA(targetsid, "kiwi");
9011     size = MAX_PATH;
9012     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9013                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9014                            &context, targetsid, &size);
9015     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9016     ok(!lstrcmpA(patchcode, "apple"),
9017        "Expected patchcode to be unchanged, got %s\n", patchcode);
9018     ok(!lstrcmpA(targetprod, "banana"),
9019        "Expected targetprod to be unchanged, got %s\n", targetprod);
9020     ok(context == 0xdeadbeef,
9021        "Expected context to be unchanged, got %d\n", context);
9022     ok(!lstrcmpA(targetsid, "kiwi"),
9023        "Expected targetsid to be unchanged, got %s\n", targetsid);
9024     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9025
9026     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9027                          (const BYTE *)"whatever", 9);
9028     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9029
9030     /* patch code value exists */
9031     lstrcpyA(patchcode, "apple");
9032     lstrcpyA(targetprod, "banana");
9033     context = 0xdeadbeef;
9034     lstrcpyA(targetsid, "kiwi");
9035     size = MAX_PATH;
9036     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9037                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9038                            &context, targetsid, &size);
9039     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9040     ok(!lstrcmpA(patchcode, patch),
9041        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9042     ok(!lstrcmpA(targetprod, prodcode),
9043        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9044     ok(context == MSIINSTALLCONTEXT_MACHINE,
9045        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9046     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9047     ok(size == 0, "Expected 0, got %d\n", size);
9048
9049     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9050     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9051     lstrcatA(keypath, prod_squashed);
9052
9053     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9054     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9055
9056     /* local UserData product key exists */
9057     lstrcpyA(patchcode, "apple");
9058     lstrcpyA(targetprod, "banana");
9059     context = 0xdeadbeef;
9060     lstrcpyA(targetsid, "kiwi");
9061     size = MAX_PATH;
9062     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9063                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9064                            &context, targetsid, &size);
9065     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9066     ok(!lstrcmpA(patchcode, patch),
9067        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9068     ok(!lstrcmpA(targetprod, prodcode),
9069        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9070     ok(context == MSIINSTALLCONTEXT_MACHINE,
9071        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9072     ok(!lstrcmpA(targetsid, ""),
9073        "Expected \"\", got \"%s\"\n", targetsid);
9074     ok(size == 0, "Expected 0, got %d\n", size);
9075
9076     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9077     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9078
9079     /* local UserData Patches key exists */
9080     lstrcpyA(patchcode, "apple");
9081     lstrcpyA(targetprod, "banana");
9082     context = 0xdeadbeef;
9083     lstrcpyA(targetsid, "kiwi");
9084     size = MAX_PATH;
9085     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9086                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9087                            &context, targetsid, &size);
9088     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9089     ok(!lstrcmpA(patchcode, patch),
9090        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9091     ok(!lstrcmpA(targetprod, prodcode),
9092        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9093     ok(context == MSIINSTALLCONTEXT_MACHINE,
9094        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9095     ok(!lstrcmpA(targetsid, ""),
9096        "Expected \"\", got \"%s\"\n", targetsid);
9097     ok(size == 0, "Expected 0, got %d\n", size);
9098
9099     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9101
9102     /* local UserData Product patch key exists */
9103     lstrcpyA(patchcode, "apple");
9104     lstrcpyA(targetprod, "banana");
9105     context = 0xdeadbeef;
9106     lstrcpyA(targetsid, "kiwi");
9107     size = MAX_PATH;
9108     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9109                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9110                            &context, targetsid, &size);
9111     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9112     ok(!lstrcmpA(patchcode, "apple"),
9113        "Expected patchcode to be unchanged, got %s\n", patchcode);
9114     ok(!lstrcmpA(targetprod, "banana"),
9115        "Expected targetprod to be unchanged, got %s\n", targetprod);
9116     ok(context == 0xdeadbeef,
9117        "Expected context to be unchanged, got %d\n", context);
9118     ok(!lstrcmpA(targetsid, "kiwi"),
9119        "Expected targetsid to be unchanged, got %s\n", targetsid);
9120     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9121
9122     data = MSIPATCHSTATE_APPLIED;
9123     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9124                          (const BYTE *)&data, sizeof(DWORD));
9125     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9126
9127     /* State value exists */
9128     lstrcpyA(patchcode, "apple");
9129     lstrcpyA(targetprod, "banana");
9130     context = 0xdeadbeef;
9131     lstrcpyA(targetsid, "kiwi");
9132     size = MAX_PATH;
9133     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9134                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9135                            &context, targetsid, &size);
9136     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9137     ok(!lstrcmpA(patchcode, patch),
9138        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9139     ok(!lstrcmpA(targetprod, prodcode),
9140        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9141     ok(context == MSIINSTALLCONTEXT_MACHINE,
9142        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9143     ok(!lstrcmpA(targetsid, ""),
9144        "Expected \"\", got \"%s\"\n", targetsid);
9145     ok(size == 0, "Expected 0, got %d\n", size);
9146
9147     /* MSIPATCHSTATE_SUPERSEDED */
9148
9149     lstrcpyA(patchcode, "apple");
9150     lstrcpyA(targetprod, "banana");
9151     context = 0xdeadbeef;
9152     lstrcpyA(targetsid, "kiwi");
9153     size = MAX_PATH;
9154     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9155                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9156                            &context, targetsid, &size);
9157     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9158     ok(!lstrcmpA(patchcode, "apple"),
9159        "Expected patchcode to be unchanged, got %s\n", patchcode);
9160     ok(!lstrcmpA(targetprod, "banana"),
9161        "Expected targetprod to be unchanged, got %s\n", targetprod);
9162     ok(context == 0xdeadbeef,
9163        "Expected context to be unchanged, got %d\n", context);
9164     ok(!lstrcmpA(targetsid, "kiwi"),
9165        "Expected targetsid to be unchanged, got %s\n", targetsid);
9166     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9167
9168     data = MSIPATCHSTATE_SUPERSEDED;
9169     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9170                          (const BYTE *)&data, sizeof(DWORD));
9171     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9172
9173     /* State value is MSIPATCHSTATE_SUPERSEDED */
9174     lstrcpyA(patchcode, "apple");
9175     lstrcpyA(targetprod, "banana");
9176     context = 0xdeadbeef;
9177     lstrcpyA(targetsid, "kiwi");
9178     size = MAX_PATH;
9179     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9180                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9181                            &context, targetsid, &size);
9182     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9183     ok(!lstrcmpA(patchcode, patch),
9184        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9185     ok(!lstrcmpA(targetprod, prodcode),
9186        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9187     ok(context == MSIINSTALLCONTEXT_MACHINE,
9188        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9189     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9190     ok(size == 0, "Expected 0, got %d\n", size);
9191
9192     /* MSIPATCHSTATE_OBSOLETED */
9193
9194     lstrcpyA(patchcode, "apple");
9195     lstrcpyA(targetprod, "banana");
9196     context = 0xdeadbeef;
9197     lstrcpyA(targetsid, "kiwi");
9198     size = MAX_PATH;
9199     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9200                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9201                            &context, targetsid, &size);
9202     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9203     ok(!lstrcmpA(patchcode, "apple"),
9204        "Expected patchcode to be unchanged, got %s\n", patchcode);
9205     ok(!lstrcmpA(targetprod, "banana"),
9206        "Expected targetprod to be unchanged, got %s\n", targetprod);
9207     ok(context == 0xdeadbeef,
9208        "Expected context to be unchanged, got %d\n", context);
9209     ok(!lstrcmpA(targetsid, "kiwi"),
9210        "Expected targetsid to be unchanged, got %s\n", targetsid);
9211     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9212
9213     data = MSIPATCHSTATE_OBSOLETED;
9214     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9215                          (const BYTE *)&data, sizeof(DWORD));
9216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9217
9218     /* State value is obsoleted */
9219     lstrcpyA(patchcode, "apple");
9220     lstrcpyA(targetprod, "banana");
9221     context = 0xdeadbeef;
9222     lstrcpyA(targetsid, "kiwi");
9223     size = MAX_PATH;
9224     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9225                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9226                            &context, targetsid, &size);
9227     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9228     ok(!lstrcmpA(patchcode, patch),
9229        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9230     ok(!lstrcmpA(targetprod, prodcode),
9231        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9232     ok(context == MSIINSTALLCONTEXT_MACHINE,
9233        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9234     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9235     ok(size == 0, "Expected 0, got %d\n", size);
9236
9237     /* MSIPATCHSTATE_REGISTERED */
9238     /* FIXME */
9239
9240     /* MSIPATCHSTATE_ALL */
9241
9242     /* 1st */
9243     lstrcpyA(patchcode, "apple");
9244     lstrcpyA(targetprod, "banana");
9245     context = 0xdeadbeef;
9246     lstrcpyA(targetsid, "kiwi");
9247     size = MAX_PATH;
9248     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9249                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9250                            &context, targetsid, &size);
9251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9252     ok(!lstrcmpA(patchcode, patch),
9253        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9254     ok(!lstrcmpA(targetprod, prodcode),
9255        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9256     ok(context == MSIINSTALLCONTEXT_MACHINE,
9257        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9258     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9259     ok(size == 0, "Expected 0, got %d\n", size);
9260
9261     /* same patch in multiple places, only one is enumerated */
9262     lstrcpyA(patchcode, "apple");
9263     lstrcpyA(targetprod, "banana");
9264     context = 0xdeadbeef;
9265     lstrcpyA(targetsid, "kiwi");
9266     size = MAX_PATH;
9267     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9268                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9269                            &context, targetsid, &size);
9270     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9271     ok(!lstrcmpA(patchcode, "apple"),
9272        "Expected patchcode to be unchanged, got %s\n", patchcode);
9273     ok(!lstrcmpA(targetprod, "banana"),
9274        "Expected targetprod to be unchanged, got %s\n", targetprod);
9275     ok(context == 0xdeadbeef,
9276        "Expected context to be unchanged, got %d\n", context);
9277     ok(!lstrcmpA(targetsid, "kiwi"),
9278        "Expected targetsid to be unchanged, got %s\n", targetsid);
9279     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9280
9281     RegDeleteValueA(patches, patch_squashed);
9282     RegDeleteValueA(patches, "Patches");
9283     delete_key(patches, "", access & KEY_WOW64_64KEY);
9284     RegCloseKey(patches);
9285     RegDeleteValueA(hpatch, "State");
9286     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9287     RegCloseKey(hpatch);
9288     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9289     RegCloseKey(udpatch);
9290     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9291     RegCloseKey(udprod);
9292     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9293     RegCloseKey(prodkey);
9294 }
9295
9296 static void test_MsiEnumPatchesEx(void)
9297 {
9298     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9299     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9300     CHAR patchcode[MAX_PATH];
9301     MSIINSTALLCONTEXT context;
9302     LPSTR usersid;
9303     DWORD size;
9304     UINT r;
9305
9306     if (!pMsiEnumPatchesExA)
9307     {
9308         win_skip("MsiEnumPatchesExA not implemented\n");
9309         return;
9310     }
9311
9312     create_test_guid(prodcode, prod_squashed);
9313     get_user_sid(&usersid);
9314
9315     /* empty szProductCode */
9316     lstrcpyA(patchcode, "apple");
9317     lstrcpyA(targetprod, "banana");
9318     context = 0xdeadbeef;
9319     lstrcpyA(targetsid, "kiwi");
9320     size = MAX_PATH;
9321     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9322                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9323                            targetsid, &size);
9324     ok(r == ERROR_INVALID_PARAMETER,
9325        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9326     ok(!lstrcmpA(patchcode, "apple"),
9327        "Expected patchcode to be unchanged, got %s\n", patchcode);
9328     ok(!lstrcmpA(targetprod, "banana"),
9329        "Expected targetprod to be unchanged, got %s\n", targetprod);
9330     ok(context == 0xdeadbeef,
9331        "Expected context to be unchanged, got %d\n", context);
9332     ok(!lstrcmpA(targetsid, "kiwi"),
9333        "Expected targetsid to be unchanged, got %s\n", targetsid);
9334     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9335
9336     /* garbage szProductCode */
9337     lstrcpyA(patchcode, "apple");
9338     lstrcpyA(targetprod, "banana");
9339     context = 0xdeadbeef;
9340     lstrcpyA(targetsid, "kiwi");
9341     size = MAX_PATH;
9342     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9343                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9344                            targetsid, &size);
9345     ok(r == ERROR_INVALID_PARAMETER,
9346        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9347     ok(!lstrcmpA(patchcode, "apple"),
9348        "Expected patchcode to be unchanged, got %s\n", patchcode);
9349     ok(!lstrcmpA(targetprod, "banana"),
9350        "Expected targetprod to be unchanged, got %s\n", targetprod);
9351     ok(context == 0xdeadbeef,
9352        "Expected context to be unchanged, got %d\n", context);
9353     ok(!lstrcmpA(targetsid, "kiwi"),
9354        "Expected targetsid to be unchanged, got %s\n", targetsid);
9355     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9356
9357     /* guid without brackets */
9358     lstrcpyA(patchcode, "apple");
9359     lstrcpyA(targetprod, "banana");
9360     context = 0xdeadbeef;
9361     lstrcpyA(targetsid, "kiwi");
9362     size = MAX_PATH;
9363     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9364                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9365                            0, patchcode, targetprod, &context,
9366                            targetsid, &size);
9367     ok(r == ERROR_INVALID_PARAMETER,
9368        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9369     ok(!lstrcmpA(patchcode, "apple"),
9370        "Expected patchcode to be unchanged, got %s\n", patchcode);
9371     ok(!lstrcmpA(targetprod, "banana"),
9372        "Expected targetprod to be unchanged, got %s\n", targetprod);
9373     ok(context == 0xdeadbeef,
9374        "Expected context to be unchanged, got %d\n", context);
9375     ok(!lstrcmpA(targetsid, "kiwi"),
9376        "Expected targetsid to be unchanged, got %s\n", targetsid);
9377     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9378
9379     /* guid with brackets */
9380     lstrcpyA(patchcode, "apple");
9381     lstrcpyA(targetprod, "banana");
9382     context = 0xdeadbeef;
9383     lstrcpyA(targetsid, "kiwi");
9384     size = MAX_PATH;
9385     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9386                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9387                            0, patchcode, targetprod, &context,
9388                            targetsid, &size);
9389     ok(r == ERROR_NO_MORE_ITEMS,
9390        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9391     ok(!lstrcmpA(patchcode, "apple"),
9392        "Expected patchcode to be unchanged, got %s\n", patchcode);
9393     ok(!lstrcmpA(targetprod, "banana"),
9394        "Expected targetprod to be unchanged, got %s\n", targetprod);
9395     ok(context == 0xdeadbeef,
9396        "Expected context to be unchanged, got %d\n", context);
9397     ok(!lstrcmpA(targetsid, "kiwi"),
9398        "Expected targetsid to be unchanged, got %s\n", targetsid);
9399     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9400
9401     /* szUserSid is S-1-5-18 */
9402     lstrcpyA(patchcode, "apple");
9403     lstrcpyA(targetprod, "banana");
9404     context = 0xdeadbeef;
9405     lstrcpyA(targetsid, "kiwi");
9406     size = MAX_PATH;
9407     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9408                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9409                            0, patchcode, targetprod, &context,
9410                            targetsid, &size);
9411     ok(r == ERROR_INVALID_PARAMETER,
9412        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9413     ok(!lstrcmpA(patchcode, "apple"),
9414        "Expected patchcode to be unchanged, got %s\n", patchcode);
9415     ok(!lstrcmpA(targetprod, "banana"),
9416        "Expected targetprod to be unchanged, got %s\n", targetprod);
9417     ok(context == 0xdeadbeef,
9418        "Expected context to be unchanged, got %d\n", context);
9419     ok(!lstrcmpA(targetsid, "kiwi"),
9420        "Expected targetsid to be unchanged, got %s\n", targetsid);
9421     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9422
9423     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9424     lstrcpyA(patchcode, "apple");
9425     lstrcpyA(targetprod, "banana");
9426     context = 0xdeadbeef;
9427     lstrcpyA(targetsid, "kiwi");
9428     size = MAX_PATH;
9429     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9430                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9431                            &context, targetsid, &size);
9432     ok(r == ERROR_INVALID_PARAMETER,
9433        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9434     ok(!lstrcmpA(patchcode, "apple"),
9435        "Expected patchcode to be unchanged, got %s\n", patchcode);
9436     ok(!lstrcmpA(targetprod, "banana"),
9437        "Expected targetprod to be unchanged, got %s\n", targetprod);
9438     ok(context == 0xdeadbeef,
9439        "Expected context to be unchanged, got %d\n", context);
9440     ok(!lstrcmpA(targetsid, "kiwi"),
9441        "Expected targetsid to be unchanged, got %s\n", targetsid);
9442     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9443
9444     /* dwContext is out of bounds */
9445     lstrcpyA(patchcode, "apple");
9446     lstrcpyA(targetprod, "banana");
9447     context = 0xdeadbeef;
9448     lstrcpyA(targetsid, "kiwi");
9449     size = MAX_PATH;
9450     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9451                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9452                            &context, targetsid, &size);
9453     ok(r == ERROR_INVALID_PARAMETER,
9454        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9455     ok(!lstrcmpA(patchcode, "apple"),
9456        "Expected patchcode to be unchanged, got %s\n", patchcode);
9457     ok(!lstrcmpA(targetprod, "banana"),
9458        "Expected targetprod to be unchanged, got %s\n", targetprod);
9459     ok(context == 0xdeadbeef,
9460        "Expected context to be unchanged, got %d\n", context);
9461     ok(!lstrcmpA(targetsid, "kiwi"),
9462        "Expected targetsid to be unchanged, got %s\n", targetsid);
9463     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9464
9465     /* dwContext is out of bounds */
9466     lstrcpyA(patchcode, "apple");
9467     lstrcpyA(targetprod, "banana");
9468     context = 0xdeadbeef;
9469     lstrcpyA(targetsid, "kiwi");
9470     size = MAX_PATH;
9471     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9472                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9473                            &context, targetsid, &size);
9474     ok(r == ERROR_INVALID_PARAMETER,
9475        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9476     ok(!lstrcmpA(patchcode, "apple"),
9477        "Expected patchcode to be unchanged, got %s\n", patchcode);
9478     ok(!lstrcmpA(targetprod, "banana"),
9479        "Expected targetprod to be unchanged, got %s\n", targetprod);
9480     ok(context == 0xdeadbeef,
9481        "Expected context to be unchanged, got %d\n", context);
9482     ok(!lstrcmpA(targetsid, "kiwi"),
9483        "Expected targetsid to be unchanged, got %s\n", targetsid);
9484     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9485
9486     /* dwFilter is out of bounds */
9487     lstrcpyA(patchcode, "apple");
9488     lstrcpyA(targetprod, "banana");
9489     context = 0xdeadbeef;
9490     lstrcpyA(targetsid, "kiwi");
9491     size = MAX_PATH;
9492     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9493                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9494                            &context, targetsid, &size);
9495     ok(r == ERROR_INVALID_PARAMETER,
9496        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9497     ok(!lstrcmpA(patchcode, "apple"),
9498        "Expected patchcode to be unchanged, got %s\n", patchcode);
9499     ok(!lstrcmpA(targetprod, "banana"),
9500        "Expected targetprod to be unchanged, got %s\n", targetprod);
9501     ok(context == 0xdeadbeef,
9502        "Expected context to be unchanged, got %d\n", context);
9503     ok(!lstrcmpA(targetsid, "kiwi"),
9504        "Expected targetsid to be unchanged, got %s\n", targetsid);
9505     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9506
9507     /* dwFilter is out of bounds */
9508     lstrcpyA(patchcode, "apple");
9509     lstrcpyA(targetprod, "banana");
9510     context = 0xdeadbeef;
9511     lstrcpyA(targetsid, "kiwi");
9512     size = MAX_PATH;
9513     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9514                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9515                            &context, targetsid, &size);
9516     ok(r == ERROR_INVALID_PARAMETER,
9517        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9518     ok(!lstrcmpA(patchcode, "apple"),
9519        "Expected patchcode to be unchanged, got %s\n", patchcode);
9520     ok(!lstrcmpA(targetprod, "banana"),
9521        "Expected targetprod to be unchanged, got %s\n", targetprod);
9522     ok(context == 0xdeadbeef,
9523        "Expected context to be unchanged, got %d\n", context);
9524     ok(!lstrcmpA(targetsid, "kiwi"),
9525        "Expected targetsid to be unchanged, got %s\n", targetsid);
9526     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9527
9528     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9529     lstrcpyA(patchcode, "apple");
9530     lstrcpyA(targetprod, "banana");
9531     context = 0xdeadbeef;
9532     lstrcpyA(targetsid, "kiwi");
9533     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9534                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9535                            &context, targetsid, NULL);
9536     ok(r == ERROR_INVALID_PARAMETER,
9537        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9538     ok(!lstrcmpA(patchcode, "apple"),
9539        "Expected patchcode to be unchanged, got %s\n", patchcode);
9540     ok(!lstrcmpA(targetprod, "banana"),
9541        "Expected targetprod to be unchanged, got %s\n", targetprod);
9542     ok(context == 0xdeadbeef,
9543        "Expected context to be unchanged, got %d\n", context);
9544     ok(!lstrcmpA(targetsid, "kiwi"),
9545        "Expected targetsid to be unchanged, got %s\n", targetsid);
9546
9547     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9548     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9549     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9550     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9551     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9552     /* FIXME: Successfully test userunmanaged with a different user */
9553     test_MsiEnumPatchesEx_machine();
9554     LocalFree(usersid);
9555 }
9556
9557 static void test_MsiEnumPatches(void)
9558 {
9559     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9560     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9561     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9562     CHAR transforms[MAX_PATH];
9563     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9564     HKEY prodkey, patches, udprod;
9565     HKEY userkey, hpatch, udpatch;
9566     DWORD size, data;
9567     LPSTR usersid;
9568     LONG res;
9569     UINT r;
9570     REGSAM access = KEY_ALL_ACCESS;
9571     BOOL wow64;
9572
9573     create_test_guid(prodcode, prod_squashed);
9574     create_test_guid(patchcode, patch_squashed);
9575     get_user_sid(&usersid);
9576
9577     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
9578         access |= KEY_WOW64_64KEY;
9579
9580     /* NULL szProduct */
9581     size = MAX_PATH;
9582     lstrcpyA(patch, "apple");
9583     lstrcpyA(transforms, "banana");
9584     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9585     ok(r == ERROR_INVALID_PARAMETER,
9586        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9587     ok(!lstrcmpA(patch, "apple"),
9588        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9589     ok(!lstrcmpA(transforms, "banana"),
9590        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9591     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9592
9593     /* empty szProduct */
9594     size = MAX_PATH;
9595     lstrcpyA(patch, "apple");
9596     lstrcpyA(transforms, "banana");
9597     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9598     ok(r == ERROR_INVALID_PARAMETER,
9599        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9600     ok(!lstrcmpA(patch, "apple"),
9601        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9602     ok(!lstrcmpA(transforms, "banana"),
9603        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9604     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9605
9606     /* garbage szProduct */
9607     size = MAX_PATH;
9608     lstrcpyA(patch, "apple");
9609     lstrcpyA(transforms, "banana");
9610     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9611     ok(r == ERROR_INVALID_PARAMETER,
9612        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9613     ok(!lstrcmpA(patch, "apple"),
9614        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9615     ok(!lstrcmpA(transforms, "banana"),
9616        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9617     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9618
9619     /* guid without brackets */
9620     size = MAX_PATH;
9621     lstrcpyA(patch, "apple");
9622     lstrcpyA(transforms, "banana");
9623     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9624                         transforms, &size);
9625     ok(r == ERROR_INVALID_PARAMETER,
9626        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9627     ok(!lstrcmpA(patch, "apple"),
9628        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9629     ok(!lstrcmpA(transforms, "banana"),
9630        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9631     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9632
9633     /* guid with brackets */
9634     size = MAX_PATH;
9635     lstrcpyA(patch, "apple");
9636     lstrcpyA(transforms, "banana");
9637     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9638                         transforms, &size);
9639     ok(r == ERROR_UNKNOWN_PRODUCT,
9640        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9641     ok(!lstrcmpA(patch, "apple"),
9642        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9643     ok(!lstrcmpA(transforms, "banana"),
9644        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9645     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9646
9647     /* same length as guid, but random */
9648     size = MAX_PATH;
9649     lstrcpyA(patch, "apple");
9650     lstrcpyA(transforms, "banana");
9651     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9652                         transforms, &size);
9653     ok(r == ERROR_INVALID_PARAMETER,
9654        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9655     ok(!lstrcmpA(patch, "apple"),
9656        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9657     ok(!lstrcmpA(transforms, "banana"),
9658        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9659     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9660
9661     /* MSIINSTALLCONTEXT_USERMANAGED */
9662
9663     size = MAX_PATH;
9664     lstrcpyA(patch, "apple");
9665     lstrcpyA(transforms, "banana");
9666     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9667     ok(r == ERROR_UNKNOWN_PRODUCT,
9668        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9669     ok(!lstrcmpA(patch, "apple"),
9670        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9671     ok(!lstrcmpA(transforms, "banana"),
9672        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9673     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9674
9675     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9676     lstrcatA(keypath, usersid);
9677     lstrcatA(keypath, "\\Installer\\Products\\");
9678     lstrcatA(keypath, prod_squashed);
9679
9680     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9681     if (res == ERROR_ACCESS_DENIED)
9682     {
9683         skip("Not enough rights to perform tests\n");
9684         LocalFree(usersid);
9685         return;
9686     }
9687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9688
9689     /* managed product key exists */
9690     size = MAX_PATH;
9691     lstrcpyA(patch, "apple");
9692     lstrcpyA(transforms, "banana");
9693     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9694     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9695     ok(!lstrcmpA(patch, "apple"),
9696        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9697     ok(!lstrcmpA(transforms, "banana"),
9698        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9699     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9700
9701     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9703
9704     /* patches key exists */
9705     size = MAX_PATH;
9706     lstrcpyA(patch, "apple");
9707     lstrcpyA(transforms, "banana");
9708     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9709     ok(r == ERROR_NO_MORE_ITEMS ||
9710        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9711        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9712     ok(!lstrcmpA(patch, "apple"),
9713        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9714     ok(!lstrcmpA(transforms, "banana"),
9715        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9716     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9717
9718     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9719                          (const BYTE *)patch_squashed,
9720                          lstrlenA(patch_squashed) + 1);
9721     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9722
9723     /* Patches value exists, is not REG_MULTI_SZ */
9724     size = MAX_PATH;
9725     lstrcpyA(patch, "apple");
9726     lstrcpyA(transforms, "banana");
9727     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9728     ok(r == ERROR_BAD_CONFIGURATION ||
9729        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9730        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9731     ok(!lstrcmpA(patch, "apple"),
9732        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9733     ok(!lstrcmpA(transforms, "banana"),
9734        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9735     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9736
9737     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9738                          (const BYTE *)"a\0b\0c\0\0", 7);
9739     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9740
9741     /* Patches value exists, is not a squashed guid */
9742     size = MAX_PATH;
9743     lstrcpyA(patch, "apple");
9744     lstrcpyA(transforms, "banana");
9745     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9746     ok(r == ERROR_BAD_CONFIGURATION,
9747        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9748     ok(!lstrcmpA(patch, "apple"),
9749        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9750     ok(!lstrcmpA(transforms, "banana"),
9751        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9752     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9753
9754     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9755     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9756                          (const BYTE *)patch_squashed,
9757                          lstrlenA(patch_squashed) + 2);
9758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9759
9760     /* Patches value exists */
9761     size = MAX_PATH;
9762     lstrcpyA(patch, "apple");
9763     lstrcpyA(transforms, "banana");
9764     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9765     ok(r == ERROR_NO_MORE_ITEMS ||
9766        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9767        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9768     ok(!lstrcmpA(patch, "apple") ||
9769        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9770        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9771     ok(!lstrcmpA(transforms, "banana"),
9772        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9773     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9774
9775     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9776                          (const BYTE *)"whatever", 9);
9777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9778
9779     /* patch squashed value exists */
9780     size = MAX_PATH;
9781     lstrcpyA(patch, "apple");
9782     lstrcpyA(transforms, "banana");
9783     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9784     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9785     ok(!lstrcmpA(patch, patchcode),
9786        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9787     ok(!lstrcmpA(transforms, "whatever"),
9788        "Expected \"whatever\", got \"%s\"\n", transforms);
9789     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9790
9791     /* lpPatchBuf is NULL */
9792     size = MAX_PATH;
9793     lstrcpyA(transforms, "banana");
9794     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9795     ok(r == ERROR_INVALID_PARAMETER,
9796        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9797     ok(!lstrcmpA(transforms, "banana"),
9798        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9799     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9800
9801     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9802     size = MAX_PATH;
9803     lstrcpyA(patch, "apple");
9804     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9805     ok(r == ERROR_INVALID_PARAMETER,
9806        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9807     ok(!lstrcmpA(patch, "apple"),
9808        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9809     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9810
9811     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9812     lstrcpyA(patch, "apple");
9813     lstrcpyA(transforms, "banana");
9814     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9815     ok(r == ERROR_INVALID_PARAMETER,
9816        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9817     ok(!lstrcmpA(patch, "apple"),
9818        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9819     ok(!lstrcmpA(transforms, "banana"),
9820        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9821
9822     /* pcchTransformsBuf is too small */
9823     size = 6;
9824     lstrcpyA(patch, "apple");
9825     lstrcpyA(transforms, "banana");
9826     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9827     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9828     ok(!lstrcmpA(patch, patchcode),
9829        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9830     ok(!lstrcmpA(transforms, "whate") ||
9831        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
9832        "Expected \"whate\", got \"%s\"\n", transforms);
9833     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
9834
9835     /* increase the index */
9836     size = MAX_PATH;
9837     lstrcpyA(patch, "apple");
9838     lstrcpyA(transforms, "banana");
9839     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9840     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9841     ok(!lstrcmpA(patch, "apple"),
9842        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9843     ok(!lstrcmpA(transforms, "banana"),
9844        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9845     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9846
9847     /* increase again */
9848     size = MAX_PATH;
9849     lstrcpyA(patch, "apple");
9850     lstrcpyA(transforms, "banana");
9851     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9852     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9853     ok(!lstrcmpA(patch, "apple"),
9854        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9855     ok(!lstrcmpA(transforms, "banana"),
9856        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9857     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9858
9859     RegDeleteValueA(patches, "Patches");
9860     delete_key(patches, "", access & KEY_WOW64_64KEY);
9861     RegCloseKey(patches);
9862     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9863     RegCloseKey(prodkey);
9864
9865     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9866
9867     size = MAX_PATH;
9868     lstrcpyA(patch, "apple");
9869     lstrcpyA(transforms, "banana");
9870     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9871     ok(r == ERROR_UNKNOWN_PRODUCT,
9872        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9873     ok(!lstrcmpA(patch, "apple"),
9874        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9875     ok(!lstrcmpA(transforms, "banana"),
9876        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9877     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9878
9879     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9880     lstrcatA(keypath, prod_squashed);
9881
9882     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9883     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9884
9885     /* current user product key exists */
9886     size = MAX_PATH;
9887     lstrcpyA(patch, "apple");
9888     lstrcpyA(transforms, "banana");
9889     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9890     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9891     ok(!lstrcmpA(patch, "apple"),
9892        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9893     ok(!lstrcmpA(transforms, "banana"),
9894        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9895     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9896
9897     res = RegCreateKeyA(prodkey, "Patches", &patches);
9898     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9899
9900     /* Patches key exists */
9901     size = MAX_PATH;
9902     lstrcpyA(patch, "apple");
9903     lstrcpyA(transforms, "banana");
9904     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9905     ok(r == ERROR_NO_MORE_ITEMS ||
9906        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9907        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9908     ok(!lstrcmpA(patch, "apple"),
9909        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9910     ok(!lstrcmpA(transforms, "banana"),
9911        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9912     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9913
9914     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9915                          (const BYTE *)patch_squashed,
9916                          lstrlenA(patch_squashed) + 1);
9917     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9918
9919     /* Patches value exists, is not REG_MULTI_SZ */
9920     size = MAX_PATH;
9921     lstrcpyA(patch, "apple");
9922     lstrcpyA(transforms, "banana");
9923     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9924     ok(r == ERROR_BAD_CONFIGURATION ||
9925        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9926        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9927     ok(!lstrcmpA(patch, "apple"),
9928        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9929     ok(!lstrcmpA(transforms, "banana"),
9930        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9931     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9932
9933     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9934                          (const BYTE *)"a\0b\0c\0\0", 7);
9935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9936
9937     /* Patches value exists, is not a squashed guid */
9938     size = MAX_PATH;
9939     lstrcpyA(patch, "apple");
9940     lstrcpyA(transforms, "banana");
9941     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9942     ok(r == ERROR_BAD_CONFIGURATION,
9943        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9944     ok(!lstrcmpA(patch, "apple"),
9945        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9946     ok(!lstrcmpA(transforms, "banana"),
9947        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9948     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9949
9950     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9951     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9952                          (const BYTE *)patch_squashed,
9953                          lstrlenA(patch_squashed) + 2);
9954     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9955
9956     /* Patches value exists */
9957     size = MAX_PATH;
9958     lstrcpyA(patch, "apple");
9959     lstrcpyA(transforms, "banana");
9960     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9961     ok(r == ERROR_NO_MORE_ITEMS ||
9962        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9963        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9964     ok(!lstrcmpA(patch, "apple") ||
9965        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9966        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9967     ok(!lstrcmpA(transforms, "banana"),
9968        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9969     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9970
9971     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9972                          (const BYTE *)"whatever", 9);
9973     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9974
9975     /* patch code value exists */
9976     size = MAX_PATH;
9977     lstrcpyA(patch, "apple");
9978     lstrcpyA(transforms, "banana");
9979     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9980     ok(r == ERROR_NO_MORE_ITEMS ||
9981        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9982        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9983     ok(!lstrcmpA(patch, "apple") ||
9984        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9985        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9986     ok(!lstrcmpA(transforms, "banana") ||
9987        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
9988        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9989     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9990
9991     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9992     lstrcatA(keypath, usersid);
9993     lstrcatA(keypath, "\\Patches\\");
9994     lstrcatA(keypath, patch_squashed);
9995
9996     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9998
9999     /* userdata patch key exists */
10000     size = MAX_PATH;
10001     lstrcpyA(patch, "apple");
10002     lstrcpyA(transforms, "banana");
10003     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10004     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10005     ok(!lstrcmpA(patch, patchcode),
10006        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10007     ok(!lstrcmpA(transforms, "whatever"),
10008        "Expected \"whatever\", got \"%s\"\n", transforms);
10009     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10010
10011     delete_key(userkey, "", access & KEY_WOW64_64KEY);
10012     RegCloseKey(userkey);
10013     RegDeleteValueA(patches, patch_squashed);
10014     RegDeleteValueA(patches, "Patches");
10015     RegDeleteKeyA(patches, "");
10016     RegCloseKey(patches);
10017     RegDeleteKeyA(prodkey, "");
10018     RegCloseKey(prodkey);
10019
10020     /* MSIINSTALLCONTEXT_MACHINE */
10021
10022     size = MAX_PATH;
10023     lstrcpyA(patch, "apple");
10024     lstrcpyA(transforms, "banana");
10025     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10026     ok(r == ERROR_UNKNOWN_PRODUCT,
10027        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10028     ok(!lstrcmpA(patch, "apple"),
10029        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10030     ok(!lstrcmpA(transforms, "banana"),
10031        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10032     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10033
10034     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10035     lstrcatA(keypath, prod_squashed);
10036
10037     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10038     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10039
10040     /* local product key exists */
10041     size = MAX_PATH;
10042     lstrcpyA(patch, "apple");
10043     lstrcpyA(transforms, "banana");
10044     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10045     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10046     ok(!lstrcmpA(patch, "apple"),
10047        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10048     ok(!lstrcmpA(transforms, "banana"),
10049        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10050     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10051
10052     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10054
10055     /* Patches key exists */
10056     size = MAX_PATH;
10057     lstrcpyA(patch, "apple");
10058     lstrcpyA(transforms, "banana");
10059     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10060     ok(r == ERROR_NO_MORE_ITEMS ||
10061        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10062        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10063     ok(!lstrcmpA(patch, "apple"),
10064        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10065     ok(!lstrcmpA(transforms, "banana"),
10066        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10067     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10068
10069     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10070                          (const BYTE *)patch_squashed,
10071                          lstrlenA(patch_squashed) + 1);
10072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10073
10074     /* Patches value exists, is not REG_MULTI_SZ */
10075     size = MAX_PATH;
10076     lstrcpyA(patch, "apple");
10077     lstrcpyA(transforms, "banana");
10078     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10079     ok(r == ERROR_BAD_CONFIGURATION ||
10080        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10081        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10082     ok(!lstrcmpA(patch, "apple"),
10083        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10084     ok(!lstrcmpA(transforms, "banana"),
10085        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10086     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10087
10088     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10089                          (const BYTE *)"a\0b\0c\0\0", 7);
10090     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10091
10092     /* Patches value exists, is not a squashed guid */
10093     size = MAX_PATH;
10094     lstrcpyA(patch, "apple");
10095     lstrcpyA(transforms, "banana");
10096     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10097     ok(r == ERROR_BAD_CONFIGURATION,
10098        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10099     ok(!lstrcmpA(patch, "apple"),
10100        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10101     ok(!lstrcmpA(transforms, "banana"),
10102        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10103     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10104
10105     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10106     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10107                          (const BYTE *)patch_squashed,
10108                          lstrlenA(patch_squashed) + 2);
10109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10110
10111     /* Patches value exists */
10112     size = MAX_PATH;
10113     lstrcpyA(patch, "apple");
10114     lstrcpyA(transforms, "banana");
10115     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10116     ok(r == ERROR_NO_MORE_ITEMS ||
10117        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10118        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10119     ok(!lstrcmpA(patch, "apple") ||
10120        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10121        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10122     ok(!lstrcmpA(transforms, "banana"),
10123        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10124     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10125
10126     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10127                          (const BYTE *)"whatever", 9);
10128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10129
10130     /* patch code value exists */
10131     size = MAX_PATH;
10132     lstrcpyA(patch, "apple");
10133     lstrcpyA(transforms, "banana");
10134     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10135     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10136     ok(!lstrcmpA(patch, patchcode),
10137        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10138     ok(!lstrcmpA(transforms, "whatever"),
10139        "Expected \"whatever\", got \"%s\"\n", transforms);
10140     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10141
10142     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10143     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10144     lstrcatA(keypath, prod_squashed);
10145
10146     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10148
10149     /* local UserData product key exists */
10150     size = MAX_PATH;
10151     lstrcpyA(patch, "apple");
10152     lstrcpyA(transforms, "banana");
10153     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10154     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10155     ok(!lstrcmpA(patch, patchcode),
10156        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10157     ok(!lstrcmpA(transforms, "whatever"),
10158        "Expected \"whatever\", got \"%s\"\n", transforms);
10159     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10160
10161     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10163
10164     /* local UserData Patches key exists */
10165     size = MAX_PATH;
10166     lstrcpyA(patch, "apple");
10167     lstrcpyA(transforms, "banana");
10168     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10169     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10170     ok(!lstrcmpA(patch, patchcode),
10171        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10172     ok(!lstrcmpA(transforms, "whatever"),
10173        "Expected \"whatever\", got \"%s\"\n", transforms);
10174     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10175
10176     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10177     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10178
10179     /* local UserData Product patch key exists */
10180     size = MAX_PATH;
10181     lstrcpyA(patch, "apple");
10182     lstrcpyA(transforms, "banana");
10183     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10184     ok(r == ERROR_NO_MORE_ITEMS ||
10185        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10186        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10187     ok(!lstrcmpA(patch, "apple") ||
10188        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10189        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10190     ok(!lstrcmpA(transforms, "banana") ||
10191        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10192        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10193     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10194
10195     data = MSIPATCHSTATE_APPLIED;
10196     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10197                          (const BYTE *)&data, sizeof(DWORD));
10198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10199
10200     /* State value exists */
10201     size = MAX_PATH;
10202     lstrcpyA(patch, "apple");
10203     lstrcpyA(transforms, "banana");
10204     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10205     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10206     ok(!lstrcmpA(patch, patchcode),
10207        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10208     ok(!lstrcmpA(transforms, "whatever"),
10209        "Expected \"whatever\", got \"%s\"\n", transforms);
10210     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10211
10212     /* now duplicate some of the tests for the W version */
10213
10214     /* pcchTransformsBuf is too small */
10215     size = 6;
10216     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
10217     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10218     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10219     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10220     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10221     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10222     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10223     ok(!lstrcmpA(patch, patchcode),
10224        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10225     ok(!lstrcmpA(transforms, "whate") ||
10226        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10227        "Expected \"whate\", got \"%s\"\n", transforms);
10228     ok(size == 8, "Expected 8, got %d\n", size);
10229
10230     /* patch code value exists */
10231     size = MAX_PATH;
10232     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10233     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10234     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10235     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10236     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10237     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10238     ok(!lstrcmpA(patch, patchcode),
10239        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10240     ok(!lstrcmpA(transforms, "whatever"),
10241        "Expected \"whatever\", got \"%s\"\n", transforms);
10242     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10243
10244     RegDeleteValueA(patches, patch_squashed);
10245     RegDeleteValueA(patches, "Patches");
10246     delete_key(patches, "", access & KEY_WOW64_64KEY);
10247     RegCloseKey(patches);
10248     RegDeleteValueA(hpatch, "State");
10249     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10250     RegCloseKey(hpatch);
10251     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10252     RegCloseKey(udpatch);
10253     delete_key(udprod, "", access & KEY_WOW64_64KEY);
10254     RegCloseKey(udprod);
10255     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10256     RegCloseKey(prodkey);
10257     LocalFree(usersid);
10258 }
10259
10260 static void test_MsiGetPatchInfoEx(void)
10261 {
10262     CHAR keypath[MAX_PATH], val[MAX_PATH];
10263     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10264     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10265     HKEY prodkey, patches, udprod, props;
10266     HKEY hpatch, udpatch, prodpatches;
10267     LPSTR usersid;
10268     DWORD size;
10269     LONG res;
10270     UINT r;
10271     REGSAM access = KEY_ALL_ACCESS;
10272     BOOL wow64;
10273
10274     if (!pMsiGetPatchInfoExA)
10275     {
10276         win_skip("MsiGetPatchInfoEx not implemented\n");
10277         return;
10278     }
10279
10280     create_test_guid(prodcode, prod_squashed);
10281     create_test_guid(patchcode, patch_squashed);
10282     get_user_sid(&usersid);
10283
10284     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
10285         access |= KEY_WOW64_64KEY;
10286
10287     /* NULL szPatchCode */
10288     lstrcpyA(val, "apple");
10289     size = MAX_PATH;
10290     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10291                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10292     ok(r == ERROR_INVALID_PARAMETER,
10293        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10294     ok(!lstrcmpA(val, "apple"),
10295        "Expected val to be unchanged, got \"%s\"\n", val);
10296     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10297
10298     /* empty szPatchCode */
10299     size = MAX_PATH;
10300     lstrcpyA(val, "apple");
10301     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10302                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10303     ok(r == ERROR_INVALID_PARAMETER,
10304        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10305     ok(!lstrcmpA(val, "apple"),
10306        "Expected val to be unchanged, got \"%s\"\n", val);
10307     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10308
10309     /* garbage szPatchCode */
10310     size = MAX_PATH;
10311     lstrcpyA(val, "apple");
10312     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
10313                             MSIINSTALLCONTEXT_USERMANAGED,
10314                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10315     ok(r == ERROR_INVALID_PARAMETER,
10316        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10317     ok(!lstrcmpA(val, "apple"),
10318        "Expected val to be unchanged, got \"%s\"\n", val);
10319     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10320
10321     /* guid without brackets */
10322     size = MAX_PATH;
10323     lstrcpyA(val, "apple");
10324     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
10325                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10326                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10327     ok(r == ERROR_INVALID_PARAMETER,
10328        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10329     ok(!lstrcmpA(val, "apple"),
10330        "Expected val to be unchanged, got \"%s\"\n", val);
10331     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10332
10333     /* guid with brackets */
10334     size = MAX_PATH;
10335     lstrcpyA(val, "apple");
10336     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
10337                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10338                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10339     ok(r == ERROR_UNKNOWN_PRODUCT,
10340        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10341     ok(!lstrcmpA(val, "apple"),
10342        "Expected val to be unchanged, got \"%s\"\n", val);
10343     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10344
10345     /* same length as guid, but random */
10346     size = MAX_PATH;
10347     lstrcpyA(val, "apple");
10348     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
10349                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10350                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10351     ok(r == ERROR_INVALID_PARAMETER,
10352        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10353     ok(!lstrcmpA(val, "apple"),
10354        "Expected val to be unchanged, got \"%s\"\n", val);
10355     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10356
10357     /* NULL szProductCode */
10358     lstrcpyA(val, "apple");
10359     size = MAX_PATH;
10360     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10361                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10362     ok(r == ERROR_INVALID_PARAMETER,
10363        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10364     ok(!lstrcmpA(val, "apple"),
10365        "Expected val to be unchanged, got \"%s\"\n", val);
10366     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10367
10368     /* empty szProductCode */
10369     size = MAX_PATH;
10370     lstrcpyA(val, "apple");
10371     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10372                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10373     ok(r == ERROR_INVALID_PARAMETER,
10374        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10375     ok(!lstrcmpA(val, "apple"),
10376        "Expected val to be unchanged, got \"%s\"\n", val);
10377     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10378
10379     /* garbage szProductCode */
10380     size = MAX_PATH;
10381     lstrcpyA(val, "apple");
10382     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
10383                             MSIINSTALLCONTEXT_USERMANAGED,
10384                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10385     ok(r == ERROR_INVALID_PARAMETER,
10386        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10387     ok(!lstrcmpA(val, "apple"),
10388        "Expected val to be unchanged, got \"%s\"\n", val);
10389     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10390
10391     /* guid without brackets */
10392     size = MAX_PATH;
10393     lstrcpyA(val, "apple");
10394     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10395                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10396                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10397     ok(r == ERROR_INVALID_PARAMETER,
10398        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10399     ok(!lstrcmpA(val, "apple"),
10400        "Expected val to be unchanged, got \"%s\"\n", val);
10401     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10402
10403     /* guid with brackets */
10404     size = MAX_PATH;
10405     lstrcpyA(val, "apple");
10406     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10407                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10408                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10409     ok(r == ERROR_UNKNOWN_PRODUCT,
10410        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10411     ok(!lstrcmpA(val, "apple"),
10412        "Expected val to be unchanged, got \"%s\"\n", val);
10413     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10414
10415     /* same length as guid, but random */
10416     size = MAX_PATH;
10417     lstrcpyA(val, "apple");
10418     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10419                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10420                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10421     ok(r == ERROR_INVALID_PARAMETER,
10422        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10423     ok(!lstrcmpA(val, "apple"),
10424        "Expected val to be unchanged, got \"%s\"\n", val);
10425     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10426
10427     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10428     size = MAX_PATH;
10429     lstrcpyA(val, "apple");
10430     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10431                             MSIINSTALLCONTEXT_USERMANAGED,
10432                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10433     ok(r == ERROR_INVALID_PARAMETER,
10434        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10435     ok(!lstrcmpA(val, "apple"),
10436        "Expected val to be unchanged, got \"%s\"\n", val);
10437     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10438
10439     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10440     size = MAX_PATH;
10441     lstrcpyA(val, "apple");
10442     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10443                             MSIINSTALLCONTEXT_USERUNMANAGED,
10444                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10445     ok(r == ERROR_INVALID_PARAMETER,
10446        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10447     ok(!lstrcmpA(val, "apple"),
10448        "Expected val to be unchanged, got \"%s\"\n", val);
10449     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10450
10451     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10452     size = MAX_PATH;
10453     lstrcpyA(val, "apple");
10454     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10455                             MSIINSTALLCONTEXT_MACHINE,
10456                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10457     ok(r == ERROR_INVALID_PARAMETER,
10458        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10459     ok(!lstrcmpA(val, "apple"),
10460        "Expected val to be unchanged, got \"%s\"\n", val);
10461     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10462
10463     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10464     size = MAX_PATH;
10465     lstrcpyA(val, "apple");
10466     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10467                             MSIINSTALLCONTEXT_MACHINE,
10468                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10469     ok(r == ERROR_INVALID_PARAMETER,
10470        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10471     ok(!lstrcmpA(val, "apple"),
10472        "Expected val to be unchanged, got \"%s\"\n", val);
10473     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10474
10475     /* dwContext is out of range */
10476     size = MAX_PATH;
10477     lstrcpyA(val, "apple");
10478     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10479                             MSIINSTALLCONTEXT_NONE,
10480                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10481     ok(r == ERROR_INVALID_PARAMETER,
10482        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10483     ok(!lstrcmpA(val, "apple"),
10484        "Expected val to be unchanged, got \"%s\"\n", val);
10485     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10486
10487     /* dwContext is out of range */
10488     size = MAX_PATH;
10489     lstrcpyA(val, "apple");
10490     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10491                             MSIINSTALLCONTEXT_ALL,
10492                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10493     ok(r == ERROR_INVALID_PARAMETER,
10494        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10495     ok(!lstrcmpA(val, "apple"),
10496        "Expected val to be unchanged, got \"%s\"\n", val);
10497     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10498
10499     /* dwContext is invalid */
10500     size = MAX_PATH;
10501     lstrcpyA(val, "apple");
10502     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10503                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10504     ok(r == ERROR_INVALID_PARAMETER,
10505        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10506     ok(!lstrcmpA(val, "apple"),
10507        "Expected val to be unchanged, got \"%s\"\n", val);
10508     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10509
10510     /* MSIINSTALLCONTEXT_USERMANAGED */
10511
10512     size = MAX_PATH;
10513     lstrcpyA(val, "apple");
10514     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10515                             MSIINSTALLCONTEXT_USERMANAGED,
10516                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10517     ok(r == ERROR_UNKNOWN_PRODUCT,
10518        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10519     ok(!lstrcmpA(val, "apple"),
10520        "Expected val to be unchanged, got \"%s\"\n", val);
10521     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10522
10523     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10524     lstrcatA(keypath, usersid);
10525     lstrcatA(keypath, "\\Products\\");
10526     lstrcatA(keypath, prod_squashed);
10527
10528     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10529     if (res == ERROR_ACCESS_DENIED)
10530     {
10531         skip("Not enough rights to perform tests\n");
10532         LocalFree(usersid);
10533         return;
10534     }
10535     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10536
10537     /* local UserData product key exists */
10538     size = MAX_PATH;
10539     lstrcpyA(val, "apple");
10540     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10541                             MSIINSTALLCONTEXT_USERMANAGED,
10542                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10543     ok(r == ERROR_UNKNOWN_PRODUCT,
10544        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10545     ok(!lstrcmpA(val, "apple"),
10546        "Expected val to be unchanged, got \"%s\"\n", val);
10547     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10548
10549     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
10550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10551
10552     /* InstallProperties key exists */
10553     size = MAX_PATH;
10554     lstrcpyA(val, "apple");
10555     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10556                             MSIINSTALLCONTEXT_USERMANAGED,
10557                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10558     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10559     ok(!lstrcmpA(val, "apple"),
10560        "Expected val to be unchanged, got \"%s\"\n", val);
10561     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10562
10563     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10564     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10565
10566     /* Patches key exists */
10567     size = MAX_PATH;
10568     lstrcpyA(val, "apple");
10569     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10570                             MSIINSTALLCONTEXT_USERMANAGED,
10571                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10572     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10573     ok(!lstrcmpA(val, "apple"),
10574        "Expected val to be unchanged, got \"%s\"\n", val);
10575     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10576
10577     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10578     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10579
10580     /* Patches key exists */
10581     size = MAX_PATH;
10582     lstrcpyA(val, "apple");
10583     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10584                             MSIINSTALLCONTEXT_USERMANAGED,
10585                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10586     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10587     ok(!lstrcmpA(val, "apple"),
10588        "Expected val to be unchanged, got \"%s\"\n", val);
10589     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10590
10591     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10592     lstrcatA(keypath, usersid);
10593     lstrcatA(keypath, "\\Installer\\Products\\");
10594     lstrcatA(keypath, prod_squashed);
10595
10596     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10597     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10598
10599     /* managed product key exists */
10600     size = MAX_PATH;
10601     lstrcpyA(val, "apple");
10602     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10603                             MSIINSTALLCONTEXT_USERMANAGED,
10604                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10605     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10606     ok(!lstrcmpA(val, "apple"),
10607        "Expected val to be unchanged, got \"%s\"\n", val);
10608     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10609
10610     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
10611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10612
10613     /* Patches key exists */
10614     size = MAX_PATH;
10615     lstrcpyA(val, "apple");
10616     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10617                             MSIINSTALLCONTEXT_USERMANAGED,
10618                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10619     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10620     ok(!lstrcmpA(val, "apple"),
10621        "Expected val to be unchanged, got \"%s\"\n", val);
10622     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10623
10624     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10625                          (const BYTE *)"transforms", 11);
10626     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10627
10628     /* specific patch value exists */
10629     size = MAX_PATH;
10630     lstrcpyA(val, "apple");
10631     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10632                             MSIINSTALLCONTEXT_USERMANAGED,
10633                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10634     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10635     ok(!lstrcmpA(val, "apple"),
10636        "Expected val to be unchanged, got \"%s\"\n", val);
10637     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10638
10639     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10640     lstrcatA(keypath, usersid);
10641     lstrcatA(keypath, "\\Patches\\");
10642     lstrcatA(keypath, patch_squashed);
10643
10644     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
10645     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10646
10647     /* UserData Patches key exists */
10648     size = MAX_PATH;
10649     lstrcpyA(val, "apple");
10650     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10651                             MSIINSTALLCONTEXT_USERMANAGED,
10652                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10653     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10654     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10655     ok(size == 0, "Expected 0, got %d\n", size);
10656
10657     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10658                          (const BYTE *)"pack", 5);
10659     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10660
10661     /* ManagedLocalPatch value exists */
10662     size = MAX_PATH;
10663     lstrcpyA(val, "apple");
10664     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10665                             MSIINSTALLCONTEXT_USERMANAGED,
10666                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10667     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10668     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10669     ok(size == 4, "Expected 4, got %d\n", size);
10670
10671     size = MAX_PATH;
10672     lstrcpyA(val, "apple");
10673     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10674                             MSIINSTALLCONTEXT_USERMANAGED,
10675                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10676     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10677     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10678     ok(size == 10, "Expected 10, got %d\n", size);
10679
10680     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10681                          (const BYTE *)"mydate", 7);
10682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10683
10684     /* Installed value exists */
10685     size = MAX_PATH;
10686     lstrcpyA(val, "apple");
10687     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10688                             MSIINSTALLCONTEXT_USERMANAGED,
10689                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10690     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10691     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10692     ok(size == 6, "Expected 6, got %d\n", size);
10693
10694     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10695                          (const BYTE *)"yes", 4);
10696     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10697
10698     /* Uninstallable value exists */
10699     size = MAX_PATH;
10700     lstrcpyA(val, "apple");
10701     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10702                             MSIINSTALLCONTEXT_USERMANAGED,
10703                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10704     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10705     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10706     ok(size == 3, "Expected 3, got %d\n", size);
10707
10708     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10709                          (const BYTE *)"good", 5);
10710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10711
10712     /* State value exists */
10713     size = MAX_PATH;
10714     lstrcpyA(val, "apple");
10715     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10716                             MSIINSTALLCONTEXT_USERMANAGED,
10717                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10718     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10719     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10720     ok(size == 4, "Expected 4, got %d\n", size);
10721
10722     size = 1;
10723     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10724                          (const BYTE *)&size, sizeof(DWORD));
10725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10726
10727     /* State value exists */
10728     size = MAX_PATH;
10729     lstrcpyA(val, "apple");
10730     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10731                             MSIINSTALLCONTEXT_USERMANAGED,
10732                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10733     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10734     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10735     ok(size == 1, "Expected 1, got %d\n", size);
10736
10737     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10738                          (const BYTE *)"display", 8);
10739     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10740
10741     /* DisplayName value exists */
10742     size = MAX_PATH;
10743     lstrcpyA(val, "apple");
10744     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10745                             MSIINSTALLCONTEXT_USERMANAGED,
10746                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10747     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10748     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10749     ok(size == 7, "Expected 7, got %d\n", size);
10750
10751     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10752                          (const BYTE *)"moreinfo", 9);
10753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10754
10755     /* MoreInfoURL value exists */
10756     size = MAX_PATH;
10757     lstrcpyA(val, "apple");
10758     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10759                             MSIINSTALLCONTEXT_USERMANAGED,
10760                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10762     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10763     ok(size == 8, "Expected 8, got %d\n", size);
10764
10765     /* szProperty is invalid */
10766     size = MAX_PATH;
10767     lstrcpyA(val, "apple");
10768     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10769                             MSIINSTALLCONTEXT_USERMANAGED,
10770                             "IDontExist", val, &size);
10771     ok(r == ERROR_UNKNOWN_PROPERTY,
10772        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10773     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10774     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10775
10776     /* lpValue is NULL, while pcchValue is non-NULL */
10777     size = MAX_PATH;
10778     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10779                             MSIINSTALLCONTEXT_USERMANAGED,
10780                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10781     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10782     ok(size == 16, "Expected 16, got %d\n", size);
10783
10784     /* pcchValue is NULL, while lpValue is non-NULL */
10785     lstrcpyA(val, "apple");
10786     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10787                             MSIINSTALLCONTEXT_USERMANAGED,
10788                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10789     ok(r == ERROR_INVALID_PARAMETER,
10790        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10791     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10792
10793     /* both lpValue and pcchValue are NULL */
10794     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10795                             MSIINSTALLCONTEXT_USERMANAGED,
10796                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10797     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10798
10799     /* pcchValue doesn't have enough room for NULL terminator */
10800     size = 8;
10801     lstrcpyA(val, "apple");
10802     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10803                             MSIINSTALLCONTEXT_USERMANAGED,
10804                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10805     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10806     ok(!lstrcmpA(val, "moreinf"),
10807        "Expected \"moreinf\", got \"%s\"\n", val);
10808     ok(size == 16, "Expected 16, got %d\n", size);
10809
10810     /* pcchValue has exactly enough room for NULL terminator */
10811     size = 9;
10812     lstrcpyA(val, "apple");
10813     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10814                             MSIINSTALLCONTEXT_USERMANAGED,
10815                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10816     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10817     ok(!lstrcmpA(val, "moreinfo"),
10818        "Expected \"moreinfo\", got \"%s\"\n", val);
10819     ok(size == 8, "Expected 8, got %d\n", size);
10820
10821     /* pcchValue is too small, lpValue is NULL */
10822     size = 0;
10823     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10824                             MSIINSTALLCONTEXT_USERMANAGED,
10825                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10826     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10827     ok(size == 16, "Expected 16, got %d\n", size);
10828
10829     RegDeleteValueA(prodpatches, patch_squashed);
10830     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
10831     RegCloseKey(prodpatches);
10832     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10833     RegCloseKey(prodkey);
10834
10835     /* UserData is sufficient for all properties
10836      * except INSTALLPROPERTY_TRANSFORMS
10837      */
10838     size = MAX_PATH;
10839     lstrcpyA(val, "apple");
10840     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10841                             MSIINSTALLCONTEXT_USERMANAGED,
10842                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10843     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10844     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10845     ok(size == 4, "Expected 4, got %d\n", size);
10846
10847     /* UserData is sufficient for all properties
10848      * except INSTALLPROPERTY_TRANSFORMS
10849      */
10850     size = MAX_PATH;
10851     lstrcpyA(val, "apple");
10852     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10853                             MSIINSTALLCONTEXT_USERMANAGED,
10854                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10855     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10856     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10857     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10858
10859     RegDeleteValueA(hpatch, "MoreInfoURL");
10860     RegDeleteValueA(hpatch, "Display");
10861     RegDeleteValueA(hpatch, "State");
10862     RegDeleteValueA(hpatch, "Uninstallable");
10863     RegDeleteValueA(hpatch, "Installed");
10864     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10865     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10866     RegCloseKey(udpatch);
10867     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10868     RegCloseKey(hpatch);
10869     delete_key(patches, "", access & KEY_WOW64_64KEY);
10870     RegCloseKey(patches);
10871     delete_key(props, "", access & KEY_WOW64_64KEY);
10872     RegCloseKey(props);
10873     delete_key(udprod, "", access & KEY_WOW64_64KEY);
10874     RegCloseKey(udprod);
10875
10876     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10877
10878     size = MAX_PATH;
10879     lstrcpyA(val, "apple");
10880     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10881                             MSIINSTALLCONTEXT_USERUNMANAGED,
10882                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10883     ok(r == ERROR_UNKNOWN_PRODUCT,
10884        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10885     ok(!lstrcmpA(val, "apple"),
10886        "Expected val to be unchanged, got \"%s\"\n", val);
10887     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10888
10889     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10890     lstrcatA(keypath, usersid);
10891     lstrcatA(keypath, "\\Products\\");
10892     lstrcatA(keypath, prod_squashed);
10893
10894     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10895     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10896
10897     /* local UserData product key exists */
10898     size = MAX_PATH;
10899     lstrcpyA(val, "apple");
10900     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10901                             MSIINSTALLCONTEXT_USERUNMANAGED,
10902                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10903     ok(r == ERROR_UNKNOWN_PRODUCT,
10904        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10905     ok(!lstrcmpA(val, "apple"),
10906        "Expected val to be unchanged, got \"%s\"\n", val);
10907     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10908
10909     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
10910     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10911
10912     /* InstallProperties key exists */
10913     size = MAX_PATH;
10914     lstrcpyA(val, "apple");
10915     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10916                             MSIINSTALLCONTEXT_USERUNMANAGED,
10917                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10918     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10919     ok(!lstrcmpA(val, "apple"),
10920        "Expected val to be unchanged, got \"%s\"\n", val);
10921     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10922
10923     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10924     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10925
10926     /* Patches key exists */
10927     size = MAX_PATH;
10928     lstrcpyA(val, "apple");
10929     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10930                             MSIINSTALLCONTEXT_USERUNMANAGED,
10931                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10932     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10933     ok(!lstrcmpA(val, "apple"),
10934        "Expected val to be unchanged, got \"%s\"\n", val);
10935     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10936
10937     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10938     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10939
10940     /* Patches key exists */
10941     size = MAX_PATH;
10942     lstrcpyA(val, "apple");
10943     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10944                             MSIINSTALLCONTEXT_USERUNMANAGED,
10945                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10946     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10947     ok(!lstrcmpA(val, "apple"),
10948        "Expected val to be unchanged, got \"%s\"\n", val);
10949     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10950
10951     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10952     lstrcatA(keypath, prod_squashed);
10953
10954     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10955     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10956
10957     /* current user product key exists */
10958     size = MAX_PATH;
10959     lstrcpyA(val, "apple");
10960     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10961                             MSIINSTALLCONTEXT_USERUNMANAGED,
10962                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10963     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10964     ok(!lstrcmpA(val, "apple"),
10965        "Expected val to be unchanged, got \"%s\"\n", val);
10966     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10967
10968     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10970
10971     /* Patches key exists */
10972     size = MAX_PATH;
10973     lstrcpyA(val, "apple");
10974     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10975                             MSIINSTALLCONTEXT_USERUNMANAGED,
10976                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10977     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10978     ok(!lstrcmpA(val, "apple"),
10979        "Expected val to be unchanged, got \"%s\"\n", val);
10980     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10981
10982     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10983                          (const BYTE *)"transforms", 11);
10984     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10985
10986     /* specific patch value exists */
10987     size = MAX_PATH;
10988     lstrcpyA(val, "apple");
10989     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10990                             MSIINSTALLCONTEXT_USERUNMANAGED,
10991                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10992     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10993     ok(!lstrcmpA(val, "apple"),
10994        "Expected val to be unchanged, got \"%s\"\n", val);
10995     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10996
10997     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10998     lstrcatA(keypath, usersid);
10999     lstrcatA(keypath, "\\Patches\\");
11000     lstrcatA(keypath, patch_squashed);
11001
11002     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11003     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11004
11005     /* UserData Patches key exists */
11006     size = MAX_PATH;
11007     lstrcpyA(val, "apple");
11008     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11009                             MSIINSTALLCONTEXT_USERUNMANAGED,
11010                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11012     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11013     ok(size == 0, "Expected 0, got %d\n", size);
11014
11015     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11016                          (const BYTE *)"pack", 5);
11017     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11018
11019     /* LocalPatch value exists */
11020     size = MAX_PATH;
11021     lstrcpyA(val, "apple");
11022     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11023                             MSIINSTALLCONTEXT_USERUNMANAGED,
11024                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11025     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11026     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11027     ok(size == 4, "Expected 4, got %d\n", size);
11028
11029     size = MAX_PATH;
11030     lstrcpyA(val, "apple");
11031     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11032                             MSIINSTALLCONTEXT_USERUNMANAGED,
11033                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11034     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11035     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11036     ok(size == 10, "Expected 10, got %d\n", size);
11037
11038     RegDeleteValueA(prodpatches, patch_squashed);
11039     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11040     RegCloseKey(prodpatches);
11041     RegDeleteKeyA(prodkey, "");
11042     RegCloseKey(prodkey);
11043
11044     /* UserData is sufficient for all properties
11045      * except INSTALLPROPERTY_TRANSFORMS
11046      */
11047     size = MAX_PATH;
11048     lstrcpyA(val, "apple");
11049     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11050                             MSIINSTALLCONTEXT_USERUNMANAGED,
11051                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11052     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11053     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11054     ok(size == 4, "Expected 4, got %d\n", size);
11055
11056     /* UserData is sufficient for all properties
11057      * except INSTALLPROPERTY_TRANSFORMS
11058      */
11059     size = MAX_PATH;
11060     lstrcpyA(val, "apple");
11061     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11062                             MSIINSTALLCONTEXT_USERUNMANAGED,
11063                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11064     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11065     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11066     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11067
11068     RegDeleteValueA(udpatch, "LocalPackage");
11069     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11070     RegCloseKey(udpatch);
11071     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11072     RegCloseKey(hpatch);
11073     delete_key(patches, "", access & KEY_WOW64_64KEY);
11074     RegCloseKey(patches);
11075     delete_key(props, "", access & KEY_WOW64_64KEY);
11076     RegCloseKey(props);
11077     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11078     RegCloseKey(udprod);
11079
11080     /* MSIINSTALLCONTEXT_MACHINE */
11081
11082     size = MAX_PATH;
11083     lstrcpyA(val, "apple");
11084     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11085                             MSIINSTALLCONTEXT_MACHINE,
11086                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11087     ok(r == ERROR_UNKNOWN_PRODUCT,
11088        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11089     ok(!lstrcmpA(val, "apple"),
11090        "Expected val to be unchanged, got \"%s\"\n", val);
11091     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11092
11093     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11094     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11095     lstrcatA(keypath, prod_squashed);
11096
11097     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11098     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11099
11100     /* local UserData product key exists */
11101     size = MAX_PATH;
11102     lstrcpyA(val, "apple");
11103     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11104                             MSIINSTALLCONTEXT_MACHINE,
11105                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11106     ok(r == ERROR_UNKNOWN_PRODUCT,
11107        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11108     ok(!lstrcmpA(val, "apple"),
11109        "Expected val to be unchanged, got \"%s\"\n", val);
11110     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11111
11112     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11113     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11114
11115     /* InstallProperties key exists */
11116     size = MAX_PATH;
11117     lstrcpyA(val, "apple");
11118     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11119                             MSIINSTALLCONTEXT_MACHINE,
11120                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11121     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11122     ok(!lstrcmpA(val, "apple"),
11123        "Expected val to be unchanged, got \"%s\"\n", val);
11124     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11125
11126     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11127     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11128
11129     /* Patches key exists */
11130     size = MAX_PATH;
11131     lstrcpyA(val, "apple");
11132     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11133                             MSIINSTALLCONTEXT_MACHINE,
11134                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11135     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11136     ok(!lstrcmpA(val, "apple"),
11137        "Expected val to be unchanged, got \"%s\"\n", val);
11138     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11139
11140     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11142
11143     /* Patches key exists */
11144     size = MAX_PATH;
11145     lstrcpyA(val, "apple");
11146     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11147                             MSIINSTALLCONTEXT_MACHINE,
11148                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11149     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11150     ok(!lstrcmpA(val, "apple"),
11151        "Expected val to be unchanged, got \"%s\"\n", val);
11152     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11153
11154     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11155     lstrcatA(keypath, prod_squashed);
11156
11157     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11159
11160     /* local product key exists */
11161     size = MAX_PATH;
11162     lstrcpyA(val, "apple");
11163     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11164                             MSIINSTALLCONTEXT_MACHINE,
11165                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11166     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11167     ok(!lstrcmpA(val, "apple"),
11168        "Expected val to be unchanged, got \"%s\"\n", val);
11169     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11170
11171     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11172     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11173
11174     /* Patches key exists */
11175     size = MAX_PATH;
11176     lstrcpyA(val, "apple");
11177     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11178                             MSIINSTALLCONTEXT_MACHINE,
11179                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11180     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11181     ok(!lstrcmpA(val, "apple"),
11182        "Expected val to be unchanged, got \"%s\"\n", val);
11183     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11184
11185     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11186                          (const BYTE *)"transforms", 11);
11187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11188
11189     /* specific patch value exists */
11190     size = MAX_PATH;
11191     lstrcpyA(val, "apple");
11192     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11193                             MSIINSTALLCONTEXT_MACHINE,
11194                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11195     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11196     ok(!lstrcmpA(val, "apple"),
11197        "Expected val to be unchanged, got \"%s\"\n", val);
11198     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11199
11200     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11201     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11202     lstrcatA(keypath, patch_squashed);
11203
11204     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11205     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11206
11207     /* UserData Patches key exists */
11208     size = MAX_PATH;
11209     lstrcpyA(val, "apple");
11210     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11211                             MSIINSTALLCONTEXT_MACHINE,
11212                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11213     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11214     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11215     ok(size == 0, "Expected 0, got %d\n", size);
11216
11217     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11218                          (const BYTE *)"pack", 5);
11219     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11220
11221     /* LocalPatch value exists */
11222     size = MAX_PATH;
11223     lstrcpyA(val, "apple");
11224     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11225                             MSIINSTALLCONTEXT_MACHINE,
11226                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11227     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11228     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11229     ok(size == 4, "Expected 4, got %d\n", size);
11230
11231     size = MAX_PATH;
11232     lstrcpyA(val, "apple");
11233     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11234                             MSIINSTALLCONTEXT_MACHINE,
11235                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11236     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11237     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11238     ok(size == 10, "Expected 10, got %d\n", size);
11239
11240     RegDeleteValueA(prodpatches, patch_squashed);
11241     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11242     RegCloseKey(prodpatches);
11243     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11244     RegCloseKey(prodkey);
11245
11246     /* UserData is sufficient for all properties
11247      * except INSTALLPROPERTY_TRANSFORMS
11248      */
11249     size = MAX_PATH;
11250     lstrcpyA(val, "apple");
11251     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11252                             MSIINSTALLCONTEXT_MACHINE,
11253                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11254     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11255     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11256     ok(size == 4, "Expected 4, got %d\n", size);
11257
11258     /* UserData is sufficient for all properties
11259      * except INSTALLPROPERTY_TRANSFORMS
11260      */
11261     size = MAX_PATH;
11262     lstrcpyA(val, "apple");
11263     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11264                             MSIINSTALLCONTEXT_MACHINE,
11265                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11266     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11267     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11268     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11269
11270     RegDeleteValueA(udpatch, "LocalPackage");
11271     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11272     RegCloseKey(udpatch);
11273     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11274     RegCloseKey(hpatch);
11275     delete_key(patches, "", access & KEY_WOW64_64KEY);
11276     RegCloseKey(patches);
11277     delete_key(props, "", access & KEY_WOW64_64KEY);
11278     RegCloseKey(props);
11279     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11280     RegCloseKey(udprod);
11281     LocalFree(usersid);
11282 }
11283
11284 static void test_MsiGetPatchInfo(void)
11285 {
11286     UINT r;
11287     char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
11288     char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
11289     WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
11290     HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
11291     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
11292     DWORD size;
11293     LONG res;
11294     REGSAM access = KEY_ALL_ACCESS;
11295     BOOL wow64;
11296
11297     create_test_guid(patch_code, patch_squashed);
11298     create_test_guid(prod_code, prod_squashed);
11299     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
11300
11301     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
11302         access |= KEY_WOW64_64KEY;
11303
11304     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
11305     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11306
11307     r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
11308     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11309
11310     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
11311     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
11312
11313     size = 0;
11314     r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
11315     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11316
11317     r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
11318     ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
11319
11320     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11321     lstrcatA(keypath, prod_squashed);
11322
11323     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
11324     if (res == ERROR_ACCESS_DENIED)
11325     {
11326         skip("Not enough rights to perform tests\n");
11327         return;
11328     }
11329     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11330
11331     /* product key exists */
11332     size = MAX_PATH;
11333     lstrcpyA(val, "apple");
11334     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11335     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11336     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11337     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11338
11339     res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
11340     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11341
11342     /* patches key exists */
11343     size = MAX_PATH;
11344     lstrcpyA(val, "apple");
11345     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11346     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11347     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11348     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11349
11350     res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
11351     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11352
11353     /* patch key exists */
11354     size = MAX_PATH;
11355     lstrcpyA(val, "apple");
11356     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11357     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11358     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11359     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11360
11361     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11362     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11363     lstrcatA(keypath, prod_squashed);
11364
11365     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
11366     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
11367
11368     /* UserData product key exists */
11369     size = MAX_PATH;
11370     lstrcpyA(val, "apple");
11371     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11372     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11373     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11374     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11375
11376     res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
11377     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11378
11379     /* InstallProperties key exists */
11380     size = MAX_PATH;
11381     lstrcpyA(val, "apple");
11382     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11383     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11384     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11385     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11386
11387     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
11388     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11389
11390     /* UserData Patches key exists */
11391     size = MAX_PATH;
11392     lstrcpyA(val, "apple");
11393     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11394     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11395     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11396     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11397
11398     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
11399     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11400
11401     res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
11402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11403
11404     /* UserData product patch key exists */
11405     size = MAX_PATH;
11406     lstrcpyA(val, "apple");
11407     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11408     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11409     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11410     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11411
11412     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11413     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11414     lstrcatA(keypath, patch_squashed);
11415
11416     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
11417     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11418
11419     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11420     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11421
11422     /* UserData Patch key exists */
11423     size = 0;
11424     lstrcpyA(val, "apple");
11425     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11426     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11427     ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11428     ok(size == 11, "expected 11 got %u\n", size);
11429
11430     size = MAX_PATH;
11431     lstrcpyA(val, "apple");
11432     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11433     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11434     ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11435     ok(size == 11, "expected 11 got %u\n", size);
11436
11437     size = 0;
11438     valW[0] = 0;
11439     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11440     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11441     ok(!valW[0], "expected 0 got %u\n", valW[0]);
11442     ok(size == 11, "expected 11 got %u\n", size);
11443
11444     size = MAX_PATH;
11445     valW[0] = 0;
11446     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11447     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11448     ok(valW[0], "expected > 0 got %u\n", valW[0]);
11449     ok(size == 11, "expected 11 got %u\n", size);
11450
11451     delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
11452     RegCloseKey(hkey_udproductpatch);
11453     delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
11454     RegCloseKey(hkey_udproductpatches);
11455     delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
11456     RegCloseKey(hkey_udpatch);
11457     delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
11458     RegCloseKey(hkey_patches);
11459     delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
11460     RegCloseKey(hkey_product);
11461     delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
11462     RegCloseKey(hkey_patch);
11463     delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
11464     RegCloseKey(hkey_udpatches);
11465     delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
11466     RegCloseKey(hkey_udprops);
11467     delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
11468     RegCloseKey(hkey_udproduct);
11469 }
11470
11471 static void test_MsiEnumProducts(void)
11472 {
11473     UINT r;
11474     int found1, found2, found3;
11475     DWORD index;
11476     char product1[39], product2[39], product3[39], guid[39];
11477     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11478     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11479     char *usersid;
11480     HKEY key1, key2, key3;
11481     REGSAM access = KEY_ALL_ACCESS;
11482     BOOL wow64;
11483
11484     create_test_guid(product1, product_squashed1);
11485     create_test_guid(product2, product_squashed2);
11486     create_test_guid(product3, product_squashed3);
11487     get_user_sid(&usersid);
11488
11489     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
11490         access |= KEY_WOW64_64KEY;
11491
11492     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11493     strcat(keypath1, product_squashed1);
11494
11495     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
11496     if (r == ERROR_ACCESS_DENIED)
11497     {
11498         skip("Not enough rights to perform tests\n");
11499         LocalFree(usersid);
11500         return;
11501     }
11502     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11503
11504     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11505     strcat(keypath2, usersid);
11506     strcat(keypath2, "\\Installer\\Products\\");
11507     strcat(keypath2, product_squashed2);
11508
11509     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
11510     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11511
11512     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
11513     strcat(keypath3, product_squashed3);
11514
11515     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
11516     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11517
11518     index = 0;
11519     r = MsiEnumProductsA(index, guid);
11520     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11521
11522     r = MsiEnumProductsA(index, NULL);
11523     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11524
11525     index = 2;
11526     r = MsiEnumProductsA(index, guid);
11527     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11528
11529     index = 0;
11530     r = MsiEnumProductsA(index, guid);
11531     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11532
11533     found1 = found2 = found3 = 0;
11534     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
11535     {
11536         if (!strcmp(product1, guid)) found1 = 1;
11537         if (!strcmp(product2, guid)) found2 = 1;
11538         if (!strcmp(product3, guid)) found3 = 1;
11539         index++;
11540     }
11541     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
11542     ok(found1, "product1 not found\n");
11543     ok(found2, "product2 not found\n");
11544     ok(found3, "product3 not found\n");
11545
11546     delete_key(key1, "", access & KEY_WOW64_64KEY);
11547     delete_key(key2, "", access & KEY_WOW64_64KEY);
11548     RegDeleteKeyA(key3, "");
11549     RegCloseKey(key1);
11550     RegCloseKey(key2);
11551     RegCloseKey(key3);
11552     LocalFree(usersid);
11553 }
11554
11555 START_TEST(msi)
11556 {
11557     init_functionpointers();
11558
11559     test_usefeature();
11560     test_null();
11561     test_getcomponentpath();
11562     test_MsiGetFileHash();
11563
11564     if (!pConvertSidToStringSidA)
11565         win_skip("ConvertSidToStringSidA not implemented\n");
11566     else
11567     {
11568         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
11569         test_MsiQueryProductState();
11570         test_MsiQueryFeatureState();
11571         test_MsiQueryComponentState();
11572         test_MsiGetComponentPath();
11573         test_MsiGetProductCode();
11574         test_MsiEnumClients();
11575         test_MsiGetProductInfo();
11576         test_MsiGetProductInfoEx();
11577         test_MsiGetUserInfo();
11578         test_MsiOpenProduct();
11579         test_MsiEnumPatchesEx();
11580         test_MsiEnumPatches();
11581         test_MsiGetPatchInfoEx();
11582         test_MsiGetPatchInfo();
11583         test_MsiEnumProducts();
11584     }
11585
11586     test_MsiGetFileVersion();
11587 }