ntdll: Set correct protection flags on sections in builtin DLLs.
[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     if (r == ERROR_ACCESS_DENIED)
301     {
302         skip("Not enough rights to perform tests\n");
303         HeapFree(GetProcessHeap(), 0, lpData);
304         RegCloseKey(hkey);
305         return;
306     }
307     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
308
309     r = MsiGetProductInfoA("", "", NULL, NULL);
310     ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
311
312     if (lpData)
313     {
314         r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
315         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
316
317         HeapFree(GetProcessHeap(), 0, lpData);
318     }
319     else
320     {
321         r = RegDeleteValueA(hkey, NULL);
322         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
323     }
324
325     r = RegCloseKey(hkey);
326     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
327
328     /* empty attribute */
329     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
330                         0, NULL, 0, access, NULL, &hkey, NULL);
331     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
332
333     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
334     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
335
336     r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
337     ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
338
339     r = RegCloseKey(hkey);
340     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
341
342     r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
343                    access & KEY_WOW64_64KEY);
344     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
345 }
346
347 static void test_getcomponentpath(void)
348 {
349     INSTALLSTATE r;
350     char buffer[0x100];
351     DWORD sz;
352
353     if(!pMsiGetComponentPathA)
354         return;
355
356     r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
357     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
358
359     r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
360     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
361
362     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
363     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
364
365     sz = sizeof buffer;
366     buffer[0]=0;
367     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
368     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
369
370     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
371         "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
372     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
373
374     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
375         "{00000000-0000-0000-0000-00000000}", buffer, &sz );
376     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
377
378     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
379         "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
380     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
381
382     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
383                             "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
384     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
385 }
386
387 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
388 {
389     HANDLE file;
390     DWORD written;
391
392     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
393     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
394     WriteFile(file, data, strlen(data), &written, NULL);
395
396     if (size)
397     {
398         SetFilePointer(file, size, NULL, FILE_BEGIN);
399         SetEndOfFile(file);
400     }
401
402     CloseHandle(file);
403 }
404
405 #define HASHSIZE sizeof(MSIFILEHASHINFO)
406
407 static const struct
408 {
409     LPCSTR data;
410     DWORD size;
411     MSIFILEHASHINFO hash;
412 } hash_data[] =
413 {
414     { "abc", 0,
415       { HASHSIZE,
416         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
417       },
418     },
419
420     { "C:\\Program Files\\msitest\\caesar\n", 0,
421       { HASHSIZE,
422         { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
423       },
424     },
425
426     { "C:\\Program Files\\msitest\\caesar\n", 500,
427       { HASHSIZE,
428         { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
429       },
430     },
431 };
432
433 static void test_MsiGetFileHash(void)
434 {
435     const char name[] = "msitest.bin";
436     UINT r;
437     MSIFILEHASHINFO hash;
438     DWORD i;
439
440     if (!pMsiGetFileHashA)
441     {
442         win_skip("MsiGetFileHash not implemented\n");
443         return;
444     }
445
446     hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
447
448     /* szFilePath is NULL */
449     r = pMsiGetFileHashA(NULL, 0, &hash);
450     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
451
452     /* szFilePath is empty */
453     r = pMsiGetFileHashA("", 0, &hash);
454     ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
455        "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
456
457     /* szFilePath is nonexistent */
458     r = pMsiGetFileHashA(name, 0, &hash);
459     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
460
461     /* dwOptions is non-zero */
462     r = pMsiGetFileHashA(name, 1, &hash);
463     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
464
465     /* pHash.dwFileHashInfoSize is not correct */
466     hash.dwFileHashInfoSize = 0;
467     r = pMsiGetFileHashA(name, 0, &hash);
468     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
469
470     /* pHash is NULL */
471     r = pMsiGetFileHashA(name, 0, NULL);
472     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
473
474     for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
475     {
476         int ret;
477
478         create_file(name, hash_data[i].data, hash_data[i].size);
479
480         memset(&hash, 0, sizeof(MSIFILEHASHINFO));
481         hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
482
483         r = pMsiGetFileHashA(name, 0, &hash);
484         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
485
486         ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
487         ok(ret == 0 ||
488            broken(ret != 0), /* win95 */
489            "Hash incorrect\n");
490
491         DeleteFile(name);
492     }
493 }
494
495 /* copied from dlls/msi/registry.c */
496 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
497 {
498     DWORD i,n=1;
499     GUID guid;
500
501     if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
502         return FALSE;
503
504     for(i=0; i<8; i++)
505         out[7-i] = in[n++];
506     n++;
507     for(i=0; i<4; i++)
508         out[11-i] = in[n++];
509     n++;
510     for(i=0; i<4; i++)
511         out[15-i] = in[n++];
512     n++;
513     for(i=0; i<2; i++)
514     {
515         out[17+i*2] = in[n++];
516         out[16+i*2] = in[n++];
517     }
518     n++;
519     for( ; i<8; i++)
520     {
521         out[17+i*2] = in[n++];
522         out[16+i*2] = in[n++];
523     }
524     out[32]=0;
525     return TRUE;
526 }
527
528 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
529 {
530     WCHAR guidW[MAX_PATH];
531     WCHAR squashedW[MAX_PATH];
532     GUID guid;
533     HRESULT hr;
534     int size;
535
536     hr = CoCreateGuid(&guid);
537     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
538
539     size = StringFromGUID2(&guid, guidW, MAX_PATH);
540     ok(size == 39, "Expected 39, got %d\n", hr);
541
542     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
543     squash_guid(guidW, squashedW);
544     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
545 }
546
547 static void get_user_sid(LPSTR *usersid)
548 {
549     HANDLE token;
550     DWORD size;
551     PTOKEN_USER user;
552
553     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
554
555     size = 0;
556     GetTokenInformation(token, TokenUser, NULL, size, &size);
557     user = HeapAlloc(GetProcessHeap(), 0, size);
558
559     GetTokenInformation(token, TokenUser, user, size, &size);
560     pConvertSidToStringSidA(user->User.Sid, usersid);
561
562     HeapFree(GetProcessHeap(), 0, user);
563     CloseHandle(token);
564 }
565
566 static void test_MsiQueryProductState(void)
567 {
568     CHAR prodcode[MAX_PATH];
569     CHAR prod_squashed[MAX_PATH];
570     CHAR keypath[MAX_PATH*2];
571     LPSTR usersid;
572     INSTALLSTATE state;
573     LONG res;
574     HKEY userkey, localkey, props;
575     HKEY prodkey;
576     DWORD data;
577     REGSAM access = KEY_ALL_ACCESS;
578     BOOL wow64;
579
580     create_test_guid(prodcode, prod_squashed);
581     get_user_sid(&usersid);
582
583     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
584         access |= KEY_WOW64_64KEY;
585
586     /* NULL prodcode */
587     state = MsiQueryProductStateA(NULL);
588     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
589
590     /* empty prodcode */
591     state = MsiQueryProductStateA("");
592     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
593
594     /* garbage prodcode */
595     state = MsiQueryProductStateA("garbage");
596     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
597
598     /* guid without brackets */
599     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
600     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
601
602     /* guid with brackets */
603     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
604     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
605
606     /* same length as guid, but random */
607     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
608     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
609
610     /* MSIINSTALLCONTEXT_USERUNMANAGED */
611
612     state = MsiQueryProductStateA(prodcode);
613     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
614
615     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
616     lstrcatA(keypath, prod_squashed);
617
618     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
620
621     /* user product key exists */
622     state = MsiQueryProductStateA(prodcode);
623     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
624
625     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
626     lstrcatA(keypath, prodcode);
627
628     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
629     if (res == ERROR_ACCESS_DENIED)
630     {
631         skip("Not enough rights to perform tests\n");
632         RegDeleteKeyA(userkey, "");
633         LocalFree(usersid);
634         return;
635     }
636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
637
638     /* local uninstall key exists */
639     state = MsiQueryProductStateA(prodcode);
640     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
641
642     data = 1;
643     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
645
646     /* WindowsInstaller value exists */
647     state = MsiQueryProductStateA(prodcode);
648     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
649
650     RegDeleteValueA(localkey, "WindowsInstaller");
651     delete_key(localkey, "", access & KEY_WOW64_64KEY);
652
653     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
654     lstrcatA(keypath, usersid);
655     lstrcatA(keypath, "\\Products\\");
656     lstrcatA(keypath, prod_squashed);
657
658     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
659     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
660
661     /* local product key exists */
662     state = MsiQueryProductStateA(prodcode);
663     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
664
665     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
667
668     /* install properties key exists */
669     state = MsiQueryProductStateA(prodcode);
670     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
671
672     data = 1;
673     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
675
676     /* WindowsInstaller value exists */
677     state = MsiQueryProductStateA(prodcode);
678     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
679
680     data = 2;
681     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
683
684     /* WindowsInstaller value is not 1 */
685     state = MsiQueryProductStateA(prodcode);
686     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
687
688     RegDeleteKeyA(userkey, "");
689
690     /* user product key does not exist */
691     state = MsiQueryProductStateA(prodcode);
692     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
693
694     RegDeleteValueA(props, "WindowsInstaller");
695     delete_key(props, "", access & KEY_WOW64_64KEY);
696     RegCloseKey(props);
697     delete_key(localkey, "", access & KEY_WOW64_64KEY);
698     RegCloseKey(localkey);
699     RegDeleteKeyA(userkey, "");
700     RegCloseKey(userkey);
701
702     /* MSIINSTALLCONTEXT_USERMANAGED */
703
704     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
705     lstrcatA(keypath, usersid);
706     lstrcatA(keypath, "\\Installer\\Products\\");
707     lstrcatA(keypath, prod_squashed);
708
709     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
711
712     state = MsiQueryProductStateA(prodcode);
713     ok(state == INSTALLSTATE_ADVERTISED,
714        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
715
716     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
717     lstrcatA(keypath, usersid);
718     lstrcatA(keypath, "\\Products\\");
719     lstrcatA(keypath, prod_squashed);
720
721     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, 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     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
729     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
730
731     state = MsiQueryProductStateA(prodcode);
732     ok(state == INSTALLSTATE_ADVERTISED,
733        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
734
735     data = 1;
736     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
737     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
738
739     /* WindowsInstaller value exists */
740     state = MsiQueryProductStateA(prodcode);
741     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
742
743     RegDeleteValueA(props, "WindowsInstaller");
744     delete_key(props, "", access & KEY_WOW64_64KEY);
745     RegCloseKey(props);
746     delete_key(localkey, "", access & KEY_WOW64_64KEY);
747     RegCloseKey(localkey);
748     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
749     RegCloseKey(prodkey);
750
751     /* MSIINSTALLCONTEXT_MACHINE */
752
753     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
754     lstrcatA(keypath, prod_squashed);
755
756     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
757     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
758
759     state = MsiQueryProductStateA(prodcode);
760     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
761
762     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
763     lstrcatA(keypath, "S-1-5-18\\Products\\");
764     lstrcatA(keypath, prod_squashed);
765
766     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, 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     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
774     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
775
776     state = MsiQueryProductStateA(prodcode);
777     ok(state == INSTALLSTATE_ADVERTISED,
778        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
779
780     data = 1;
781     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
783
784     /* WindowsInstaller value exists */
785     state = MsiQueryProductStateA(prodcode);
786     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
787
788     RegDeleteValueA(props, "WindowsInstaller");
789     delete_key(props, "", access & KEY_WOW64_64KEY);
790     RegCloseKey(props);
791     delete_key(localkey, "", access & KEY_WOW64_64KEY);
792     RegCloseKey(localkey);
793     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
794     RegCloseKey(prodkey);
795
796     LocalFree(usersid);
797 }
798
799 static const char table_enc85[] =
800 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
801 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
802 "yz{}~";
803
804 /*
805  *  Encodes a base85 guid given a GUID pointer
806  *  Caller should provide a 21 character buffer for the encoded string.
807  */
808 static void encode_base85_guid( GUID *guid, LPWSTR str )
809 {
810     unsigned int x, *p, i;
811
812     p = (unsigned int*) guid;
813     for( i=0; i<4; i++ )
814     {
815         x = p[i];
816         *str++ = table_enc85[x%85];
817         x = x/85;
818         *str++ = table_enc85[x%85];
819         x = x/85;
820         *str++ = table_enc85[x%85];
821         x = x/85;
822         *str++ = table_enc85[x%85];
823         x = x/85;
824         *str++ = table_enc85[x%85];
825     }
826     *str = 0;
827 }
828
829 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
830 {
831     WCHAR guidW[MAX_PATH];
832     WCHAR base85W[MAX_PATH];
833     WCHAR squashedW[MAX_PATH];
834     GUID guid;
835     HRESULT hr;
836     int size;
837
838     hr = CoCreateGuid(&guid);
839     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
840
841     size = StringFromGUID2(&guid, guidW, MAX_PATH);
842     ok(size == 39, "Expected 39, got %d\n", hr);
843
844     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
845     encode_base85_guid(&guid, base85W);
846     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
847     squash_guid(guidW, squashedW);
848     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
849 }
850
851 static void test_MsiQueryFeatureState(void)
852 {
853     HKEY userkey, localkey, compkey, compkey2;
854     CHAR prodcode[MAX_PATH];
855     CHAR prod_squashed[MAX_PATH];
856     CHAR component[MAX_PATH];
857     CHAR comp_base85[MAX_PATH];
858     CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
859     CHAR keypath[MAX_PATH*2];
860     INSTALLSTATE state;
861     LPSTR usersid;
862     LONG res;
863     REGSAM access = KEY_ALL_ACCESS;
864     BOOL wow64;
865
866     create_test_guid(prodcode, prod_squashed);
867     compose_base85_guid(component, comp_base85, comp_squashed);
868     compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
869     get_user_sid(&usersid);
870
871     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
872         access |= KEY_WOW64_64KEY;
873
874     /* NULL prodcode */
875     state = MsiQueryFeatureStateA(NULL, "feature");
876     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
877
878     /* empty prodcode */
879     state = MsiQueryFeatureStateA("", "feature");
880     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
881
882     /* garbage prodcode */
883     state = MsiQueryFeatureStateA("garbage", "feature");
884     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
885
886     /* guid without brackets */
887     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
888     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
889
890     /* guid with brackets */
891     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
892     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
893
894     /* same length as guid, but random */
895     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
896     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
897
898     /* NULL szFeature */
899     state = MsiQueryFeatureStateA(prodcode, NULL);
900     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
901
902     /* empty szFeature */
903     state = MsiQueryFeatureStateA(prodcode, "");
904     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
905
906     /* feature key does not exist yet */
907     state = MsiQueryFeatureStateA(prodcode, "feature");
908     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
909
910     /* MSIINSTALLCONTEXT_USERUNMANAGED */
911
912     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
913     lstrcatA(keypath, prod_squashed);
914
915     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
917
918     /* feature key exists */
919     state = MsiQueryFeatureStateA(prodcode, "feature");
920     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
921
922     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
924
925     /* feature value exists */
926     state = MsiQueryFeatureStateA(prodcode, "feature");
927     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
928
929     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
930     lstrcatA(keypath, usersid);
931     lstrcatA(keypath, "\\Products\\");
932     lstrcatA(keypath, prod_squashed);
933     lstrcatA(keypath, "\\Features");
934
935     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
936     if (res == ERROR_ACCESS_DENIED)
937     {
938         skip("Not enough rights to perform tests\n");
939         RegDeleteKeyA(userkey, "");
940         RegCloseKey(userkey);
941         LocalFree(usersid);
942         return;
943     }
944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
945
946     /* userdata features key exists */
947     state = MsiQueryFeatureStateA(prodcode, "feature");
948     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
949
950     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
952
953     state = MsiQueryFeatureStateA(prodcode, "feature");
954     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
955
956     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
958
959     state = MsiQueryFeatureStateA(prodcode, "feature");
960     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
961
962     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
964
965     state = MsiQueryFeatureStateA(prodcode, "feature");
966     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
967
968     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
970
971     state = MsiQueryFeatureStateA(prodcode, "feature");
972     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
973
974     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
975     lstrcatA(keypath, usersid);
976     lstrcatA(keypath, "\\Components\\");
977     lstrcatA(keypath, comp_squashed);
978
979     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
980     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
981
982     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
983     lstrcatA(keypath, usersid);
984     lstrcatA(keypath, "\\Components\\");
985     lstrcatA(keypath, comp_squashed2);
986
987     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
988     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
989
990     state = MsiQueryFeatureStateA(prodcode, "feature");
991     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
992
993     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
994     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
995
996     state = MsiQueryFeatureStateA(prodcode, "feature");
997     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
998
999     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1001
1002     state = MsiQueryFeatureStateA(prodcode, "feature");
1003     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1004
1005     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1006     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1007
1008     /* INSTALLSTATE_LOCAL */
1009     state = MsiQueryFeatureStateA(prodcode, "feature");
1010     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1011
1012     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1014
1015     /* INSTALLSTATE_SOURCE */
1016     state = MsiQueryFeatureStateA(prodcode, "feature");
1017     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1018
1019     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1020     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1021
1022     /* bad INSTALLSTATE_SOURCE */
1023     state = MsiQueryFeatureStateA(prodcode, "feature");
1024     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1025
1026     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1027     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1028
1029     /* INSTALLSTATE_SOURCE */
1030     state = MsiQueryFeatureStateA(prodcode, "feature");
1031     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1032
1033     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1035
1036     /* bad INSTALLSTATE_SOURCE */
1037     state = MsiQueryFeatureStateA(prodcode, "feature");
1038     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1039
1040     RegDeleteValueA(compkey, prod_squashed);
1041     RegDeleteValueA(compkey2, prod_squashed);
1042     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1043     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1044     RegDeleteValueA(localkey, "feature");
1045     RegDeleteValueA(userkey, "feature");
1046     RegDeleteKeyA(userkey, "");
1047     RegCloseKey(compkey);
1048     RegCloseKey(compkey2);
1049     RegCloseKey(localkey);
1050     RegCloseKey(userkey);
1051
1052     /* MSIINSTALLCONTEXT_USERMANAGED */
1053
1054     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1055     lstrcatA(keypath, usersid);
1056     lstrcatA(keypath, "\\Installer\\Features\\");
1057     lstrcatA(keypath, prod_squashed);
1058
1059     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1061
1062     /* feature key exists */
1063     state = MsiQueryFeatureStateA(prodcode, "feature");
1064     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1065
1066     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1067     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1068
1069     /* feature value exists */
1070     state = MsiQueryFeatureStateA(prodcode, "feature");
1071     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1072
1073     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1074     lstrcatA(keypath, usersid);
1075     lstrcatA(keypath, "\\Products\\");
1076     lstrcatA(keypath, prod_squashed);
1077     lstrcatA(keypath, "\\Features");
1078
1079     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1081
1082     /* userdata features key exists */
1083     state = MsiQueryFeatureStateA(prodcode, "feature");
1084     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1085
1086     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1088
1089     state = MsiQueryFeatureStateA(prodcode, "feature");
1090     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1091
1092     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1094
1095     state = MsiQueryFeatureStateA(prodcode, "feature");
1096     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1097
1098     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1099     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1100
1101     state = MsiQueryFeatureStateA(prodcode, "feature");
1102     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1103
1104     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1105     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1106
1107     state = MsiQueryFeatureStateA(prodcode, "feature");
1108     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1109
1110     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1111     lstrcatA(keypath, usersid);
1112     lstrcatA(keypath, "\\Components\\");
1113     lstrcatA(keypath, comp_squashed);
1114
1115     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1117
1118     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1119     lstrcatA(keypath, usersid);
1120     lstrcatA(keypath, "\\Components\\");
1121     lstrcatA(keypath, comp_squashed2);
1122
1123     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1124     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1125
1126     state = MsiQueryFeatureStateA(prodcode, "feature");
1127     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1128
1129     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1130     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1131
1132     state = MsiQueryFeatureStateA(prodcode, "feature");
1133     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1134
1135     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1136     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1137
1138     state = MsiQueryFeatureStateA(prodcode, "feature");
1139     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1140
1141     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1142     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1143
1144     state = MsiQueryFeatureStateA(prodcode, "feature");
1145     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1146
1147     RegDeleteValueA(compkey, prod_squashed);
1148     RegDeleteValueA(compkey2, prod_squashed);
1149     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1150     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1151     RegDeleteValueA(localkey, "feature");
1152     RegDeleteValueA(userkey, "feature");
1153     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1154     RegCloseKey(compkey);
1155     RegCloseKey(compkey2);
1156     RegCloseKey(localkey);
1157     RegCloseKey(userkey);
1158
1159     /* MSIINSTALLCONTEXT_MACHINE */
1160
1161     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1162     lstrcatA(keypath, prod_squashed);
1163
1164     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1166
1167     /* feature key exists */
1168     state = MsiQueryFeatureStateA(prodcode, "feature");
1169     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1170
1171     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1172     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1173
1174     /* feature value exists */
1175     state = MsiQueryFeatureStateA(prodcode, "feature");
1176     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1177
1178     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1179     lstrcatA(keypath, "S-1-5-18\\Products\\");
1180     lstrcatA(keypath, prod_squashed);
1181     lstrcatA(keypath, "\\Features");
1182
1183     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1184     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1185
1186     /* userdata features key exists */
1187     state = MsiQueryFeatureStateA(prodcode, "feature");
1188     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1189
1190     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1191     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1192
1193     state = MsiQueryFeatureStateA(prodcode, "feature");
1194     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1195
1196     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1198
1199     state = MsiQueryFeatureStateA(prodcode, "feature");
1200     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1201
1202     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1203     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1204
1205     state = MsiQueryFeatureStateA(prodcode, "feature");
1206     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1207
1208     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1209     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1210
1211     state = MsiQueryFeatureStateA(prodcode, "feature");
1212     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1213
1214     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1215     lstrcatA(keypath, "S-1-5-18\\Components\\");
1216     lstrcatA(keypath, comp_squashed);
1217
1218     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1219     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1220
1221     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1222     lstrcatA(keypath, "S-1-5-18\\Components\\");
1223     lstrcatA(keypath, comp_squashed2);
1224
1225     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1227
1228     state = MsiQueryFeatureStateA(prodcode, "feature");
1229     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1230
1231     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1232     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1233
1234     state = MsiQueryFeatureStateA(prodcode, "feature");
1235     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1236
1237     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1239
1240     state = MsiQueryFeatureStateA(prodcode, "feature");
1241     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1242
1243     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1244     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1245
1246     state = MsiQueryFeatureStateA(prodcode, "feature");
1247     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1248
1249     RegDeleteValueA(compkey, prod_squashed);
1250     RegDeleteValueA(compkey2, prod_squashed);
1251     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1252     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1253     RegDeleteValueA(localkey, "feature");
1254     RegDeleteValueA(userkey, "feature");
1255     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1256     RegCloseKey(compkey);
1257     RegCloseKey(compkey2);
1258     RegCloseKey(localkey);
1259     RegCloseKey(userkey);
1260     LocalFree(usersid);
1261 }
1262
1263 static void test_MsiQueryComponentState(void)
1264 {
1265     HKEY compkey, prodkey;
1266     CHAR prodcode[MAX_PATH];
1267     CHAR prod_squashed[MAX_PATH];
1268     CHAR component[MAX_PATH];
1269     CHAR comp_base85[MAX_PATH];
1270     CHAR comp_squashed[MAX_PATH];
1271     CHAR keypath[MAX_PATH];
1272     INSTALLSTATE state;
1273     LPSTR usersid;
1274     LONG res;
1275     UINT r;
1276     REGSAM access = KEY_ALL_ACCESS;
1277     BOOL wow64;
1278
1279     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1280
1281     if (!pMsiQueryComponentStateA)
1282     {
1283         win_skip("MsiQueryComponentStateA not implemented\n");
1284         return;
1285     }
1286
1287     create_test_guid(prodcode, prod_squashed);
1288     compose_base85_guid(component, comp_base85, comp_squashed);
1289     get_user_sid(&usersid);
1290
1291     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
1292         access |= KEY_WOW64_64KEY;
1293
1294     /* NULL szProductCode */
1295     state = MAGIC_ERROR;
1296     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1297     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1298     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1299
1300     /* empty szProductCode */
1301     state = MAGIC_ERROR;
1302     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1303     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1304     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1305
1306     /* random szProductCode */
1307     state = MAGIC_ERROR;
1308     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1309     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1310     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1311
1312     /* GUID-length szProductCode */
1313     state = MAGIC_ERROR;
1314     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1315     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1316     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1317
1318     /* GUID-length with brackets */
1319     state = MAGIC_ERROR;
1320     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1321     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1322     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1323
1324     /* actual GUID */
1325     state = MAGIC_ERROR;
1326     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1327     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1328     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1329
1330     state = MAGIC_ERROR;
1331     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1332     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1333     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1334
1335     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1336     lstrcatA(keypath, prod_squashed);
1337
1338     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1339     if (res == ERROR_ACCESS_DENIED)
1340     {
1341         skip("Not enough rights to perform tests\n");
1342         LocalFree(usersid);
1343         return;
1344     }
1345     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1346
1347     state = MAGIC_ERROR;
1348     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1349     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1350     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1351
1352     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1353     RegCloseKey(prodkey);
1354
1355     /* create local system product key */
1356     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1357     lstrcatA(keypath, prod_squashed);
1358     lstrcatA(keypath, "\\InstallProperties");
1359
1360     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1362
1363     /* local system product key exists */
1364     state = MAGIC_ERROR;
1365     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1366     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1367     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1368
1369     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1371
1372     /* LocalPackage value exists */
1373     state = MAGIC_ERROR;
1374     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1375     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1376     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1377
1378     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1379     lstrcatA(keypath, comp_squashed);
1380
1381     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1382     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1383
1384     /* component key exists */
1385     state = MAGIC_ERROR;
1386     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1387     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1388     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1389
1390     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1391     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1392
1393     /* component\product exists */
1394     state = MAGIC_ERROR;
1395     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1396     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1397     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1398        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1399
1400     /* NULL component, product exists */
1401     state = MAGIC_ERROR;
1402     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1403     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1404     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1405
1406     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1407     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1408
1409     /* INSTALLSTATE_LOCAL */
1410     state = MAGIC_ERROR;
1411     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1412     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1413     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1414
1415     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1417
1418     /* INSTALLSTATE_SOURCE */
1419     state = MAGIC_ERROR;
1420     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1421     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1422     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1423
1424     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1425     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1426
1427     /* bad INSTALLSTATE_SOURCE */
1428     state = MAGIC_ERROR;
1429     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1430     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1431     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1432
1433     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1435
1436     /* INSTALLSTATE_SOURCE */
1437     state = MAGIC_ERROR;
1438     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1439     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1440     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1441
1442     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1443     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1444
1445     /* bad INSTALLSTATE_SOURCE */
1446     state = MAGIC_ERROR;
1447     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1448     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1449     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1450
1451     RegDeleteValueA(prodkey, "LocalPackage");
1452     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1453     RegDeleteValueA(compkey, prod_squashed);
1454     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1455     RegCloseKey(prodkey);
1456     RegCloseKey(compkey);
1457
1458     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1459
1460     state = MAGIC_ERROR;
1461     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1462     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1463     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1464
1465     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1466     lstrcatA(keypath, prod_squashed);
1467
1468     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1469     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1470
1471     state = MAGIC_ERROR;
1472     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1473     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1474     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1475
1476     RegDeleteKeyA(prodkey, "");
1477     RegCloseKey(prodkey);
1478
1479     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1480     lstrcatA(keypath, usersid);
1481     lstrcatA(keypath, "\\Products\\");
1482     lstrcatA(keypath, prod_squashed);
1483     lstrcatA(keypath, "\\InstallProperties");
1484
1485     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1486     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1487
1488     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1489     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1490
1491     RegCloseKey(prodkey);
1492
1493     state = MAGIC_ERROR;
1494     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1495     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1496     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1497
1498     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1499     lstrcatA(keypath, usersid);
1500     lstrcatA(keypath, "\\Components\\");
1501     lstrcatA(keypath, comp_squashed);
1502
1503     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1504     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1505
1506     /* component key exists */
1507     state = MAGIC_ERROR;
1508     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1509     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1510     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1511
1512     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1513     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1514
1515     /* component\product exists */
1516     state = MAGIC_ERROR;
1517     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1518     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1519     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1520        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1521
1522     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1524
1525     state = MAGIC_ERROR;
1526     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1527     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1528     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1529
1530     /* MSIINSTALLCONTEXT_USERMANAGED */
1531
1532     state = MAGIC_ERROR;
1533     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1534     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1535     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1536
1537     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1538     lstrcatA(keypath, prod_squashed);
1539
1540     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1541     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1542
1543     state = MAGIC_ERROR;
1544     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1545     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1546     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1547
1548     RegDeleteKeyA(prodkey, "");
1549     RegCloseKey(prodkey);
1550
1551     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1552     lstrcatA(keypath, usersid);
1553     lstrcatA(keypath, "\\Installer\\Products\\");
1554     lstrcatA(keypath, prod_squashed);
1555
1556     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1557     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1558
1559     state = MAGIC_ERROR;
1560     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1561     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1562     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1563
1564     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1565     RegCloseKey(prodkey);
1566
1567     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1568     lstrcatA(keypath, usersid);
1569     lstrcatA(keypath, "\\Products\\");
1570     lstrcatA(keypath, prod_squashed);
1571     lstrcatA(keypath, "\\InstallProperties");
1572
1573     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1574     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1575
1576     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1578
1579     state = MAGIC_ERROR;
1580     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1581     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1582     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1583
1584     RegDeleteValueA(prodkey, "LocalPackage");
1585     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1586     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1587     RegDeleteValueA(compkey, prod_squashed);
1588     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1589     RegCloseKey(prodkey);
1590     RegCloseKey(compkey);
1591     LocalFree(usersid);
1592 }
1593
1594 static void test_MsiGetComponentPath(void)
1595 {
1596     HKEY compkey, prodkey, installprop;
1597     CHAR prodcode[MAX_PATH];
1598     CHAR prod_squashed[MAX_PATH];
1599     CHAR component[MAX_PATH];
1600     CHAR comp_base85[MAX_PATH];
1601     CHAR comp_squashed[MAX_PATH];
1602     CHAR keypath[MAX_PATH];
1603     CHAR path[MAX_PATH];
1604     INSTALLSTATE state;
1605     LPSTR usersid;
1606     DWORD size, val;
1607     REGSAM access = KEY_ALL_ACCESS;
1608     BOOL wow64;
1609     LONG res;
1610
1611     create_test_guid(prodcode, prod_squashed);
1612     compose_base85_guid(component, comp_base85, comp_squashed);
1613     get_user_sid(&usersid);
1614
1615     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
1616         access |= KEY_WOW64_64KEY;
1617
1618     /* NULL szProduct */
1619     size = MAX_PATH;
1620     state = MsiGetComponentPathA(NULL, component, path, &size);
1621     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1622     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1623
1624     /* NULL szComponent */
1625     size = MAX_PATH;
1626     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1627     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1628     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1629
1630     size = MAX_PATH;
1631     state = MsiLocateComponentA(NULL, path, &size);
1632     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1633     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1634
1635     /* NULL lpPathBuf */
1636     size = MAX_PATH;
1637     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1638     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1639     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1640
1641     size = MAX_PATH;
1642     state = MsiLocateComponentA(component, NULL, &size);
1643     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1644     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1645
1646     /* NULL pcchBuf */
1647     size = MAX_PATH;
1648     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1649     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1650     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1651
1652     size = MAX_PATH;
1653     state = MsiLocateComponentA(component, path, NULL);
1654     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1655     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1656
1657     /* all params valid */
1658     size = MAX_PATH;
1659     state = MsiGetComponentPathA(prodcode, component, path, &size);
1660     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1661     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1662
1663     size = MAX_PATH;
1664     state = MsiLocateComponentA(component, path, &size);
1665     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1666     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1667
1668     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1669     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1670     lstrcatA(keypath, comp_squashed);
1671
1672     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1673     if (res == ERROR_ACCESS_DENIED)
1674     {
1675         skip("Not enough rights to perform tests\n");
1676         LocalFree(usersid);
1677         return;
1678     }
1679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1680
1681     /* local system component key exists */
1682     size = MAX_PATH;
1683     state = MsiGetComponentPathA(prodcode, component, path, &size);
1684     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1685     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1686
1687     size = MAX_PATH;
1688     state = MsiLocateComponentA(component, path, &size);
1689     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1690     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1691
1692     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1694
1695     /* product value exists */
1696     path[0] = 0;
1697     size = MAX_PATH;
1698     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
1704     size = MAX_PATH;
1705     state = MsiLocateComponentA(component, path, &size);
1706     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1707     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1708     ok(size == 10, "Expected 10, got %d\n", size);
1709
1710     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1711     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1712     lstrcatA(keypath, prod_squashed);
1713     lstrcatA(keypath, "\\InstallProperties");
1714
1715     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1717
1718     val = 1;
1719     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1721
1722     /* install properties key exists */
1723     path[0] = 0;
1724     size = MAX_PATH;
1725     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
1731     size = MAX_PATH;
1732     state = MsiLocateComponentA(component, path, &size);
1733     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1734     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1735     ok(size == 10, "Expected 10, got %d\n", size);
1736
1737     create_file("C:\\imapath", "C:\\imapath", 11);
1738
1739     /* file exists */
1740     path[0] = 0;
1741     size = MAX_PATH;
1742     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
1748     size = MAX_PATH;
1749     state = MsiLocateComponentA(component, path, &size);
1750     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1751     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1752     ok(size == 10, "Expected 10, got %d\n", size);
1753
1754     RegDeleteValueA(compkey, prod_squashed);
1755     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1756     RegDeleteValueA(installprop, "WindowsInstaller");
1757     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1758     RegCloseKey(compkey);
1759     RegCloseKey(installprop);
1760     DeleteFileA("C:\\imapath");
1761
1762     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1763     lstrcatA(keypath, "Installer\\UserData\\");
1764     lstrcatA(keypath, usersid);
1765     lstrcatA(keypath, "\\Components\\");
1766     lstrcatA(keypath, comp_squashed);
1767
1768     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1769     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1770
1771     /* user managed component key exists */
1772     size = MAX_PATH;
1773     state = MsiGetComponentPathA(prodcode, component, path, &size);
1774     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1775     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1776
1777     size = MAX_PATH;
1778     state = MsiLocateComponentA(component, path, &size);
1779     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1780     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1781
1782     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1783     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1784
1785     /* product value exists */
1786     path[0] = 0;
1787     size = MAX_PATH;
1788     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
1794     size = MAX_PATH;
1795     state = MsiLocateComponentA(component, path, &size);
1796     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1797     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1798     ok(size == 10, "Expected 10, got %d\n", size);
1799
1800     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1801     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1802     lstrcatA(keypath, prod_squashed);
1803     lstrcatA(keypath, "\\InstallProperties");
1804
1805     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1806     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1807
1808     val = 1;
1809     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1810     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1811
1812     /* install properties key exists */
1813     path[0] = 0;
1814     size = MAX_PATH;
1815     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
1821     size = MAX_PATH;
1822     state = MsiLocateComponentA(component, path, &size);
1823     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1824     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1825     ok(size == 10, "Expected 10, got %d\n", size);
1826
1827     create_file("C:\\imapath", "C:\\imapath", 11);
1828
1829     /* file exists */
1830     path[0] = 0;
1831     size = MAX_PATH;
1832     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
1838     size = MAX_PATH;
1839     state = MsiLocateComponentA(component, path, &size);
1840     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1841     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1842     ok(size == 10, "Expected 10, got %d\n", size);
1843
1844     RegDeleteValueA(compkey, prod_squashed);
1845     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1846     RegDeleteValueA(installprop, "WindowsInstaller");
1847     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1848     RegCloseKey(compkey);
1849     RegCloseKey(installprop);
1850     DeleteFileA("C:\\imapath");
1851
1852     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1853     lstrcatA(keypath, "Installer\\Managed\\");
1854     lstrcatA(keypath, usersid);
1855     lstrcatA(keypath, "\\Installer\\Products\\");
1856     lstrcatA(keypath, prod_squashed);
1857
1858     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1859     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1860
1861     /* user managed product key exists */
1862     size = MAX_PATH;
1863     state = MsiGetComponentPathA(prodcode, component, path, &size);
1864     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1865     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1866
1867     size = MAX_PATH;
1868     state = MsiLocateComponentA(component, path, &size);
1869     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1870     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1871
1872     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1873     lstrcatA(keypath, "Installer\\UserData\\");
1874     lstrcatA(keypath, usersid);
1875     lstrcatA(keypath, "\\Components\\");
1876     lstrcatA(keypath, comp_squashed);
1877
1878     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1880
1881     /* user managed component key exists */
1882     size = MAX_PATH;
1883     state = MsiGetComponentPathA(prodcode, component, path, &size);
1884     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1885     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1886
1887     size = MAX_PATH;
1888     state = MsiLocateComponentA(component, path, &size);
1889     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1890     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1891
1892     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1893     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1894
1895     /* product value exists */
1896     path[0] = 0;
1897     size = MAX_PATH;
1898     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
1904     size = MAX_PATH;
1905     state = MsiLocateComponentA(component, path, &size);
1906     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1907     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1908     ok(size == 10, "Expected 10, got %d\n", size);
1909
1910     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1911     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1912     lstrcatA(keypath, prod_squashed);
1913     lstrcatA(keypath, "\\InstallProperties");
1914
1915     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1917
1918     val = 1;
1919     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1920     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1921
1922     /* install properties key exists */
1923     path[0] = 0;
1924     size = MAX_PATH;
1925     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
1931     size = MAX_PATH;
1932     state = MsiLocateComponentA(component, path, &size);
1933     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1934     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1935     ok(size == 10, "Expected 10, got %d\n", size);
1936
1937     create_file("C:\\imapath", "C:\\imapath", 11);
1938
1939     /* file exists */
1940     path[0] = 0;
1941     size = MAX_PATH;
1942     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
1948     size = MAX_PATH;
1949     state = MsiLocateComponentA(component, path, &size);
1950     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1951     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1952     ok(size == 10, "Expected 10, got %d\n", size);
1953
1954     RegDeleteValueA(compkey, prod_squashed);
1955     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1956     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1957     RegDeleteValueA(installprop, "WindowsInstaller");
1958     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1959     RegCloseKey(prodkey);
1960     RegCloseKey(compkey);
1961     RegCloseKey(installprop);
1962     DeleteFileA("C:\\imapath");
1963
1964     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1965     lstrcatA(keypath, prod_squashed);
1966
1967     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1968     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1969
1970     /* user unmanaged product key exists */
1971     size = MAX_PATH;
1972     state = MsiGetComponentPathA(prodcode, component, path, &size);
1973     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1974     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1975
1976     size = MAX_PATH;
1977     state = MsiLocateComponentA(component, path, &size);
1978     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1979     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1980
1981     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1982     lstrcatA(keypath, "Installer\\UserData\\");
1983     lstrcatA(keypath, usersid);
1984     lstrcatA(keypath, "\\Components\\");
1985     lstrcatA(keypath, comp_squashed);
1986
1987     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1988     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1989
1990     /* user unmanaged component key exists */
1991     size = MAX_PATH;
1992     state = MsiGetComponentPathA(prodcode, component, path, &size);
1993     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1994     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1995
1996     size = MAX_PATH;
1997     state = MsiLocateComponentA(component, path, &size);
1998     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1999     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2000
2001     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2002     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2003
2004     /* product value exists */
2005     path[0] = 0;
2006     size = MAX_PATH;
2007     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
2013     size = MAX_PATH;
2014     state = MsiLocateComponentA(component, path, &size);
2015     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2016     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2017     ok(size == 10, "Expected 10, got %d\n", size);
2018
2019     create_file("C:\\imapath", "C:\\imapath", 11);
2020
2021     /* file exists */
2022     path[0] = 0;
2023     size = MAX_PATH;
2024     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
2030     size = MAX_PATH;
2031     state = MsiLocateComponentA(component, path, &size);
2032     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2033     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2034     ok(size == 10, "Expected 10, got %d\n", size);
2035
2036     RegDeleteValueA(compkey, prod_squashed);
2037     RegDeleteKeyA(prodkey, "");
2038     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2039     RegCloseKey(prodkey);
2040     RegCloseKey(compkey);
2041     DeleteFileA("C:\\imapath");
2042
2043     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2044     lstrcatA(keypath, prod_squashed);
2045
2046     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2047     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2048
2049     /* local classes product key exists */
2050     size = MAX_PATH;
2051     state = MsiGetComponentPathA(prodcode, component, path, &size);
2052     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2053     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2054
2055     size = MAX_PATH;
2056     state = MsiLocateComponentA(component, path, &size);
2057     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2058     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2059
2060     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2061     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2062     lstrcatA(keypath, comp_squashed);
2063
2064     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2065     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2066
2067     /* local user component key exists */
2068     size = MAX_PATH;
2069     state = MsiGetComponentPathA(prodcode, component, path, &size);
2070     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2071     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2072
2073     size = MAX_PATH;
2074     state = MsiLocateComponentA(component, path, &size);
2075     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2076     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2077
2078     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2080
2081     /* product value exists */
2082     path[0] = 0;
2083     size = MAX_PATH;
2084     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
2090     size = MAX_PATH;
2091     state = MsiLocateComponentA(component, path, &size);
2092     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2093     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2094     ok(size == 10, "Expected 10, got %d\n", size);
2095
2096     create_file("C:\\imapath", "C:\\imapath", 11);
2097
2098     /* file exists */
2099     path[0] = 0;
2100     size = MAX_PATH;
2101     state = MsiGetComponentPathA(prodcode, 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     path[0] = 0;
2107     size = MAX_PATH;
2108     state = MsiLocateComponentA(component, path, &size);
2109     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2110     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2111     ok(size == 10, "Expected 10, got %d\n", size);
2112
2113     RegDeleteValueA(compkey, prod_squashed);
2114     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2115     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2116     RegCloseKey(prodkey);
2117     RegCloseKey(compkey);
2118     DeleteFileA("C:\\imapath");
2119     LocalFree(usersid);
2120 }
2121
2122 static void test_MsiGetProductCode(void)
2123 {
2124     HKEY compkey, prodkey;
2125     CHAR prodcode[MAX_PATH];
2126     CHAR prod_squashed[MAX_PATH];
2127     CHAR prodcode2[MAX_PATH];
2128     CHAR prod2_squashed[MAX_PATH];
2129     CHAR component[MAX_PATH];
2130     CHAR comp_base85[MAX_PATH];
2131     CHAR comp_squashed[MAX_PATH];
2132     CHAR keypath[MAX_PATH];
2133     CHAR product[MAX_PATH];
2134     LPSTR usersid;
2135     LONG res;
2136     UINT r;
2137     REGSAM access = KEY_ALL_ACCESS;
2138     BOOL wow64;
2139
2140     create_test_guid(prodcode, prod_squashed);
2141     create_test_guid(prodcode2, prod2_squashed);
2142     compose_base85_guid(component, comp_base85, comp_squashed);
2143     get_user_sid(&usersid);
2144
2145     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
2146         access |= KEY_WOW64_64KEY;
2147
2148     /* szComponent is NULL */
2149     lstrcpyA(product, "prod");
2150     r = MsiGetProductCodeA(NULL, product);
2151     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2152     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2153
2154     /* szComponent is empty */
2155     lstrcpyA(product, "prod");
2156     r = MsiGetProductCodeA("", product);
2157     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2158     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2159
2160     /* garbage szComponent */
2161     lstrcpyA(product, "prod");
2162     r = MsiGetProductCodeA("garbage", product);
2163     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2164     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2165
2166     /* guid without brackets */
2167     lstrcpyA(product, "prod");
2168     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
2169     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2170     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2171
2172     /* guid with brackets */
2173     lstrcpyA(product, "prod");
2174     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
2175     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2176     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2177
2178     /* same length as guid, but random */
2179     lstrcpyA(product, "prod");
2180     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
2181     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2182     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2183
2184     /* all params correct, szComponent not published */
2185     lstrcpyA(product, "prod");
2186     r = MsiGetProductCodeA(component, product);
2187     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2188     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2189
2190     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2191     lstrcatA(keypath, "Installer\\UserData\\");
2192     lstrcatA(keypath, usersid);
2193     lstrcatA(keypath, "\\Components\\");
2194     lstrcatA(keypath, comp_squashed);
2195
2196     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2197     if (res == ERROR_ACCESS_DENIED)
2198     {
2199         skip("Not enough rights to perform tests\n");
2200         LocalFree(usersid);
2201         return;
2202     }
2203     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2204
2205     /* user unmanaged component key exists */
2206     lstrcpyA(product, "prod");
2207     r = MsiGetProductCodeA(component, product);
2208     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2209     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2210
2211     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2213
2214     /* product value exists */
2215     lstrcpyA(product, "prod");
2216     r = MsiGetProductCodeA(component, product);
2217     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2218     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2219
2220     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2221     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2222
2223     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2224     lstrcatA(keypath, "Installer\\Managed\\");
2225     lstrcatA(keypath, usersid);
2226     lstrcatA(keypath, "\\Installer\\Products\\");
2227     lstrcatA(keypath, prod_squashed);
2228
2229     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2230     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2231
2232     /* user managed product key of first product exists */
2233     lstrcpyA(product, "prod");
2234     r = MsiGetProductCodeA(component, product);
2235     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2236     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2237
2238     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2239     RegCloseKey(prodkey);
2240
2241     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2242     lstrcatA(keypath, prod_squashed);
2243
2244     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2245     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2246
2247     /* user unmanaged product key exists */
2248     lstrcpyA(product, "prod");
2249     r = MsiGetProductCodeA(component, product);
2250     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2251     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2252
2253     RegDeleteKeyA(prodkey, "");
2254     RegCloseKey(prodkey);
2255
2256     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2257     lstrcatA(keypath, prod_squashed);
2258
2259     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2260     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2261
2262     /* local classes product key exists */
2263     lstrcpyA(product, "prod");
2264     r = MsiGetProductCodeA(component, product);
2265     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2266     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2267
2268     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2269     RegCloseKey(prodkey);
2270
2271     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2272     lstrcatA(keypath, "Installer\\Managed\\");
2273     lstrcatA(keypath, usersid);
2274     lstrcatA(keypath, "\\Installer\\Products\\");
2275     lstrcatA(keypath, prod2_squashed);
2276
2277     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2279
2280     /* user managed product key of second product exists */
2281     lstrcpyA(product, "prod");
2282     r = MsiGetProductCodeA(component, product);
2283     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2284     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2285
2286     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2287     RegCloseKey(prodkey);
2288     RegDeleteValueA(compkey, prod_squashed);
2289     RegDeleteValueA(compkey, prod2_squashed);
2290     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2291     RegCloseKey(compkey);
2292
2293     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2294     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2295     lstrcatA(keypath, comp_squashed);
2296
2297     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2298     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2299
2300     /* local user component key exists */
2301     lstrcpyA(product, "prod");
2302     r = MsiGetProductCodeA(component, product);
2303     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2304     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2305
2306     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2308
2309     /* product value exists */
2310     lstrcpyA(product, "prod");
2311     r = MsiGetProductCodeA(component, product);
2312     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2313     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2314
2315     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2317
2318     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2319     lstrcatA(keypath, "Installer\\Managed\\");
2320     lstrcatA(keypath, usersid);
2321     lstrcatA(keypath, "\\Installer\\Products\\");
2322     lstrcatA(keypath, prod_squashed);
2323
2324     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2326
2327     /* user managed product key of first product exists */
2328     lstrcpyA(product, "prod");
2329     r = MsiGetProductCodeA(component, product);
2330     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2331     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2332
2333     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2334     RegCloseKey(prodkey);
2335
2336     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2337     lstrcatA(keypath, prod_squashed);
2338
2339     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2340     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2341
2342     /* user unmanaged product key exists */
2343     lstrcpyA(product, "prod");
2344     r = MsiGetProductCodeA(component, product);
2345     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2346     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2347
2348     RegDeleteKeyA(prodkey, "");
2349     RegCloseKey(prodkey);
2350
2351     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2352     lstrcatA(keypath, prod_squashed);
2353
2354     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2356
2357     /* local classes product key exists */
2358     lstrcpyA(product, "prod");
2359     r = MsiGetProductCodeA(component, product);
2360     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2361     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2362
2363     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2364     RegCloseKey(prodkey);
2365
2366     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2367     lstrcatA(keypath, "Installer\\Managed\\");
2368     lstrcatA(keypath, usersid);
2369     lstrcatA(keypath, "\\Installer\\Products\\");
2370     lstrcatA(keypath, prod2_squashed);
2371
2372     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2373     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2374
2375     /* user managed product key of second product exists */
2376     lstrcpyA(product, "prod");
2377     r = MsiGetProductCodeA(component, product);
2378     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2379     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2380
2381     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2382     RegCloseKey(prodkey);
2383     RegDeleteValueA(compkey, prod_squashed);
2384     RegDeleteValueA(compkey, prod2_squashed);
2385     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2386     RegCloseKey(compkey);
2387     LocalFree(usersid);
2388 }
2389
2390 static void test_MsiEnumClients(void)
2391 {
2392     HKEY compkey;
2393     CHAR prodcode[MAX_PATH];
2394     CHAR prod_squashed[MAX_PATH];
2395     CHAR prodcode2[MAX_PATH];
2396     CHAR prod2_squashed[MAX_PATH];
2397     CHAR component[MAX_PATH];
2398     CHAR comp_base85[MAX_PATH];
2399     CHAR comp_squashed[MAX_PATH];
2400     CHAR product[MAX_PATH];
2401     CHAR keypath[MAX_PATH];
2402     LPSTR usersid;
2403     LONG res;
2404     UINT r;
2405     REGSAM access = KEY_ALL_ACCESS;
2406     BOOL wow64;
2407
2408     create_test_guid(prodcode, prod_squashed);
2409     create_test_guid(prodcode2, prod2_squashed);
2410     compose_base85_guid(component, comp_base85, comp_squashed);
2411     get_user_sid(&usersid);
2412
2413     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
2414         access |= KEY_WOW64_64KEY;
2415
2416     /* NULL szComponent */
2417     product[0] = '\0';
2418     r = MsiEnumClientsA(NULL, 0, product);
2419     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2420     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2421
2422     /* empty szComponent */
2423     product[0] = '\0';
2424     r = MsiEnumClientsA("", 0, product);
2425     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2426     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2427
2428     /* NULL lpProductBuf */
2429     r = MsiEnumClientsA(component, 0, NULL);
2430     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2431
2432     /* all params correct, component missing */
2433     product[0] = '\0';
2434     r = MsiEnumClientsA(component, 0, product);
2435     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2436     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2437
2438     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2439     lstrcatA(keypath, "Installer\\UserData\\");
2440     lstrcatA(keypath, usersid);
2441     lstrcatA(keypath, "\\Components\\");
2442     lstrcatA(keypath, comp_squashed);
2443
2444     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2445     if (res == ERROR_ACCESS_DENIED)
2446     {
2447         skip("Not enough rights to perform tests\n");
2448         LocalFree(usersid);
2449         return;
2450     }
2451     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2452
2453     /* user unmanaged component key exists */
2454     product[0] = '\0';
2455     r = MsiEnumClientsA(component, 0, product);
2456     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2457     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2458
2459     /* index > 0, no products exist */
2460     product[0] = '\0';
2461     r = MsiEnumClientsA(component, 1, product);
2462     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2463     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2464
2465     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2466     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2467
2468     /* product value exists */
2469     r = MsiEnumClientsA(component, 0, product);
2470     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2471     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2472
2473     /* try index 0 again */
2474     product[0] = '\0';
2475     r = MsiEnumClientsA(component, 0, product);
2476     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2477     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2478
2479     /* try index 1, second product value does not exist */
2480     product[0] = '\0';
2481     r = MsiEnumClientsA(component, 1, product);
2482     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2483     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2484
2485     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2486     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2487
2488     /* try index 1, second product value does exist */
2489     product[0] = '\0';
2490     r = MsiEnumClientsA(component, 1, product);
2491     todo_wine
2492     {
2493         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2494         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2495     }
2496
2497     /* start the enumeration over */
2498     product[0] = '\0';
2499     r = MsiEnumClientsA(component, 0, 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     /* correctly query second product */
2505     product[0] = '\0';
2506     r = MsiEnumClientsA(component, 1, product);
2507     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2508     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2509        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2510
2511     RegDeleteValueA(compkey, prod_squashed);
2512     RegDeleteValueA(compkey, prod2_squashed);
2513     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2514     RegCloseKey(compkey);
2515
2516     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2517     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2518     lstrcatA(keypath, comp_squashed);
2519
2520     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2521     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2522
2523     /* user local component key exists */
2524     product[0] = '\0';
2525     r = MsiEnumClientsA(component, 0, product);
2526     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2527     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2528
2529     /* index > 0, no products exist */
2530     product[0] = '\0';
2531     r = MsiEnumClientsA(component, 1, product);
2532     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2533     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2534
2535     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2536     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2537
2538     /* product value exists */
2539     product[0] = '\0';
2540     r = MsiEnumClientsA(component, 0, product);
2541     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2542     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2543
2544     /* try index 0 again */
2545     product[0] = '\0';
2546     r = MsiEnumClientsA(component, 0, product);
2547     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2548
2549     /* try index 1, second product value does not exist */
2550     product[0] = '\0';
2551     r = MsiEnumClientsA(component, 1, product);
2552     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2553     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2554
2555     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2557
2558     /* try index 1, second product value does exist */
2559     product[0] = '\0';
2560     r = MsiEnumClientsA(component, 1, product);
2561     todo_wine
2562     {
2563         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2564         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2565     }
2566
2567     /* start the enumeration over */
2568     product[0] = '\0';
2569     r = MsiEnumClientsA(component, 0, 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     /* correctly query second product */
2575     product[0] = '\0';
2576     r = MsiEnumClientsA(component, 1, product);
2577     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2578     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2579        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2580
2581     RegDeleteValueA(compkey, prod_squashed);
2582     RegDeleteValueA(compkey, prod2_squashed);
2583     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2584     RegCloseKey(compkey);
2585     LocalFree(usersid);
2586 }
2587
2588 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2589                              LPSTR *langcheck, LPDWORD langchecksz)
2590 {
2591     LPSTR version;
2592     VS_FIXEDFILEINFO *ffi;
2593     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2594     USHORT *lang;
2595
2596     version = HeapAlloc(GetProcessHeap(), 0, size);
2597     GetFileVersionInfoA(path, 0, size, version);
2598
2599     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2600     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2601     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2602             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2603             LOWORD(ffi->dwFileVersionLS));
2604     *verchecksz = lstrlenA(*vercheck);
2605
2606     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2607     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2608     sprintf(*langcheck, "%d", *lang);
2609     *langchecksz = lstrlenA(*langcheck);
2610
2611     HeapFree(GetProcessHeap(), 0, version);
2612 }
2613
2614 static void test_MsiGetFileVersion(void)
2615 {
2616     UINT r;
2617     DWORD versz, langsz;
2618     char version[MAX_PATH];
2619     char lang[MAX_PATH];
2620     char path[MAX_PATH];
2621     LPSTR vercheck, langcheck;
2622     DWORD verchecksz, langchecksz;
2623
2624     /* NULL szFilePath */
2625     versz = MAX_PATH;
2626     langsz = MAX_PATH;
2627     lstrcpyA(version, "version");
2628     lstrcpyA(lang, "lang");
2629     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2630     ok(r == ERROR_INVALID_PARAMETER,
2631        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2632     ok(!lstrcmpA(version, "version"),
2633        "Expected version to be unchanged, got %s\n", version);
2634     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2635     ok(!lstrcmpA(lang, "lang"),
2636        "Expected lang to be unchanged, got %s\n", lang);
2637     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2638
2639     /* empty szFilePath */
2640     versz = MAX_PATH;
2641     langsz = MAX_PATH;
2642     lstrcpyA(version, "version");
2643     lstrcpyA(lang, "lang");
2644     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2645     ok(r == ERROR_FILE_NOT_FOUND,
2646        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2647     ok(!lstrcmpA(version, "version"),
2648        "Expected version to be unchanged, got %s\n", version);
2649     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2650     ok(!lstrcmpA(lang, "lang"),
2651        "Expected lang to be unchanged, got %s\n", lang);
2652     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2653
2654     /* nonexistent szFilePath */
2655     versz = MAX_PATH;
2656     langsz = MAX_PATH;
2657     lstrcpyA(version, "version");
2658     lstrcpyA(lang, "lang");
2659     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2660     ok(r == ERROR_FILE_NOT_FOUND,
2661        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2662     ok(!lstrcmpA(version, "version"),
2663        "Expected version to be unchanged, got %s\n", version);
2664     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2665     ok(!lstrcmpA(lang, "lang"),
2666        "Expected lang to be unchanged, got %s\n", lang);
2667     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2668
2669     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2670     versz = MAX_PATH;
2671     langsz = MAX_PATH;
2672     lstrcpyA(version, "version");
2673     lstrcpyA(lang, "lang");
2674     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2675     ok(r == ERROR_INVALID_PARAMETER,
2676        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2677     ok(!lstrcmpA(version, "version"),
2678        "Expected version to be unchanged, got %s\n", version);
2679     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2680     ok(!lstrcmpA(lang, "lang"),
2681        "Expected lang to be unchanged, got %s\n", lang);
2682     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2683
2684     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2685     versz = MAX_PATH;
2686     langsz = MAX_PATH;
2687     lstrcpyA(version, "version");
2688     lstrcpyA(lang, "lang");
2689     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2690     ok(r == ERROR_INVALID_PARAMETER,
2691        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2692     ok(!lstrcmpA(version, "version"),
2693        "Expected version to be unchanged, got %s\n", version);
2694     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2695     ok(!lstrcmpA(lang, "lang"),
2696        "Expected lang to be unchanged, got %s\n", lang);
2697     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2698
2699     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2700     versz = 0;
2701     langsz = MAX_PATH;
2702     lstrcpyA(version, "version");
2703     lstrcpyA(lang, "lang");
2704     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2705     ok(r == ERROR_FILE_NOT_FOUND,
2706        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2707     ok(!lstrcmpA(version, "version"),
2708        "Expected version to be unchanged, got %s\n", version);
2709     ok(versz == 0, "Expected 0, got %d\n", versz);
2710     ok(!lstrcmpA(lang, "lang"),
2711        "Expected lang to be unchanged, got %s\n", lang);
2712     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2713
2714     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2715     versz = MAX_PATH;
2716     langsz = 0;
2717     lstrcpyA(version, "version");
2718     lstrcpyA(lang, "lang");
2719     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2720     ok(r == ERROR_FILE_NOT_FOUND,
2721        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2722     ok(!lstrcmpA(version, "version"),
2723        "Expected version to be unchanged, got %s\n", version);
2724     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2725     ok(!lstrcmpA(lang, "lang"),
2726        "Expected lang to be unchanged, got %s\n", lang);
2727     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2728
2729     /* nonexistent szFilePath, rest NULL */
2730     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2731     ok(r == ERROR_FILE_NOT_FOUND,
2732        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2733
2734     create_file("ver.txt", "ver.txt", 20);
2735
2736     /* file exists, no version information */
2737     versz = MAX_PATH;
2738     langsz = MAX_PATH;
2739     lstrcpyA(version, "version");
2740     lstrcpyA(lang, "lang");
2741     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2742     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2743     ok(!lstrcmpA(version, "version"),
2744        "Expected version to be unchanged, got %s\n", version);
2745     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2746     ok(!lstrcmpA(lang, "lang"),
2747        "Expected lang to be unchanged, got %s\n", lang);
2748     ok(r == ERROR_FILE_INVALID,
2749        "Expected ERROR_FILE_INVALID, got %d\n", r);
2750
2751     DeleteFileA("ver.txt");
2752
2753     /* relative path, has version information */
2754     versz = MAX_PATH;
2755     langsz = MAX_PATH;
2756     lstrcpyA(version, "version");
2757     lstrcpyA(lang, "lang");
2758     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2759     todo_wine
2760     {
2761         ok(r == ERROR_FILE_NOT_FOUND,
2762            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2763         ok(!lstrcmpA(version, "version"),
2764            "Expected version to be unchanged, got %s\n", version);
2765         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2766         ok(!lstrcmpA(lang, "lang"),
2767            "Expected lang to be unchanged, got %s\n", lang);
2768         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2769     }
2770
2771     GetSystemDirectoryA(path, MAX_PATH);
2772     lstrcatA(path, "\\kernel32.dll");
2773
2774     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2775
2776     /* absolute path, has version information */
2777     versz = MAX_PATH;
2778     langsz = MAX_PATH;
2779     lstrcpyA(version, "version");
2780     lstrcpyA(lang, "lang");
2781     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2782     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2783     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2784     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2785     ok(!lstrcmpA(version, vercheck),
2786         "Expected %s, got %s\n", vercheck, version);
2787
2788     /* only check version */
2789     versz = MAX_PATH;
2790     lstrcpyA(version, "version");
2791     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2792     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2793     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2794     ok(!lstrcmpA(version, vercheck),
2795        "Expected %s, got %s\n", vercheck, version);
2796
2797     /* only check language */
2798     langsz = MAX_PATH;
2799     lstrcpyA(lang, "lang");
2800     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2801     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2802     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2803
2804     /* check neither version nor language */
2805     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2806     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2807
2808     /* get pcchVersionBuf */
2809     versz = MAX_PATH;
2810     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2811     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2812     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2813
2814     /* get pcchLangBuf */
2815     langsz = MAX_PATH;
2816     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2817     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2818     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
2819
2820     /* pcchVersionBuf not big enough */
2821     versz = 5;
2822     lstrcpyA(version, "version");
2823     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2824     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2825     ok(!strncmp(version, vercheck, 4),
2826        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2827     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2828
2829     /* pcchLangBuf not big enough */
2830     langsz = 3;
2831     lstrcpyA(lang, "lang");
2832     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2833     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2834     ok(!strncmp(lang, langcheck, 2),
2835        "Expected first character of %s, got %s\n", langcheck, lang);
2836     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
2837
2838     HeapFree(GetProcessHeap(), 0, vercheck);
2839     HeapFree(GetProcessHeap(), 0, langcheck);
2840 }
2841
2842 static void test_MsiGetProductInfo(void)
2843 {
2844     UINT r;
2845     LONG res;
2846     HKEY propkey, source;
2847     HKEY prodkey, localkey;
2848     CHAR prodcode[MAX_PATH];
2849     CHAR prod_squashed[MAX_PATH];
2850     CHAR packcode[MAX_PATH];
2851     CHAR pack_squashed[MAX_PATH];
2852     CHAR buf[MAX_PATH];
2853     CHAR keypath[MAX_PATH];
2854     LPSTR usersid;
2855     DWORD sz, val = 42;
2856     REGSAM access = KEY_ALL_ACCESS;
2857     BOOL wow64;
2858
2859     create_test_guid(prodcode, prod_squashed);
2860     create_test_guid(packcode, pack_squashed);
2861     get_user_sid(&usersid);
2862
2863     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
2864         access |= KEY_WOW64_64KEY;
2865
2866     /* NULL szProduct */
2867     sz = MAX_PATH;
2868     lstrcpyA(buf, "apple");
2869     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2870     ok(r == ERROR_INVALID_PARAMETER,
2871        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2872     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2873     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2874
2875     /* empty szProduct */
2876     sz = MAX_PATH;
2877     lstrcpyA(buf, "apple");
2878     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2879     ok(r == ERROR_INVALID_PARAMETER,
2880        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2881     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2882     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2883
2884     /* garbage szProduct */
2885     sz = MAX_PATH;
2886     lstrcpyA(buf, "apple");
2887     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2888     ok(r == ERROR_INVALID_PARAMETER,
2889        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2890     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2891     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2892
2893     /* guid without brackets */
2894     sz = MAX_PATH;
2895     lstrcpyA(buf, "apple");
2896     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2897                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2898     ok(r == ERROR_INVALID_PARAMETER,
2899        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2900     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2901     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2902
2903     /* guid with brackets */
2904     sz = MAX_PATH;
2905     lstrcpyA(buf, "apple");
2906     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2907                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2908     ok(r == ERROR_UNKNOWN_PRODUCT,
2909        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2910     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2911     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2912
2913     /* same length as guid, but random */
2914     sz = MAX_PATH;
2915     lstrcpyA(buf, "apple");
2916     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2917                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2918     ok(r == ERROR_INVALID_PARAMETER,
2919        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2920     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2921     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2922
2923     /* not installed, NULL szAttribute */
2924     sz = MAX_PATH;
2925     lstrcpyA(buf, "apple");
2926     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2927     ok(r == ERROR_INVALID_PARAMETER,
2928        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2929     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2930     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2931
2932     /* not installed, NULL lpValueBuf */
2933     sz = MAX_PATH;
2934     lstrcpyA(buf, "apple");
2935     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2936     ok(r == ERROR_UNKNOWN_PRODUCT,
2937        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2938     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2939     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2940
2941     /* not installed, NULL pcchValueBuf */
2942     sz = MAX_PATH;
2943     lstrcpyA(buf, "apple");
2944     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2945     ok(r == ERROR_INVALID_PARAMETER,
2946        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2947     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2948     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2949
2950     /* created guid cannot possibly be an installed product code */
2951     sz = MAX_PATH;
2952     lstrcpyA(buf, "apple");
2953     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2954     ok(r == ERROR_UNKNOWN_PRODUCT,
2955        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2956     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2957     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2958
2959     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2960     lstrcatA(keypath, usersid);
2961     lstrcatA(keypath, "\\Installer\\Products\\");
2962     lstrcatA(keypath, prod_squashed);
2963
2964     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2965     if (res == ERROR_ACCESS_DENIED)
2966     {
2967         skip("Not enough rights to perform tests\n");
2968         LocalFree(usersid);
2969         return;
2970     }
2971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2972
2973     /* managed product code exists */
2974     sz = MAX_PATH;
2975     lstrcpyA(buf, "apple");
2976     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2977     ok(r == ERROR_UNKNOWN_PROPERTY,
2978        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2979     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2980     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2981
2982     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2983     RegCloseKey(prodkey);
2984
2985     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2986     lstrcatA(keypath, usersid);
2987     lstrcatA(keypath, "\\Products\\");
2988     lstrcatA(keypath, prod_squashed);
2989
2990     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2992
2993     /* local user product code exists */
2994     sz = MAX_PATH;
2995     lstrcpyA(buf, "apple");
2996     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2997     ok(r == ERROR_UNKNOWN_PRODUCT,
2998        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2999     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3000     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3001
3002     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
3003     lstrcatA(keypath, usersid);
3004     lstrcatA(keypath, "\\Installer\\Products\\");
3005     lstrcatA(keypath, prod_squashed);
3006
3007     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3009
3010     /* both local and managed product code exist */
3011     sz = MAX_PATH;
3012     lstrcpyA(buf, "apple");
3013     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3014     ok(r == ERROR_UNKNOWN_PROPERTY,
3015        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3016     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3017     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3018
3019     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3020     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3021
3022     /* InstallProperties key exists */
3023     sz = MAX_PATH;
3024     lstrcpyA(buf, "apple");
3025     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3027     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3028     ok(sz == 0, "Expected 0, got %d\n", sz);
3029
3030     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3032
3033     /* HelpLink value exists */
3034     sz = MAX_PATH;
3035     lstrcpyA(buf, "apple");
3036     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3037     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3038     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3039     ok(sz == 4, "Expected 4, got %d\n", sz);
3040
3041     /* pcchBuf is NULL */
3042     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
3043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3044
3045     /* lpValueBuf is NULL */
3046     sz = MAX_PATH;
3047     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3048     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3049     ok(sz == 4, "Expected 4, got %d\n", sz);
3050
3051     /* lpValueBuf is NULL, pcchValueBuf is too small */
3052     sz = 2;
3053     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3054     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3055     ok(sz == 4, "Expected 4, got %d\n", sz);
3056
3057     /* lpValueBuf is non-NULL, pcchValueBuf is too small */
3058     sz = 2;
3059     lstrcpyA(buf, "apple");
3060     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3061     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
3062     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3063     ok(sz == 4, "Expected 4, got %d\n", sz);
3064
3065     /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
3066     sz = 4;
3067     lstrcpyA(buf, "apple");
3068     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3069     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3070     ok(!lstrcmpA(buf, "apple"),
3071        "Expected buf to remain unchanged, got \"%s\"\n", buf);
3072     ok(sz == 4, "Expected 4, got %d\n", sz);
3073
3074     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
3075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3076
3077     /* random property not supported by MSI, value exists */
3078     sz = MAX_PATH;
3079     lstrcpyA(buf, "apple");
3080     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
3081     ok(r == ERROR_UNKNOWN_PROPERTY,
3082        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3083     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3084     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3085
3086     RegDeleteValueA(propkey, "IMadeThis");
3087     RegDeleteValueA(propkey, "HelpLink");
3088     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3089     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3090     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3091     RegCloseKey(propkey);
3092     RegCloseKey(localkey);
3093     RegCloseKey(prodkey);
3094
3095     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3096     lstrcatA(keypath, prod_squashed);
3097
3098     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3099     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3100
3101     /* user product key exists */
3102     sz = MAX_PATH;
3103     lstrcpyA(buf, "apple");
3104     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3105     ok(r == ERROR_UNKNOWN_PROPERTY,
3106        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3107     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3108     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3109
3110     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3111     lstrcatA(keypath, usersid);
3112     lstrcatA(keypath, "\\Products\\");
3113     lstrcatA(keypath, prod_squashed);
3114
3115     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3117
3118     /* local user product key exists */
3119     sz = MAX_PATH;
3120     lstrcpyA(buf, "apple");
3121     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3122     ok(r == ERROR_UNKNOWN_PROPERTY,
3123        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3124     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3125     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3126
3127     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3129
3130     /* InstallProperties key exists */
3131     sz = MAX_PATH;
3132     lstrcpyA(buf, "apple");
3133     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3134     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3135     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3136     ok(sz == 0, "Expected 0, got %d\n", sz);
3137
3138     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3140
3141     /* HelpLink value exists */
3142     sz = MAX_PATH;
3143     lstrcpyA(buf, "apple");
3144     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3146     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3147     ok(sz == 4, "Expected 4, got %d\n", sz);
3148
3149     RegDeleteValueA(propkey, "HelpLink");
3150     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3151     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3152     RegDeleteKeyA(prodkey, "");
3153     RegCloseKey(propkey);
3154     RegCloseKey(localkey);
3155     RegCloseKey(prodkey);
3156
3157     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3158     lstrcatA(keypath, prod_squashed);
3159
3160     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3161     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3162
3163     /* classes product key exists */
3164     sz = MAX_PATH;
3165     lstrcpyA(buf, "apple");
3166     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3167     ok(r == ERROR_UNKNOWN_PROPERTY,
3168        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3169     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3170     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3171
3172     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3173     lstrcatA(keypath, usersid);
3174     lstrcatA(keypath, "\\Products\\");
3175     lstrcatA(keypath, prod_squashed);
3176
3177     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3179
3180     /* local user product key exists */
3181     sz = MAX_PATH;
3182     lstrcpyA(buf, "apple");
3183     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3184     ok(r == ERROR_UNKNOWN_PROPERTY,
3185        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3186     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3187     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3188
3189     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3190     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3191
3192     /* InstallProperties key exists */
3193     sz = MAX_PATH;
3194     lstrcpyA(buf, "apple");
3195     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3196     ok(r == ERROR_UNKNOWN_PROPERTY,
3197        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3198     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3199     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3200
3201     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3202     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3203     RegCloseKey(propkey);
3204     RegCloseKey(localkey);
3205
3206     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3207     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
3208     lstrcatA(keypath, prod_squashed);
3209
3210     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3212
3213     /* Local System product key exists */
3214     sz = MAX_PATH;
3215     lstrcpyA(buf, "apple");
3216     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3217     ok(r == ERROR_UNKNOWN_PROPERTY,
3218         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3219     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3220     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3221
3222     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3223     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3224
3225     /* InstallProperties key exists */
3226     sz = MAX_PATH;
3227     lstrcpyA(buf, "apple");
3228     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3229     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3230     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3231     ok(sz == 0, "Expected 0, got %d\n", sz);
3232
3233     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3234     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3235
3236     /* HelpLink value exists */
3237     sz = MAX_PATH;
3238     lstrcpyA(buf, "apple");
3239     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3240     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3241     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3242     ok(sz == 4, "Expected 4, got %d\n", sz);
3243
3244     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
3245                          (const BYTE *)&val, sizeof(DWORD));
3246     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3247
3248     /* HelpLink type is REG_DWORD */
3249     sz = MAX_PATH;
3250     lstrcpyA(buf, "apple");
3251     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3252     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3253     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3254     ok(sz == 2, "Expected 2, got %d\n", sz);
3255
3256     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
3257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3258
3259     /* DisplayName value exists */
3260     sz = MAX_PATH;
3261     lstrcpyA(buf, "apple");
3262     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3263     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3264     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3265     ok(sz == 4, "Expected 4, got %d\n", sz);
3266
3267     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
3268                          (const BYTE *)&val, sizeof(DWORD));
3269     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3270
3271     /* DisplayName type is REG_DWORD */
3272     sz = MAX_PATH;
3273     lstrcpyA(buf, "apple");
3274     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3275     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3276     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3277     ok(sz == 2, "Expected 2, got %d\n", sz);
3278
3279     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3281
3282     /* DisplayVersion value exists */
3283     sz = MAX_PATH;
3284     lstrcpyA(buf, "apple");
3285     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3287     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3288     ok(sz == 5, "Expected 5, got %d\n", sz);
3289
3290     res = RegSetValueExA(propkey, "DisplayVersion", 0,
3291                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3292     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3293
3294     /* DisplayVersion type is REG_DWORD */
3295     sz = MAX_PATH;
3296     lstrcpyA(buf, "apple");
3297     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3298     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3299     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3300     ok(sz == 2, "Expected 2, got %d\n", sz);
3301
3302     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3304
3305     /* HelpTelephone value exists */
3306     sz = MAX_PATH;
3307     lstrcpyA(buf, "apple");
3308     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3309     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3310     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3311     ok(sz == 4, "Expected 4, got %d\n", sz);
3312
3313     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3314                          (const BYTE *)&val, sizeof(DWORD));
3315     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3316
3317     /* HelpTelephone type is REG_DWORD */
3318     sz = MAX_PATH;
3319     lstrcpyA(buf, "apple");
3320     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3321     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3322     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3323     ok(sz == 2, "Expected 2, got %d\n", sz);
3324
3325     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3326     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3327
3328     /* InstallLocation value exists */
3329     sz = MAX_PATH;
3330     lstrcpyA(buf, "apple");
3331     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3332     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3333     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3334     ok(sz == 3, "Expected 3, got %d\n", sz);
3335
3336     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3337                          (const BYTE *)&val, sizeof(DWORD));
3338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3339
3340     /* InstallLocation type is REG_DWORD */
3341     sz = MAX_PATH;
3342     lstrcpyA(buf, "apple");
3343     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3344     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3345     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3346     ok(sz == 2, "Expected 2, got %d\n", sz);
3347
3348     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3349     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3350
3351     /* InstallSource value exists */
3352     sz = MAX_PATH;
3353     lstrcpyA(buf, "apple");
3354     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3355     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3356     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3357     ok(sz == 6, "Expected 6, got %d\n", sz);
3358
3359     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3360                          (const BYTE *)&val, sizeof(DWORD));
3361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3362
3363     /* InstallSource type is REG_DWORD */
3364     sz = MAX_PATH;
3365     lstrcpyA(buf, "apple");
3366     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3367     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3368     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3369     ok(sz == 2, "Expected 2, got %d\n", sz);
3370
3371     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3372     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3373
3374     /* InstallDate value exists */
3375     sz = MAX_PATH;
3376     lstrcpyA(buf, "apple");
3377     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3378     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3379     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3380     ok(sz == 4, "Expected 4, got %d\n", sz);
3381
3382     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3383                          (const BYTE *)&val, sizeof(DWORD));
3384     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3385
3386     /* InstallDate type is REG_DWORD */
3387     sz = MAX_PATH;
3388     lstrcpyA(buf, "apple");
3389     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3390     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3391     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3392     ok(sz == 2, "Expected 2, got %d\n", sz);
3393
3394     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3395     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3396
3397     /* Publisher value exists */
3398     sz = MAX_PATH;
3399     lstrcpyA(buf, "apple");
3400     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3401     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3402     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3403     ok(sz == 3, "Expected 3, got %d\n", sz);
3404
3405     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3406                          (const BYTE *)&val, sizeof(DWORD));
3407     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3408
3409     /* Publisher type is REG_DWORD */
3410     sz = MAX_PATH;
3411     lstrcpyA(buf, "apple");
3412     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3413     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3414     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3415     ok(sz == 2, "Expected 2, got %d\n", sz);
3416
3417     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3418     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3419
3420     /* LocalPackage value exists */
3421     sz = MAX_PATH;
3422     lstrcpyA(buf, "apple");
3423     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3425     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3426     ok(sz == 4, "Expected 4, got %d\n", sz);
3427
3428     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3429                          (const BYTE *)&val, sizeof(DWORD));
3430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3431
3432     /* LocalPackage type is REG_DWORD */
3433     sz = MAX_PATH;
3434     lstrcpyA(buf, "apple");
3435     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3436     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3437     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3438     ok(sz == 2, "Expected 2, got %d\n", sz);
3439
3440     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3441     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3442
3443     /* UrlInfoAbout value exists */
3444     sz = MAX_PATH;
3445     lstrcpyA(buf, "apple");
3446     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3447     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3448     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3449     ok(sz == 5, "Expected 5, got %d\n", sz);
3450
3451     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3452                          (const BYTE *)&val, sizeof(DWORD));
3453     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3454
3455     /* UrlInfoAbout type is REG_DWORD */
3456     sz = MAX_PATH;
3457     lstrcpyA(buf, "apple");
3458     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3459     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3460     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3461     ok(sz == 2, "Expected 2, got %d\n", sz);
3462
3463     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3464     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3465
3466     /* UrlUpdateInfo value exists */
3467     sz = MAX_PATH;
3468     lstrcpyA(buf, "apple");
3469     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3470     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3471     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3472     ok(sz == 4, "Expected 4, got %d\n", sz);
3473
3474     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3475                          (const BYTE *)&val, sizeof(DWORD));
3476     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3477
3478     /* UrlUpdateInfo type is REG_DWORD */
3479     sz = MAX_PATH;
3480     lstrcpyA(buf, "apple");
3481     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3483     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3484     ok(sz == 2, "Expected 2, got %d\n", sz);
3485
3486     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3487     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3488
3489     /* VersionMinor value exists */
3490     sz = MAX_PATH;
3491     lstrcpyA(buf, "apple");
3492     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3494     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3495     ok(sz == 1, "Expected 1, got %d\n", sz);
3496
3497     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3498                          (const BYTE *)&val, sizeof(DWORD));
3499     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3500
3501     /* VersionMinor type is REG_DWORD */
3502     sz = MAX_PATH;
3503     lstrcpyA(buf, "apple");
3504     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3505     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3506     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3507     ok(sz == 2, "Expected 2, got %d\n", sz);
3508
3509     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3510     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3511
3512     /* VersionMajor value exists */
3513     sz = MAX_PATH;
3514     lstrcpyA(buf, "apple");
3515     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3516     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3517     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3518     ok(sz == 1, "Expected 1, got %d\n", sz);
3519
3520     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3521                          (const BYTE *)&val, sizeof(DWORD));
3522     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3523
3524     /* VersionMajor type is REG_DWORD */
3525     sz = MAX_PATH;
3526     lstrcpyA(buf, "apple");
3527     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3528     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3529     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3530     ok(sz == 2, "Expected 2, got %d\n", sz);
3531
3532     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3534
3535     /* ProductID value exists */
3536     sz = MAX_PATH;
3537     lstrcpyA(buf, "apple");
3538     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3539     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3540     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3541     ok(sz == 2, "Expected 2, got %d\n", sz);
3542
3543     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3544                          (const BYTE *)&val, sizeof(DWORD));
3545     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3546
3547     /* ProductID type is REG_DWORD */
3548     sz = MAX_PATH;
3549     lstrcpyA(buf, "apple");
3550     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3551     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3552     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3553     ok(sz == 2, "Expected 2, got %d\n", sz);
3554
3555     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3557
3558     /* RegCompany value exists */
3559     sz = MAX_PATH;
3560     lstrcpyA(buf, "apple");
3561     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3562     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3563     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3564     ok(sz == 4, "Expected 4, got %d\n", sz);
3565
3566     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3567                          (const BYTE *)&val, sizeof(DWORD));
3568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3569
3570     /* RegCompany type is REG_DWORD */
3571     sz = MAX_PATH;
3572     lstrcpyA(buf, "apple");
3573     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3574     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3575     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3576     ok(sz == 2, "Expected 2, got %d\n", sz);
3577
3578     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3580
3581     /* RegOwner value exists */
3582     sz = MAX_PATH;
3583     lstrcpyA(buf, "apple");
3584     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3585     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3586     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3587     ok(sz == 3, "Expected 3, got %d\n", sz);
3588
3589     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3590                          (const BYTE *)&val, sizeof(DWORD));
3591     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3592
3593     /* RegOwner type is REG_DWORD */
3594     sz = MAX_PATH;
3595     lstrcpyA(buf, "apple");
3596     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3597     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3598     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3599     ok(sz == 2, "Expected 2, got %d\n", sz);
3600
3601     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3602     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3603
3604     /* InstanceType value exists */
3605     sz = MAX_PATH;
3606     lstrcpyA(buf, "apple");
3607     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3608     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3609     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3610     ok(sz == 0, "Expected 0, got %d\n", sz);
3611
3612     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3613                          (const BYTE *)&val, sizeof(DWORD));
3614     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3615
3616     /* InstanceType type is REG_DWORD */
3617     sz = MAX_PATH;
3618     lstrcpyA(buf, "apple");
3619     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3620     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3621     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3622     ok(sz == 0, "Expected 0, got %d\n", sz);
3623
3624     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3625     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3626
3627     /* InstanceType value exists */
3628     sz = MAX_PATH;
3629     lstrcpyA(buf, "apple");
3630     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3631     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3632     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3633     ok(sz == 4, "Expected 4, got %d\n", sz);
3634
3635     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3636                          (const BYTE *)&val, sizeof(DWORD));
3637     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3638
3639     /* InstanceType type is REG_DWORD */
3640     sz = MAX_PATH;
3641     lstrcpyA(buf, "apple");
3642     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3643     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3644     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3645     ok(sz == 2, "Expected 2, got %d\n", sz);
3646
3647     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3648     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3649
3650     /* Transforms value exists */
3651     sz = MAX_PATH;
3652     lstrcpyA(buf, "apple");
3653     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3654     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3655     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3656     ok(sz == 0, "Expected 0, got %d\n", sz);
3657
3658     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3659                          (const BYTE *)&val, sizeof(DWORD));
3660     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3661
3662     /* Transforms type is REG_DWORD */
3663     sz = MAX_PATH;
3664     lstrcpyA(buf, "apple");
3665     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3666     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3667     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3668     ok(sz == 0, "Expected 0, got %d\n", sz);
3669
3670     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3671     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3672
3673     /* Transforms value exists */
3674     sz = MAX_PATH;
3675     lstrcpyA(buf, "apple");
3676     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3677     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3678     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3679     ok(sz == 6, "Expected 6, got %d\n", sz);
3680
3681     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3682                          (const BYTE *)&val, sizeof(DWORD));
3683     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3684
3685     /* Transforms type is REG_DWORD */
3686     sz = MAX_PATH;
3687     lstrcpyA(buf, "apple");
3688     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3689     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3690     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3691     ok(sz == 2, "Expected 2, got %d\n", sz);
3692
3693     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3694     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3695
3696     /* Language value exists */
3697     sz = MAX_PATH;
3698     lstrcpyA(buf, "apple");
3699     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3700     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3701     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3702     ok(sz == 0, "Expected 0, got %d\n", sz);
3703
3704     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3705                          (const BYTE *)&val, sizeof(DWORD));
3706     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3707
3708     /* Language type is REG_DWORD */
3709     sz = MAX_PATH;
3710     lstrcpyA(buf, "apple");
3711     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3712     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3713     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3714     ok(sz == 0, "Expected 0, got %d\n", sz);
3715
3716     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3717     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3718
3719     /* Language value exists */
3720     sz = MAX_PATH;
3721     lstrcpyA(buf, "apple");
3722     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3723     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3724     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3725     ok(sz == 4, "Expected 4, got %d\n", sz);
3726
3727     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3728                          (const BYTE *)&val, sizeof(DWORD));
3729     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3730
3731     /* Language type is REG_DWORD */
3732     sz = MAX_PATH;
3733     lstrcpyA(buf, "apple");
3734     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3735     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3736     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3737     ok(sz == 2, "Expected 2, got %d\n", sz);
3738
3739     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3741
3742     /* ProductName value exists */
3743     sz = MAX_PATH;
3744     lstrcpyA(buf, "apple");
3745     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3746     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3747     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3748     ok(sz == 0, "Expected 0, got %d\n", sz);
3749
3750     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3751                          (const BYTE *)&val, sizeof(DWORD));
3752     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3753
3754     /* ProductName type is REG_DWORD */
3755     sz = MAX_PATH;
3756     lstrcpyA(buf, "apple");
3757     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3758     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3759     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3760     ok(sz == 0, "Expected 0, got %d\n", sz);
3761
3762     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3763     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3764
3765     /* ProductName value exists */
3766     sz = MAX_PATH;
3767     lstrcpyA(buf, "apple");
3768     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3769     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3770     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3771     ok(sz == 4, "Expected 4, got %d\n", sz);
3772
3773     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3774                          (const BYTE *)&val, sizeof(DWORD));
3775     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3776
3777     /* ProductName type is REG_DWORD */
3778     sz = MAX_PATH;
3779     lstrcpyA(buf, "apple");
3780     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3781     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3782     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3783     ok(sz == 2, "Expected 2, got %d\n", sz);
3784
3785     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3786     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3787
3788     /* Assignment value exists */
3789     sz = MAX_PATH;
3790     lstrcpyA(buf, "apple");
3791     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3792     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3793     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3794     ok(sz == 0, "Expected 0, got %d\n", sz);
3795
3796     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3797                          (const BYTE *)&val, sizeof(DWORD));
3798     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3799
3800     /* Assignment type is REG_DWORD */
3801     sz = MAX_PATH;
3802     lstrcpyA(buf, "apple");
3803     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3805     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3806     ok(sz == 0, "Expected 0, got %d\n", sz);
3807
3808     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3809     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3810
3811     /* Assignment value exists */
3812     sz = MAX_PATH;
3813     lstrcpyA(buf, "apple");
3814     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3815     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3816     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3817     ok(sz == 2, "Expected 2, got %d\n", sz);
3818
3819     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3820                          (const BYTE *)&val, sizeof(DWORD));
3821     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3822
3823     /* Assignment type is REG_DWORD */
3824     sz = MAX_PATH;
3825     lstrcpyA(buf, "apple");
3826     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3827     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3828     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3829     ok(sz == 2, "Expected 2, got %d\n", sz);
3830
3831     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3832     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3833
3834     /* PackageCode value exists */
3835     sz = MAX_PATH;
3836     lstrcpyA(buf, "apple");
3837     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3838     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3839     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3840     ok(sz == 0, "Expected 0, got %d\n", sz);
3841
3842     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3843                          (const BYTE *)&val, sizeof(DWORD));
3844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3845
3846     /* PackageCode type is REG_DWORD */
3847     sz = MAX_PATH;
3848     lstrcpyA(buf, "apple");
3849     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3850     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3851     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3852     ok(sz == 0, "Expected 0, got %d\n", sz);
3853
3854     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3855     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3856
3857     /* PackageCode value exists */
3858     sz = MAX_PATH;
3859     lstrcpyA(buf, "apple");
3860     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3861     ok(r == ERROR_BAD_CONFIGURATION,
3862        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3863     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3864     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3865
3866     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3867                          (const BYTE *)&val, sizeof(DWORD));
3868     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3869
3870     /* PackageCode type is REG_DWORD */
3871     sz = MAX_PATH;
3872     lstrcpyA(buf, "apple");
3873     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3875     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3876     ok(sz == 2, "Expected 2, got %d\n", sz);
3877
3878     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3880
3881     /* PackageCode value exists */
3882     sz = MAX_PATH;
3883     lstrcpyA(buf, "apple");
3884     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3885     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3886     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3887     ok(sz == 38, "Expected 38, got %d\n", sz);
3888
3889     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3891
3892     /* Version value exists */
3893     sz = MAX_PATH;
3894     lstrcpyA(buf, "apple");
3895     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3896     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3897     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3898     ok(sz == 0, "Expected 0, got %d\n", sz);
3899
3900     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3901                          (const BYTE *)&val, sizeof(DWORD));
3902     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3903
3904     /* Version type is REG_DWORD */
3905     sz = MAX_PATH;
3906     lstrcpyA(buf, "apple");
3907     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3908     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3909     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3910     ok(sz == 0, "Expected 0, got %d\n", sz);
3911
3912     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3913     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3914
3915     /* Version value exists */
3916     sz = MAX_PATH;
3917     lstrcpyA(buf, "apple");
3918     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3919     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3920     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3921     ok(sz == 3, "Expected 3, got %d\n", sz);
3922
3923     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3924                          (const BYTE *)&val, sizeof(DWORD));
3925     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3926
3927     /* Version type is REG_DWORD */
3928     sz = MAX_PATH;
3929     lstrcpyA(buf, "apple");
3930     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3931     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3932     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3933     ok(sz == 2, "Expected 2, got %d\n", sz);
3934
3935     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3936     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3937
3938     /* ProductIcon value exists */
3939     sz = MAX_PATH;
3940     lstrcpyA(buf, "apple");
3941     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3942     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3943     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3944     ok(sz == 0, "Expected 0, got %d\n", sz);
3945
3946     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3947                          (const BYTE *)&val, sizeof(DWORD));
3948     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3949
3950     /* ProductIcon type is REG_DWORD */
3951     sz = MAX_PATH;
3952     lstrcpyA(buf, "apple");
3953     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3954     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3955     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3956     ok(sz == 0, "Expected 0, got %d\n", sz);
3957
3958     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3959     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3960
3961     /* ProductIcon value exists */
3962     sz = MAX_PATH;
3963     lstrcpyA(buf, "apple");
3964     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3965     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3966     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3967     ok(sz == 3, "Expected 3, got %d\n", sz);
3968
3969     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3970                          (const BYTE *)&val, sizeof(DWORD));
3971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3972
3973     /* ProductIcon type is REG_DWORD */
3974     sz = MAX_PATH;
3975     lstrcpyA(buf, "apple");
3976     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3978     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3979     ok(sz == 2, "Expected 2, got %d\n", sz);
3980
3981     /* SourceList key does not exist */
3982     sz = MAX_PATH;
3983     lstrcpyA(buf, "apple");
3984     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3985     ok(r == ERROR_UNKNOWN_PRODUCT,
3986        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3987     ok(!lstrcmpA(buf, "apple"),
3988        "Expected buf to be unchanged, got \"%s\"\n", buf);
3989     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
3990
3991     res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
3992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3993
3994     /* SourceList key exists, but PackageName val does not exist */
3995     sz = MAX_PATH;
3996     lstrcpyA(buf, "apple");
3997     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3998     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3999     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4000     ok(sz == 0, "Expected 0, got %d\n", sz);
4001
4002     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
4003     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4004
4005     /* PackageName val exists */
4006     sz = MAX_PATH;
4007     lstrcpyA(buf, "apple");
4008     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4009     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4010     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
4011     ok(sz == 8, "Expected 8, got %d\n", sz);
4012
4013     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
4014                          (const BYTE *)&val, sizeof(DWORD));
4015     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4016
4017     /* PackageName type is REG_DWORD */
4018     sz = MAX_PATH;
4019     lstrcpyA(buf, "apple");
4020     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4021     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4022     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4023     ok(sz == 2, "Expected 2, got %d\n", sz);
4024
4025     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4026     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4027
4028     /* Authorized value exists */
4029     sz = MAX_PATH;
4030     lstrcpyA(buf, "apple");
4031     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4032     if (r != ERROR_UNKNOWN_PROPERTY)
4033     {
4034         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4035         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4036         ok(sz == 0, "Expected 0, got %d\n", sz);
4037     }
4038
4039     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
4040                          (const BYTE *)&val, sizeof(DWORD));
4041     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4042
4043     /* AuthorizedLUAApp type is REG_DWORD */
4044     sz = MAX_PATH;
4045     lstrcpyA(buf, "apple");
4046     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4047     if (r != ERROR_UNKNOWN_PROPERTY)
4048     {
4049         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4050         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4051         ok(sz == 0, "Expected 0, got %d\n", sz);
4052     }
4053
4054     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4055     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4056
4057     /* Authorized value exists */
4058     sz = MAX_PATH;
4059     lstrcpyA(buf, "apple");
4060     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4061     if (r != ERROR_UNKNOWN_PROPERTY)
4062     {
4063         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4064         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4065         ok(sz == 4, "Expected 4, got %d\n", sz);
4066     }
4067
4068     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
4069                          (const BYTE *)&val, sizeof(DWORD));
4070     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4071
4072     /* AuthorizedLUAApp type is REG_DWORD */
4073     sz = MAX_PATH;
4074     lstrcpyA(buf, "apple");
4075     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4076     if (r != ERROR_UNKNOWN_PROPERTY)
4077     {
4078         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4079         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4080         ok(sz == 2, "Expected 2, got %d\n", sz);
4081     }
4082
4083     RegDeleteValueA(propkey, "HelpLink");
4084     RegDeleteValueA(propkey, "DisplayName");
4085     RegDeleteValueA(propkey, "DisplayVersion");
4086     RegDeleteValueA(propkey, "HelpTelephone");
4087     RegDeleteValueA(propkey, "InstallLocation");
4088     RegDeleteValueA(propkey, "InstallSource");
4089     RegDeleteValueA(propkey, "InstallDate");
4090     RegDeleteValueA(propkey, "Publisher");
4091     RegDeleteValueA(propkey, "LocalPackage");
4092     RegDeleteValueA(propkey, "UrlInfoAbout");
4093     RegDeleteValueA(propkey, "UrlUpdateInfo");
4094     RegDeleteValueA(propkey, "VersionMinor");
4095     RegDeleteValueA(propkey, "VersionMajor");
4096     RegDeleteValueA(propkey, "ProductID");
4097     RegDeleteValueA(propkey, "RegCompany");
4098     RegDeleteValueA(propkey, "RegOwner");
4099     RegDeleteValueA(propkey, "InstanceType");
4100     RegDeleteValueA(propkey, "Transforms");
4101     RegDeleteValueA(propkey, "Language");
4102     RegDeleteValueA(propkey, "ProductName");
4103     RegDeleteValueA(propkey, "Assignment");
4104     RegDeleteValueA(propkey, "PackageCode");
4105     RegDeleteValueA(propkey, "Version");
4106     RegDeleteValueA(propkey, "ProductIcon");
4107     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4108     delete_key(propkey, "", access & KEY_WOW64_64KEY);
4109     delete_key(localkey, "", access & KEY_WOW64_64KEY);
4110     RegDeleteValueA(prodkey, "InstanceType");
4111     RegDeleteValueA(prodkey, "Transforms");
4112     RegDeleteValueA(prodkey, "Language");
4113     RegDeleteValueA(prodkey, "ProductName");
4114     RegDeleteValueA(prodkey, "Assignment");
4115     RegDeleteValueA(prodkey, "PackageCode");
4116     RegDeleteValueA(prodkey, "Version");
4117     RegDeleteValueA(prodkey, "ProductIcon");
4118     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4119     RegDeleteValueA(source, "PackageName");
4120     delete_key(source, "", access & KEY_WOW64_64KEY);
4121     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4122     RegCloseKey(propkey);
4123     RegCloseKey(localkey);
4124     RegCloseKey(source);
4125     RegCloseKey(prodkey);
4126     LocalFree(usersid);
4127 }
4128
4129 static void test_MsiGetProductInfoEx(void)
4130 {
4131     UINT r;
4132     LONG res;
4133     HKEY propkey, userkey;
4134     HKEY prodkey, localkey;
4135     CHAR prodcode[MAX_PATH];
4136     CHAR prod_squashed[MAX_PATH];
4137     CHAR packcode[MAX_PATH];
4138     CHAR pack_squashed[MAX_PATH];
4139     CHAR buf[MAX_PATH];
4140     CHAR keypath[MAX_PATH];
4141     LPSTR usersid;
4142     DWORD sz;
4143     REGSAM access = KEY_ALL_ACCESS;
4144     BOOL wow64;
4145
4146     if (!pMsiGetProductInfoExA)
4147     {
4148         win_skip("MsiGetProductInfoExA is not available\n");
4149         return;
4150     }
4151
4152     create_test_guid(prodcode, prod_squashed);
4153     create_test_guid(packcode, pack_squashed);
4154     get_user_sid(&usersid);
4155
4156     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
4157         access |= KEY_WOW64_64KEY;
4158
4159     /* NULL szProductCode */
4160     sz = MAX_PATH;
4161     lstrcpyA(buf, "apple");
4162     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4163                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4164     ok(r == ERROR_INVALID_PARAMETER,
4165        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4166     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4167     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4168
4169     /* empty szProductCode */
4170     sz = MAX_PATH;
4171     lstrcpyA(buf, "apple");
4172     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4173                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4174     ok(r == ERROR_INVALID_PARAMETER,
4175        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4176     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4177     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4178
4179     /* garbage szProductCode */
4180     sz = MAX_PATH;
4181     lstrcpyA(buf, "apple");
4182     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4183                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4184     ok(r == ERROR_INVALID_PARAMETER,
4185        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4186     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4187     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4188
4189     /* guid without brackets */
4190     sz = MAX_PATH;
4191     lstrcpyA(buf, "apple");
4192     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
4193                               MSIINSTALLCONTEXT_USERUNMANAGED,
4194                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4195     ok(r == ERROR_INVALID_PARAMETER,
4196        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4197     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4198     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4199
4200     /* guid with brackets */
4201     sz = MAX_PATH;
4202     lstrcpyA(buf, "apple");
4203     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
4204                               MSIINSTALLCONTEXT_USERUNMANAGED,
4205                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4206     ok(r == ERROR_UNKNOWN_PRODUCT,
4207        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4208     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4209     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4210
4211     /* szValue is non-NULL while pcchValue is NULL */
4212     lstrcpyA(buf, "apple");
4213     r = pMsiGetProductInfoExA(prodcode, usersid,
4214                               MSIINSTALLCONTEXT_USERUNMANAGED,
4215                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
4216     ok(r == ERROR_INVALID_PARAMETER,
4217        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4218     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4219
4220     /* dwContext is out of range */
4221     sz = MAX_PATH;
4222     lstrcpyA(buf, "apple");
4223     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
4224                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4225     ok(r == ERROR_INVALID_PARAMETER,
4226        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4227     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4228     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4229
4230     /* szProperty is NULL */
4231     sz = MAX_PATH;
4232     lstrcpyA(buf, "apple");
4233     r = pMsiGetProductInfoExA(prodcode, usersid,
4234                               MSIINSTALLCONTEXT_USERUNMANAGED,
4235                               NULL, buf, &sz);
4236     ok(r == ERROR_INVALID_PARAMETER,
4237        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4238     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4239     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4240
4241     /* szProperty is empty */
4242     sz = MAX_PATH;
4243     lstrcpyA(buf, "apple");
4244     r = pMsiGetProductInfoExA(prodcode, usersid,
4245                               MSIINSTALLCONTEXT_USERUNMANAGED,
4246                               "", buf, &sz);
4247     ok(r == ERROR_INVALID_PARAMETER,
4248        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4249     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4250     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4251
4252     /* szProperty is not a valid property */
4253     sz = MAX_PATH;
4254     lstrcpyA(buf, "apple");
4255     r = pMsiGetProductInfoExA(prodcode, usersid,
4256                               MSIINSTALLCONTEXT_USERUNMANAGED,
4257                               "notvalid", buf, &sz);
4258     ok(r == ERROR_UNKNOWN_PRODUCT,
4259        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4260     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4261     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4262
4263     /* same length as guid, but random */
4264     sz = MAX_PATH;
4265     lstrcpyA(buf, "apple");
4266     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
4267                               MSIINSTALLCONTEXT_USERUNMANAGED,
4268                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4269     ok(r == ERROR_INVALID_PARAMETER,
4270        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4271     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4272     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4273
4274     /* MSIINSTALLCONTEXT_USERUNMANAGED */
4275
4276     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4277     lstrcatA(keypath, usersid);
4278     lstrcatA(keypath, "\\Products\\");
4279     lstrcatA(keypath, prod_squashed);
4280
4281     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4282     if (res == ERROR_ACCESS_DENIED)
4283     {
4284         skip("Not enough rights to perform tests\n");
4285         LocalFree(usersid);
4286         return;
4287     }
4288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4289
4290     /* local user product key exists */
4291     sz = MAX_PATH;
4292     lstrcpyA(buf, "apple");
4293     r = pMsiGetProductInfoExA(prodcode, usersid,
4294                               MSIINSTALLCONTEXT_USERUNMANAGED,
4295                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4296     ok(r == ERROR_UNKNOWN_PRODUCT,
4297        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4298     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4299     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4300
4301     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4303
4304     /* InstallProperties key exists */
4305     sz = MAX_PATH;
4306     lstrcpyA(buf, "apple");
4307     r = pMsiGetProductInfoExA(prodcode, usersid,
4308                               MSIINSTALLCONTEXT_USERUNMANAGED,
4309                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4310     ok(r == ERROR_UNKNOWN_PRODUCT,
4311        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4312     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4313     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4314
4315     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4317
4318     /* LocalPackage value exists */
4319     sz = MAX_PATH;
4320     lstrcpyA(buf, "apple");
4321     r = pMsiGetProductInfoExA(prodcode, usersid,
4322                               MSIINSTALLCONTEXT_USERUNMANAGED,
4323                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4324     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4325     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4326     ok(sz == 1, "Expected 1, got %d\n", sz);
4327
4328     RegDeleteValueA(propkey, "LocalPackage");
4329
4330     /* LocalPackage value must exist */
4331     sz = MAX_PATH;
4332     lstrcpyA(buf, "apple");
4333     r = pMsiGetProductInfoExA(prodcode, usersid,
4334                               MSIINSTALLCONTEXT_USERUNMANAGED,
4335                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4336     ok(r == ERROR_UNKNOWN_PRODUCT,
4337        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4338     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4339     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4340
4341     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4343
4344     /* LocalPackage exists, but HelpLink does not exist */
4345     sz = MAX_PATH;
4346     lstrcpyA(buf, "apple");
4347     r = pMsiGetProductInfoExA(prodcode, usersid,
4348                               MSIINSTALLCONTEXT_USERUNMANAGED,
4349                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4350     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4351     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4352     ok(sz == 0, "Expected 0, got %d\n", sz);
4353
4354     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4356
4357     /* HelpLink value exists */
4358     sz = MAX_PATH;
4359     lstrcpyA(buf, "apple");
4360     r = pMsiGetProductInfoExA(prodcode, usersid,
4361                               MSIINSTALLCONTEXT_USERUNMANAGED,
4362                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4364     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4365     ok(sz == 4, "Expected 4, got %d\n", sz);
4366
4367     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4369
4370     /* HelpTelephone value exists */
4371     sz = MAX_PATH;
4372     lstrcpyA(buf, "apple");
4373     r = pMsiGetProductInfoExA(prodcode, usersid,
4374                               MSIINSTALLCONTEXT_USERUNMANAGED,
4375                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4376     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4377     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4378     ok(sz == 5, "Expected 5, got %d\n", sz);
4379
4380     /* szValue and pcchValue are NULL */
4381     r = pMsiGetProductInfoExA(prodcode, usersid,
4382                               MSIINSTALLCONTEXT_USERUNMANAGED,
4383                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4384     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4385
4386     /* pcchValue is exactly 5 */
4387     sz = 5;
4388     lstrcpyA(buf, "apple");
4389     r = pMsiGetProductInfoExA(prodcode, usersid,
4390                               MSIINSTALLCONTEXT_USERUNMANAGED,
4391                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4392     ok(r == ERROR_MORE_DATA,
4393        "Expected ERROR_MORE_DATA, got %d\n", r);
4394     ok(sz == 10, "Expected 10, got %d\n", sz);
4395
4396     /* szValue is NULL, pcchValue is exactly 5 */
4397     sz = 5;
4398     r = pMsiGetProductInfoExA(prodcode, usersid,
4399                               MSIINSTALLCONTEXT_USERUNMANAGED,
4400                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4401     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4402     ok(sz == 10, "Expected 10, got %d\n", sz);
4403
4404     /* szValue is NULL, pcchValue is MAX_PATH */
4405     sz = MAX_PATH;
4406     r = pMsiGetProductInfoExA(prodcode, usersid,
4407                               MSIINSTALLCONTEXT_USERUNMANAGED,
4408                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4410     ok(sz == 10, "Expected 10, got %d\n", sz);
4411
4412     /* pcchValue is exactly 0 */
4413     sz = 0;
4414     lstrcpyA(buf, "apple");
4415     r = pMsiGetProductInfoExA(prodcode, usersid,
4416                               MSIINSTALLCONTEXT_USERUNMANAGED,
4417                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4418     ok(r == ERROR_MORE_DATA,
4419        "Expected ERROR_MORE_DATA, got %d\n", r);
4420     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4421     ok(sz == 10, "Expected 10, got %d\n", sz);
4422
4423     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4424     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4425
4426     /* szProperty is not a valid property */
4427     sz = MAX_PATH;
4428     lstrcpyA(buf, "apple");
4429     r = pMsiGetProductInfoExA(prodcode, usersid,
4430                               MSIINSTALLCONTEXT_USERUNMANAGED,
4431                               "notvalid", buf, &sz);
4432     ok(r == ERROR_UNKNOWN_PROPERTY,
4433        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4434     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4435     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4436
4437     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4439
4440     /* InstallDate value exists */
4441     sz = MAX_PATH;
4442     lstrcpyA(buf, "apple");
4443     r = pMsiGetProductInfoExA(prodcode, usersid,
4444                               MSIINSTALLCONTEXT_USERUNMANAGED,
4445                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4446     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4447     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4448     ok(sz == 4, "Expected 4, got %d\n", sz);
4449
4450     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4451     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4452
4453     /* DisplayName value exists */
4454     sz = MAX_PATH;
4455     lstrcpyA(buf, "apple");
4456     r = pMsiGetProductInfoExA(prodcode, usersid,
4457                               MSIINSTALLCONTEXT_USERUNMANAGED,
4458                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4459     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4460     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4461     ok(sz == 4, "Expected 4, got %d\n", sz);
4462
4463     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4464     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4465
4466     /* InstallLocation value exists */
4467     sz = MAX_PATH;
4468     lstrcpyA(buf, "apple");
4469     r = pMsiGetProductInfoExA(prodcode, usersid,
4470                               MSIINSTALLCONTEXT_USERUNMANAGED,
4471                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4472     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4473     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4474     ok(sz == 3, "Expected 3, got %d\n", sz);
4475
4476     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4477     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4478
4479     /* InstallSource value exists */
4480     sz = MAX_PATH;
4481     lstrcpyA(buf, "apple");
4482     r = pMsiGetProductInfoExA(prodcode, usersid,
4483                               MSIINSTALLCONTEXT_USERUNMANAGED,
4484                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4485     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4486     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4487     ok(sz == 6, "Expected 6, got %d\n", sz);
4488
4489     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4490     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4491
4492     /* LocalPackage value exists */
4493     sz = MAX_PATH;
4494     lstrcpyA(buf, "apple");
4495     r = pMsiGetProductInfoExA(prodcode, usersid,
4496                               MSIINSTALLCONTEXT_USERUNMANAGED,
4497                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4498     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4499     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4500     ok(sz == 5, "Expected 5, got %d\n", sz);
4501
4502     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4504
4505     /* Publisher value exists */
4506     sz = MAX_PATH;
4507     lstrcpyA(buf, "apple");
4508     r = pMsiGetProductInfoExA(prodcode, usersid,
4509                               MSIINSTALLCONTEXT_USERUNMANAGED,
4510                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4511     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4512     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4513     ok(sz == 3, "Expected 3, got %d\n", sz);
4514
4515     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4516     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4517
4518     /* URLInfoAbout value exists */
4519     sz = MAX_PATH;
4520     lstrcpyA(buf, "apple");
4521     r = pMsiGetProductInfoExA(prodcode, usersid,
4522                               MSIINSTALLCONTEXT_USERUNMANAGED,
4523                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4524     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4525     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4526     ok(sz == 5, "Expected 5, got %d\n", sz);
4527
4528     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4530
4531     /* URLUpdateInfo value exists */
4532     sz = MAX_PATH;
4533     lstrcpyA(buf, "apple");
4534     r = pMsiGetProductInfoExA(prodcode, usersid,
4535                               MSIINSTALLCONTEXT_USERUNMANAGED,
4536                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4537     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4538     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4539     ok(sz == 6, "Expected 6, got %d\n", sz);
4540
4541     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4543
4544     /* VersionMinor value exists */
4545     sz = MAX_PATH;
4546     lstrcpyA(buf, "apple");
4547     r = pMsiGetProductInfoExA(prodcode, usersid,
4548                               MSIINSTALLCONTEXT_USERUNMANAGED,
4549                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4551     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4552     ok(sz == 1, "Expected 1, got %d\n", sz);
4553
4554     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4555     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4556
4557     /* VersionMajor value exists */
4558     sz = MAX_PATH;
4559     lstrcpyA(buf, "apple");
4560     r = pMsiGetProductInfoExA(prodcode, usersid,
4561                               MSIINSTALLCONTEXT_USERUNMANAGED,
4562                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4563     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4564     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4565     ok(sz == 1, "Expected 1, got %d\n", sz);
4566
4567     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4569
4570     /* DisplayVersion value exists */
4571     sz = MAX_PATH;
4572     lstrcpyA(buf, "apple");
4573     r = pMsiGetProductInfoExA(prodcode, usersid,
4574                               MSIINSTALLCONTEXT_USERUNMANAGED,
4575                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4576     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4577     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4578     ok(sz == 5, "Expected 5, got %d\n", sz);
4579
4580     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4581     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4582
4583     /* ProductID value exists */
4584     sz = MAX_PATH;
4585     lstrcpyA(buf, "apple");
4586     r = pMsiGetProductInfoExA(prodcode, usersid,
4587                               MSIINSTALLCONTEXT_USERUNMANAGED,
4588                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4589     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4590     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4591     ok(sz == 2, "Expected 2, got %d\n", sz);
4592
4593     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4594     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4595
4596     /* RegCompany value exists */
4597     sz = MAX_PATH;
4598     lstrcpyA(buf, "apple");
4599     r = pMsiGetProductInfoExA(prodcode, usersid,
4600                               MSIINSTALLCONTEXT_USERUNMANAGED,
4601                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4602     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4603     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4604     ok(sz == 4, "Expected 4, got %d\n", sz);
4605
4606     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4608
4609     /* RegOwner value exists */
4610     sz = MAX_PATH;
4611     lstrcpyA(buf, "apple");
4612     r = pMsiGetProductInfoExA(prodcode, usersid,
4613                               MSIINSTALLCONTEXT_USERUNMANAGED,
4614                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4615     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4616     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4617     ok(sz == 5, "Expected 5, got %d\n", sz);
4618
4619     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4620     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4621
4622     /* Transforms value exists */
4623     sz = MAX_PATH;
4624     lstrcpyA(buf, "apple");
4625     r = pMsiGetProductInfoExA(prodcode, usersid,
4626                               MSIINSTALLCONTEXT_USERUNMANAGED,
4627                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4628     ok(r == ERROR_UNKNOWN_PRODUCT,
4629        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4630     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4631     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4632
4633     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4635
4636     /* Language value exists */
4637     sz = MAX_PATH;
4638     lstrcpyA(buf, "apple");
4639     r = pMsiGetProductInfoExA(prodcode, usersid,
4640                               MSIINSTALLCONTEXT_USERUNMANAGED,
4641                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4642     ok(r == ERROR_UNKNOWN_PRODUCT,
4643        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4644     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4645     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4646
4647     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4648     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4649
4650     /* ProductName value exists */
4651     sz = MAX_PATH;
4652     lstrcpyA(buf, "apple");
4653     r = pMsiGetProductInfoExA(prodcode, usersid,
4654                               MSIINSTALLCONTEXT_USERUNMANAGED,
4655                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4656     ok(r == ERROR_UNKNOWN_PRODUCT,
4657        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4658     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4659     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4660
4661     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4662     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4663
4664     /* FIXME */
4665
4666     /* AssignmentType value exists */
4667     sz = MAX_PATH;
4668     lstrcpyA(buf, "apple");
4669     r = pMsiGetProductInfoExA(prodcode, usersid,
4670                               MSIINSTALLCONTEXT_USERUNMANAGED,
4671                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4672     ok(r == ERROR_UNKNOWN_PRODUCT,
4673        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4674     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4675     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4676
4677     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4678     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4679
4680     /* PackageCode value exists */
4681     sz = MAX_PATH;
4682     lstrcpyA(buf, "apple");
4683     r = pMsiGetProductInfoExA(prodcode, usersid,
4684                               MSIINSTALLCONTEXT_USERUNMANAGED,
4685                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4686     ok(r == ERROR_UNKNOWN_PRODUCT,
4687        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4688     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4689     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4690
4691     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4692     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4693
4694     /* Version value exists */
4695     sz = MAX_PATH;
4696     lstrcpyA(buf, "apple");
4697     r = pMsiGetProductInfoExA(prodcode, usersid,
4698                               MSIINSTALLCONTEXT_USERUNMANAGED,
4699                               INSTALLPROPERTY_VERSION, buf, &sz);
4700     ok(r == ERROR_UNKNOWN_PRODUCT,
4701        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4702     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4703     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4704
4705     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4706     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4707
4708     /* ProductIcon value exists */
4709     sz = MAX_PATH;
4710     lstrcpyA(buf, "apple");
4711     r = pMsiGetProductInfoExA(prodcode, usersid,
4712                               MSIINSTALLCONTEXT_USERUNMANAGED,
4713                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4714     ok(r == ERROR_UNKNOWN_PRODUCT,
4715        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4716     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4717     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4718
4719     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4721
4722     /* PackageName value exists */
4723     sz = MAX_PATH;
4724     lstrcpyA(buf, "apple");
4725     r = pMsiGetProductInfoExA(prodcode, usersid,
4726                               MSIINSTALLCONTEXT_USERUNMANAGED,
4727                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4728     ok(r == ERROR_UNKNOWN_PRODUCT,
4729        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4730     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4731     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4732
4733     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4735
4736     /* AuthorizedLUAApp value exists */
4737     sz = MAX_PATH;
4738     lstrcpyA(buf, "apple");
4739     r = pMsiGetProductInfoExA(prodcode, usersid,
4740                               MSIINSTALLCONTEXT_USERUNMANAGED,
4741                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4742     ok(r == ERROR_UNKNOWN_PRODUCT,
4743        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4744     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4745     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4746
4747     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4748     RegDeleteValueA(propkey, "PackageName");
4749     RegDeleteValueA(propkey, "ProductIcon");
4750     RegDeleteValueA(propkey, "Version");
4751     RegDeleteValueA(propkey, "PackageCode");
4752     RegDeleteValueA(propkey, "AssignmentType");
4753     RegDeleteValueA(propkey, "ProductName");
4754     RegDeleteValueA(propkey, "Language");
4755     RegDeleteValueA(propkey, "Transforms");
4756     RegDeleteValueA(propkey, "RegOwner");
4757     RegDeleteValueA(propkey, "RegCompany");
4758     RegDeleteValueA(propkey, "ProductID");
4759     RegDeleteValueA(propkey, "DisplayVersion");
4760     RegDeleteValueA(propkey, "VersionMajor");
4761     RegDeleteValueA(propkey, "VersionMinor");
4762     RegDeleteValueA(propkey, "URLUpdateInfo");
4763     RegDeleteValueA(propkey, "URLInfoAbout");
4764     RegDeleteValueA(propkey, "Publisher");
4765     RegDeleteValueA(propkey, "LocalPackage");
4766     RegDeleteValueA(propkey, "InstallSource");
4767     RegDeleteValueA(propkey, "InstallLocation");
4768     RegDeleteValueA(propkey, "DisplayName");
4769     RegDeleteValueA(propkey, "InstallDate");
4770     RegDeleteValueA(propkey, "HelpTelephone");
4771     RegDeleteValueA(propkey, "HelpLink");
4772     RegDeleteValueA(propkey, "LocalPackage");
4773     RegDeleteKeyA(propkey, "");
4774     RegCloseKey(propkey);
4775     RegDeleteKeyA(localkey, "");
4776     RegCloseKey(localkey);
4777
4778     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4779     lstrcatA(keypath, usersid);
4780     lstrcatA(keypath, "\\Installer\\Products\\");
4781     lstrcatA(keypath, prod_squashed);
4782
4783     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
4784     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4785
4786     /* user product key exists */
4787     sz = MAX_PATH;
4788     lstrcpyA(buf, "apple");
4789     r = pMsiGetProductInfoExA(prodcode, usersid,
4790                               MSIINSTALLCONTEXT_USERUNMANAGED,
4791                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4792     ok(r == ERROR_UNKNOWN_PRODUCT,
4793        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4794     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4795     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4796
4797     RegDeleteKeyA(userkey, "");
4798     RegCloseKey(userkey);
4799
4800     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4801     lstrcatA(keypath, prod_squashed);
4802
4803     res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4804     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4805
4806     sz = MAX_PATH;
4807     lstrcpyA(buf, "apple");
4808     r = pMsiGetProductInfoExA(prodcode, usersid,
4809                               MSIINSTALLCONTEXT_USERUNMANAGED,
4810                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4811     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4812     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4813     ok(sz == 1, "Expected 1, got %d\n", sz);
4814
4815     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4816     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4817
4818     /* HelpLink value exists */
4819     sz = MAX_PATH;
4820     lstrcpyA(buf, "apple");
4821     r = pMsiGetProductInfoExA(prodcode, usersid,
4822                               MSIINSTALLCONTEXT_USERUNMANAGED,
4823                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4824     ok(r == ERROR_UNKNOWN_PROPERTY,
4825        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4826     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4827     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4828
4829     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4830     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4831
4832     /* HelpTelephone value exists */
4833     sz = MAX_PATH;
4834     lstrcpyA(buf, "apple");
4835     r = pMsiGetProductInfoExA(prodcode, usersid,
4836                               MSIINSTALLCONTEXT_USERUNMANAGED,
4837                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4838     ok(r == ERROR_UNKNOWN_PROPERTY,
4839        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4840     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4841     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4842
4843     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4845
4846     /* InstallDate value exists */
4847     sz = MAX_PATH;
4848     lstrcpyA(buf, "apple");
4849     r = pMsiGetProductInfoExA(prodcode, usersid,
4850                               MSIINSTALLCONTEXT_USERUNMANAGED,
4851                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4852     ok(r == ERROR_UNKNOWN_PROPERTY,
4853        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4854     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4855     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4856
4857     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4858     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4859
4860     /* DisplayName value exists */
4861     sz = MAX_PATH;
4862     lstrcpyA(buf, "apple");
4863     r = pMsiGetProductInfoExA(prodcode, usersid,
4864                               MSIINSTALLCONTEXT_USERUNMANAGED,
4865                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4866     ok(r == ERROR_UNKNOWN_PROPERTY,
4867        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4868     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4869     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4870
4871     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4872     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4873
4874     /* InstallLocation value exists */
4875     sz = MAX_PATH;
4876     lstrcpyA(buf, "apple");
4877     r = pMsiGetProductInfoExA(prodcode, usersid,
4878                               MSIINSTALLCONTEXT_USERUNMANAGED,
4879                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4880     ok(r == ERROR_UNKNOWN_PROPERTY,
4881        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4882     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4883     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4884
4885     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4887
4888     /* InstallSource value exists */
4889     sz = MAX_PATH;
4890     lstrcpyA(buf, "apple");
4891     r = pMsiGetProductInfoExA(prodcode, usersid,
4892                               MSIINSTALLCONTEXT_USERUNMANAGED,
4893                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4894     ok(r == ERROR_UNKNOWN_PROPERTY,
4895        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4896     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4897     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4898
4899     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4900     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4901
4902     /* LocalPackage value exists */
4903     sz = MAX_PATH;
4904     lstrcpyA(buf, "apple");
4905     r = pMsiGetProductInfoExA(prodcode, usersid,
4906                               MSIINSTALLCONTEXT_USERUNMANAGED,
4907                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4908     ok(r == ERROR_UNKNOWN_PROPERTY,
4909        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4910     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4911     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4912
4913     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4915
4916     /* Publisher value exists */
4917     sz = MAX_PATH;
4918     lstrcpyA(buf, "apple");
4919     r = pMsiGetProductInfoExA(prodcode, usersid,
4920                               MSIINSTALLCONTEXT_USERUNMANAGED,
4921                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4922     ok(r == ERROR_UNKNOWN_PROPERTY,
4923        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4924     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4925     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4926
4927     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4929
4930     /* URLInfoAbout value exists */
4931     sz = MAX_PATH;
4932     lstrcpyA(buf, "apple");
4933     r = pMsiGetProductInfoExA(prodcode, usersid,
4934                               MSIINSTALLCONTEXT_USERUNMANAGED,
4935                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4936     ok(r == ERROR_UNKNOWN_PROPERTY,
4937        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4938     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4939     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4940
4941     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4943
4944     /* URLUpdateInfo value exists */
4945     sz = MAX_PATH;
4946     lstrcpyA(buf, "apple");
4947     r = pMsiGetProductInfoExA(prodcode, usersid,
4948                               MSIINSTALLCONTEXT_USERUNMANAGED,
4949                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4950     ok(r == ERROR_UNKNOWN_PROPERTY,
4951        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4952     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4953     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4954
4955     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4957
4958     /* VersionMinor value exists */
4959     sz = MAX_PATH;
4960     lstrcpyA(buf, "apple");
4961     r = pMsiGetProductInfoExA(prodcode, usersid,
4962                               MSIINSTALLCONTEXT_USERUNMANAGED,
4963                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4964     ok(r == ERROR_UNKNOWN_PROPERTY,
4965        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4966     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4967     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4968
4969     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4970     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4971
4972     /* VersionMajor value exists */
4973     sz = MAX_PATH;
4974     lstrcpyA(buf, "apple");
4975     r = pMsiGetProductInfoExA(prodcode, usersid,
4976                               MSIINSTALLCONTEXT_USERUNMANAGED,
4977                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4978     ok(r == ERROR_UNKNOWN_PROPERTY,
4979        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4980     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4981     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4982
4983     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4984     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4985
4986     /* DisplayVersion value exists */
4987     sz = MAX_PATH;
4988     lstrcpyA(buf, "apple");
4989     r = pMsiGetProductInfoExA(prodcode, usersid,
4990                               MSIINSTALLCONTEXT_USERUNMANAGED,
4991                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4992     ok(r == ERROR_UNKNOWN_PROPERTY,
4993        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4994     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4995     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4996
4997     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4999
5000     /* ProductID value exists */
5001     sz = MAX_PATH;
5002     lstrcpyA(buf, "apple");
5003     r = pMsiGetProductInfoExA(prodcode, usersid,
5004                               MSIINSTALLCONTEXT_USERUNMANAGED,
5005                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5006     ok(r == ERROR_UNKNOWN_PROPERTY,
5007        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5008     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5009     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5010
5011     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5012     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5013
5014     /* RegCompany value exists */
5015     sz = MAX_PATH;
5016     lstrcpyA(buf, "apple");
5017     r = pMsiGetProductInfoExA(prodcode, usersid,
5018                               MSIINSTALLCONTEXT_USERUNMANAGED,
5019                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5020     ok(r == ERROR_UNKNOWN_PROPERTY,
5021        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5022     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5023     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5024
5025     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5026     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5027
5028     /* RegOwner value exists */
5029     sz = MAX_PATH;
5030     lstrcpyA(buf, "apple");
5031     r = pMsiGetProductInfoExA(prodcode, usersid,
5032                               MSIINSTALLCONTEXT_USERUNMANAGED,
5033                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5034     ok(r == ERROR_UNKNOWN_PROPERTY,
5035        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5036     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5037     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5038
5039     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5040     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5041
5042     /* Transforms value exists */
5043     sz = MAX_PATH;
5044     lstrcpyA(buf, "apple");
5045     r = pMsiGetProductInfoExA(prodcode, usersid,
5046                               MSIINSTALLCONTEXT_USERUNMANAGED,
5047                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5048     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5049     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5050     ok(sz == 5, "Expected 5, got %d\n", sz);
5051
5052     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5054
5055     /* Language value exists */
5056     sz = MAX_PATH;
5057     lstrcpyA(buf, "apple");
5058     r = pMsiGetProductInfoExA(prodcode, usersid,
5059                               MSIINSTALLCONTEXT_USERUNMANAGED,
5060                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5062     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5063     ok(sz == 4, "Expected 4, got %d\n", sz);
5064
5065     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5067
5068     /* ProductName value exists */
5069     sz = MAX_PATH;
5070     lstrcpyA(buf, "apple");
5071     r = pMsiGetProductInfoExA(prodcode, usersid,
5072                               MSIINSTALLCONTEXT_USERUNMANAGED,
5073                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5074     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5075     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5076     ok(sz == 4, "Expected 4, got %d\n", sz);
5077
5078     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5080
5081     /* FIXME */
5082
5083     /* AssignmentType value exists */
5084     sz = MAX_PATH;
5085     lstrcpyA(buf, "apple");
5086     r = pMsiGetProductInfoExA(prodcode, usersid,
5087                               MSIINSTALLCONTEXT_USERUNMANAGED,
5088                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5090     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5091     ok(sz == 0, "Expected 0, got %d\n", sz);
5092
5093     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5094     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5095
5096     /* FIXME */
5097
5098     /* PackageCode value exists */
5099     sz = MAX_PATH;
5100     lstrcpyA(buf, "apple");
5101     r = pMsiGetProductInfoExA(prodcode, usersid,
5102                               MSIINSTALLCONTEXT_USERUNMANAGED,
5103                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5104     todo_wine
5105     {
5106         ok(r == ERROR_BAD_CONFIGURATION,
5107            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5108         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5109         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5110     }
5111
5112     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5113     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5114
5115     /* Version value exists */
5116     sz = MAX_PATH;
5117     lstrcpyA(buf, "apple");
5118     r = pMsiGetProductInfoExA(prodcode, usersid,
5119                               MSIINSTALLCONTEXT_USERUNMANAGED,
5120                               INSTALLPROPERTY_VERSION, buf, &sz);
5121     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5122     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5123     ok(sz == 3, "Expected 3, got %d\n", sz);
5124
5125     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5126     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5127
5128     /* ProductIcon value exists */
5129     sz = MAX_PATH;
5130     lstrcpyA(buf, "apple");
5131     r = pMsiGetProductInfoExA(prodcode, usersid,
5132                               MSIINSTALLCONTEXT_USERUNMANAGED,
5133                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5134     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5135     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5136     ok(sz == 4, "Expected 4, got %d\n", sz);
5137
5138     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5140
5141     /* PackageName value exists */
5142     sz = MAX_PATH;
5143     lstrcpyA(buf, "apple");
5144     r = pMsiGetProductInfoExA(prodcode, usersid,
5145                               MSIINSTALLCONTEXT_USERUNMANAGED,
5146                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5147     todo_wine
5148     {
5149         ok(r == ERROR_UNKNOWN_PRODUCT,
5150            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5151         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5152         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5153     }
5154
5155     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5156     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5157
5158     /* AuthorizedLUAApp value exists */
5159     sz = MAX_PATH;
5160     lstrcpyA(buf, "apple");
5161     r = pMsiGetProductInfoExA(prodcode, usersid,
5162                               MSIINSTALLCONTEXT_USERUNMANAGED,
5163                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5165     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5166     ok(sz == 4, "Expected 4, got %d\n", sz);
5167
5168     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5169     RegDeleteValueA(prodkey, "PackageName");
5170     RegDeleteValueA(prodkey, "ProductIcon");
5171     RegDeleteValueA(prodkey, "Version");
5172     RegDeleteValueA(prodkey, "PackageCode");
5173     RegDeleteValueA(prodkey, "AssignmentType");
5174     RegDeleteValueA(prodkey, "ProductName");
5175     RegDeleteValueA(prodkey, "Language");
5176     RegDeleteValueA(prodkey, "Transforms");
5177     RegDeleteValueA(prodkey, "RegOwner");
5178     RegDeleteValueA(prodkey, "RegCompany");
5179     RegDeleteValueA(prodkey, "ProductID");
5180     RegDeleteValueA(prodkey, "DisplayVersion");
5181     RegDeleteValueA(prodkey, "VersionMajor");
5182     RegDeleteValueA(prodkey, "VersionMinor");
5183     RegDeleteValueA(prodkey, "URLUpdateInfo");
5184     RegDeleteValueA(prodkey, "URLInfoAbout");
5185     RegDeleteValueA(prodkey, "Publisher");
5186     RegDeleteValueA(prodkey, "LocalPackage");
5187     RegDeleteValueA(prodkey, "InstallSource");
5188     RegDeleteValueA(prodkey, "InstallLocation");
5189     RegDeleteValueA(prodkey, "DisplayName");
5190     RegDeleteValueA(prodkey, "InstallDate");
5191     RegDeleteValueA(prodkey, "HelpTelephone");
5192     RegDeleteValueA(prodkey, "HelpLink");
5193     RegDeleteValueA(prodkey, "LocalPackage");
5194     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5195     RegCloseKey(prodkey);
5196
5197     /* MSIINSTALLCONTEXT_USERMANAGED */
5198
5199     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5200     lstrcatA(keypath, usersid);
5201     lstrcatA(keypath, "\\Products\\");
5202     lstrcatA(keypath, prod_squashed);
5203
5204     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5205     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5206
5207     /* local user product key exists */
5208     sz = MAX_PATH;
5209     lstrcpyA(buf, "apple");
5210     r = pMsiGetProductInfoExA(prodcode, usersid,
5211                               MSIINSTALLCONTEXT_USERMANAGED,
5212                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5213     ok(r == ERROR_UNKNOWN_PRODUCT,
5214        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5215     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5216     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5217
5218     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5219     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5220
5221     /* InstallProperties key exists */
5222     sz = MAX_PATH;
5223     lstrcpyA(buf, "apple");
5224     r = pMsiGetProductInfoExA(prodcode, usersid,
5225                               MSIINSTALLCONTEXT_USERMANAGED,
5226                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5227     ok(r == ERROR_UNKNOWN_PRODUCT,
5228        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5229     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5230     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5231
5232     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5233     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5234
5235     /* ManagedLocalPackage value exists */
5236     sz = MAX_PATH;
5237     lstrcpyA(buf, "apple");
5238     r = pMsiGetProductInfoExA(prodcode, usersid,
5239                               MSIINSTALLCONTEXT_USERMANAGED,
5240                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5241     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5242     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5243     ok(sz == 1, "Expected 1, got %d\n", sz);
5244
5245     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5246     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5247
5248     /* HelpLink value exists */
5249     sz = MAX_PATH;
5250     lstrcpyA(buf, "apple");
5251     r = pMsiGetProductInfoExA(prodcode, usersid,
5252                               MSIINSTALLCONTEXT_USERMANAGED,
5253                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5254     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5255     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5256     ok(sz == 4, "Expected 4, got %d\n", sz);
5257
5258     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5259     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5260
5261     /* HelpTelephone value exists */
5262     sz = MAX_PATH;
5263     lstrcpyA(buf, "apple");
5264     r = pMsiGetProductInfoExA(prodcode, usersid,
5265                               MSIINSTALLCONTEXT_USERMANAGED,
5266                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5267     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5268     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5269     ok(sz == 5, "Expected 5, got %d\n", sz);
5270
5271     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5273
5274     /* InstallDate value exists */
5275     sz = MAX_PATH;
5276     lstrcpyA(buf, "apple");
5277     r = pMsiGetProductInfoExA(prodcode, usersid,
5278                               MSIINSTALLCONTEXT_USERMANAGED,
5279                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5280     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5281     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5282     ok(sz == 4, "Expected 4, got %d\n", sz);
5283
5284     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5286
5287     /* DisplayName value exists */
5288     sz = MAX_PATH;
5289     lstrcpyA(buf, "apple");
5290     r = pMsiGetProductInfoExA(prodcode, usersid,
5291                               MSIINSTALLCONTEXT_USERMANAGED,
5292                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5293     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5294     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5295     ok(sz == 4, "Expected 4, got %d\n", sz);
5296
5297     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5298     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5299
5300     /* InstallLocation value exists */
5301     sz = MAX_PATH;
5302     lstrcpyA(buf, "apple");
5303     r = pMsiGetProductInfoExA(prodcode, usersid,
5304                               MSIINSTALLCONTEXT_USERMANAGED,
5305                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5306     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5307     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5308     ok(sz == 3, "Expected 3, got %d\n", sz);
5309
5310     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5311     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5312
5313     /* InstallSource value exists */
5314     sz = MAX_PATH;
5315     lstrcpyA(buf, "apple");
5316     r = pMsiGetProductInfoExA(prodcode, usersid,
5317                               MSIINSTALLCONTEXT_USERMANAGED,
5318                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5319     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5320     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5321     ok(sz == 6, "Expected 6, got %d\n", sz);
5322
5323     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5325
5326     /* LocalPackage value exists */
5327     sz = MAX_PATH;
5328     lstrcpyA(buf, "apple");
5329     r = pMsiGetProductInfoExA(prodcode, usersid,
5330                               MSIINSTALLCONTEXT_USERMANAGED,
5331                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5332     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5333     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5334     ok(sz == 5, "Expected 5, got %d\n", sz);
5335
5336     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5337     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5338
5339     /* Publisher value exists */
5340     sz = MAX_PATH;
5341     lstrcpyA(buf, "apple");
5342     r = pMsiGetProductInfoExA(prodcode, usersid,
5343                               MSIINSTALLCONTEXT_USERMANAGED,
5344                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5345     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5346     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5347     ok(sz == 3, "Expected 3, got %d\n", sz);
5348
5349     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5351
5352     /* URLInfoAbout value exists */
5353     sz = MAX_PATH;
5354     lstrcpyA(buf, "apple");
5355     r = pMsiGetProductInfoExA(prodcode, usersid,
5356                               MSIINSTALLCONTEXT_USERMANAGED,
5357                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5358     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5359     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5360     ok(sz == 5, "Expected 5, got %d\n", sz);
5361
5362     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5363     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5364
5365     /* URLUpdateInfo value exists */
5366     sz = MAX_PATH;
5367     lstrcpyA(buf, "apple");
5368     r = pMsiGetProductInfoExA(prodcode, usersid,
5369                               MSIINSTALLCONTEXT_USERMANAGED,
5370                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5372     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5373     ok(sz == 6, "Expected 6, got %d\n", sz);
5374
5375     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5377
5378     /* VersionMinor value exists */
5379     sz = MAX_PATH;
5380     lstrcpyA(buf, "apple");
5381     r = pMsiGetProductInfoExA(prodcode, usersid,
5382                               MSIINSTALLCONTEXT_USERMANAGED,
5383                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5384     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5385     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5386     ok(sz == 1, "Expected 1, got %d\n", sz);
5387
5388     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5389     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5390
5391     /* VersionMajor value exists */
5392     sz = MAX_PATH;
5393     lstrcpyA(buf, "apple");
5394     r = pMsiGetProductInfoExA(prodcode, usersid,
5395                               MSIINSTALLCONTEXT_USERMANAGED,
5396                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5397     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5398     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5399     ok(sz == 1, "Expected 1, got %d\n", sz);
5400
5401     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5403
5404     /* DisplayVersion value exists */
5405     sz = MAX_PATH;
5406     lstrcpyA(buf, "apple");
5407     r = pMsiGetProductInfoExA(prodcode, usersid,
5408                               MSIINSTALLCONTEXT_USERMANAGED,
5409                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5410     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5411     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5412     ok(sz == 5, "Expected 5, got %d\n", sz);
5413
5414     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5415     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5416
5417     /* ProductID value exists */
5418     sz = MAX_PATH;
5419     lstrcpyA(buf, "apple");
5420     r = pMsiGetProductInfoExA(prodcode, usersid,
5421                               MSIINSTALLCONTEXT_USERMANAGED,
5422                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5423     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5424     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5425     ok(sz == 2, "Expected 2, got %d\n", sz);
5426
5427     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5428     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5429
5430     /* RegCompany value exists */
5431     sz = MAX_PATH;
5432     lstrcpyA(buf, "apple");
5433     r = pMsiGetProductInfoExA(prodcode, usersid,
5434                               MSIINSTALLCONTEXT_USERMANAGED,
5435                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5436     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5437     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5438     ok(sz == 4, "Expected 4, got %d\n", sz);
5439
5440     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5441     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5442
5443     /* RegOwner value exists */
5444     sz = MAX_PATH;
5445     lstrcpyA(buf, "apple");
5446     r = pMsiGetProductInfoExA(prodcode, usersid,
5447                               MSIINSTALLCONTEXT_USERMANAGED,
5448                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5449     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5450     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5451     ok(sz == 5, "Expected 5, got %d\n", sz);
5452
5453     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5454     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5455
5456     /* Transforms value exists */
5457     sz = MAX_PATH;
5458     lstrcpyA(buf, "apple");
5459     r = pMsiGetProductInfoExA(prodcode, usersid,
5460                               MSIINSTALLCONTEXT_USERMANAGED,
5461                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5462     ok(r == ERROR_UNKNOWN_PRODUCT,
5463        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5464     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5465     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5466
5467     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5468     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5469
5470     /* Language value exists */
5471     sz = MAX_PATH;
5472     lstrcpyA(buf, "apple");
5473     r = pMsiGetProductInfoExA(prodcode, usersid,
5474                               MSIINSTALLCONTEXT_USERMANAGED,
5475                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5476     ok(r == ERROR_UNKNOWN_PRODUCT,
5477        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5478     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5479     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5480
5481     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5482     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5483
5484     /* ProductName value exists */
5485     sz = MAX_PATH;
5486     lstrcpyA(buf, "apple");
5487     r = pMsiGetProductInfoExA(prodcode, usersid,
5488                               MSIINSTALLCONTEXT_USERMANAGED,
5489                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5490     ok(r == ERROR_UNKNOWN_PRODUCT,
5491        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5492     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5493     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5494
5495     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5496     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5497
5498     /* FIXME */
5499
5500     /* AssignmentType value exists */
5501     sz = MAX_PATH;
5502     lstrcpyA(buf, "apple");
5503     r = pMsiGetProductInfoExA(prodcode, usersid,
5504                               MSIINSTALLCONTEXT_USERMANAGED,
5505                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5506     ok(r == ERROR_UNKNOWN_PRODUCT,
5507        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5508     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5509     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5510
5511     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5513
5514     /* PackageCode value exists */
5515     sz = MAX_PATH;
5516     lstrcpyA(buf, "apple");
5517     r = pMsiGetProductInfoExA(prodcode, usersid,
5518                               MSIINSTALLCONTEXT_USERMANAGED,
5519                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5520     ok(r == ERROR_UNKNOWN_PRODUCT,
5521        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5522     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5523     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5524
5525     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5527
5528     /* Version value exists */
5529     sz = MAX_PATH;
5530     lstrcpyA(buf, "apple");
5531     r = pMsiGetProductInfoExA(prodcode, usersid,
5532                               MSIINSTALLCONTEXT_USERMANAGED,
5533                               INSTALLPROPERTY_VERSION, buf, &sz);
5534     ok(r == ERROR_UNKNOWN_PRODUCT,
5535        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5536     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5537     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5538
5539     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5541
5542     /* ProductIcon value exists */
5543     sz = MAX_PATH;
5544     lstrcpyA(buf, "apple");
5545     r = pMsiGetProductInfoExA(prodcode, usersid,
5546                               MSIINSTALLCONTEXT_USERMANAGED,
5547                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5548     ok(r == ERROR_UNKNOWN_PRODUCT,
5549        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5550     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5551     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5552
5553     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5555
5556     /* PackageName value exists */
5557     sz = MAX_PATH;
5558     lstrcpyA(buf, "apple");
5559     r = pMsiGetProductInfoExA(prodcode, usersid,
5560                               MSIINSTALLCONTEXT_USERMANAGED,
5561                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5562     ok(r == ERROR_UNKNOWN_PRODUCT,
5563        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5564     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5565     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5566
5567     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5569
5570     /* AuthorizedLUAApp value exists */
5571     sz = MAX_PATH;
5572     lstrcpyA(buf, "apple");
5573     r = pMsiGetProductInfoExA(prodcode, usersid,
5574                               MSIINSTALLCONTEXT_USERMANAGED,
5575                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5576     ok(r == ERROR_UNKNOWN_PRODUCT,
5577        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5578     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5579     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5580
5581     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5582     RegDeleteValueA(propkey, "PackageName");
5583     RegDeleteValueA(propkey, "ProductIcon");
5584     RegDeleteValueA(propkey, "Version");
5585     RegDeleteValueA(propkey, "PackageCode");
5586     RegDeleteValueA(propkey, "AssignmentType");
5587     RegDeleteValueA(propkey, "ProductName");
5588     RegDeleteValueA(propkey, "Language");
5589     RegDeleteValueA(propkey, "Transforms");
5590     RegDeleteValueA(propkey, "RegOwner");
5591     RegDeleteValueA(propkey, "RegCompany");
5592     RegDeleteValueA(propkey, "ProductID");
5593     RegDeleteValueA(propkey, "DisplayVersion");
5594     RegDeleteValueA(propkey, "VersionMajor");
5595     RegDeleteValueA(propkey, "VersionMinor");
5596     RegDeleteValueA(propkey, "URLUpdateInfo");
5597     RegDeleteValueA(propkey, "URLInfoAbout");
5598     RegDeleteValueA(propkey, "Publisher");
5599     RegDeleteValueA(propkey, "LocalPackage");
5600     RegDeleteValueA(propkey, "InstallSource");
5601     RegDeleteValueA(propkey, "InstallLocation");
5602     RegDeleteValueA(propkey, "DisplayName");
5603     RegDeleteValueA(propkey, "InstallDate");
5604     RegDeleteValueA(propkey, "HelpTelephone");
5605     RegDeleteValueA(propkey, "HelpLink");
5606     RegDeleteValueA(propkey, "ManagedLocalPackage");
5607     delete_key(propkey, "", access & KEY_WOW64_64KEY);
5608     RegCloseKey(propkey);
5609     delete_key(localkey, "", access & KEY_WOW64_64KEY);
5610     RegCloseKey(localkey);
5611
5612     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5613     lstrcatA(keypath, usersid);
5614     lstrcatA(keypath, "\\Installer\\Products\\");
5615     lstrcatA(keypath, prod_squashed);
5616
5617     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5619
5620     /* user product key exists */
5621     sz = MAX_PATH;
5622     lstrcpyA(buf, "apple");
5623     r = pMsiGetProductInfoExA(prodcode, usersid,
5624                               MSIINSTALLCONTEXT_USERMANAGED,
5625                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5626     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5627     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5628     ok(sz == 1, "Expected 1, got %d\n", sz);
5629
5630     delete_key(userkey, "", access & KEY_WOW64_64KEY);
5631     RegCloseKey(userkey);
5632
5633     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5634     lstrcatA(keypath, prod_squashed);
5635
5636     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5637     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5638
5639     /* current user product key exists */
5640     sz = MAX_PATH;
5641     lstrcpyA(buf, "apple");
5642     r = pMsiGetProductInfoExA(prodcode, usersid,
5643                               MSIINSTALLCONTEXT_USERMANAGED,
5644                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5645     ok(r == ERROR_UNKNOWN_PRODUCT,
5646        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5647     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5648     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5649
5650     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5651     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5652
5653     /* HelpLink value exists, user product key does not exist */
5654     sz = MAX_PATH;
5655     lstrcpyA(buf, "apple");
5656     r = pMsiGetProductInfoExA(prodcode, usersid,
5657                               MSIINSTALLCONTEXT_USERMANAGED,
5658                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5659     ok(r == ERROR_UNKNOWN_PRODUCT,
5660        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5661     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5662     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5663
5664     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5665     lstrcatA(keypath, usersid);
5666     lstrcatA(keypath, "\\Installer\\Products\\");
5667     lstrcatA(keypath, prod_squashed);
5668
5669     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5670     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5671
5672     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5673     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5674
5675     /* HelpLink value exists, user product key does exist */
5676     sz = MAX_PATH;
5677     lstrcpyA(buf, "apple");
5678     r = pMsiGetProductInfoExA(prodcode, usersid,
5679                               MSIINSTALLCONTEXT_USERMANAGED,
5680                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5681     ok(r == ERROR_UNKNOWN_PROPERTY,
5682        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5683     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5684     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5685
5686     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5688
5689     /* HelpTelephone value exists */
5690     sz = MAX_PATH;
5691     lstrcpyA(buf, "apple");
5692     r = pMsiGetProductInfoExA(prodcode, usersid,
5693                               MSIINSTALLCONTEXT_USERMANAGED,
5694                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5695     ok(r == ERROR_UNKNOWN_PROPERTY,
5696        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5697     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5698     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5699
5700     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5701     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5702
5703     /* InstallDate value exists */
5704     sz = MAX_PATH;
5705     lstrcpyA(buf, "apple");
5706     r = pMsiGetProductInfoExA(prodcode, usersid,
5707                               MSIINSTALLCONTEXT_USERMANAGED,
5708                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5709     ok(r == ERROR_UNKNOWN_PROPERTY,
5710        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5711     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5712     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5713
5714     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5715     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5716
5717     /* DisplayName value exists */
5718     sz = MAX_PATH;
5719     lstrcpyA(buf, "apple");
5720     r = pMsiGetProductInfoExA(prodcode, usersid,
5721                               MSIINSTALLCONTEXT_USERMANAGED,
5722                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5723     ok(r == ERROR_UNKNOWN_PROPERTY,
5724        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5725     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5726     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5727
5728     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5729     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5730
5731     /* InstallLocation value exists */
5732     sz = MAX_PATH;
5733     lstrcpyA(buf, "apple");
5734     r = pMsiGetProductInfoExA(prodcode, usersid,
5735                               MSIINSTALLCONTEXT_USERMANAGED,
5736                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5737     ok(r == ERROR_UNKNOWN_PROPERTY,
5738        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5739     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5740     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5741
5742     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5743     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5744
5745     /* InstallSource value exists */
5746     sz = MAX_PATH;
5747     lstrcpyA(buf, "apple");
5748     r = pMsiGetProductInfoExA(prodcode, usersid,
5749                               MSIINSTALLCONTEXT_USERMANAGED,
5750                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5751     ok(r == ERROR_UNKNOWN_PROPERTY,
5752        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5753     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5754     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5755
5756     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5757     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5758
5759     /* LocalPackage value exists */
5760     sz = MAX_PATH;
5761     lstrcpyA(buf, "apple");
5762     r = pMsiGetProductInfoExA(prodcode, usersid,
5763                               MSIINSTALLCONTEXT_USERMANAGED,
5764                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5765     ok(r == ERROR_UNKNOWN_PROPERTY,
5766        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5767     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5768     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5769
5770     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5771     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5772
5773     /* Publisher value exists */
5774     sz = MAX_PATH;
5775     lstrcpyA(buf, "apple");
5776     r = pMsiGetProductInfoExA(prodcode, usersid,
5777                               MSIINSTALLCONTEXT_USERMANAGED,
5778                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5779     ok(r == ERROR_UNKNOWN_PROPERTY,
5780        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5781     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5782     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5783
5784     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5786
5787     /* URLInfoAbout value exists */
5788     sz = MAX_PATH;
5789     lstrcpyA(buf, "apple");
5790     r = pMsiGetProductInfoExA(prodcode, usersid,
5791                               MSIINSTALLCONTEXT_USERMANAGED,
5792                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5793     ok(r == ERROR_UNKNOWN_PROPERTY,
5794        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5795     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5796     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5797
5798     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5799     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5800
5801     /* URLUpdateInfo value exists */
5802     sz = MAX_PATH;
5803     lstrcpyA(buf, "apple");
5804     r = pMsiGetProductInfoExA(prodcode, usersid,
5805                               MSIINSTALLCONTEXT_USERMANAGED,
5806                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5807     ok(r == ERROR_UNKNOWN_PROPERTY,
5808        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5809     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5810     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5811
5812     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5813     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5814
5815     /* VersionMinor value exists */
5816     sz = MAX_PATH;
5817     lstrcpyA(buf, "apple");
5818     r = pMsiGetProductInfoExA(prodcode, usersid,
5819                               MSIINSTALLCONTEXT_USERMANAGED,
5820                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5821     ok(r == ERROR_UNKNOWN_PROPERTY,
5822        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5823     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5824     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5825
5826     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5827     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5828
5829     /* VersionMajor value exists */
5830     sz = MAX_PATH;
5831     lstrcpyA(buf, "apple");
5832     r = pMsiGetProductInfoExA(prodcode, usersid,
5833                               MSIINSTALLCONTEXT_USERMANAGED,
5834                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5835     ok(r == ERROR_UNKNOWN_PROPERTY,
5836        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5837     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5838     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5839
5840     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5841     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5842
5843     /* DisplayVersion value exists */
5844     sz = MAX_PATH;
5845     lstrcpyA(buf, "apple");
5846     r = pMsiGetProductInfoExA(prodcode, usersid,
5847                               MSIINSTALLCONTEXT_USERMANAGED,
5848                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5849     ok(r == ERROR_UNKNOWN_PROPERTY,
5850        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5851     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5852     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5853
5854     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5855     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5856
5857     /* ProductID value exists */
5858     sz = MAX_PATH;
5859     lstrcpyA(buf, "apple");
5860     r = pMsiGetProductInfoExA(prodcode, usersid,
5861                               MSIINSTALLCONTEXT_USERMANAGED,
5862                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5863     ok(r == ERROR_UNKNOWN_PROPERTY,
5864        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5865     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5866     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5867
5868     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5869     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5870
5871     /* RegCompany value exists */
5872     sz = MAX_PATH;
5873     lstrcpyA(buf, "apple");
5874     r = pMsiGetProductInfoExA(prodcode, usersid,
5875                               MSIINSTALLCONTEXT_USERMANAGED,
5876                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5877     ok(r == ERROR_UNKNOWN_PROPERTY,
5878        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5879     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5880     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5881
5882     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5883     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5884
5885     /* RegOwner value exists */
5886     sz = MAX_PATH;
5887     lstrcpyA(buf, "apple");
5888     r = pMsiGetProductInfoExA(prodcode, usersid,
5889                               MSIINSTALLCONTEXT_USERMANAGED,
5890                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5891     ok(r == ERROR_UNKNOWN_PROPERTY,
5892        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5893     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5894     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5895
5896     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5897     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5898
5899     /* Transforms value exists */
5900     sz = MAX_PATH;
5901     lstrcpyA(buf, "apple");
5902     r = pMsiGetProductInfoExA(prodcode, usersid,
5903                               MSIINSTALLCONTEXT_USERMANAGED,
5904                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5905     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5906     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5907     ok(sz == 5, "Expected 5, got %d\n", sz);
5908
5909     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5910     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5911
5912     /* Language value exists */
5913     sz = MAX_PATH;
5914     lstrcpyA(buf, "apple");
5915     r = pMsiGetProductInfoExA(prodcode, usersid,
5916                               MSIINSTALLCONTEXT_USERMANAGED,
5917                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5918     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5919     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5920     ok(sz == 4, "Expected 4, got %d\n", sz);
5921
5922     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5924
5925     /* ProductName value exists */
5926     sz = MAX_PATH;
5927     lstrcpyA(buf, "apple");
5928     r = pMsiGetProductInfoExA(prodcode, usersid,
5929                               MSIINSTALLCONTEXT_USERMANAGED,
5930                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5931     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5932     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5933     ok(sz == 4, "Expected 4, got %d\n", sz);
5934
5935     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5936     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5937
5938     /* FIXME */
5939
5940     /* AssignmentType value exists */
5941     sz = MAX_PATH;
5942     lstrcpyA(buf, "apple");
5943     r = pMsiGetProductInfoExA(prodcode, usersid,
5944                               MSIINSTALLCONTEXT_USERMANAGED,
5945                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5946     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5947     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5948     ok(sz == 0, "Expected 0, got %d\n", sz);
5949
5950     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5952
5953     /* FIXME */
5954
5955     /* PackageCode value exists */
5956     sz = MAX_PATH;
5957     lstrcpyA(buf, "apple");
5958     r = pMsiGetProductInfoExA(prodcode, usersid,
5959                               MSIINSTALLCONTEXT_USERMANAGED,
5960                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5961     todo_wine
5962     {
5963         ok(r == ERROR_BAD_CONFIGURATION,
5964            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5965         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5966         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5967     }
5968
5969     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5970     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5971
5972     /* Version value exists */
5973     sz = MAX_PATH;
5974     lstrcpyA(buf, "apple");
5975     r = pMsiGetProductInfoExA(prodcode, usersid,
5976                               MSIINSTALLCONTEXT_USERMANAGED,
5977                               INSTALLPROPERTY_VERSION, buf, &sz);
5978     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5979     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5980     ok(sz == 3, "Expected 3, got %d\n", sz);
5981
5982     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5984
5985     /* ProductIcon value exists */
5986     sz = MAX_PATH;
5987     lstrcpyA(buf, "apple");
5988     r = pMsiGetProductInfoExA(prodcode, usersid,
5989                               MSIINSTALLCONTEXT_USERMANAGED,
5990                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5991     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5992     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5993     ok(sz == 4, "Expected 4, got %d\n", sz);
5994
5995     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5997
5998     /* PackageName value exists */
5999     sz = MAX_PATH;
6000     lstrcpyA(buf, "apple");
6001     r = pMsiGetProductInfoExA(prodcode, usersid,
6002                               MSIINSTALLCONTEXT_USERMANAGED,
6003                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6004     todo_wine
6005     {
6006         ok(r == ERROR_UNKNOWN_PRODUCT,
6007            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6008         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6009         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6010     }
6011
6012     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6014
6015     /* AuthorizedLUAApp value exists */
6016     sz = MAX_PATH;
6017     lstrcpyA(buf, "apple");
6018     r = pMsiGetProductInfoExA(prodcode, usersid,
6019                               MSIINSTALLCONTEXT_USERMANAGED,
6020                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6021     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6022     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6023     ok(sz == 4, "Expected 4, got %d\n", sz);
6024
6025     RegDeleteValueA(userkey, "AuthorizedLUAApp");
6026     RegDeleteValueA(userkey, "PackageName");
6027     RegDeleteValueA(userkey, "ProductIcon");
6028     RegDeleteValueA(userkey, "Version");
6029     RegDeleteValueA(userkey, "PackageCode");
6030     RegDeleteValueA(userkey, "AssignmentType");
6031     RegDeleteValueA(userkey, "ProductName");
6032     RegDeleteValueA(userkey, "Language");
6033     RegDeleteValueA(userkey, "Transforms");
6034     RegDeleteValueA(userkey, "RegOwner");
6035     RegDeleteValueA(userkey, "RegCompany");
6036     RegDeleteValueA(userkey, "ProductID");
6037     RegDeleteValueA(userkey, "DisplayVersion");
6038     RegDeleteValueA(userkey, "VersionMajor");
6039     RegDeleteValueA(userkey, "VersionMinor");
6040     RegDeleteValueA(userkey, "URLUpdateInfo");
6041     RegDeleteValueA(userkey, "URLInfoAbout");
6042     RegDeleteValueA(userkey, "Publisher");
6043     RegDeleteValueA(userkey, "LocalPackage");
6044     RegDeleteValueA(userkey, "InstallSource");
6045     RegDeleteValueA(userkey, "InstallLocation");
6046     RegDeleteValueA(userkey, "DisplayName");
6047     RegDeleteValueA(userkey, "InstallDate");
6048     RegDeleteValueA(userkey, "HelpTelephone");
6049     RegDeleteValueA(userkey, "HelpLink");
6050     delete_key(userkey, "", access & KEY_WOW64_64KEY);
6051     RegCloseKey(userkey);
6052     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6053     RegCloseKey(prodkey);
6054
6055     /* MSIINSTALLCONTEXT_MACHINE */
6056
6057     /* szUserSid is non-NULL */
6058     sz = MAX_PATH;
6059     lstrcpyA(buf, "apple");
6060     r = pMsiGetProductInfoExA(prodcode, usersid,
6061                               MSIINSTALLCONTEXT_MACHINE,
6062                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6063     ok(r == ERROR_INVALID_PARAMETER,
6064        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6065     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6066     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6067
6068     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
6069     lstrcatA(keypath, prod_squashed);
6070
6071     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6073
6074     /* local system product key exists */
6075     sz = MAX_PATH;
6076     lstrcpyA(buf, "apple");
6077     r = pMsiGetProductInfoExA(prodcode, NULL,
6078                               MSIINSTALLCONTEXT_MACHINE,
6079                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6080     ok(r == ERROR_UNKNOWN_PRODUCT,
6081        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6082     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6083     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6084
6085     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6087
6088     /* InstallProperties key exists */
6089     sz = MAX_PATH;
6090     lstrcpyA(buf, "apple");
6091     r = pMsiGetProductInfoExA(prodcode, NULL,
6092                               MSIINSTALLCONTEXT_MACHINE,
6093                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6094     ok(r == ERROR_UNKNOWN_PRODUCT,
6095        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6096     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6097     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6098
6099     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6101
6102     /* LocalPackage value exists */
6103     sz = MAX_PATH;
6104     lstrcpyA(buf, "apple");
6105     r = pMsiGetProductInfoExA(prodcode, NULL,
6106                               MSIINSTALLCONTEXT_MACHINE,
6107                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6108     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6109     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6110     ok(sz == 1, "Expected 1, got %d\n", sz);
6111
6112     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6113     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6114
6115     /* HelpLink value exists */
6116     sz = MAX_PATH;
6117     lstrcpyA(buf, "apple");
6118     r = pMsiGetProductInfoExA(prodcode, NULL,
6119                               MSIINSTALLCONTEXT_MACHINE,
6120                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6121     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6122     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6123     ok(sz == 4, "Expected 4, got %d\n", sz);
6124
6125     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6126     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6127
6128     /* HelpTelephone value exists */
6129     sz = MAX_PATH;
6130     lstrcpyA(buf, "apple");
6131     r = pMsiGetProductInfoExA(prodcode, NULL,
6132                               MSIINSTALLCONTEXT_MACHINE,
6133                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6134     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6135     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6136     ok(sz == 5, "Expected 5, got %d\n", sz);
6137
6138     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6140
6141     /* InstallDate value exists */
6142     sz = MAX_PATH;
6143     lstrcpyA(buf, "apple");
6144     r = pMsiGetProductInfoExA(prodcode, NULL,
6145                               MSIINSTALLCONTEXT_MACHINE,
6146                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6147     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6148     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6149     ok(sz == 4, "Expected 4, got %d\n", sz);
6150
6151     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6152     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6153
6154     /* DisplayName value exists */
6155     sz = MAX_PATH;
6156     lstrcpyA(buf, "apple");
6157     r = pMsiGetProductInfoExA(prodcode, NULL,
6158                               MSIINSTALLCONTEXT_MACHINE,
6159                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6160     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6161     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6162     ok(sz == 4, "Expected 4, got %d\n", sz);
6163
6164     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6166
6167     /* InstallLocation value exists */
6168     sz = MAX_PATH;
6169     lstrcpyA(buf, "apple");
6170     r = pMsiGetProductInfoExA(prodcode, NULL,
6171                               MSIINSTALLCONTEXT_MACHINE,
6172                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6173     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6174     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6175     ok(sz == 3, "Expected 3, got %d\n", sz);
6176
6177     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6179
6180     /* InstallSource value exists */
6181     sz = MAX_PATH;
6182     lstrcpyA(buf, "apple");
6183     r = pMsiGetProductInfoExA(prodcode, NULL,
6184                               MSIINSTALLCONTEXT_MACHINE,
6185                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6186     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6187     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6188     ok(sz == 6, "Expected 6, got %d\n", sz);
6189
6190     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6191     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6192
6193     /* LocalPackage value exists */
6194     sz = MAX_PATH;
6195     lstrcpyA(buf, "apple");
6196     r = pMsiGetProductInfoExA(prodcode, NULL,
6197                               MSIINSTALLCONTEXT_MACHINE,
6198                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6199     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6200     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6201     ok(sz == 5, "Expected 5, got %d\n", sz);
6202
6203     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6205
6206     /* Publisher value exists */
6207     sz = MAX_PATH;
6208     lstrcpyA(buf, "apple");
6209     r = pMsiGetProductInfoExA(prodcode, NULL,
6210                               MSIINSTALLCONTEXT_MACHINE,
6211                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6212     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6213     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6214     ok(sz == 3, "Expected 3, got %d\n", sz);
6215
6216     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6218
6219     /* URLInfoAbout value exists */
6220     sz = MAX_PATH;
6221     lstrcpyA(buf, "apple");
6222     r = pMsiGetProductInfoExA(prodcode, NULL,
6223                               MSIINSTALLCONTEXT_MACHINE,
6224                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6225     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6226     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6227     ok(sz == 5, "Expected 5, got %d\n", sz);
6228
6229     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6230     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6231
6232     /* URLUpdateInfo value exists */
6233     sz = MAX_PATH;
6234     lstrcpyA(buf, "apple");
6235     r = pMsiGetProductInfoExA(prodcode, NULL,
6236                               MSIINSTALLCONTEXT_MACHINE,
6237                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6239     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6240     ok(sz == 6, "Expected 6, got %d\n", sz);
6241
6242     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6243     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6244
6245     /* VersionMinor value exists */
6246     sz = MAX_PATH;
6247     lstrcpyA(buf, "apple");
6248     r = pMsiGetProductInfoExA(prodcode, NULL,
6249                               MSIINSTALLCONTEXT_MACHINE,
6250                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6252     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6253     ok(sz == 1, "Expected 1, got %d\n", sz);
6254
6255     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6257
6258     /* VersionMajor value exists */
6259     sz = MAX_PATH;
6260     lstrcpyA(buf, "apple");
6261     r = pMsiGetProductInfoExA(prodcode, NULL,
6262                               MSIINSTALLCONTEXT_MACHINE,
6263                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6264     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6265     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6266     ok(sz == 1, "Expected 1, got %d\n", sz);
6267
6268     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6269     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6270
6271     /* DisplayVersion value exists */
6272     sz = MAX_PATH;
6273     lstrcpyA(buf, "apple");
6274     r = pMsiGetProductInfoExA(prodcode, NULL,
6275                               MSIINSTALLCONTEXT_MACHINE,
6276                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6278     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6279     ok(sz == 5, "Expected 5, got %d\n", sz);
6280
6281     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6283
6284     /* ProductID value exists */
6285     sz = MAX_PATH;
6286     lstrcpyA(buf, "apple");
6287     r = pMsiGetProductInfoExA(prodcode, NULL,
6288                               MSIINSTALLCONTEXT_MACHINE,
6289                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6290     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6291     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6292     ok(sz == 2, "Expected 2, got %d\n", sz);
6293
6294     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6295     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6296
6297     /* RegCompany value exists */
6298     sz = MAX_PATH;
6299     lstrcpyA(buf, "apple");
6300     r = pMsiGetProductInfoExA(prodcode, NULL,
6301                               MSIINSTALLCONTEXT_MACHINE,
6302                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6303     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6304     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6305     ok(sz == 4, "Expected 4, got %d\n", sz);
6306
6307     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6309
6310     /* RegOwner value exists */
6311     sz = MAX_PATH;
6312     lstrcpyA(buf, "apple");
6313     r = pMsiGetProductInfoExA(prodcode, NULL,
6314                               MSIINSTALLCONTEXT_MACHINE,
6315                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6316     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6317     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6318     ok(sz == 5, "Expected 5, got %d\n", sz);
6319
6320     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6321     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6322
6323     /* Transforms value exists */
6324     sz = MAX_PATH;
6325     lstrcpyA(buf, "apple");
6326     r = pMsiGetProductInfoExA(prodcode, NULL,
6327                               MSIINSTALLCONTEXT_MACHINE,
6328                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6329     ok(r == ERROR_UNKNOWN_PRODUCT,
6330        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6331     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6332     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6333
6334     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6335     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6336
6337     /* Language value exists */
6338     sz = MAX_PATH;
6339     lstrcpyA(buf, "apple");
6340     r = pMsiGetProductInfoExA(prodcode, NULL,
6341                               MSIINSTALLCONTEXT_MACHINE,
6342                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6343     ok(r == ERROR_UNKNOWN_PRODUCT,
6344        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6345     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6346     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6347
6348     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6349     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6350
6351     /* ProductName value exists */
6352     sz = MAX_PATH;
6353     lstrcpyA(buf, "apple");
6354     r = pMsiGetProductInfoExA(prodcode, NULL,
6355                               MSIINSTALLCONTEXT_MACHINE,
6356                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6357     ok(r == ERROR_UNKNOWN_PRODUCT,
6358        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6359     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6360     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6361
6362     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6363     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6364
6365     /* FIXME */
6366
6367     /* AssignmentType value exists */
6368     sz = MAX_PATH;
6369     lstrcpyA(buf, "apple");
6370     r = pMsiGetProductInfoExA(prodcode, NULL,
6371                               MSIINSTALLCONTEXT_MACHINE,
6372                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6373     ok(r == ERROR_UNKNOWN_PRODUCT,
6374        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6375     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6376     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6377
6378     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6380
6381     /* PackageCode value exists */
6382     sz = MAX_PATH;
6383     lstrcpyA(buf, "apple");
6384     r = pMsiGetProductInfoExA(prodcode, NULL,
6385                               MSIINSTALLCONTEXT_MACHINE,
6386                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6387     ok(r == ERROR_UNKNOWN_PRODUCT,
6388        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6389     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6390     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6391
6392     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6393     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6394
6395     /* Version value exists */
6396     sz = MAX_PATH;
6397     lstrcpyA(buf, "apple");
6398     r = pMsiGetProductInfoExA(prodcode, NULL,
6399                               MSIINSTALLCONTEXT_MACHINE,
6400                               INSTALLPROPERTY_VERSION, buf, &sz);
6401     ok(r == ERROR_UNKNOWN_PRODUCT,
6402        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6403     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6404     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6405
6406     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6407     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6408
6409     /* ProductIcon value exists */
6410     sz = MAX_PATH;
6411     lstrcpyA(buf, "apple");
6412     r = pMsiGetProductInfoExA(prodcode, NULL,
6413                               MSIINSTALLCONTEXT_MACHINE,
6414                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6415     ok(r == ERROR_UNKNOWN_PRODUCT,
6416        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6417     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6418     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6419
6420     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6421     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6422
6423     /* PackageName value exists */
6424     sz = MAX_PATH;
6425     lstrcpyA(buf, "apple");
6426     r = pMsiGetProductInfoExA(prodcode, NULL,
6427                               MSIINSTALLCONTEXT_MACHINE,
6428                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6429     ok(r == ERROR_UNKNOWN_PRODUCT,
6430        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6431     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6432     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6433
6434     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6435     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6436
6437     /* AuthorizedLUAApp value exists */
6438     sz = MAX_PATH;
6439     lstrcpyA(buf, "apple");
6440     r = pMsiGetProductInfoExA(prodcode, NULL,
6441                               MSIINSTALLCONTEXT_MACHINE,
6442                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6443     ok(r == ERROR_UNKNOWN_PRODUCT,
6444        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6445     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6446     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6447
6448     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6449     RegDeleteValueA(propkey, "PackageName");
6450     RegDeleteValueA(propkey, "ProductIcon");
6451     RegDeleteValueA(propkey, "Version");
6452     RegDeleteValueA(propkey, "PackageCode");
6453     RegDeleteValueA(propkey, "AssignmentType");
6454     RegDeleteValueA(propkey, "ProductName");
6455     RegDeleteValueA(propkey, "Language");
6456     RegDeleteValueA(propkey, "Transforms");
6457     RegDeleteValueA(propkey, "RegOwner");
6458     RegDeleteValueA(propkey, "RegCompany");
6459     RegDeleteValueA(propkey, "ProductID");
6460     RegDeleteValueA(propkey, "DisplayVersion");
6461     RegDeleteValueA(propkey, "VersionMajor");
6462     RegDeleteValueA(propkey, "VersionMinor");
6463     RegDeleteValueA(propkey, "URLUpdateInfo");
6464     RegDeleteValueA(propkey, "URLInfoAbout");
6465     RegDeleteValueA(propkey, "Publisher");
6466     RegDeleteValueA(propkey, "LocalPackage");
6467     RegDeleteValueA(propkey, "InstallSource");
6468     RegDeleteValueA(propkey, "InstallLocation");
6469     RegDeleteValueA(propkey, "DisplayName");
6470     RegDeleteValueA(propkey, "InstallDate");
6471     RegDeleteValueA(propkey, "HelpTelephone");
6472     RegDeleteValueA(propkey, "HelpLink");
6473     RegDeleteValueA(propkey, "LocalPackage");
6474     delete_key(propkey, "", access & KEY_WOW64_64KEY);
6475     RegCloseKey(propkey);
6476     delete_key(localkey, "", access & KEY_WOW64_64KEY);
6477     RegCloseKey(localkey);
6478
6479     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6480     lstrcatA(keypath, prod_squashed);
6481
6482     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6483     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6484
6485     /* local classes product key exists */
6486     sz = MAX_PATH;
6487     lstrcpyA(buf, "apple");
6488     r = pMsiGetProductInfoExA(prodcode, NULL,
6489                               MSIINSTALLCONTEXT_MACHINE,
6490                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6491     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6492     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6493     ok(sz == 1, "Expected 1, got %d\n", sz);
6494
6495     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6496     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6497
6498     /* HelpLink value exists */
6499     sz = MAX_PATH;
6500     lstrcpyA(buf, "apple");
6501     r = pMsiGetProductInfoExA(prodcode, NULL,
6502                               MSIINSTALLCONTEXT_MACHINE,
6503                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6504     ok(r == ERROR_UNKNOWN_PROPERTY,
6505        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6506     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6507     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6508
6509     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6510     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6511
6512     /* HelpTelephone value exists */
6513     sz = MAX_PATH;
6514     lstrcpyA(buf, "apple");
6515     r = pMsiGetProductInfoExA(prodcode, NULL,
6516                               MSIINSTALLCONTEXT_MACHINE,
6517                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6518     ok(r == ERROR_UNKNOWN_PROPERTY,
6519        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6520     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6521     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6522
6523     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6524     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6525
6526     /* InstallDate value exists */
6527     sz = MAX_PATH;
6528     lstrcpyA(buf, "apple");
6529     r = pMsiGetProductInfoExA(prodcode, NULL,
6530                               MSIINSTALLCONTEXT_MACHINE,
6531                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6532     ok(r == ERROR_UNKNOWN_PROPERTY,
6533        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6534     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6535     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6536
6537     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6538     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6539
6540     /* DisplayName value exists */
6541     sz = MAX_PATH;
6542     lstrcpyA(buf, "apple");
6543     r = pMsiGetProductInfoExA(prodcode, NULL,
6544                               MSIINSTALLCONTEXT_MACHINE,
6545                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6546     ok(r == ERROR_UNKNOWN_PROPERTY,
6547        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6548     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6549     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6550
6551     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6552     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6553
6554     /* InstallLocation value exists */
6555     sz = MAX_PATH;
6556     lstrcpyA(buf, "apple");
6557     r = pMsiGetProductInfoExA(prodcode, NULL,
6558                               MSIINSTALLCONTEXT_MACHINE,
6559                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6560     ok(r == ERROR_UNKNOWN_PROPERTY,
6561        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6562     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6563     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6564
6565     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6566     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6567
6568     /* InstallSource value exists */
6569     sz = MAX_PATH;
6570     lstrcpyA(buf, "apple");
6571     r = pMsiGetProductInfoExA(prodcode, NULL,
6572                               MSIINSTALLCONTEXT_MACHINE,
6573                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6574     ok(r == ERROR_UNKNOWN_PROPERTY,
6575        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6576     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6577     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6578
6579     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6580     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6581
6582     /* LocalPackage value exists */
6583     sz = MAX_PATH;
6584     lstrcpyA(buf, "apple");
6585     r = pMsiGetProductInfoExA(prodcode, NULL,
6586                               MSIINSTALLCONTEXT_MACHINE,
6587                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6588     ok(r == ERROR_UNKNOWN_PROPERTY,
6589        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6590     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6591     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6592
6593     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6594     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6595
6596     /* Publisher value exists */
6597     sz = MAX_PATH;
6598     lstrcpyA(buf, "apple");
6599     r = pMsiGetProductInfoExA(prodcode, NULL,
6600                               MSIINSTALLCONTEXT_MACHINE,
6601                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6602     ok(r == ERROR_UNKNOWN_PROPERTY,
6603        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6604     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6605     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6606
6607     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6608     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6609
6610     /* URLInfoAbout value exists */
6611     sz = MAX_PATH;
6612     lstrcpyA(buf, "apple");
6613     r = pMsiGetProductInfoExA(prodcode, NULL,
6614                               MSIINSTALLCONTEXT_MACHINE,
6615                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6616     ok(r == ERROR_UNKNOWN_PROPERTY,
6617        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6618     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6619     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6620
6621     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6622     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6623
6624     /* URLUpdateInfo value exists */
6625     sz = MAX_PATH;
6626     lstrcpyA(buf, "apple");
6627     r = pMsiGetProductInfoExA(prodcode, NULL,
6628                               MSIINSTALLCONTEXT_MACHINE,
6629                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6630     ok(r == ERROR_UNKNOWN_PROPERTY,
6631        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6632     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6633     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6634
6635     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6637
6638     /* VersionMinor value exists */
6639     sz = MAX_PATH;
6640     lstrcpyA(buf, "apple");
6641     r = pMsiGetProductInfoExA(prodcode, NULL,
6642                               MSIINSTALLCONTEXT_MACHINE,
6643                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6644     ok(r == ERROR_UNKNOWN_PROPERTY,
6645        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6646     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6647     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6648
6649     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6651
6652     /* VersionMajor value exists */
6653     sz = MAX_PATH;
6654     lstrcpyA(buf, "apple");
6655     r = pMsiGetProductInfoExA(prodcode, NULL,
6656                               MSIINSTALLCONTEXT_MACHINE,
6657                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6658     ok(r == ERROR_UNKNOWN_PROPERTY,
6659        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6660     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6661     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6662
6663     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6664     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6665
6666     /* DisplayVersion value exists */
6667     sz = MAX_PATH;
6668     lstrcpyA(buf, "apple");
6669     r = pMsiGetProductInfoExA(prodcode, NULL,
6670                               MSIINSTALLCONTEXT_MACHINE,
6671                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6672     ok(r == ERROR_UNKNOWN_PROPERTY,
6673        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6674     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6675     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6676
6677     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6678     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6679
6680     /* ProductID value exists */
6681     sz = MAX_PATH;
6682     lstrcpyA(buf, "apple");
6683     r = pMsiGetProductInfoExA(prodcode, NULL,
6684                               MSIINSTALLCONTEXT_MACHINE,
6685                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6686     ok(r == ERROR_UNKNOWN_PROPERTY,
6687        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6688     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6689     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6690
6691     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6692     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6693
6694     /* RegCompany value exists */
6695     sz = MAX_PATH;
6696     lstrcpyA(buf, "apple");
6697     r = pMsiGetProductInfoExA(prodcode, NULL,
6698                               MSIINSTALLCONTEXT_MACHINE,
6699                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6700     ok(r == ERROR_UNKNOWN_PROPERTY,
6701        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6702     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6703     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6704
6705     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6706     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6707
6708     /* RegOwner value exists */
6709     sz = MAX_PATH;
6710     lstrcpyA(buf, "apple");
6711     r = pMsiGetProductInfoExA(prodcode, NULL,
6712                               MSIINSTALLCONTEXT_MACHINE,
6713                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6714     ok(r == ERROR_UNKNOWN_PROPERTY,
6715        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6716     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6717     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6718
6719     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6721
6722     /* Transforms value exists */
6723     sz = MAX_PATH;
6724     lstrcpyA(buf, "apple");
6725     r = pMsiGetProductInfoExA(prodcode, NULL,
6726                               MSIINSTALLCONTEXT_MACHINE,
6727                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6728     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6729     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6730     ok(sz == 5, "Expected 5, got %d\n", sz);
6731
6732     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6733     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6734
6735     /* Language value exists */
6736     sz = MAX_PATH;
6737     lstrcpyA(buf, "apple");
6738     r = pMsiGetProductInfoExA(prodcode, NULL,
6739                               MSIINSTALLCONTEXT_MACHINE,
6740                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6741     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6742     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6743     ok(sz == 4, "Expected 4, got %d\n", sz);
6744
6745     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6747
6748     /* ProductName value exists */
6749     sz = MAX_PATH;
6750     lstrcpyA(buf, "apple");
6751     r = pMsiGetProductInfoExA(prodcode, NULL,
6752                               MSIINSTALLCONTEXT_MACHINE,
6753                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6754     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6755     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6756     ok(sz == 4, "Expected 4, got %d\n", sz);
6757
6758     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6759     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6760
6761     /* FIXME */
6762
6763     /* AssignmentType value exists */
6764     sz = MAX_PATH;
6765     lstrcpyA(buf, "apple");
6766     r = pMsiGetProductInfoExA(prodcode, NULL,
6767                               MSIINSTALLCONTEXT_MACHINE,
6768                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6769     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6770     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6771     ok(sz == 0, "Expected 0, got %d\n", sz);
6772
6773     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6774     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6775
6776     /* FIXME */
6777
6778     /* PackageCode value exists */
6779     sz = MAX_PATH;
6780     lstrcpyA(buf, "apple");
6781     r = pMsiGetProductInfoExA(prodcode, NULL,
6782                               MSIINSTALLCONTEXT_MACHINE,
6783                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6784     todo_wine
6785     {
6786         ok(r == ERROR_BAD_CONFIGURATION,
6787            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6788         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6789         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6790     }
6791
6792     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6793     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6794
6795     /* Version value exists */
6796     sz = MAX_PATH;
6797     lstrcpyA(buf, "apple");
6798     r = pMsiGetProductInfoExA(prodcode, NULL,
6799                               MSIINSTALLCONTEXT_MACHINE,
6800                               INSTALLPROPERTY_VERSION, buf, &sz);
6801     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6802     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6803     ok(sz == 3, "Expected 3, got %d\n", sz);
6804
6805     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6806     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6807
6808     /* ProductIcon value exists */
6809     sz = MAX_PATH;
6810     lstrcpyA(buf, "apple");
6811     r = pMsiGetProductInfoExA(prodcode, NULL,
6812                               MSIINSTALLCONTEXT_MACHINE,
6813                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6814     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6815     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6816     ok(sz == 4, "Expected 4, got %d\n", sz);
6817
6818     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6819     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6820
6821     /* PackageName value exists */
6822     sz = MAX_PATH;
6823     lstrcpyA(buf, "apple");
6824     r = pMsiGetProductInfoExA(prodcode, NULL,
6825                               MSIINSTALLCONTEXT_MACHINE,
6826                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6827     todo_wine
6828     {
6829         ok(r == ERROR_UNKNOWN_PRODUCT,
6830            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6831         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6832         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6833     }
6834
6835     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6836     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6837
6838     /* AuthorizedLUAApp value exists */
6839     sz = MAX_PATH;
6840     lstrcpyA(buf, "apple");
6841     r = pMsiGetProductInfoExA(prodcode, NULL,
6842                               MSIINSTALLCONTEXT_MACHINE,
6843                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6844     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6845     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6846     ok(sz == 4, "Expected 4, got %d\n", sz);
6847
6848     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6849     RegDeleteValueA(prodkey, "PackageName");
6850     RegDeleteValueA(prodkey, "ProductIcon");
6851     RegDeleteValueA(prodkey, "Version");
6852     RegDeleteValueA(prodkey, "PackageCode");
6853     RegDeleteValueA(prodkey, "AssignmentType");
6854     RegDeleteValueA(prodkey, "ProductName");
6855     RegDeleteValueA(prodkey, "Language");
6856     RegDeleteValueA(prodkey, "Transforms");
6857     RegDeleteValueA(prodkey, "RegOwner");
6858     RegDeleteValueA(prodkey, "RegCompany");
6859     RegDeleteValueA(prodkey, "ProductID");
6860     RegDeleteValueA(prodkey, "DisplayVersion");
6861     RegDeleteValueA(prodkey, "VersionMajor");
6862     RegDeleteValueA(prodkey, "VersionMinor");
6863     RegDeleteValueA(prodkey, "URLUpdateInfo");
6864     RegDeleteValueA(prodkey, "URLInfoAbout");
6865     RegDeleteValueA(prodkey, "Publisher");
6866     RegDeleteValueA(prodkey, "LocalPackage");
6867     RegDeleteValueA(prodkey, "InstallSource");
6868     RegDeleteValueA(prodkey, "InstallLocation");
6869     RegDeleteValueA(prodkey, "DisplayName");
6870     RegDeleteValueA(prodkey, "InstallDate");
6871     RegDeleteValueA(prodkey, "HelpTelephone");
6872     RegDeleteValueA(prodkey, "HelpLink");
6873     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6874     RegCloseKey(prodkey);
6875     LocalFree(usersid);
6876 }
6877
6878 #define INIT_USERINFO() \
6879     lstrcpyA(user, "apple"); \
6880     lstrcpyA(org, "orange"); \
6881     lstrcpyA(serial, "banana"); \
6882     usersz = orgsz = serialsz = MAX_PATH;
6883
6884 static void test_MsiGetUserInfo(void)
6885 {
6886     USERINFOSTATE state;
6887     CHAR user[MAX_PATH];
6888     CHAR org[MAX_PATH];
6889     CHAR serial[MAX_PATH];
6890     DWORD usersz, orgsz, serialsz;
6891     CHAR keypath[MAX_PATH * 2];
6892     CHAR prodcode[MAX_PATH];
6893     CHAR prod_squashed[MAX_PATH];
6894     HKEY prodkey, userprod, props;
6895     LPSTR usersid;
6896     LONG res;
6897     REGSAM access = KEY_ALL_ACCESS;
6898     BOOL wow64;
6899
6900     create_test_guid(prodcode, prod_squashed);
6901     get_user_sid(&usersid);
6902
6903     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
6904         access |= KEY_WOW64_64KEY;
6905
6906     /* NULL szProduct */
6907     INIT_USERINFO();
6908     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6909     ok(state == USERINFOSTATE_INVALIDARG,
6910        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6911     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6912     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6913     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6914     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6915     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6916     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6917
6918     /* empty szProductCode */
6919     INIT_USERINFO();
6920     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6921     ok(state == USERINFOSTATE_INVALIDARG,
6922        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6923     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6924     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6925     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6926     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6927     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6928     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6929
6930     /* garbage szProductCode */
6931     INIT_USERINFO();
6932     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6933     ok(state == USERINFOSTATE_INVALIDARG,
6934        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6935     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6936     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6937     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6938     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6939     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6940     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6941
6942     /* guid without brackets */
6943     INIT_USERINFO();
6944     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6945                             user, &usersz, org, &orgsz, serial, &serialsz);
6946     ok(state == USERINFOSTATE_INVALIDARG,
6947        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6948     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6949     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6950     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6951     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6952     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6953     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6954
6955     /* guid with brackets */
6956     INIT_USERINFO();
6957     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6958                             user, &usersz, org, &orgsz, serial, &serialsz);
6959     ok(state == USERINFOSTATE_UNKNOWN,
6960        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6961     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6962     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6963     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6964     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6965     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6966     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6967
6968     /* NULL lpUserNameBuf */
6969     INIT_USERINFO();
6970     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6971     ok(state == USERINFOSTATE_UNKNOWN,
6972        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6973     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6974     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6975     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6976     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6977     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6978
6979     /* NULL pcchUserNameBuf */
6980     INIT_USERINFO();
6981     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6982     ok(state == USERINFOSTATE_INVALIDARG,
6983        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6984     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6985     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6986     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6987     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6988     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6989
6990     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6991     INIT_USERINFO();
6992     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6993     ok(state == USERINFOSTATE_UNKNOWN,
6994        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6995     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6996     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6997     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6998     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6999
7000     /* NULL lpOrgNameBuf */
7001     INIT_USERINFO();
7002     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
7003     ok(state == USERINFOSTATE_UNKNOWN,
7004        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7005     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7006     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7007     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7008     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7009     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7010
7011     /* NULL pcchOrgNameBuf */
7012     INIT_USERINFO();
7013     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
7014     ok(state == USERINFOSTATE_INVALIDARG,
7015        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7016     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7017     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7018     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7019     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7020     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7021
7022     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
7023     INIT_USERINFO();
7024     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
7025     ok(state == USERINFOSTATE_UNKNOWN,
7026        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7027     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7028     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7029     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7030     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7031
7032     /* NULL lpSerialBuf */
7033     INIT_USERINFO();
7034     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
7035     ok(state == USERINFOSTATE_UNKNOWN,
7036        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7037     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7038     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7039     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7040     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7041     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7042
7043     /* NULL pcchSerialBuf */
7044     INIT_USERINFO();
7045     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
7046     ok(state == USERINFOSTATE_INVALIDARG,
7047        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7048     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7049     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7050     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7051     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7052     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7053
7054     /* both lpSerialBuf and pcchSerialBuf NULL */
7055     INIT_USERINFO();
7056     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
7057     ok(state == USERINFOSTATE_UNKNOWN,
7058        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7059     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7060     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7061     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7062     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7063
7064     /* MSIINSTALLCONTEXT_USERMANAGED */
7065
7066     /* create local system product key */
7067     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7068     lstrcatA(keypath, usersid);
7069     lstrcatA(keypath, "\\Installer\\Products\\");
7070     lstrcatA(keypath, prod_squashed);
7071
7072     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7073     if (res == ERROR_ACCESS_DENIED)
7074     {
7075         skip("Not enough rights to perform tests\n");
7076         LocalFree(usersid);
7077         return;
7078     }
7079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7080
7081     /* managed product key exists */
7082     INIT_USERINFO();
7083     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7084     ok(state == USERINFOSTATE_ABSENT,
7085        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7086     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7087     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7088     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7089     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7090     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7091     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7092
7093     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7094     lstrcatA(keypath, "Installer\\UserData\\");
7095     lstrcatA(keypath, usersid);
7096     lstrcatA(keypath, "\\Products\\");
7097     lstrcatA(keypath, prod_squashed);
7098
7099     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7101
7102     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7103     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7104
7105     /* InstallProperties key exists */
7106     INIT_USERINFO();
7107     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7108     ok(state == USERINFOSTATE_ABSENT,
7109        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7110     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7111     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7112     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7113     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7114     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7115     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7116
7117     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7118     INIT_USERINFO();
7119     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7120     ok(state == USERINFOSTATE_ABSENT,
7121        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7122     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7123     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7124     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7125     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7126
7127     /* RegOwner, RegCompany don't exist, out params are NULL */
7128     INIT_USERINFO();
7129     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7130     ok(state == USERINFOSTATE_ABSENT,
7131        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7132     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7133     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7134
7135     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7136     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7137
7138     /* RegOwner value exists */
7139     INIT_USERINFO();
7140     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7141     ok(state == USERINFOSTATE_ABSENT,
7142        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7143     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7144     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7145     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7146     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7147     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7148     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7149
7150     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7151     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7152
7153     /* RegCompany value exists */
7154     INIT_USERINFO();
7155     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7156     ok(state == USERINFOSTATE_ABSENT,
7157        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7158     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7159     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7160     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7161     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7162     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7163     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7164
7165     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7166     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7167
7168     /* ProductID value exists */
7169     INIT_USERINFO();
7170     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7171     ok(state == USERINFOSTATE_PRESENT,
7172        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7173     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7174     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7175     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7176     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7177     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7178     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7179
7180     /* pcchUserNameBuf is too small */
7181     INIT_USERINFO();
7182     usersz = 0;
7183     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7184     ok(state == USERINFOSTATE_MOREDATA,
7185        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7186     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7187     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7188     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7189     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7190     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7191     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7192
7193     /* pcchUserNameBuf has no room for NULL terminator */
7194     INIT_USERINFO();
7195     usersz = 5;
7196     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7197     ok(state == USERINFOSTATE_MOREDATA,
7198        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7199     todo_wine
7200     {
7201         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7202     }
7203     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7204     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7205     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7206     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7207     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7208
7209     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
7210     INIT_USERINFO();
7211     usersz = 0;
7212     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7213     ok(state == USERINFOSTATE_PRESENT,
7214        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7215     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7216     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7217     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7218     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7219     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7220     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7221
7222     RegDeleteValueA(props, "ProductID");
7223     RegDeleteValueA(props, "RegCompany");
7224     RegDeleteValueA(props, "RegOwner");
7225     delete_key(props, "", access & KEY_WOW64_64KEY);
7226     RegCloseKey(props);
7227     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7228     RegCloseKey(userprod);
7229     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7230     RegCloseKey(prodkey);
7231
7232     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7233
7234     /* create local system product key */
7235     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7236     lstrcatA(keypath, prod_squashed);
7237
7238     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7240
7241     /* product key exists */
7242     INIT_USERINFO();
7243     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7244     ok(state == USERINFOSTATE_ABSENT,
7245        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7246     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7247     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7248     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7249     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7250     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7251     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7252
7253     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7254     lstrcatA(keypath, "Installer\\UserData\\");
7255     lstrcatA(keypath, usersid);
7256     lstrcatA(keypath, "\\Products\\");
7257     lstrcatA(keypath, prod_squashed);
7258
7259     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7260     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7261
7262     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7263     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7264
7265     /* InstallProperties key exists */
7266     INIT_USERINFO();
7267     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7268     ok(state == USERINFOSTATE_ABSENT,
7269        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7270     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7271     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7272     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7273     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7274     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7275     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7276
7277     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7278     INIT_USERINFO();
7279     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7280     ok(state == USERINFOSTATE_ABSENT,
7281        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7282     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7283     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7284     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7285     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7286
7287     /* RegOwner, RegCompany don't exist, out params are NULL */
7288     INIT_USERINFO();
7289     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7290     ok(state == USERINFOSTATE_ABSENT,
7291        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7292     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7293     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7294
7295     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7297
7298     /* RegOwner value exists */
7299     INIT_USERINFO();
7300     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7301     ok(state == USERINFOSTATE_ABSENT,
7302        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7303     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7304     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7305     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7306     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7307     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7308     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7309
7310     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7311     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7312
7313     /* RegCompany value exists */
7314     INIT_USERINFO();
7315     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7316     ok(state == USERINFOSTATE_ABSENT,
7317        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7318     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7319     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7320     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7321     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7322     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7323     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7324
7325     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7326     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7327
7328     /* ProductID value exists */
7329     INIT_USERINFO();
7330     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7331     ok(state == USERINFOSTATE_PRESENT,
7332        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7333     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7334     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7335     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7336     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7337     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7338     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7339
7340     RegDeleteValueA(props, "ProductID");
7341     RegDeleteValueA(props, "RegCompany");
7342     RegDeleteValueA(props, "RegOwner");
7343     delete_key(props, "", access & KEY_WOW64_64KEY);
7344     RegCloseKey(props);
7345     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7346     RegCloseKey(userprod);
7347     RegDeleteKeyA(prodkey, "");
7348     RegCloseKey(prodkey);
7349
7350     /* MSIINSTALLCONTEXT_MACHINE */
7351
7352     /* create local system product key */
7353     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7354     lstrcatA(keypath, prod_squashed);
7355
7356     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7357     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7358
7359     /* product key exists */
7360     INIT_USERINFO();
7361     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7362     ok(state == USERINFOSTATE_ABSENT,
7363        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7364     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7365     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7366     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7367     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7368     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7369     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7370
7371     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7372     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7373     lstrcatA(keypath, "\\Products\\");
7374     lstrcatA(keypath, prod_squashed);
7375
7376     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7378
7379     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7380     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7381
7382     /* InstallProperties key exists */
7383     INIT_USERINFO();
7384     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7385     ok(state == USERINFOSTATE_ABSENT,
7386        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7387     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7388     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7389     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7390     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7391     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7392     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7393
7394     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7395     INIT_USERINFO();
7396     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7397     ok(state == USERINFOSTATE_ABSENT,
7398        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7399     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7400     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7401     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7402     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7403
7404     /* RegOwner, RegCompany don't exist, out params are NULL */
7405     INIT_USERINFO();
7406     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7407     ok(state == USERINFOSTATE_ABSENT,
7408        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7409     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7410     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7411
7412     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7413     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7414
7415     /* RegOwner value exists */
7416     INIT_USERINFO();
7417     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7418     ok(state == USERINFOSTATE_ABSENT,
7419        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7420     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7421     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7422     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7423     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7424     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7425     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7426
7427     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7428     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7429
7430     /* RegCompany value exists */
7431     INIT_USERINFO();
7432     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7433     ok(state == USERINFOSTATE_ABSENT,
7434        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7435     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7436     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7437     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7438     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7439     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7440     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7441
7442     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7443     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7444
7445     /* ProductID value exists */
7446     INIT_USERINFO();
7447     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7448     ok(state == USERINFOSTATE_PRESENT,
7449        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7450     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7451     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7452     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7453     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7454     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7455     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7456
7457     RegDeleteValueA(props, "ProductID");
7458     RegDeleteValueA(props, "RegCompany");
7459     RegDeleteValueA(props, "RegOwner");
7460     delete_key(props, "", access & KEY_WOW64_64KEY);
7461     RegCloseKey(props);
7462     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7463     RegCloseKey(userprod);
7464     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7465     RegCloseKey(prodkey);
7466     LocalFree(usersid);
7467 }
7468
7469 static void test_MsiOpenProduct(void)
7470 {
7471     MSIHANDLE hprod, hdb;
7472     CHAR val[MAX_PATH];
7473     CHAR path[MAX_PATH];
7474     CHAR keypath[MAX_PATH*2];
7475     CHAR prodcode[MAX_PATH];
7476     CHAR prod_squashed[MAX_PATH];
7477     HKEY prodkey, userkey, props;
7478     LPSTR usersid;
7479     DWORD size;
7480     LONG res;
7481     UINT r;
7482     REGSAM access = KEY_ALL_ACCESS;
7483     BOOL wow64;
7484
7485     GetCurrentDirectoryA(MAX_PATH, path);
7486     lstrcatA(path, "\\");
7487
7488     create_test_guid(prodcode, prod_squashed);
7489     get_user_sid(&usersid);
7490
7491     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
7492         access |= KEY_WOW64_64KEY;
7493
7494     hdb = create_package_db(prodcode);
7495     MsiCloseHandle(hdb);
7496
7497     /* NULL szProduct */
7498     hprod = 0xdeadbeef;
7499     r = MsiOpenProductA(NULL, &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     /* empty szProduct */
7505     hprod = 0xdeadbeef;
7506     r = MsiOpenProductA("", &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     /* garbage szProduct */
7512     hprod = 0xdeadbeef;
7513     r = MsiOpenProductA("garbage", &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 without brackets */
7519     hprod = 0xdeadbeef;
7520     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7521     ok(r == ERROR_INVALID_PARAMETER,
7522        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7523     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7524
7525     /* guid with brackets */
7526     hprod = 0xdeadbeef;
7527     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7528     ok(r == ERROR_UNKNOWN_PRODUCT,
7529        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7530     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7531
7532     /* same length as guid, but random */
7533     hprod = 0xdeadbeef;
7534     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
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     /* hProduct is NULL */
7540     hprod = 0xdeadbeef;
7541     r = MsiOpenProductA(prodcode, NULL);
7542     ok(r == ERROR_INVALID_PARAMETER,
7543        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7544     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7545
7546     /* MSIINSTALLCONTEXT_USERMANAGED */
7547
7548     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7549     lstrcatA(keypath, "Installer\\Managed\\");
7550     lstrcatA(keypath, usersid);
7551     lstrcatA(keypath, "\\Installer\\Products\\");
7552     lstrcatA(keypath, prod_squashed);
7553
7554     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7555     if (res == ERROR_ACCESS_DENIED)
7556     {
7557         skip("Not enough rights to perform tests\n");
7558         LocalFree(usersid);
7559         return;
7560     }
7561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7562
7563     /* managed product key exists */
7564     hprod = 0xdeadbeef;
7565     r = MsiOpenProductA(prodcode, &hprod);
7566     ok(r == ERROR_UNKNOWN_PRODUCT,
7567        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7568     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7569
7570     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7571     lstrcatA(keypath, "Installer\\UserData\\");
7572     lstrcatA(keypath, usersid);
7573     lstrcatA(keypath, "\\Products\\");
7574     lstrcatA(keypath, prod_squashed);
7575
7576     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7578
7579     /* user product key exists */
7580     hprod = 0xdeadbeef;
7581     r = MsiOpenProductA(prodcode, &hprod);
7582     ok(r == ERROR_UNKNOWN_PRODUCT,
7583        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7584     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7585
7586     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7587     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7588
7589     /* InstallProperties key exists */
7590     hprod = 0xdeadbeef;
7591     r = MsiOpenProductA(prodcode, &hprod);
7592     ok(r == ERROR_UNKNOWN_PRODUCT,
7593        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7594     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7595
7596     lstrcpyA(val, path);
7597     lstrcatA(val, "\\winetest.msi");
7598     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7599                          (const BYTE *)val, lstrlenA(val) + 1);
7600     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7601
7602     /* ManagedLocalPackage value exists */
7603     hprod = 0xdeadbeef;
7604     r = MsiOpenProductA(prodcode, &hprod);
7605     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7606     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7607
7608     size = MAX_PATH;
7609     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7610     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7611     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7612     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7613
7614     MsiCloseHandle(hprod);
7615
7616     RegDeleteValueA(props, "ManagedLocalPackage");
7617     delete_key(props, "", access & KEY_WOW64_64KEY);
7618     RegCloseKey(props);
7619     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7620     RegCloseKey(userkey);
7621     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7622     RegCloseKey(prodkey);
7623
7624     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7625
7626     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7627     lstrcatA(keypath, prod_squashed);
7628
7629     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7631
7632     /* unmanaged product key exists */
7633     hprod = 0xdeadbeef;
7634     r = MsiOpenProductA(prodcode, &hprod);
7635     ok(r == ERROR_UNKNOWN_PRODUCT,
7636        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7637     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7638
7639     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7640     lstrcatA(keypath, "Installer\\UserData\\");
7641     lstrcatA(keypath, usersid);
7642     lstrcatA(keypath, "\\Products\\");
7643     lstrcatA(keypath, prod_squashed);
7644
7645     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7646     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7647
7648     /* user product key exists */
7649     hprod = 0xdeadbeef;
7650     r = MsiOpenProductA(prodcode, &hprod);
7651     ok(r == ERROR_UNKNOWN_PRODUCT,
7652        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7653     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7654
7655     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7657
7658     /* InstallProperties key exists */
7659     hprod = 0xdeadbeef;
7660     r = MsiOpenProductA(prodcode, &hprod);
7661     ok(r == ERROR_UNKNOWN_PRODUCT,
7662        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7663     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7664
7665     lstrcpyA(val, path);
7666     lstrcatA(val, "\\winetest.msi");
7667     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7668                          (const BYTE *)val, lstrlenA(val) + 1);
7669     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7670
7671     /* LocalPackage value exists */
7672     hprod = 0xdeadbeef;
7673     r = MsiOpenProductA(prodcode, &hprod);
7674     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7675     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7676
7677     size = MAX_PATH;
7678     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7679     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7680     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7681     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7682
7683     MsiCloseHandle(hprod);
7684
7685     RegDeleteValueA(props, "LocalPackage");
7686     delete_key(props, "", access & KEY_WOW64_64KEY);
7687     RegCloseKey(props);
7688     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7689     RegCloseKey(userkey);
7690     RegDeleteKeyA(prodkey, "");
7691     RegCloseKey(prodkey);
7692
7693     /* MSIINSTALLCONTEXT_MACHINE */
7694
7695     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7696     lstrcatA(keypath, prod_squashed);
7697
7698     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7700
7701     /* managed product key exists */
7702     hprod = 0xdeadbeef;
7703     r = MsiOpenProductA(prodcode, &hprod);
7704     ok(r == ERROR_UNKNOWN_PRODUCT,
7705        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7706     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7707
7708     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7709     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7710     lstrcatA(keypath, prod_squashed);
7711
7712     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7714
7715     /* user product key exists */
7716     hprod = 0xdeadbeef;
7717     r = MsiOpenProductA(prodcode, &hprod);
7718     ok(r == ERROR_UNKNOWN_PRODUCT,
7719        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7720     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7721
7722     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7723     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7724
7725     /* InstallProperties key exists */
7726     hprod = 0xdeadbeef;
7727     r = MsiOpenProductA(prodcode, &hprod);
7728     ok(r == ERROR_UNKNOWN_PRODUCT,
7729        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7730     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7731
7732     lstrcpyA(val, path);
7733     lstrcatA(val, "\\winetest.msi");
7734     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7735                          (const BYTE *)val, lstrlenA(val) + 1);
7736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7737
7738     /* LocalPackage value exists */
7739     hprod = 0xdeadbeef;
7740     r = MsiOpenProductA(prodcode, &hprod);
7741     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7742     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7743
7744     size = MAX_PATH;
7745     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7746     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7747     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7748     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7749
7750     MsiCloseHandle(hprod);
7751
7752     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7753                          (const BYTE *)"winetest.msi", 13);
7754     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7755
7756     /* LocalPackage has just the package name */
7757     hprod = 0xdeadbeef;
7758     r = MsiOpenProductA(prodcode, &hprod);
7759     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7760        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7761     if (r == ERROR_SUCCESS)
7762         MsiCloseHandle(hprod);
7763     else
7764         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7765
7766     lstrcpyA(val, path);
7767     lstrcatA(val, "\\winetest.msi");
7768     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7769                          (const BYTE *)val, lstrlenA(val) + 1);
7770     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7771
7772     DeleteFileA(msifile);
7773
7774     /* local package does not exist */
7775     hprod = 0xdeadbeef;
7776     r = MsiOpenProductA(prodcode, &hprod);
7777     ok(r == ERROR_UNKNOWN_PRODUCT,
7778        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7779     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7780
7781     RegDeleteValueA(props, "LocalPackage");
7782     delete_key(props, "", access & KEY_WOW64_64KEY);
7783     RegCloseKey(props);
7784     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7785     RegCloseKey(userkey);
7786     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7787     RegCloseKey(prodkey);
7788
7789     DeleteFileA(msifile);
7790     LocalFree(usersid);
7791 }
7792
7793 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7794 {
7795     MSIINSTALLCONTEXT context;
7796     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7797     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7798     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7799     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7800     HKEY prodkey, patches, udprod, udpatch, hpatch;
7801     DWORD size, data;
7802     LONG res;
7803     UINT r;
7804     REGSAM access = KEY_ALL_ACCESS;
7805     BOOL wow64;
7806
7807     create_test_guid(prodcode, prod_squashed);
7808     create_test_guid(patch, patch_squashed);
7809
7810     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
7811         access |= KEY_WOW64_64KEY;
7812
7813     /* MSIPATCHSTATE_APPLIED */
7814
7815     lstrcpyA(patchcode, "apple");
7816     lstrcpyA(targetprod, "banana");
7817     context = 0xdeadbeef;
7818     lstrcpyA(targetsid, "kiwi");
7819     size = MAX_PATH;
7820     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7821                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7822                            &context, targetsid, &size);
7823     if (r == ERROR_ACCESS_DENIED)
7824     {
7825         skip("Not enough rights to perform tests\n");
7826         return;
7827     }
7828     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7829     ok(!lstrcmpA(patchcode, "apple"),
7830        "Expected patchcode to be unchanged, got %s\n", patchcode);
7831     ok(!lstrcmpA(targetprod, "banana"),
7832        "Expected targetprod to be unchanged, got %s\n", targetprod);
7833     ok(context == 0xdeadbeef,
7834        "Expected context to be unchanged, got %d\n", context);
7835     ok(!lstrcmpA(targetsid, "kiwi"),
7836        "Expected targetsid to be unchanged, got %s\n", targetsid);
7837     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7838
7839     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7840     lstrcatA(keypath, expectedsid);
7841     lstrcatA(keypath, "\\Installer\\Products\\");
7842     lstrcatA(keypath, prod_squashed);
7843
7844     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7845     if (res == ERROR_ACCESS_DENIED)
7846     {
7847         skip("Not enough rights to perform tests\n");
7848         return;
7849     }
7850     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7851
7852     /* managed product key exists */
7853     lstrcpyA(patchcode, "apple");
7854     lstrcpyA(targetprod, "banana");
7855     context = 0xdeadbeef;
7856     lstrcpyA(targetsid, "kiwi");
7857     size = MAX_PATH;
7858     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7859                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7860                            &context, targetsid, &size);
7861     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7862     ok(!lstrcmpA(patchcode, "apple"),
7863        "Expected patchcode to be unchanged, got %s\n", patchcode);
7864     ok(!lstrcmpA(targetprod, "banana"),
7865        "Expected targetprod to be unchanged, got %s\n", targetprod);
7866     ok(context == 0xdeadbeef,
7867        "Expected context to be unchanged, got %d\n", context);
7868     ok(!lstrcmpA(targetsid, "kiwi"),
7869        "Expected targetsid to be unchanged, got %s\n", targetsid);
7870     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7871
7872     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
7873     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7874
7875     /* patches key exists */
7876     lstrcpyA(patchcode, "apple");
7877     lstrcpyA(targetprod, "banana");
7878     context = 0xdeadbeef;
7879     lstrcpyA(targetsid, "kiwi");
7880     size = MAX_PATH;
7881     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7882                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7883                            &context, targetsid, &size);
7884     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7885     ok(!lstrcmpA(patchcode, "apple"),
7886        "Expected patchcode to be unchanged, got %s\n", patchcode);
7887     ok(!lstrcmpA(targetprod, "banana"),
7888        "Expected targetprod to be unchanged, got %s\n", targetprod);
7889     ok(context == 0xdeadbeef,
7890        "Expected context to be unchanged, got %d\n", context);
7891     ok(!lstrcmpA(targetsid, "kiwi"),
7892        "Expected targetsid to be unchanged, got %s\n", targetsid);
7893     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7894
7895     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7896                          (const BYTE *)patch_squashed,
7897                          lstrlenA(patch_squashed) + 1);
7898     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7899
7900     /* Patches value exists, is not REG_MULTI_SZ */
7901     lstrcpyA(patchcode, "apple");
7902     lstrcpyA(targetprod, "banana");
7903     context = 0xdeadbeef;
7904     lstrcpyA(targetsid, "kiwi");
7905     size = MAX_PATH;
7906     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7907                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7908                            &context, targetsid, &size);
7909     ok(r == ERROR_BAD_CONFIGURATION,
7910        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7911     ok(!lstrcmpA(patchcode, "apple"),
7912        "Expected patchcode to be unchanged, got %s\n", patchcode);
7913     ok(!lstrcmpA(targetprod, "banana"),
7914        "Expected targetprod to be unchanged, got %s\n", targetprod);
7915     ok(context == 0xdeadbeef,
7916        "Expected context to be unchanged, got %d\n", context);
7917     ok(!lstrcmpA(targetsid, "kiwi"),
7918        "Expected targetsid to be unchanged, got %s\n", targetsid);
7919     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7920
7921     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7922                          (const BYTE *)"a\0b\0c\0\0", 7);
7923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7924
7925     /* Patches value exists, is not a squashed guid */
7926     lstrcpyA(patchcode, "apple");
7927     lstrcpyA(targetprod, "banana");
7928     context = 0xdeadbeef;
7929     lstrcpyA(targetsid, "kiwi");
7930     size = MAX_PATH;
7931     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7932                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7933                            &context, targetsid, &size);
7934     ok(r == ERROR_BAD_CONFIGURATION,
7935        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7936     ok(!lstrcmpA(patchcode, "apple"),
7937        "Expected patchcode to be unchanged, got %s\n", patchcode);
7938     ok(!lstrcmpA(targetprod, "banana"),
7939        "Expected targetprod to be unchanged, got %s\n", targetprod);
7940     ok(context == 0xdeadbeef,
7941        "Expected context to be unchanged, got %d\n", context);
7942     ok(!lstrcmpA(targetsid, "kiwi"),
7943        "Expected targetsid to be unchanged, got %s\n", targetsid);
7944     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7945
7946     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
7947     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7948                          (const BYTE *)patch_squashed,
7949                          lstrlenA(patch_squashed) + 2);
7950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7951
7952     /* Patches value exists */
7953     lstrcpyA(patchcode, "apple");
7954     lstrcpyA(targetprod, "banana");
7955     context = 0xdeadbeef;
7956     lstrcpyA(targetsid, "kiwi");
7957     size = MAX_PATH;
7958     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7959                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7960                            &context, targetsid, &size);
7961     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7962     ok(!lstrcmpA(patchcode, "apple"),
7963        "Expected patchcode to be unchanged, got %s\n", patchcode);
7964     ok(!lstrcmpA(targetprod, "banana"),
7965        "Expected targetprod to be unchanged, got %s\n", targetprod);
7966     ok(context == 0xdeadbeef,
7967        "Expected context to be unchanged, got %d\n", context);
7968     ok(!lstrcmpA(targetsid, "kiwi"),
7969        "Expected targetsid to be unchanged, got %s\n", targetsid);
7970     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7971
7972     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7973                          (const BYTE *)"whatever", 9);
7974     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7975
7976     /* patch squashed value exists */
7977     lstrcpyA(patchcode, "apple");
7978     lstrcpyA(targetprod, "banana");
7979     context = 0xdeadbeef;
7980     lstrcpyA(targetsid, "kiwi");
7981     size = MAX_PATH;
7982     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7983                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7984                            &context, targetsid, &size);
7985     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7986     ok(!lstrcmpA(patchcode, patch),
7987        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7988     ok(!lstrcmpA(targetprod, prodcode),
7989        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7990     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7991        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7992     ok(!lstrcmpA(targetsid, expectedsid),
7993        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7994     ok(size == lstrlenA(expectedsid),
7995        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7996
7997     /* increase the index */
7998     lstrcpyA(patchcode, "apple");
7999     lstrcpyA(targetprod, "banana");
8000     context = 0xdeadbeef;
8001     lstrcpyA(targetsid, "kiwi");
8002     size = MAX_PATH;
8003     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8004                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
8005                            &context, targetsid, &size);
8006     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8007     ok(!lstrcmpA(patchcode, "apple"),
8008        "Expected patchcode to be unchanged, got %s\n", patchcode);
8009     ok(!lstrcmpA(targetprod, "banana"),
8010        "Expected targetprod to be unchanged, got %s\n", targetprod);
8011     ok(context == 0xdeadbeef,
8012        "Expected context to be unchanged, got %d\n", context);
8013     ok(!lstrcmpA(targetsid, "kiwi"),
8014        "Expected targetsid to be unchanged, got %s\n", targetsid);
8015     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8016
8017     /* increase again */
8018     lstrcpyA(patchcode, "apple");
8019     lstrcpyA(targetprod, "banana");
8020     context = 0xdeadbeef;
8021     lstrcpyA(targetsid, "kiwi");
8022     size = MAX_PATH;
8023     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8024                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
8025                            &context, targetsid, &size);
8026     ok(r == ERROR_INVALID_PARAMETER,
8027        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8028     ok(!lstrcmpA(patchcode, "apple"),
8029        "Expected patchcode to be unchanged, got %s\n", patchcode);
8030     ok(!lstrcmpA(targetprod, "banana"),
8031        "Expected targetprod to be unchanged, got %s\n", targetprod);
8032     ok(context == 0xdeadbeef,
8033        "Expected context to be unchanged, got %d\n", context);
8034     ok(!lstrcmpA(targetsid, "kiwi"),
8035        "Expected targetsid to be unchanged, got %s\n", targetsid);
8036     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8037
8038     /* szPatchCode is NULL */
8039     lstrcpyA(targetprod, "banana");
8040     context = 0xdeadbeef;
8041     lstrcpyA(targetsid, "kiwi");
8042     size = MAX_PATH;
8043     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8044                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
8045                            &context, targetsid, &size);
8046     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8047     ok(!lstrcmpA(targetprod, prodcode),
8048        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8049     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8050        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8051     ok(!lstrcmpA(targetsid, expectedsid),
8052        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8053     ok(size == lstrlenA(expectedsid),
8054        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8055
8056     /* szTargetProductCode is NULL */
8057     lstrcpyA(patchcode, "apple");
8058     context = 0xdeadbeef;
8059     lstrcpyA(targetsid, "kiwi");
8060     size = MAX_PATH;
8061     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8062                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
8063                            &context, targetsid, &size);
8064     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8065     ok(!lstrcmpA(patchcode, patch),
8066        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8067     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8068        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8069     ok(!lstrcmpA(targetsid, expectedsid),
8070        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8071     ok(size == lstrlenA(expectedsid),
8072        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8073
8074     /* pdwTargetProductContext is NULL */
8075     lstrcpyA(patchcode, "apple");
8076     lstrcpyA(targetprod, "banana");
8077     lstrcpyA(targetsid, "kiwi");
8078     size = MAX_PATH;
8079     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8080                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8081                            NULL, targetsid, &size);
8082     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8083     ok(!lstrcmpA(patchcode, patch),
8084        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8085     ok(!lstrcmpA(targetprod, prodcode),
8086        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8087     ok(!lstrcmpA(targetsid, expectedsid),
8088        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8089     ok(size == lstrlenA(expectedsid),
8090        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8091
8092     /* szTargetUserSid is NULL */
8093     lstrcpyA(patchcode, "apple");
8094     lstrcpyA(targetprod, "banana");
8095     context = 0xdeadbeef;
8096     size = MAX_PATH;
8097     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8098                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8099                            &context, NULL, &size);
8100     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8101     ok(!lstrcmpA(patchcode, patch),
8102        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8103     ok(!lstrcmpA(targetprod, prodcode),
8104        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8105     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8106        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8107     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8108        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8109
8110     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
8111     lstrcpyA(patchcode, "apple");
8112     lstrcpyA(targetprod, "banana");
8113     context = 0xdeadbeef;
8114     lstrcpyA(targetsid, "kiwi");
8115     size = lstrlenA(expectedsid);
8116     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8117                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8118                            &context, targetsid, &size);
8119     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8120     ok(!lstrcmpA(patchcode, patch),
8121        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8122     ok(!lstrcmpA(targetprod, prodcode),
8123        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8124     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8125        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8126     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
8127        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8128     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8129        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8130
8131     /* pcchTargetUserSid has enough room for NULL terminator */
8132     lstrcpyA(patchcode, "apple");
8133     lstrcpyA(targetprod, "banana");
8134     context = 0xdeadbeef;
8135     lstrcpyA(targetsid, "kiwi");
8136     size = lstrlenA(expectedsid) + 1;
8137     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8138                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8139                            &context, targetsid, &size);
8140     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8141     ok(!lstrcmpA(patchcode, patch),
8142        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8143     ok(!lstrcmpA(targetprod, prodcode),
8144        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8145     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8146        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8147     ok(!lstrcmpA(targetsid, expectedsid),
8148        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8149     ok(size == lstrlenA(expectedsid),
8150        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8151
8152     /* both szTargetuserSid and pcchTargetUserSid are NULL */
8153     lstrcpyA(patchcode, "apple");
8154     lstrcpyA(targetprod, "banana");
8155     context = 0xdeadbeef;
8156     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8157                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8158                            &context, NULL, NULL);
8159     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8160     ok(!lstrcmpA(patchcode, patch),
8161        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8162     ok(!lstrcmpA(targetprod, prodcode),
8163        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8164     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8165        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8166
8167     /* MSIPATCHSTATE_SUPERSEDED */
8168
8169     lstrcpyA(patchcode, "apple");
8170     lstrcpyA(targetprod, "banana");
8171     context = 0xdeadbeef;
8172     lstrcpyA(targetsid, "kiwi");
8173     size = MAX_PATH;
8174     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8175                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8176                            &context, targetsid, &size);
8177     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8178     ok(!lstrcmpA(patchcode, "apple"),
8179        "Expected patchcode to be unchanged, got %s\n", patchcode);
8180     ok(!lstrcmpA(targetprod, "banana"),
8181        "Expected targetprod to be unchanged, got %s\n", targetprod);
8182     ok(context == 0xdeadbeef,
8183        "Expected context to be unchanged, got %d\n", context);
8184     ok(!lstrcmpA(targetsid, "kiwi"),
8185        "Expected targetsid to be unchanged, got %s\n", targetsid);
8186     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8187
8188     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8189     lstrcatA(keypath, expectedsid);
8190     lstrcatA(keypath, "\\Products\\");
8191     lstrcatA(keypath, prod_squashed);
8192
8193     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8194     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8195
8196     /* UserData product key exists */
8197     lstrcpyA(patchcode, "apple");
8198     lstrcpyA(targetprod, "banana");
8199     context = 0xdeadbeef;
8200     lstrcpyA(targetsid, "kiwi");
8201     size = MAX_PATH;
8202     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8203                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8204                            &context, targetsid, &size);
8205     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8206     ok(!lstrcmpA(patchcode, "apple"),
8207        "Expected patchcode to be unchanged, got %s\n", patchcode);
8208     ok(!lstrcmpA(targetprod, "banana"),
8209        "Expected targetprod to be unchanged, got %s\n", targetprod);
8210     ok(context == 0xdeadbeef,
8211        "Expected context to be unchanged, got %d\n", context);
8212     ok(!lstrcmpA(targetsid, "kiwi"),
8213        "Expected targetsid to be unchanged, got %s\n", targetsid);
8214     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8215
8216     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8218
8219     /* UserData patches key exists */
8220     lstrcpyA(patchcode, "apple");
8221     lstrcpyA(targetprod, "banana");
8222     context = 0xdeadbeef;
8223     lstrcpyA(targetsid, "kiwi");
8224     size = MAX_PATH;
8225     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8226                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8227                            &context, targetsid, &size);
8228     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8229     ok(!lstrcmpA(patchcode, "apple"),
8230        "Expected patchcode to be unchanged, got %s\n", patchcode);
8231     ok(!lstrcmpA(targetprod, "banana"),
8232        "Expected targetprod to be unchanged, got %s\n", targetprod);
8233     ok(context == 0xdeadbeef,
8234        "Expected context to be unchanged, got %d\n", context);
8235     ok(!lstrcmpA(targetsid, "kiwi"),
8236        "Expected targetsid to be unchanged, got %s\n", targetsid);
8237     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8238
8239     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8240     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8241
8242     /* specific UserData patch key exists */
8243     lstrcpyA(patchcode, "apple");
8244     lstrcpyA(targetprod, "banana");
8245     context = 0xdeadbeef;
8246     lstrcpyA(targetsid, "kiwi");
8247     size = MAX_PATH;
8248     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8249                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8250                            &context, targetsid, &size);
8251     ok(r == ERROR_BAD_CONFIGURATION,
8252        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8253     ok(!lstrcmpA(patchcode, "apple"),
8254        "Expected patchcode to be unchanged, got %s\n", patchcode);
8255     ok(!lstrcmpA(targetprod, "banana"),
8256        "Expected targetprod to be unchanged, got %s\n", targetprod);
8257     ok(context == 0xdeadbeef,
8258        "Expected context to be unchanged, got %d\n", context);
8259     ok(!lstrcmpA(targetsid, "kiwi"),
8260        "Expected targetsid to be unchanged, got %s\n", targetsid);
8261     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8262
8263     data = MSIPATCHSTATE_SUPERSEDED;
8264     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8265                          (const BYTE *)&data, sizeof(DWORD));
8266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8267
8268     /* State value exists */
8269     lstrcpyA(patchcode, "apple");
8270     lstrcpyA(targetprod, "banana");
8271     context = 0xdeadbeef;
8272     lstrcpyA(targetsid, "kiwi");
8273     size = MAX_PATH;
8274     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8275                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8276                            &context, targetsid, &size);
8277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8278     ok(!lstrcmpA(patchcode, patch),
8279        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8280     ok(!lstrcmpA(targetprod, prodcode),
8281        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8282     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8283        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8284     ok(!lstrcmpA(targetsid, expectedsid),
8285        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8286     ok(size == lstrlenA(expectedsid),
8287        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8288
8289     /* MSIPATCHSTATE_OBSOLETED */
8290
8291     lstrcpyA(patchcode, "apple");
8292     lstrcpyA(targetprod, "banana");
8293     context = 0xdeadbeef;
8294     lstrcpyA(targetsid, "kiwi");
8295     size = MAX_PATH;
8296     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8297                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8298                            &context, targetsid, &size);
8299     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8300     ok(!lstrcmpA(patchcode, "apple"),
8301        "Expected patchcode to be unchanged, got %s\n", patchcode);
8302     ok(!lstrcmpA(targetprod, "banana"),
8303        "Expected targetprod to be unchanged, got %s\n", targetprod);
8304     ok(context == 0xdeadbeef,
8305        "Expected context to be unchanged, got %d\n", context);
8306     ok(!lstrcmpA(targetsid, "kiwi"),
8307        "Expected targetsid to be unchanged, got %s\n", targetsid);
8308     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8309
8310     data = MSIPATCHSTATE_OBSOLETED;
8311     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8312                          (const BYTE *)&data, sizeof(DWORD));
8313     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8314
8315     /* State value is obsoleted */
8316     lstrcpyA(patchcode, "apple");
8317     lstrcpyA(targetprod, "banana");
8318     context = 0xdeadbeef;
8319     lstrcpyA(targetsid, "kiwi");
8320     size = MAX_PATH;
8321     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8322                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8323                            &context, targetsid, &size);
8324     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8325     ok(!lstrcmpA(patchcode, patch),
8326        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8327     ok(!lstrcmpA(targetprod, prodcode),
8328        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8329     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8330        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8331     ok(!lstrcmpA(targetsid, expectedsid),
8332        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8333     ok(size == lstrlenA(expectedsid),
8334        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8335
8336     /* MSIPATCHSTATE_REGISTERED */
8337     /* FIXME */
8338
8339     /* MSIPATCHSTATE_ALL */
8340
8341     /* 1st */
8342     lstrcpyA(patchcode, "apple");
8343     lstrcpyA(targetprod, "banana");
8344     context = 0xdeadbeef;
8345     lstrcpyA(targetsid, "kiwi");
8346     size = MAX_PATH;
8347     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8348                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8349                            &context, targetsid, &size);
8350     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8351     ok(!lstrcmpA(patchcode, patch),
8352        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8353     ok(!lstrcmpA(targetprod, prodcode),
8354        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8355     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8356        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8357     ok(!lstrcmpA(targetsid, expectedsid),
8358        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8359     ok(size == lstrlenA(expectedsid),
8360        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8361
8362     /* same patch in multiple places, only one is enumerated */
8363     lstrcpyA(patchcode, "apple");
8364     lstrcpyA(targetprod, "banana");
8365     context = 0xdeadbeef;
8366     lstrcpyA(targetsid, "kiwi");
8367     size = MAX_PATH;
8368     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8369                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8370                            &context, targetsid, &size);
8371     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8372     ok(!lstrcmpA(patchcode, "apple"),
8373        "Expected patchcode to be unchanged, got %s\n", patchcode);
8374     ok(!lstrcmpA(targetprod, "banana"),
8375        "Expected targetprod to be unchanged, got %s\n", targetprod);
8376     ok(context == 0xdeadbeef,
8377        "Expected context to be unchanged, got %d\n", context);
8378     ok(!lstrcmpA(targetsid, "kiwi"),
8379        "Expected targetsid to be unchanged, got %s\n", targetsid);
8380     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8381
8382     RegDeleteValueA(hpatch, "State");
8383     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8384     RegCloseKey(hpatch);
8385     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8386     RegCloseKey(udpatch);
8387     delete_key(udprod, "", access & KEY_WOW64_64KEY);
8388     RegCloseKey(udprod);
8389     RegDeleteValueA(patches, "Patches");
8390     delete_key(patches, "", access & KEY_WOW64_64KEY);
8391     RegCloseKey(patches);
8392     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8393     RegCloseKey(prodkey);
8394 }
8395
8396 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8397 {
8398     MSIINSTALLCONTEXT context;
8399     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8400     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8401     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8402     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8403     HKEY prodkey, patches, udprod, udpatch;
8404     HKEY userkey, hpatch;
8405     DWORD size, data;
8406     LONG res;
8407     UINT r;
8408     REGSAM access = KEY_ALL_ACCESS;
8409     BOOL wow64;
8410
8411     create_test_guid(prodcode, prod_squashed);
8412     create_test_guid(patch, patch_squashed);
8413
8414     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
8415         access |= KEY_WOW64_64KEY;
8416
8417     /* MSIPATCHSTATE_APPLIED */
8418
8419     lstrcpyA(patchcode, "apple");
8420     lstrcpyA(targetprod, "banana");
8421     context = 0xdeadbeef;
8422     lstrcpyA(targetsid, "kiwi");
8423     size = MAX_PATH;
8424     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8425                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8426                            &context, targetsid, &size);
8427     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8428     ok(!lstrcmpA(patchcode, "apple"),
8429        "Expected patchcode to be unchanged, got %s\n", patchcode);
8430     ok(!lstrcmpA(targetprod, "banana"),
8431        "Expected targetprod to be unchanged, got %s\n", targetprod);
8432     ok(context == 0xdeadbeef,
8433        "Expected context to be unchanged, got %d\n", context);
8434     ok(!lstrcmpA(targetsid, "kiwi"),
8435        "Expected targetsid to be unchanged, got %s\n", targetsid);
8436     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8437
8438     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8439     lstrcatA(keypath, prod_squashed);
8440
8441     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8442     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8443
8444     /* current user product key exists */
8445     lstrcpyA(patchcode, "apple");
8446     lstrcpyA(targetprod, "banana");
8447     context = 0xdeadbeef;
8448     lstrcpyA(targetsid, "kiwi");
8449     size = MAX_PATH;
8450     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8451                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8452                            &context, targetsid, &size);
8453     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8454     ok(!lstrcmpA(patchcode, "apple"),
8455        "Expected patchcode to be unchanged, got %s\n", patchcode);
8456     ok(!lstrcmpA(targetprod, "banana"),
8457        "Expected targetprod to be unchanged, got %s\n", targetprod);
8458     ok(context == 0xdeadbeef,
8459        "Expected context to be unchanged, got %d\n", context);
8460     ok(!lstrcmpA(targetsid, "kiwi"),
8461        "Expected targetsid to be unchanged, got %s\n", targetsid);
8462     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8463
8464     res = RegCreateKeyA(prodkey, "Patches", &patches);
8465     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8466
8467     /* Patches key exists */
8468     lstrcpyA(patchcode, "apple");
8469     lstrcpyA(targetprod, "banana");
8470     context = 0xdeadbeef;
8471     lstrcpyA(targetsid, "kiwi");
8472     size = MAX_PATH;
8473     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8474                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8475                            &context, targetsid, &size);
8476     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8477     ok(!lstrcmpA(patchcode, "apple"),
8478        "Expected patchcode to be unchanged, got %s\n", patchcode);
8479     ok(!lstrcmpA(targetprod, "banana"),
8480        "Expected targetprod to be unchanged, got %s\n", targetprod);
8481     ok(context == 0xdeadbeef,
8482        "Expected context to be unchanged, got %d\n", context);
8483     ok(!lstrcmpA(targetsid, "kiwi"),
8484        "Expected targetsid to be unchanged, got %s\n", targetsid);
8485     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8486
8487     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8488                          (const BYTE *)patch_squashed,
8489                          lstrlenA(patch_squashed) + 1);
8490     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8491
8492     /* Patches value exists, is not REG_MULTI_SZ */
8493     lstrcpyA(patchcode, "apple");
8494     lstrcpyA(targetprod, "banana");
8495     context = 0xdeadbeef;
8496     lstrcpyA(targetsid, "kiwi");
8497     size = MAX_PATH;
8498     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8499                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8500                            &context, targetsid, &size);
8501     ok(r == ERROR_BAD_CONFIGURATION,
8502        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8503     ok(!lstrcmpA(patchcode, "apple"),
8504        "Expected patchcode to be unchanged, got %s\n", patchcode);
8505     ok(!lstrcmpA(targetprod, "banana"),
8506        "Expected targetprod to be unchanged, got %s\n", targetprod);
8507     ok(context == 0xdeadbeef,
8508        "Expected context to be unchanged, got %d\n", context);
8509     ok(!lstrcmpA(targetsid, "kiwi"),
8510        "Expected targetsid to be unchanged, got %s\n", targetsid);
8511     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8512
8513     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8514                          (const BYTE *)"a\0b\0c\0\0", 7);
8515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8516
8517     /* Patches value exists, is not a squashed guid */
8518     lstrcpyA(patchcode, "apple");
8519     lstrcpyA(targetprod, "banana");
8520     context = 0xdeadbeef;
8521     lstrcpyA(targetsid, "kiwi");
8522     size = MAX_PATH;
8523     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8524                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8525                            &context, targetsid, &size);
8526     ok(r == ERROR_BAD_CONFIGURATION,
8527        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8528     ok(!lstrcmpA(patchcode, "apple"),
8529        "Expected patchcode to be unchanged, got %s\n", patchcode);
8530     ok(!lstrcmpA(targetprod, "banana"),
8531        "Expected targetprod to be unchanged, got %s\n", targetprod);
8532     ok(context == 0xdeadbeef,
8533        "Expected context to be unchanged, got %d\n", context);
8534     ok(!lstrcmpA(targetsid, "kiwi"),
8535        "Expected targetsid to be unchanged, got %s\n", targetsid);
8536     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8537
8538     patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
8539     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8540                          (const BYTE *)patch_squashed,
8541                          lstrlenA(patch_squashed) + 2);
8542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8543
8544     /* Patches value exists */
8545     lstrcpyA(patchcode, "apple");
8546     lstrcpyA(targetprod, "banana");
8547     context = 0xdeadbeef;
8548     lstrcpyA(targetsid, "kiwi");
8549     size = MAX_PATH;
8550     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8551                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8552                            &context, targetsid, &size);
8553     ok(r == ERROR_NO_MORE_ITEMS ||
8554        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8555        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8556     ok(!lstrcmpA(patchcode, "apple"),
8557        "Expected patchcode to be unchanged, got %s\n", patchcode);
8558     ok(!lstrcmpA(targetprod, "banana"),
8559        "Expected targetprod to be unchanged, got %s\n", targetprod);
8560     ok(context == 0xdeadbeef,
8561        "Expected context to be unchanged, got %d\n", context);
8562     ok(!lstrcmpA(targetsid, "kiwi"),
8563        "Expected targetsid to be unchanged, got %s\n", targetsid);
8564     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8565
8566     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8567                          (const BYTE *)"whatever", 9);
8568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8569
8570     /* patch code value exists */
8571     lstrcpyA(patchcode, "apple");
8572     lstrcpyA(targetprod, "banana");
8573     context = 0xdeadbeef;
8574     lstrcpyA(targetsid, "kiwi");
8575     size = MAX_PATH;
8576     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8577                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8578                            &context, targetsid, &size);
8579     ok(r == ERROR_NO_MORE_ITEMS ||
8580        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8581        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8582     ok(!lstrcmpA(patchcode, "apple"),
8583        "Expected patchcode to be unchanged, got %s\n", patchcode);
8584     ok(!lstrcmpA(targetprod, "banana"),
8585        "Expected targetprod to be unchanged, got %s\n", targetprod);
8586     ok(context == 0xdeadbeef,
8587        "Expected context to be unchanged, got %d\n", context);
8588     ok(!lstrcmpA(targetsid, "kiwi"),
8589        "Expected targetsid to be unchanged, got %s\n", targetsid);
8590     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8591
8592     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8593     lstrcatA(keypath, expectedsid);
8594     lstrcatA(keypath, "\\Patches\\");
8595     lstrcatA(keypath, patch_squashed);
8596
8597     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8598     if (res == ERROR_ACCESS_DENIED)
8599     {
8600         skip("Not enough rights to perform tests\n");
8601         goto error;
8602     }
8603     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8604
8605     /* userdata patch key exists */
8606     lstrcpyA(patchcode, "apple");
8607     lstrcpyA(targetprod, "banana");
8608     context = 0xdeadbeef;
8609     lstrcpyA(targetsid, "kiwi");
8610     size = MAX_PATH;
8611     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8612                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8613                            &context, targetsid, &size);
8614     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8615     ok(!lstrcmpA(patchcode, patch),
8616        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8617     ok(!lstrcmpA(targetprod, prodcode),
8618        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8619     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8620        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8621     ok(!lstrcmpA(targetsid, expectedsid),
8622        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8623     ok(size == lstrlenA(expectedsid),
8624        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8625
8626     /* MSIPATCHSTATE_SUPERSEDED */
8627
8628     lstrcpyA(patchcode, "apple");
8629     lstrcpyA(targetprod, "banana");
8630     context = 0xdeadbeef;
8631     lstrcpyA(targetsid, "kiwi");
8632     size = MAX_PATH;
8633     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8634                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8635                            &context, targetsid, &size);
8636     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8637     ok(!lstrcmpA(patchcode, "apple"),
8638        "Expected patchcode to be unchanged, got %s\n", patchcode);
8639     ok(!lstrcmpA(targetprod, "banana"),
8640        "Expected targetprod to be unchanged, got %s\n", targetprod);
8641     ok(context == 0xdeadbeef,
8642        "Expected context to be unchanged, got %d\n", context);
8643     ok(!lstrcmpA(targetsid, "kiwi"),
8644        "Expected targetsid to be unchanged, got %s\n", targetsid);
8645     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8646
8647     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8648     lstrcatA(keypath, expectedsid);
8649     lstrcatA(keypath, "\\Products\\");
8650     lstrcatA(keypath, prod_squashed);
8651
8652     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8654
8655     /* UserData product key exists */
8656     lstrcpyA(patchcode, "apple");
8657     lstrcpyA(targetprod, "banana");
8658     context = 0xdeadbeef;
8659     lstrcpyA(targetsid, "kiwi");
8660     size = MAX_PATH;
8661     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8662                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8663                            &context, targetsid, &size);
8664     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8665     ok(!lstrcmpA(patchcode, "apple"),
8666        "Expected patchcode to be unchanged, got %s\n", patchcode);
8667     ok(!lstrcmpA(targetprod, "banana"),
8668        "Expected targetprod to be unchanged, got %s\n", targetprod);
8669     ok(context == 0xdeadbeef,
8670        "Expected context to be unchanged, got %d\n", context);
8671     ok(!lstrcmpA(targetsid, "kiwi"),
8672        "Expected targetsid to be unchanged, got %s\n", targetsid);
8673     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8674
8675     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8676     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8677
8678     /* UserData patches key exists */
8679     lstrcpyA(patchcode, "apple");
8680     lstrcpyA(targetprod, "banana");
8681     context = 0xdeadbeef;
8682     lstrcpyA(targetsid, "kiwi");
8683     size = MAX_PATH;
8684     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8685                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8686                            &context, targetsid, &size);
8687     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8688     ok(!lstrcmpA(patchcode, "apple"),
8689        "Expected patchcode to be unchanged, got %s\n", patchcode);
8690     ok(!lstrcmpA(targetprod, "banana"),
8691        "Expected targetprod to be unchanged, got %s\n", targetprod);
8692     ok(context == 0xdeadbeef,
8693        "Expected context to be unchanged, got %d\n", context);
8694     ok(!lstrcmpA(targetsid, "kiwi"),
8695        "Expected targetsid to be unchanged, got %s\n", targetsid);
8696     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8697
8698     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8700
8701     /* specific UserData patch key exists */
8702     lstrcpyA(patchcode, "apple");
8703     lstrcpyA(targetprod, "banana");
8704     context = 0xdeadbeef;
8705     lstrcpyA(targetsid, "kiwi");
8706     size = MAX_PATH;
8707     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8708                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8709                            &context, targetsid, &size);
8710     ok(r == ERROR_BAD_CONFIGURATION,
8711        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8712     ok(!lstrcmpA(patchcode, "apple"),
8713        "Expected patchcode to be unchanged, got %s\n", patchcode);
8714     ok(!lstrcmpA(targetprod, "banana"),
8715        "Expected targetprod to be unchanged, got %s\n", targetprod);
8716     ok(context == 0xdeadbeef,
8717        "Expected context to be unchanged, got %d\n", context);
8718     ok(!lstrcmpA(targetsid, "kiwi"),
8719        "Expected targetsid to be unchanged, got %s\n", targetsid);
8720     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8721
8722     data = MSIPATCHSTATE_SUPERSEDED;
8723     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8724                          (const BYTE *)&data, sizeof(DWORD));
8725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8726
8727     /* State value exists */
8728     lstrcpyA(patchcode, "apple");
8729     lstrcpyA(targetprod, "banana");
8730     context = 0xdeadbeef;
8731     lstrcpyA(targetsid, "kiwi");
8732     size = MAX_PATH;
8733     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8734                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8735                            &context, targetsid, &size);
8736     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8737     ok(!lstrcmpA(patchcode, patch),
8738        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8739     ok(!lstrcmpA(targetprod, prodcode),
8740        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8741     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8742        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8743     ok(!lstrcmpA(targetsid, expectedsid),
8744        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8745     ok(size == lstrlenA(expectedsid),
8746        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8747
8748     /* MSIPATCHSTATE_OBSOLETED */
8749
8750     lstrcpyA(patchcode, "apple");
8751     lstrcpyA(targetprod, "banana");
8752     context = 0xdeadbeef;
8753     lstrcpyA(targetsid, "kiwi");
8754     size = MAX_PATH;
8755     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8756                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8757                            &context, targetsid, &size);
8758     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8759     ok(!lstrcmpA(patchcode, "apple"),
8760        "Expected patchcode to be unchanged, got %s\n", patchcode);
8761     ok(!lstrcmpA(targetprod, "banana"),
8762        "Expected targetprod to be unchanged, got %s\n", targetprod);
8763     ok(context == 0xdeadbeef,
8764        "Expected context to be unchanged, got %d\n", context);
8765     ok(!lstrcmpA(targetsid, "kiwi"),
8766        "Expected targetsid to be unchanged, got %s\n", targetsid);
8767     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8768
8769     data = MSIPATCHSTATE_OBSOLETED;
8770     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8771                          (const BYTE *)&data, sizeof(DWORD));
8772     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8773
8774     /* State value is obsoleted */
8775     lstrcpyA(patchcode, "apple");
8776     lstrcpyA(targetprod, "banana");
8777     context = 0xdeadbeef;
8778     lstrcpyA(targetsid, "kiwi");
8779     size = MAX_PATH;
8780     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8781                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8782                            &context, targetsid, &size);
8783     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8784     ok(!lstrcmpA(patchcode, patch),
8785        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8786     ok(!lstrcmpA(targetprod, prodcode),
8787        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8788     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8789        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8790     ok(!lstrcmpA(targetsid, expectedsid),
8791        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8792     ok(size == lstrlenA(expectedsid),
8793        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8794
8795     /* MSIPATCHSTATE_REGISTERED */
8796     /* FIXME */
8797
8798     /* MSIPATCHSTATE_ALL */
8799
8800     /* 1st */
8801     lstrcpyA(patchcode, "apple");
8802     lstrcpyA(targetprod, "banana");
8803     context = 0xdeadbeef;
8804     lstrcpyA(targetsid, "kiwi");
8805     size = MAX_PATH;
8806     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8807                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8808                            &context, targetsid, &size);
8809     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8810     ok(!lstrcmpA(patchcode, patch),
8811        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8812     ok(!lstrcmpA(targetprod, prodcode),
8813        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8814     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8815        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8816     ok(!lstrcmpA(targetsid, expectedsid),
8817        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8818     ok(size == lstrlenA(expectedsid),
8819        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8820
8821     /* same patch in multiple places, only one is enumerated */
8822     lstrcpyA(patchcode, "apple");
8823     lstrcpyA(targetprod, "banana");
8824     context = 0xdeadbeef;
8825     lstrcpyA(targetsid, "kiwi");
8826     size = MAX_PATH;
8827     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8828                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8829                            &context, targetsid, &size);
8830     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8831     ok(!lstrcmpA(patchcode, "apple"),
8832        "Expected patchcode to be unchanged, got %s\n", patchcode);
8833     ok(!lstrcmpA(targetprod, "banana"),
8834        "Expected targetprod to be unchanged, got %s\n", targetprod);
8835     ok(context == 0xdeadbeef,
8836        "Expected context to be unchanged, got %d\n", context);
8837     ok(!lstrcmpA(targetsid, "kiwi"),
8838        "Expected targetsid to be unchanged, got %s\n", targetsid);
8839     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8840
8841     RegDeleteValueA(hpatch, "State");
8842     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8843     RegCloseKey(hpatch);
8844     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8845     RegCloseKey(udpatch);
8846     delete_key(udprod, "", access & KEY_WOW64_64KEY);
8847     RegCloseKey(udprod);
8848     delete_key(userkey, "", access & KEY_WOW64_64KEY);
8849     RegCloseKey(userkey);
8850     RegDeleteValueA(patches, patch_squashed);
8851     RegDeleteValueA(patches, "Patches");
8852
8853 error:
8854     RegDeleteKeyA(patches, "");
8855     RegCloseKey(patches);
8856     RegDeleteKeyA(prodkey, "");
8857     RegCloseKey(prodkey);
8858 }
8859
8860 static void test_MsiEnumPatchesEx_machine(void)
8861 {
8862     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8863     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8864     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8865     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8866     HKEY prodkey, patches, udprod, udpatch;
8867     HKEY hpatch;
8868     MSIINSTALLCONTEXT context;
8869     DWORD size, data;
8870     LONG res;
8871     UINT r;
8872     REGSAM access = KEY_ALL_ACCESS;
8873     BOOL wow64;
8874
8875     create_test_guid(prodcode, prod_squashed);
8876     create_test_guid(patch, patch_squashed);
8877
8878     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
8879         access |= KEY_WOW64_64KEY;
8880
8881     /* MSIPATCHSTATE_APPLIED */
8882
8883     lstrcpyA(patchcode, "apple");
8884     lstrcpyA(targetprod, "banana");
8885     context = 0xdeadbeef;
8886     lstrcpyA(targetsid, "kiwi");
8887     size = MAX_PATH;
8888     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8889                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8890                            &context, targetsid, &size);
8891     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8892     ok(!lstrcmpA(patchcode, "apple"),
8893        "Expected patchcode to be unchanged, got %s\n", patchcode);
8894     ok(!lstrcmpA(targetprod, "banana"),
8895        "Expected targetprod to be unchanged, got %s\n", targetprod);
8896     ok(context == 0xdeadbeef,
8897        "Expected context to be unchanged, got %d\n", context);
8898     ok(!lstrcmpA(targetsid, "kiwi"),
8899        "Expected targetsid to be unchanged, got %s\n", targetsid);
8900     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8901
8902     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8903     lstrcatA(keypath, prod_squashed);
8904
8905     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8906     if (res == ERROR_ACCESS_DENIED)
8907     {
8908         skip("Not enough rights to perform tests\n");
8909         return;
8910     }
8911     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8912
8913     /* local product key exists */
8914     lstrcpyA(patchcode, "apple");
8915     lstrcpyA(targetprod, "banana");
8916     context = 0xdeadbeef;
8917     lstrcpyA(targetsid, "kiwi");
8918     size = MAX_PATH;
8919     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8920                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8921                            &context, targetsid, &size);
8922     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8923     ok(!lstrcmpA(patchcode, "apple"),
8924        "Expected patchcode to be unchanged, got %s\n", patchcode);
8925     ok(!lstrcmpA(targetprod, "banana"),
8926        "Expected targetprod to be unchanged, got %s\n", targetprod);
8927     ok(context == 0xdeadbeef,
8928        "Expected context to be unchanged, got %d\n", context);
8929     ok(!lstrcmpA(targetsid, "kiwi"),
8930        "Expected targetsid to be unchanged, got %s\n", targetsid);
8931     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8932
8933     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
8934     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8935
8936     /* Patches key exists */
8937     lstrcpyA(patchcode, "apple");
8938     lstrcpyA(targetprod, "banana");
8939     context = 0xdeadbeef;
8940     lstrcpyA(targetsid, "kiwi");
8941     size = MAX_PATH;
8942     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8943                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8944                            &context, targetsid, &size);
8945     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8946     ok(!lstrcmpA(patchcode, "apple"),
8947        "Expected patchcode to be unchanged, got %s\n", patchcode);
8948     ok(!lstrcmpA(targetprod, "banana"),
8949        "Expected targetprod to be unchanged, got %s\n", targetprod);
8950     ok(context == 0xdeadbeef,
8951        "Expected context to be unchanged, got %d\n", context);
8952     ok(!lstrcmpA(targetsid, "kiwi"),
8953        "Expected targetsid to be unchanged, got %s\n", targetsid);
8954     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8955
8956     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8957                          (const BYTE *)patch_squashed,
8958                          lstrlenA(patch_squashed) + 1);
8959     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8960
8961     /* Patches value exists, is not REG_MULTI_SZ */
8962     lstrcpyA(patchcode, "apple");
8963     lstrcpyA(targetprod, "banana");
8964     context = 0xdeadbeef;
8965     lstrcpyA(targetsid, "kiwi");
8966     size = MAX_PATH;
8967     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8968                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8969                            &context, targetsid, &size);
8970     ok(r == ERROR_BAD_CONFIGURATION,
8971        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8972     ok(!lstrcmpA(patchcode, "apple"),
8973        "Expected patchcode to be unchanged, got %s\n", patchcode);
8974     ok(!lstrcmpA(targetprod, "banana"),
8975        "Expected targetprod to be unchanged, got %s\n", targetprod);
8976     ok(context == 0xdeadbeef,
8977        "Expected context to be unchanged, got %d\n", context);
8978     ok(!lstrcmpA(targetsid, "kiwi"),
8979        "Expected targetsid to be unchanged, got %s\n", targetsid);
8980     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8981
8982     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8983                          (const BYTE *)"a\0b\0c\0\0", 7);
8984     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8985
8986     /* Patches value exists, is not a squashed guid */
8987     lstrcpyA(patchcode, "apple");
8988     lstrcpyA(targetprod, "banana");
8989     context = 0xdeadbeef;
8990     lstrcpyA(targetsid, "kiwi");
8991     size = MAX_PATH;
8992     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8993                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8994                            &context, targetsid, &size);
8995     ok(r == ERROR_BAD_CONFIGURATION,
8996        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8997     ok(!lstrcmpA(patchcode, "apple"),
8998        "Expected patchcode to be unchanged, got %s\n", patchcode);
8999     ok(!lstrcmpA(targetprod, "banana"),
9000        "Expected targetprod to be unchanged, got %s\n", targetprod);
9001     ok(context == 0xdeadbeef,
9002        "Expected context to be unchanged, got %d\n", context);
9003     ok(!lstrcmpA(targetsid, "kiwi"),
9004        "Expected targetsid to be unchanged, got %s\n", targetsid);
9005     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9006
9007     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9008     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9009                          (const BYTE *)patch_squashed,
9010                          lstrlenA(patch_squashed) + 2);
9011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9012
9013     /* Patches value exists */
9014     lstrcpyA(patchcode, "apple");
9015     lstrcpyA(targetprod, "banana");
9016     context = 0xdeadbeef;
9017     lstrcpyA(targetsid, "kiwi");
9018     size = MAX_PATH;
9019     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9020                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9021                            &context, targetsid, &size);
9022     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9023     ok(!lstrcmpA(patchcode, "apple"),
9024        "Expected patchcode to be unchanged, got %s\n", patchcode);
9025     ok(!lstrcmpA(targetprod, "banana"),
9026        "Expected targetprod to be unchanged, got %s\n", targetprod);
9027     ok(context == 0xdeadbeef,
9028        "Expected context to be unchanged, got %d\n", context);
9029     ok(!lstrcmpA(targetsid, "kiwi"),
9030        "Expected targetsid to be unchanged, got %s\n", targetsid);
9031     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9032
9033     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9034                          (const BYTE *)"whatever", 9);
9035     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9036
9037     /* patch code value exists */
9038     lstrcpyA(patchcode, "apple");
9039     lstrcpyA(targetprod, "banana");
9040     context = 0xdeadbeef;
9041     lstrcpyA(targetsid, "kiwi");
9042     size = MAX_PATH;
9043     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9044                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9045                            &context, targetsid, &size);
9046     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9047     ok(!lstrcmpA(patchcode, patch),
9048        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9049     ok(!lstrcmpA(targetprod, prodcode),
9050        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9051     ok(context == MSIINSTALLCONTEXT_MACHINE,
9052        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9053     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9054     ok(size == 0, "Expected 0, got %d\n", size);
9055
9056     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9057     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9058     lstrcatA(keypath, prod_squashed);
9059
9060     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9062
9063     /* local UserData product key exists */
9064     lstrcpyA(patchcode, "apple");
9065     lstrcpyA(targetprod, "banana");
9066     context = 0xdeadbeef;
9067     lstrcpyA(targetsid, "kiwi");
9068     size = MAX_PATH;
9069     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9070                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9071                            &context, targetsid, &size);
9072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9073     ok(!lstrcmpA(patchcode, patch),
9074        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9075     ok(!lstrcmpA(targetprod, prodcode),
9076        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9077     ok(context == MSIINSTALLCONTEXT_MACHINE,
9078        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9079     ok(!lstrcmpA(targetsid, ""),
9080        "Expected \"\", got \"%s\"\n", targetsid);
9081     ok(size == 0, "Expected 0, got %d\n", size);
9082
9083     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9084     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9085
9086     /* local UserData Patches key exists */
9087     lstrcpyA(patchcode, "apple");
9088     lstrcpyA(targetprod, "banana");
9089     context = 0xdeadbeef;
9090     lstrcpyA(targetsid, "kiwi");
9091     size = MAX_PATH;
9092     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9093                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9094                            &context, targetsid, &size);
9095     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9096     ok(!lstrcmpA(patchcode, patch),
9097        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9098     ok(!lstrcmpA(targetprod, prodcode),
9099        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9100     ok(context == MSIINSTALLCONTEXT_MACHINE,
9101        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9102     ok(!lstrcmpA(targetsid, ""),
9103        "Expected \"\", got \"%s\"\n", targetsid);
9104     ok(size == 0, "Expected 0, got %d\n", size);
9105
9106     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9107     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9108
9109     /* local UserData Product patch key exists */
9110     lstrcpyA(patchcode, "apple");
9111     lstrcpyA(targetprod, "banana");
9112     context = 0xdeadbeef;
9113     lstrcpyA(targetsid, "kiwi");
9114     size = MAX_PATH;
9115     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9116                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9117                            &context, targetsid, &size);
9118     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9119     ok(!lstrcmpA(patchcode, "apple"),
9120        "Expected patchcode to be unchanged, got %s\n", patchcode);
9121     ok(!lstrcmpA(targetprod, "banana"),
9122        "Expected targetprod to be unchanged, got %s\n", targetprod);
9123     ok(context == 0xdeadbeef,
9124        "Expected context to be unchanged, got %d\n", context);
9125     ok(!lstrcmpA(targetsid, "kiwi"),
9126        "Expected targetsid to be unchanged, got %s\n", targetsid);
9127     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9128
9129     data = MSIPATCHSTATE_APPLIED;
9130     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9131                          (const BYTE *)&data, sizeof(DWORD));
9132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9133
9134     /* State value exists */
9135     lstrcpyA(patchcode, "apple");
9136     lstrcpyA(targetprod, "banana");
9137     context = 0xdeadbeef;
9138     lstrcpyA(targetsid, "kiwi");
9139     size = MAX_PATH;
9140     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9141                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9142                            &context, targetsid, &size);
9143     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9144     ok(!lstrcmpA(patchcode, patch),
9145        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9146     ok(!lstrcmpA(targetprod, prodcode),
9147        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9148     ok(context == MSIINSTALLCONTEXT_MACHINE,
9149        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9150     ok(!lstrcmpA(targetsid, ""),
9151        "Expected \"\", got \"%s\"\n", targetsid);
9152     ok(size == 0, "Expected 0, got %d\n", size);
9153
9154     /* MSIPATCHSTATE_SUPERSEDED */
9155
9156     lstrcpyA(patchcode, "apple");
9157     lstrcpyA(targetprod, "banana");
9158     context = 0xdeadbeef;
9159     lstrcpyA(targetsid, "kiwi");
9160     size = MAX_PATH;
9161     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9162                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9163                            &context, targetsid, &size);
9164     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9165     ok(!lstrcmpA(patchcode, "apple"),
9166        "Expected patchcode to be unchanged, got %s\n", patchcode);
9167     ok(!lstrcmpA(targetprod, "banana"),
9168        "Expected targetprod to be unchanged, got %s\n", targetprod);
9169     ok(context == 0xdeadbeef,
9170        "Expected context to be unchanged, got %d\n", context);
9171     ok(!lstrcmpA(targetsid, "kiwi"),
9172        "Expected targetsid to be unchanged, got %s\n", targetsid);
9173     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9174
9175     data = MSIPATCHSTATE_SUPERSEDED;
9176     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9177                          (const BYTE *)&data, sizeof(DWORD));
9178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9179
9180     /* State value is MSIPATCHSTATE_SUPERSEDED */
9181     lstrcpyA(patchcode, "apple");
9182     lstrcpyA(targetprod, "banana");
9183     context = 0xdeadbeef;
9184     lstrcpyA(targetsid, "kiwi");
9185     size = MAX_PATH;
9186     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9187                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9188                            &context, targetsid, &size);
9189     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9190     ok(!lstrcmpA(patchcode, patch),
9191        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9192     ok(!lstrcmpA(targetprod, prodcode),
9193        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9194     ok(context == MSIINSTALLCONTEXT_MACHINE,
9195        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9196     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9197     ok(size == 0, "Expected 0, got %d\n", size);
9198
9199     /* MSIPATCHSTATE_OBSOLETED */
9200
9201     lstrcpyA(patchcode, "apple");
9202     lstrcpyA(targetprod, "banana");
9203     context = 0xdeadbeef;
9204     lstrcpyA(targetsid, "kiwi");
9205     size = MAX_PATH;
9206     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9207                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9208                            &context, targetsid, &size);
9209     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9210     ok(!lstrcmpA(patchcode, "apple"),
9211        "Expected patchcode to be unchanged, got %s\n", patchcode);
9212     ok(!lstrcmpA(targetprod, "banana"),
9213        "Expected targetprod to be unchanged, got %s\n", targetprod);
9214     ok(context == 0xdeadbeef,
9215        "Expected context to be unchanged, got %d\n", context);
9216     ok(!lstrcmpA(targetsid, "kiwi"),
9217        "Expected targetsid to be unchanged, got %s\n", targetsid);
9218     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9219
9220     data = MSIPATCHSTATE_OBSOLETED;
9221     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9222                          (const BYTE *)&data, sizeof(DWORD));
9223     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9224
9225     /* State value is obsoleted */
9226     lstrcpyA(patchcode, "apple");
9227     lstrcpyA(targetprod, "banana");
9228     context = 0xdeadbeef;
9229     lstrcpyA(targetsid, "kiwi");
9230     size = MAX_PATH;
9231     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9232                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9233                            &context, targetsid, &size);
9234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9235     ok(!lstrcmpA(patchcode, patch),
9236        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9237     ok(!lstrcmpA(targetprod, prodcode),
9238        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9239     ok(context == MSIINSTALLCONTEXT_MACHINE,
9240        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9241     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9242     ok(size == 0, "Expected 0, got %d\n", size);
9243
9244     /* MSIPATCHSTATE_REGISTERED */
9245     /* FIXME */
9246
9247     /* MSIPATCHSTATE_ALL */
9248
9249     /* 1st */
9250     lstrcpyA(patchcode, "apple");
9251     lstrcpyA(targetprod, "banana");
9252     context = 0xdeadbeef;
9253     lstrcpyA(targetsid, "kiwi");
9254     size = MAX_PATH;
9255     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9256                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9257                            &context, targetsid, &size);
9258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9259     ok(!lstrcmpA(patchcode, patch),
9260        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9261     ok(!lstrcmpA(targetprod, prodcode),
9262        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9263     ok(context == MSIINSTALLCONTEXT_MACHINE,
9264        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9265     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9266     ok(size == 0, "Expected 0, got %d\n", size);
9267
9268     /* same patch in multiple places, only one is enumerated */
9269     lstrcpyA(patchcode, "apple");
9270     lstrcpyA(targetprod, "banana");
9271     context = 0xdeadbeef;
9272     lstrcpyA(targetsid, "kiwi");
9273     size = MAX_PATH;
9274     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9275                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9276                            &context, targetsid, &size);
9277     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9278     ok(!lstrcmpA(patchcode, "apple"),
9279        "Expected patchcode to be unchanged, got %s\n", patchcode);
9280     ok(!lstrcmpA(targetprod, "banana"),
9281        "Expected targetprod to be unchanged, got %s\n", targetprod);
9282     ok(context == 0xdeadbeef,
9283        "Expected context to be unchanged, got %d\n", context);
9284     ok(!lstrcmpA(targetsid, "kiwi"),
9285        "Expected targetsid to be unchanged, got %s\n", targetsid);
9286     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9287
9288     RegDeleteValueA(patches, patch_squashed);
9289     RegDeleteValueA(patches, "Patches");
9290     delete_key(patches, "", access & KEY_WOW64_64KEY);
9291     RegCloseKey(patches);
9292     RegDeleteValueA(hpatch, "State");
9293     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9294     RegCloseKey(hpatch);
9295     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9296     RegCloseKey(udpatch);
9297     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9298     RegCloseKey(udprod);
9299     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9300     RegCloseKey(prodkey);
9301 }
9302
9303 static void test_MsiEnumPatchesEx(void)
9304 {
9305     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9306     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9307     CHAR patchcode[MAX_PATH];
9308     MSIINSTALLCONTEXT context;
9309     LPSTR usersid;
9310     DWORD size;
9311     UINT r;
9312
9313     if (!pMsiEnumPatchesExA)
9314     {
9315         win_skip("MsiEnumPatchesExA not implemented\n");
9316         return;
9317     }
9318
9319     create_test_guid(prodcode, prod_squashed);
9320     get_user_sid(&usersid);
9321
9322     /* empty szProductCode */
9323     lstrcpyA(patchcode, "apple");
9324     lstrcpyA(targetprod, "banana");
9325     context = 0xdeadbeef;
9326     lstrcpyA(targetsid, "kiwi");
9327     size = MAX_PATH;
9328     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9329                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9330                            targetsid, &size);
9331     ok(r == ERROR_INVALID_PARAMETER,
9332        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9333     ok(!lstrcmpA(patchcode, "apple"),
9334        "Expected patchcode to be unchanged, got %s\n", patchcode);
9335     ok(!lstrcmpA(targetprod, "banana"),
9336        "Expected targetprod to be unchanged, got %s\n", targetprod);
9337     ok(context == 0xdeadbeef,
9338        "Expected context to be unchanged, got %d\n", context);
9339     ok(!lstrcmpA(targetsid, "kiwi"),
9340        "Expected targetsid to be unchanged, got %s\n", targetsid);
9341     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9342
9343     /* garbage szProductCode */
9344     lstrcpyA(patchcode, "apple");
9345     lstrcpyA(targetprod, "banana");
9346     context = 0xdeadbeef;
9347     lstrcpyA(targetsid, "kiwi");
9348     size = MAX_PATH;
9349     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9350                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9351                            targetsid, &size);
9352     ok(r == ERROR_INVALID_PARAMETER,
9353        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9354     ok(!lstrcmpA(patchcode, "apple"),
9355        "Expected patchcode to be unchanged, got %s\n", patchcode);
9356     ok(!lstrcmpA(targetprod, "banana"),
9357        "Expected targetprod to be unchanged, got %s\n", targetprod);
9358     ok(context == 0xdeadbeef,
9359        "Expected context to be unchanged, got %d\n", context);
9360     ok(!lstrcmpA(targetsid, "kiwi"),
9361        "Expected targetsid to be unchanged, got %s\n", targetsid);
9362     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9363
9364     /* guid without brackets */
9365     lstrcpyA(patchcode, "apple");
9366     lstrcpyA(targetprod, "banana");
9367     context = 0xdeadbeef;
9368     lstrcpyA(targetsid, "kiwi");
9369     size = MAX_PATH;
9370     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9371                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9372                            0, patchcode, targetprod, &context,
9373                            targetsid, &size);
9374     ok(r == ERROR_INVALID_PARAMETER,
9375        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9376     ok(!lstrcmpA(patchcode, "apple"),
9377        "Expected patchcode to be unchanged, got %s\n", patchcode);
9378     ok(!lstrcmpA(targetprod, "banana"),
9379        "Expected targetprod to be unchanged, got %s\n", targetprod);
9380     ok(context == 0xdeadbeef,
9381        "Expected context to be unchanged, got %d\n", context);
9382     ok(!lstrcmpA(targetsid, "kiwi"),
9383        "Expected targetsid to be unchanged, got %s\n", targetsid);
9384     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9385
9386     /* guid with brackets */
9387     lstrcpyA(patchcode, "apple");
9388     lstrcpyA(targetprod, "banana");
9389     context = 0xdeadbeef;
9390     lstrcpyA(targetsid, "kiwi");
9391     size = MAX_PATH;
9392     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9393                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9394                            0, patchcode, targetprod, &context,
9395                            targetsid, &size);
9396     ok(r == ERROR_NO_MORE_ITEMS,
9397        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9398     ok(!lstrcmpA(patchcode, "apple"),
9399        "Expected patchcode to be unchanged, got %s\n", patchcode);
9400     ok(!lstrcmpA(targetprod, "banana"),
9401        "Expected targetprod to be unchanged, got %s\n", targetprod);
9402     ok(context == 0xdeadbeef,
9403        "Expected context to be unchanged, got %d\n", context);
9404     ok(!lstrcmpA(targetsid, "kiwi"),
9405        "Expected targetsid to be unchanged, got %s\n", targetsid);
9406     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9407
9408     /* szUserSid is S-1-5-18 */
9409     lstrcpyA(patchcode, "apple");
9410     lstrcpyA(targetprod, "banana");
9411     context = 0xdeadbeef;
9412     lstrcpyA(targetsid, "kiwi");
9413     size = MAX_PATH;
9414     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9415                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9416                            0, patchcode, targetprod, &context,
9417                            targetsid, &size);
9418     ok(r == ERROR_INVALID_PARAMETER,
9419        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9420     ok(!lstrcmpA(patchcode, "apple"),
9421        "Expected patchcode to be unchanged, got %s\n", patchcode);
9422     ok(!lstrcmpA(targetprod, "banana"),
9423        "Expected targetprod to be unchanged, got %s\n", targetprod);
9424     ok(context == 0xdeadbeef,
9425        "Expected context to be unchanged, got %d\n", context);
9426     ok(!lstrcmpA(targetsid, "kiwi"),
9427        "Expected targetsid to be unchanged, got %s\n", targetsid);
9428     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9429
9430     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9431     lstrcpyA(patchcode, "apple");
9432     lstrcpyA(targetprod, "banana");
9433     context = 0xdeadbeef;
9434     lstrcpyA(targetsid, "kiwi");
9435     size = MAX_PATH;
9436     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9437                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9438                            &context, targetsid, &size);
9439     ok(r == ERROR_INVALID_PARAMETER,
9440        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9441     ok(!lstrcmpA(patchcode, "apple"),
9442        "Expected patchcode to be unchanged, got %s\n", patchcode);
9443     ok(!lstrcmpA(targetprod, "banana"),
9444        "Expected targetprod to be unchanged, got %s\n", targetprod);
9445     ok(context == 0xdeadbeef,
9446        "Expected context to be unchanged, got %d\n", context);
9447     ok(!lstrcmpA(targetsid, "kiwi"),
9448        "Expected targetsid to be unchanged, got %s\n", targetsid);
9449     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9450
9451     /* dwContext is out of bounds */
9452     lstrcpyA(patchcode, "apple");
9453     lstrcpyA(targetprod, "banana");
9454     context = 0xdeadbeef;
9455     lstrcpyA(targetsid, "kiwi");
9456     size = MAX_PATH;
9457     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9458                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9459                            &context, targetsid, &size);
9460     ok(r == ERROR_INVALID_PARAMETER,
9461        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9462     ok(!lstrcmpA(patchcode, "apple"),
9463        "Expected patchcode to be unchanged, got %s\n", patchcode);
9464     ok(!lstrcmpA(targetprod, "banana"),
9465        "Expected targetprod to be unchanged, got %s\n", targetprod);
9466     ok(context == 0xdeadbeef,
9467        "Expected context to be unchanged, got %d\n", context);
9468     ok(!lstrcmpA(targetsid, "kiwi"),
9469        "Expected targetsid to be unchanged, got %s\n", targetsid);
9470     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9471
9472     /* dwContext is out of bounds */
9473     lstrcpyA(patchcode, "apple");
9474     lstrcpyA(targetprod, "banana");
9475     context = 0xdeadbeef;
9476     lstrcpyA(targetsid, "kiwi");
9477     size = MAX_PATH;
9478     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9479                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9480                            &context, targetsid, &size);
9481     ok(r == ERROR_INVALID_PARAMETER,
9482        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9483     ok(!lstrcmpA(patchcode, "apple"),
9484        "Expected patchcode to be unchanged, got %s\n", patchcode);
9485     ok(!lstrcmpA(targetprod, "banana"),
9486        "Expected targetprod to be unchanged, got %s\n", targetprod);
9487     ok(context == 0xdeadbeef,
9488        "Expected context to be unchanged, got %d\n", context);
9489     ok(!lstrcmpA(targetsid, "kiwi"),
9490        "Expected targetsid to be unchanged, got %s\n", targetsid);
9491     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9492
9493     /* dwFilter is out of bounds */
9494     lstrcpyA(patchcode, "apple");
9495     lstrcpyA(targetprod, "banana");
9496     context = 0xdeadbeef;
9497     lstrcpyA(targetsid, "kiwi");
9498     size = MAX_PATH;
9499     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9500                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9501                            &context, targetsid, &size);
9502     ok(r == ERROR_INVALID_PARAMETER,
9503        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9504     ok(!lstrcmpA(patchcode, "apple"),
9505        "Expected patchcode to be unchanged, got %s\n", patchcode);
9506     ok(!lstrcmpA(targetprod, "banana"),
9507        "Expected targetprod to be unchanged, got %s\n", targetprod);
9508     ok(context == 0xdeadbeef,
9509        "Expected context to be unchanged, got %d\n", context);
9510     ok(!lstrcmpA(targetsid, "kiwi"),
9511        "Expected targetsid to be unchanged, got %s\n", targetsid);
9512     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9513
9514     /* dwFilter is out of bounds */
9515     lstrcpyA(patchcode, "apple");
9516     lstrcpyA(targetprod, "banana");
9517     context = 0xdeadbeef;
9518     lstrcpyA(targetsid, "kiwi");
9519     size = MAX_PATH;
9520     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9521                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9522                            &context, targetsid, &size);
9523     ok(r == ERROR_INVALID_PARAMETER,
9524        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9525     ok(!lstrcmpA(patchcode, "apple"),
9526        "Expected patchcode to be unchanged, got %s\n", patchcode);
9527     ok(!lstrcmpA(targetprod, "banana"),
9528        "Expected targetprod to be unchanged, got %s\n", targetprod);
9529     ok(context == 0xdeadbeef,
9530        "Expected context to be unchanged, got %d\n", context);
9531     ok(!lstrcmpA(targetsid, "kiwi"),
9532        "Expected targetsid to be unchanged, got %s\n", targetsid);
9533     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9534
9535     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9536     lstrcpyA(patchcode, "apple");
9537     lstrcpyA(targetprod, "banana");
9538     context = 0xdeadbeef;
9539     lstrcpyA(targetsid, "kiwi");
9540     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9541                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9542                            &context, targetsid, NULL);
9543     ok(r == ERROR_INVALID_PARAMETER,
9544        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9545     ok(!lstrcmpA(patchcode, "apple"),
9546        "Expected patchcode to be unchanged, got %s\n", patchcode);
9547     ok(!lstrcmpA(targetprod, "banana"),
9548        "Expected targetprod to be unchanged, got %s\n", targetprod);
9549     ok(context == 0xdeadbeef,
9550        "Expected context to be unchanged, got %d\n", context);
9551     ok(!lstrcmpA(targetsid, "kiwi"),
9552        "Expected targetsid to be unchanged, got %s\n", targetsid);
9553
9554     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9555     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9556     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9557     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9558     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9559     /* FIXME: Successfully test userunmanaged with a different user */
9560     test_MsiEnumPatchesEx_machine();
9561     LocalFree(usersid);
9562 }
9563
9564 static void test_MsiEnumPatches(void)
9565 {
9566     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9567     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9568     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9569     CHAR transforms[MAX_PATH];
9570     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9571     HKEY prodkey, patches, udprod;
9572     HKEY userkey, hpatch, udpatch;
9573     DWORD size, data;
9574     LPSTR usersid;
9575     LONG res;
9576     UINT r;
9577     REGSAM access = KEY_ALL_ACCESS;
9578     BOOL wow64;
9579
9580     create_test_guid(prodcode, prod_squashed);
9581     create_test_guid(patchcode, patch_squashed);
9582     get_user_sid(&usersid);
9583
9584     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
9585         access |= KEY_WOW64_64KEY;
9586
9587     /* NULL szProduct */
9588     size = MAX_PATH;
9589     lstrcpyA(patch, "apple");
9590     lstrcpyA(transforms, "banana");
9591     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9592     ok(r == ERROR_INVALID_PARAMETER,
9593        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9594     ok(!lstrcmpA(patch, "apple"),
9595        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9596     ok(!lstrcmpA(transforms, "banana"),
9597        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9598     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9599
9600     /* empty szProduct */
9601     size = MAX_PATH;
9602     lstrcpyA(patch, "apple");
9603     lstrcpyA(transforms, "banana");
9604     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9605     ok(r == ERROR_INVALID_PARAMETER,
9606        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9607     ok(!lstrcmpA(patch, "apple"),
9608        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9609     ok(!lstrcmpA(transforms, "banana"),
9610        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9611     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9612
9613     /* garbage szProduct */
9614     size = MAX_PATH;
9615     lstrcpyA(patch, "apple");
9616     lstrcpyA(transforms, "banana");
9617     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9618     ok(r == ERROR_INVALID_PARAMETER,
9619        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9620     ok(!lstrcmpA(patch, "apple"),
9621        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9622     ok(!lstrcmpA(transforms, "banana"),
9623        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9624     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9625
9626     /* guid without brackets */
9627     size = MAX_PATH;
9628     lstrcpyA(patch, "apple");
9629     lstrcpyA(transforms, "banana");
9630     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9631                         transforms, &size);
9632     ok(r == ERROR_INVALID_PARAMETER,
9633        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9634     ok(!lstrcmpA(patch, "apple"),
9635        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9636     ok(!lstrcmpA(transforms, "banana"),
9637        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9638     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9639
9640     /* guid with brackets */
9641     size = MAX_PATH;
9642     lstrcpyA(patch, "apple");
9643     lstrcpyA(transforms, "banana");
9644     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9645                         transforms, &size);
9646     ok(r == ERROR_UNKNOWN_PRODUCT,
9647        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9648     ok(!lstrcmpA(patch, "apple"),
9649        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9650     ok(!lstrcmpA(transforms, "banana"),
9651        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9652     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9653
9654     /* same length as guid, but random */
9655     size = MAX_PATH;
9656     lstrcpyA(patch, "apple");
9657     lstrcpyA(transforms, "banana");
9658     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9659                         transforms, &size);
9660     ok(r == ERROR_INVALID_PARAMETER,
9661        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9662     ok(!lstrcmpA(patch, "apple"),
9663        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9664     ok(!lstrcmpA(transforms, "banana"),
9665        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9666     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9667
9668     /* MSIINSTALLCONTEXT_USERMANAGED */
9669
9670     size = MAX_PATH;
9671     lstrcpyA(patch, "apple");
9672     lstrcpyA(transforms, "banana");
9673     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9674     ok(r == ERROR_UNKNOWN_PRODUCT,
9675        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9676     ok(!lstrcmpA(patch, "apple"),
9677        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9678     ok(!lstrcmpA(transforms, "banana"),
9679        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9680     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9681
9682     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9683     lstrcatA(keypath, usersid);
9684     lstrcatA(keypath, "\\Installer\\Products\\");
9685     lstrcatA(keypath, prod_squashed);
9686
9687     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9688     if (res == ERROR_ACCESS_DENIED)
9689     {
9690         skip("Not enough rights to perform tests\n");
9691         LocalFree(usersid);
9692         return;
9693     }
9694     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9695
9696     /* managed product key exists */
9697     size = MAX_PATH;
9698     lstrcpyA(patch, "apple");
9699     lstrcpyA(transforms, "banana");
9700     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9701     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9702     ok(!lstrcmpA(patch, "apple"),
9703        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9704     ok(!lstrcmpA(transforms, "banana"),
9705        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9706     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9707
9708     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9710
9711     /* patches key exists */
9712     size = MAX_PATH;
9713     lstrcpyA(patch, "apple");
9714     lstrcpyA(transforms, "banana");
9715     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9716     ok(r == ERROR_NO_MORE_ITEMS ||
9717        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9718        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9719     ok(!lstrcmpA(patch, "apple"),
9720        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9721     ok(!lstrcmpA(transforms, "banana"),
9722        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9723     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9724
9725     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9726                          (const BYTE *)patch_squashed,
9727                          lstrlenA(patch_squashed) + 1);
9728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9729
9730     /* Patches value exists, is not REG_MULTI_SZ */
9731     size = MAX_PATH;
9732     lstrcpyA(patch, "apple");
9733     lstrcpyA(transforms, "banana");
9734     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9735     ok(r == ERROR_BAD_CONFIGURATION ||
9736        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9737        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9738     ok(!lstrcmpA(patch, "apple"),
9739        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9740     ok(!lstrcmpA(transforms, "banana"),
9741        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9742     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9743
9744     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9745                          (const BYTE *)"a\0b\0c\0\0", 7);
9746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9747
9748     /* Patches value exists, is not a squashed guid */
9749     size = MAX_PATH;
9750     lstrcpyA(patch, "apple");
9751     lstrcpyA(transforms, "banana");
9752     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9753     ok(r == ERROR_BAD_CONFIGURATION,
9754        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9755     ok(!lstrcmpA(patch, "apple"),
9756        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9757     ok(!lstrcmpA(transforms, "banana"),
9758        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9759     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9760
9761     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9762     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9763                          (const BYTE *)patch_squashed,
9764                          lstrlenA(patch_squashed) + 2);
9765     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9766
9767     /* Patches value exists */
9768     size = MAX_PATH;
9769     lstrcpyA(patch, "apple");
9770     lstrcpyA(transforms, "banana");
9771     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9772     ok(r == ERROR_NO_MORE_ITEMS ||
9773        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9774        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9775     ok(!lstrcmpA(patch, "apple") ||
9776        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9777        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9778     ok(!lstrcmpA(transforms, "banana"),
9779        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9780     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9781
9782     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9783                          (const BYTE *)"whatever", 9);
9784     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9785
9786     /* patch squashed value exists */
9787     size = MAX_PATH;
9788     lstrcpyA(patch, "apple");
9789     lstrcpyA(transforms, "banana");
9790     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9791     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9792     ok(!lstrcmpA(patch, patchcode),
9793        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9794     ok(!lstrcmpA(transforms, "whatever"),
9795        "Expected \"whatever\", got \"%s\"\n", transforms);
9796     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9797
9798     /* lpPatchBuf is NULL */
9799     size = MAX_PATH;
9800     lstrcpyA(transforms, "banana");
9801     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9802     ok(r == ERROR_INVALID_PARAMETER,
9803        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9804     ok(!lstrcmpA(transforms, "banana"),
9805        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9806     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9807
9808     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9809     size = MAX_PATH;
9810     lstrcpyA(patch, "apple");
9811     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9812     ok(r == ERROR_INVALID_PARAMETER,
9813        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9814     ok(!lstrcmpA(patch, "apple"),
9815        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9816     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9817
9818     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9819     lstrcpyA(patch, "apple");
9820     lstrcpyA(transforms, "banana");
9821     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9822     ok(r == ERROR_INVALID_PARAMETER,
9823        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9824     ok(!lstrcmpA(patch, "apple"),
9825        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9826     ok(!lstrcmpA(transforms, "banana"),
9827        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9828
9829     /* pcchTransformsBuf is too small */
9830     size = 6;
9831     lstrcpyA(patch, "apple");
9832     lstrcpyA(transforms, "banana");
9833     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9834     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9835     ok(!lstrcmpA(patch, patchcode),
9836        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9837     ok(!lstrcmpA(transforms, "whate") ||
9838        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
9839        "Expected \"whate\", got \"%s\"\n", transforms);
9840     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
9841
9842     /* increase the index */
9843     size = MAX_PATH;
9844     lstrcpyA(patch, "apple");
9845     lstrcpyA(transforms, "banana");
9846     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9847     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9848     ok(!lstrcmpA(patch, "apple"),
9849        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9850     ok(!lstrcmpA(transforms, "banana"),
9851        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9852     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9853
9854     /* increase again */
9855     size = MAX_PATH;
9856     lstrcpyA(patch, "apple");
9857     lstrcpyA(transforms, "banana");
9858     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9859     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9860     ok(!lstrcmpA(patch, "apple"),
9861        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9862     ok(!lstrcmpA(transforms, "banana"),
9863        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9864     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9865
9866     RegDeleteValueA(patches, "Patches");
9867     delete_key(patches, "", access & KEY_WOW64_64KEY);
9868     RegCloseKey(patches);
9869     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9870     RegCloseKey(prodkey);
9871
9872     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9873
9874     size = MAX_PATH;
9875     lstrcpyA(patch, "apple");
9876     lstrcpyA(transforms, "banana");
9877     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9878     ok(r == ERROR_UNKNOWN_PRODUCT,
9879        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9880     ok(!lstrcmpA(patch, "apple"),
9881        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9882     ok(!lstrcmpA(transforms, "banana"),
9883        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9884     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9885
9886     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9887     lstrcatA(keypath, prod_squashed);
9888
9889     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9891
9892     /* current user product key exists */
9893     size = MAX_PATH;
9894     lstrcpyA(patch, "apple");
9895     lstrcpyA(transforms, "banana");
9896     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9897     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9898     ok(!lstrcmpA(patch, "apple"),
9899        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9900     ok(!lstrcmpA(transforms, "banana"),
9901        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9902     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9903
9904     res = RegCreateKeyA(prodkey, "Patches", &patches);
9905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9906
9907     /* Patches key exists */
9908     size = MAX_PATH;
9909     lstrcpyA(patch, "apple");
9910     lstrcpyA(transforms, "banana");
9911     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9912     ok(r == ERROR_NO_MORE_ITEMS ||
9913        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9914        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9915     ok(!lstrcmpA(patch, "apple"),
9916        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9917     ok(!lstrcmpA(transforms, "banana"),
9918        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9919     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9920
9921     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9922                          (const BYTE *)patch_squashed,
9923                          lstrlenA(patch_squashed) + 1);
9924     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9925
9926     /* Patches value exists, is not REG_MULTI_SZ */
9927     size = MAX_PATH;
9928     lstrcpyA(patch, "apple");
9929     lstrcpyA(transforms, "banana");
9930     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9931     ok(r == ERROR_BAD_CONFIGURATION ||
9932        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9933        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9934     ok(!lstrcmpA(patch, "apple"),
9935        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9936     ok(!lstrcmpA(transforms, "banana"),
9937        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9938     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9939
9940     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9941                          (const BYTE *)"a\0b\0c\0\0", 7);
9942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9943
9944     /* Patches value exists, is not a squashed guid */
9945     size = MAX_PATH;
9946     lstrcpyA(patch, "apple");
9947     lstrcpyA(transforms, "banana");
9948     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9949     ok(r == ERROR_BAD_CONFIGURATION,
9950        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9951     ok(!lstrcmpA(patch, "apple"),
9952        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9953     ok(!lstrcmpA(transforms, "banana"),
9954        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9955     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9956
9957     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9958     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9959                          (const BYTE *)patch_squashed,
9960                          lstrlenA(patch_squashed) + 2);
9961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9962
9963     /* Patches value exists */
9964     size = MAX_PATH;
9965     lstrcpyA(patch, "apple");
9966     lstrcpyA(transforms, "banana");
9967     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9968     ok(r == ERROR_NO_MORE_ITEMS ||
9969        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9970        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9971     ok(!lstrcmpA(patch, "apple") ||
9972        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9973        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9974     ok(!lstrcmpA(transforms, "banana"),
9975        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9976     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9977
9978     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9979                          (const BYTE *)"whatever", 9);
9980     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9981
9982     /* patch code value exists */
9983     size = MAX_PATH;
9984     lstrcpyA(patch, "apple");
9985     lstrcpyA(transforms, "banana");
9986     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9987     ok(r == ERROR_NO_MORE_ITEMS ||
9988        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9989        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9990     ok(!lstrcmpA(patch, "apple") ||
9991        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9992        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9993     ok(!lstrcmpA(transforms, "banana") ||
9994        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
9995        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9996     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9997
9998     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9999     lstrcatA(keypath, usersid);
10000     lstrcatA(keypath, "\\Patches\\");
10001     lstrcatA(keypath, patch_squashed);
10002
10003     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
10004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10005
10006     /* userdata patch key exists */
10007     size = MAX_PATH;
10008     lstrcpyA(patch, "apple");
10009     lstrcpyA(transforms, "banana");
10010     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10012     ok(!lstrcmpA(patch, patchcode),
10013        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10014     ok(!lstrcmpA(transforms, "whatever"),
10015        "Expected \"whatever\", got \"%s\"\n", transforms);
10016     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10017
10018     delete_key(userkey, "", access & KEY_WOW64_64KEY);
10019     RegCloseKey(userkey);
10020     RegDeleteValueA(patches, patch_squashed);
10021     RegDeleteValueA(patches, "Patches");
10022     RegDeleteKeyA(patches, "");
10023     RegCloseKey(patches);
10024     RegDeleteKeyA(prodkey, "");
10025     RegCloseKey(prodkey);
10026
10027     /* MSIINSTALLCONTEXT_MACHINE */
10028
10029     size = MAX_PATH;
10030     lstrcpyA(patch, "apple");
10031     lstrcpyA(transforms, "banana");
10032     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10033     ok(r == ERROR_UNKNOWN_PRODUCT,
10034        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10035     ok(!lstrcmpA(patch, "apple"),
10036        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10037     ok(!lstrcmpA(transforms, "banana"),
10038        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10039     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10040
10041     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10042     lstrcatA(keypath, prod_squashed);
10043
10044     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10045     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10046
10047     /* local product key exists */
10048     size = MAX_PATH;
10049     lstrcpyA(patch, "apple");
10050     lstrcpyA(transforms, "banana");
10051     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10052     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10053     ok(!lstrcmpA(patch, "apple"),
10054        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10055     ok(!lstrcmpA(transforms, "banana"),
10056        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10057     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10058
10059     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10061
10062     /* Patches key exists */
10063     size = MAX_PATH;
10064     lstrcpyA(patch, "apple");
10065     lstrcpyA(transforms, "banana");
10066     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10067     ok(r == ERROR_NO_MORE_ITEMS ||
10068        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10069        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10070     ok(!lstrcmpA(patch, "apple"),
10071        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10072     ok(!lstrcmpA(transforms, "banana"),
10073        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10074     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10075
10076     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10077                          (const BYTE *)patch_squashed,
10078                          lstrlenA(patch_squashed) + 1);
10079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10080
10081     /* Patches value exists, is not REG_MULTI_SZ */
10082     size = MAX_PATH;
10083     lstrcpyA(patch, "apple");
10084     lstrcpyA(transforms, "banana");
10085     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10086     ok(r == ERROR_BAD_CONFIGURATION ||
10087        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10088        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10089     ok(!lstrcmpA(patch, "apple"),
10090        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10091     ok(!lstrcmpA(transforms, "banana"),
10092        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10093     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10094
10095     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10096                          (const BYTE *)"a\0b\0c\0\0", 7);
10097     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10098
10099     /* Patches value exists, is not a squashed guid */
10100     size = MAX_PATH;
10101     lstrcpyA(patch, "apple");
10102     lstrcpyA(transforms, "banana");
10103     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10104     ok(r == ERROR_BAD_CONFIGURATION,
10105        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10106     ok(!lstrcmpA(patch, "apple"),
10107        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10108     ok(!lstrcmpA(transforms, "banana"),
10109        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10110     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10111
10112     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10113     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10114                          (const BYTE *)patch_squashed,
10115                          lstrlenA(patch_squashed) + 2);
10116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10117
10118     /* Patches value exists */
10119     size = MAX_PATH;
10120     lstrcpyA(patch, "apple");
10121     lstrcpyA(transforms, "banana");
10122     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10123     ok(r == ERROR_NO_MORE_ITEMS ||
10124        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10125        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10126     ok(!lstrcmpA(patch, "apple") ||
10127        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10128        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10129     ok(!lstrcmpA(transforms, "banana"),
10130        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10131     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10132
10133     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10134                          (const BYTE *)"whatever", 9);
10135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10136
10137     /* patch code value exists */
10138     size = MAX_PATH;
10139     lstrcpyA(patch, "apple");
10140     lstrcpyA(transforms, "banana");
10141     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10142     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10143     ok(!lstrcmpA(patch, patchcode),
10144        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10145     ok(!lstrcmpA(transforms, "whatever"),
10146        "Expected \"whatever\", got \"%s\"\n", transforms);
10147     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10148
10149     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10150     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10151     lstrcatA(keypath, prod_squashed);
10152
10153     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10154     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10155
10156     /* local UserData product key exists */
10157     size = MAX_PATH;
10158     lstrcpyA(patch, "apple");
10159     lstrcpyA(transforms, "banana");
10160     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10161     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10162     ok(!lstrcmpA(patch, patchcode),
10163        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10164     ok(!lstrcmpA(transforms, "whatever"),
10165        "Expected \"whatever\", got \"%s\"\n", transforms);
10166     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10167
10168     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10170
10171     /* local UserData Patches key exists */
10172     size = MAX_PATH;
10173     lstrcpyA(patch, "apple");
10174     lstrcpyA(transforms, "banana");
10175     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10177     ok(!lstrcmpA(patch, patchcode),
10178        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10179     ok(!lstrcmpA(transforms, "whatever"),
10180        "Expected \"whatever\", got \"%s\"\n", transforms);
10181     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10182
10183     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10184     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10185
10186     /* local UserData Product patch key exists */
10187     size = MAX_PATH;
10188     lstrcpyA(patch, "apple");
10189     lstrcpyA(transforms, "banana");
10190     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10191     ok(r == ERROR_NO_MORE_ITEMS ||
10192        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10193        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10194     ok(!lstrcmpA(patch, "apple") ||
10195        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10196        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10197     ok(!lstrcmpA(transforms, "banana") ||
10198        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10199        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10200     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10201
10202     data = MSIPATCHSTATE_APPLIED;
10203     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10204                          (const BYTE *)&data, sizeof(DWORD));
10205     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10206
10207     /* State value exists */
10208     size = MAX_PATH;
10209     lstrcpyA(patch, "apple");
10210     lstrcpyA(transforms, "banana");
10211     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10212     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10213     ok(!lstrcmpA(patch, patchcode),
10214        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10215     ok(!lstrcmpA(transforms, "whatever"),
10216        "Expected \"whatever\", got \"%s\"\n", transforms);
10217     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10218
10219     /* now duplicate some of the tests for the W version */
10220
10221     /* pcchTransformsBuf is too small */
10222     size = 6;
10223     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
10224     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10225     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10226     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10227     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10228     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10229     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10230     ok(!lstrcmpA(patch, patchcode),
10231        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10232     ok(!lstrcmpA(transforms, "whate") ||
10233        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10234        "Expected \"whate\", got \"%s\"\n", transforms);
10235     ok(size == 8, "Expected 8, got %d\n", size);
10236
10237     /* patch code value exists */
10238     size = MAX_PATH;
10239     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10240     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10241     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10242     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10243     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10244     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10245     ok(!lstrcmpA(patch, patchcode),
10246        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10247     ok(!lstrcmpA(transforms, "whatever"),
10248        "Expected \"whatever\", got \"%s\"\n", transforms);
10249     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10250
10251     RegDeleteValueA(patches, patch_squashed);
10252     RegDeleteValueA(patches, "Patches");
10253     delete_key(patches, "", access & KEY_WOW64_64KEY);
10254     RegCloseKey(patches);
10255     RegDeleteValueA(hpatch, "State");
10256     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10257     RegCloseKey(hpatch);
10258     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10259     RegCloseKey(udpatch);
10260     delete_key(udprod, "", access & KEY_WOW64_64KEY);
10261     RegCloseKey(udprod);
10262     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10263     RegCloseKey(prodkey);
10264     LocalFree(usersid);
10265 }
10266
10267 static void test_MsiGetPatchInfoEx(void)
10268 {
10269     CHAR keypath[MAX_PATH], val[MAX_PATH];
10270     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10271     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10272     HKEY prodkey, patches, udprod, props;
10273     HKEY hpatch, udpatch, prodpatches;
10274     LPSTR usersid;
10275     DWORD size;
10276     LONG res;
10277     UINT r;
10278     REGSAM access = KEY_ALL_ACCESS;
10279     BOOL wow64;
10280
10281     if (!pMsiGetPatchInfoExA)
10282     {
10283         win_skip("MsiGetPatchInfoEx not implemented\n");
10284         return;
10285     }
10286
10287     create_test_guid(prodcode, prod_squashed);
10288     create_test_guid(patchcode, patch_squashed);
10289     get_user_sid(&usersid);
10290
10291     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
10292         access |= KEY_WOW64_64KEY;
10293
10294     /* NULL szPatchCode */
10295     lstrcpyA(val, "apple");
10296     size = MAX_PATH;
10297     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10298                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10299     ok(r == ERROR_INVALID_PARAMETER,
10300        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10301     ok(!lstrcmpA(val, "apple"),
10302        "Expected val to be unchanged, got \"%s\"\n", val);
10303     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10304
10305     /* empty szPatchCode */
10306     size = MAX_PATH;
10307     lstrcpyA(val, "apple");
10308     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10309                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10310     ok(r == ERROR_INVALID_PARAMETER,
10311        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10312     ok(!lstrcmpA(val, "apple"),
10313        "Expected val to be unchanged, got \"%s\"\n", val);
10314     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10315
10316     /* garbage szPatchCode */
10317     size = MAX_PATH;
10318     lstrcpyA(val, "apple");
10319     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
10320                             MSIINSTALLCONTEXT_USERMANAGED,
10321                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10322     ok(r == ERROR_INVALID_PARAMETER,
10323        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10324     ok(!lstrcmpA(val, "apple"),
10325        "Expected val to be unchanged, got \"%s\"\n", val);
10326     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10327
10328     /* guid without brackets */
10329     size = MAX_PATH;
10330     lstrcpyA(val, "apple");
10331     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
10332                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10333                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10334     ok(r == ERROR_INVALID_PARAMETER,
10335        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10336     ok(!lstrcmpA(val, "apple"),
10337        "Expected val to be unchanged, got \"%s\"\n", val);
10338     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10339
10340     /* guid with brackets */
10341     size = MAX_PATH;
10342     lstrcpyA(val, "apple");
10343     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
10344                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10345                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10346     ok(r == ERROR_UNKNOWN_PRODUCT,
10347        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10348     ok(!lstrcmpA(val, "apple"),
10349        "Expected val to be unchanged, got \"%s\"\n", val);
10350     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10351
10352     /* same length as guid, but random */
10353     size = MAX_PATH;
10354     lstrcpyA(val, "apple");
10355     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
10356                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10357                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10358     ok(r == ERROR_INVALID_PARAMETER,
10359        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10360     ok(!lstrcmpA(val, "apple"),
10361        "Expected val to be unchanged, got \"%s\"\n", val);
10362     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10363
10364     /* NULL szProductCode */
10365     lstrcpyA(val, "apple");
10366     size = MAX_PATH;
10367     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10368                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10369     ok(r == ERROR_INVALID_PARAMETER,
10370        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10371     ok(!lstrcmpA(val, "apple"),
10372        "Expected val to be unchanged, got \"%s\"\n", val);
10373     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10374
10375     /* empty szProductCode */
10376     size = MAX_PATH;
10377     lstrcpyA(val, "apple");
10378     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10379                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10380     ok(r == ERROR_INVALID_PARAMETER,
10381        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10382     ok(!lstrcmpA(val, "apple"),
10383        "Expected val to be unchanged, got \"%s\"\n", val);
10384     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10385
10386     /* garbage szProductCode */
10387     size = MAX_PATH;
10388     lstrcpyA(val, "apple");
10389     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
10390                             MSIINSTALLCONTEXT_USERMANAGED,
10391                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10392     ok(r == ERROR_INVALID_PARAMETER,
10393        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10394     ok(!lstrcmpA(val, "apple"),
10395        "Expected val to be unchanged, got \"%s\"\n", val);
10396     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10397
10398     /* guid without brackets */
10399     size = MAX_PATH;
10400     lstrcpyA(val, "apple");
10401     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10402                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10403                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10404     ok(r == ERROR_INVALID_PARAMETER,
10405        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10406     ok(!lstrcmpA(val, "apple"),
10407        "Expected val to be unchanged, got \"%s\"\n", val);
10408     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10409
10410     /* guid with brackets */
10411     size = MAX_PATH;
10412     lstrcpyA(val, "apple");
10413     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10414                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10415                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10416     ok(r == ERROR_UNKNOWN_PRODUCT,
10417        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10418     ok(!lstrcmpA(val, "apple"),
10419        "Expected val to be unchanged, got \"%s\"\n", val);
10420     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10421
10422     /* same length as guid, but random */
10423     size = MAX_PATH;
10424     lstrcpyA(val, "apple");
10425     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10426                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10427                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10428     ok(r == ERROR_INVALID_PARAMETER,
10429        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10430     ok(!lstrcmpA(val, "apple"),
10431        "Expected val to be unchanged, got \"%s\"\n", val);
10432     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10433
10434     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10435     size = MAX_PATH;
10436     lstrcpyA(val, "apple");
10437     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10438                             MSIINSTALLCONTEXT_USERMANAGED,
10439                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10440     ok(r == ERROR_INVALID_PARAMETER,
10441        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10442     ok(!lstrcmpA(val, "apple"),
10443        "Expected val to be unchanged, got \"%s\"\n", val);
10444     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10445
10446     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10447     size = MAX_PATH;
10448     lstrcpyA(val, "apple");
10449     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10450                             MSIINSTALLCONTEXT_USERUNMANAGED,
10451                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10452     ok(r == ERROR_INVALID_PARAMETER,
10453        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10454     ok(!lstrcmpA(val, "apple"),
10455        "Expected val to be unchanged, got \"%s\"\n", val);
10456     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10457
10458     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10459     size = MAX_PATH;
10460     lstrcpyA(val, "apple");
10461     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10462                             MSIINSTALLCONTEXT_MACHINE,
10463                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10464     ok(r == ERROR_INVALID_PARAMETER,
10465        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10466     ok(!lstrcmpA(val, "apple"),
10467        "Expected val to be unchanged, got \"%s\"\n", val);
10468     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10469
10470     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10471     size = MAX_PATH;
10472     lstrcpyA(val, "apple");
10473     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10474                             MSIINSTALLCONTEXT_MACHINE,
10475                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10476     ok(r == ERROR_INVALID_PARAMETER,
10477        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10478     ok(!lstrcmpA(val, "apple"),
10479        "Expected val to be unchanged, got \"%s\"\n", val);
10480     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10481
10482     /* dwContext is out of range */
10483     size = MAX_PATH;
10484     lstrcpyA(val, "apple");
10485     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10486                             MSIINSTALLCONTEXT_NONE,
10487                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10488     ok(r == ERROR_INVALID_PARAMETER,
10489        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10490     ok(!lstrcmpA(val, "apple"),
10491        "Expected val to be unchanged, got \"%s\"\n", val);
10492     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10493
10494     /* dwContext is out of range */
10495     size = MAX_PATH;
10496     lstrcpyA(val, "apple");
10497     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10498                             MSIINSTALLCONTEXT_ALL,
10499                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10500     ok(r == ERROR_INVALID_PARAMETER,
10501        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10502     ok(!lstrcmpA(val, "apple"),
10503        "Expected val to be unchanged, got \"%s\"\n", val);
10504     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10505
10506     /* dwContext is invalid */
10507     size = MAX_PATH;
10508     lstrcpyA(val, "apple");
10509     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10510                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10511     ok(r == ERROR_INVALID_PARAMETER,
10512        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10513     ok(!lstrcmpA(val, "apple"),
10514        "Expected val to be unchanged, got \"%s\"\n", val);
10515     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10516
10517     /* MSIINSTALLCONTEXT_USERMANAGED */
10518
10519     size = MAX_PATH;
10520     lstrcpyA(val, "apple");
10521     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10522                             MSIINSTALLCONTEXT_USERMANAGED,
10523                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10524     ok(r == ERROR_UNKNOWN_PRODUCT,
10525        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10526     ok(!lstrcmpA(val, "apple"),
10527        "Expected val to be unchanged, got \"%s\"\n", val);
10528     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10529
10530     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10531     lstrcatA(keypath, usersid);
10532     lstrcatA(keypath, "\\Products\\");
10533     lstrcatA(keypath, prod_squashed);
10534
10535     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10536     if (res == ERROR_ACCESS_DENIED)
10537     {
10538         skip("Not enough rights to perform tests\n");
10539         LocalFree(usersid);
10540         return;
10541     }
10542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10543
10544     /* local UserData product key exists */
10545     size = MAX_PATH;
10546     lstrcpyA(val, "apple");
10547     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10548                             MSIINSTALLCONTEXT_USERMANAGED,
10549                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10550     ok(r == ERROR_UNKNOWN_PRODUCT,
10551        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10552     ok(!lstrcmpA(val, "apple"),
10553        "Expected val to be unchanged, got \"%s\"\n", val);
10554     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10555
10556     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
10557     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10558
10559     /* InstallProperties key exists */
10560     size = MAX_PATH;
10561     lstrcpyA(val, "apple");
10562     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10563                             MSIINSTALLCONTEXT_USERMANAGED,
10564                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10565     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10566     ok(!lstrcmpA(val, "apple"),
10567        "Expected val to be unchanged, got \"%s\"\n", val);
10568     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10569
10570     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10572
10573     /* Patches key exists */
10574     size = MAX_PATH;
10575     lstrcpyA(val, "apple");
10576     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10577                             MSIINSTALLCONTEXT_USERMANAGED,
10578                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10579     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10580     ok(!lstrcmpA(val, "apple"),
10581        "Expected val to be unchanged, got \"%s\"\n", val);
10582     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10583
10584     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10585     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10586
10587     /* Patches key exists */
10588     size = MAX_PATH;
10589     lstrcpyA(val, "apple");
10590     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10591                             MSIINSTALLCONTEXT_USERMANAGED,
10592                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10593     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10594     ok(!lstrcmpA(val, "apple"),
10595        "Expected val to be unchanged, got \"%s\"\n", val);
10596     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10597
10598     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10599     lstrcatA(keypath, usersid);
10600     lstrcatA(keypath, "\\Installer\\Products\\");
10601     lstrcatA(keypath, prod_squashed);
10602
10603     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10605
10606     /* managed product key exists */
10607     size = MAX_PATH;
10608     lstrcpyA(val, "apple");
10609     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10610                             MSIINSTALLCONTEXT_USERMANAGED,
10611                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10612     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10613     ok(!lstrcmpA(val, "apple"),
10614        "Expected val to be unchanged, got \"%s\"\n", val);
10615     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10616
10617     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
10618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10619
10620     /* Patches key exists */
10621     size = MAX_PATH;
10622     lstrcpyA(val, "apple");
10623     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10624                             MSIINSTALLCONTEXT_USERMANAGED,
10625                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10626     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10627     ok(!lstrcmpA(val, "apple"),
10628        "Expected val to be unchanged, got \"%s\"\n", val);
10629     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10630
10631     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10632                          (const BYTE *)"transforms", 11);
10633     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10634
10635     /* specific patch value exists */
10636     size = MAX_PATH;
10637     lstrcpyA(val, "apple");
10638     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10639                             MSIINSTALLCONTEXT_USERMANAGED,
10640                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10641     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10642     ok(!lstrcmpA(val, "apple"),
10643        "Expected val to be unchanged, got \"%s\"\n", val);
10644     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10645
10646     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10647     lstrcatA(keypath, usersid);
10648     lstrcatA(keypath, "\\Patches\\");
10649     lstrcatA(keypath, patch_squashed);
10650
10651     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
10652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10653
10654     /* UserData Patches key exists */
10655     size = MAX_PATH;
10656     lstrcpyA(val, "apple");
10657     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10658                             MSIINSTALLCONTEXT_USERMANAGED,
10659                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10660     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10661     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10662     ok(size == 0, "Expected 0, got %d\n", size);
10663
10664     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10665                          (const BYTE *)"pack", 5);
10666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10667
10668     /* ManagedLocalPatch value exists */
10669     size = MAX_PATH;
10670     lstrcpyA(val, "apple");
10671     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10672                             MSIINSTALLCONTEXT_USERMANAGED,
10673                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10674     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10675     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10676     ok(size == 4, "Expected 4, got %d\n", size);
10677
10678     size = MAX_PATH;
10679     lstrcpyA(val, "apple");
10680     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10681                             MSIINSTALLCONTEXT_USERMANAGED,
10682                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10683     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10684     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10685     ok(size == 10, "Expected 10, got %d\n", size);
10686
10687     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10688                          (const BYTE *)"mydate", 7);
10689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10690
10691     /* Installed value exists */
10692     size = MAX_PATH;
10693     lstrcpyA(val, "apple");
10694     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10695                             MSIINSTALLCONTEXT_USERMANAGED,
10696                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10697     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10698     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10699     ok(size == 6, "Expected 6, got %d\n", size);
10700
10701     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10702                          (const BYTE *)"yes", 4);
10703     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10704
10705     /* Uninstallable value exists */
10706     size = MAX_PATH;
10707     lstrcpyA(val, "apple");
10708     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10709                             MSIINSTALLCONTEXT_USERMANAGED,
10710                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10711     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10712     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10713     ok(size == 3, "Expected 3, got %d\n", size);
10714
10715     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10716                          (const BYTE *)"good", 5);
10717     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10718
10719     /* State value exists */
10720     size = MAX_PATH;
10721     lstrcpyA(val, "apple");
10722     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10723                             MSIINSTALLCONTEXT_USERMANAGED,
10724                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10726     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10727     ok(size == 4, "Expected 4, got %d\n", size);
10728
10729     size = 1;
10730     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10731                          (const BYTE *)&size, sizeof(DWORD));
10732     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10733
10734     /* State value exists */
10735     size = MAX_PATH;
10736     lstrcpyA(val, "apple");
10737     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10738                             MSIINSTALLCONTEXT_USERMANAGED,
10739                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10740     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10741     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10742     ok(size == 1, "Expected 1, got %d\n", size);
10743
10744     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10745                          (const BYTE *)"display", 8);
10746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10747
10748     /* DisplayName value exists */
10749     size = MAX_PATH;
10750     lstrcpyA(val, "apple");
10751     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10752                             MSIINSTALLCONTEXT_USERMANAGED,
10753                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10754     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10755     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10756     ok(size == 7, "Expected 7, got %d\n", size);
10757
10758     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10759                          (const BYTE *)"moreinfo", 9);
10760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10761
10762     /* MoreInfoURL value exists */
10763     size = MAX_PATH;
10764     lstrcpyA(val, "apple");
10765     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10766                             MSIINSTALLCONTEXT_USERMANAGED,
10767                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10769     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10770     ok(size == 8, "Expected 8, got %d\n", size);
10771
10772     /* szProperty is invalid */
10773     size = MAX_PATH;
10774     lstrcpyA(val, "apple");
10775     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10776                             MSIINSTALLCONTEXT_USERMANAGED,
10777                             "IDontExist", val, &size);
10778     ok(r == ERROR_UNKNOWN_PROPERTY,
10779        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10780     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10781     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10782
10783     /* lpValue is NULL, while pcchValue is non-NULL */
10784     size = MAX_PATH;
10785     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10786                             MSIINSTALLCONTEXT_USERMANAGED,
10787                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10788     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10789     ok(size == 16, "Expected 16, got %d\n", size);
10790
10791     /* pcchValue is NULL, while lpValue is non-NULL */
10792     lstrcpyA(val, "apple");
10793     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10794                             MSIINSTALLCONTEXT_USERMANAGED,
10795                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10796     ok(r == ERROR_INVALID_PARAMETER,
10797        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10798     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10799
10800     /* both lpValue and pcchValue are NULL */
10801     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10802                             MSIINSTALLCONTEXT_USERMANAGED,
10803                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10805
10806     /* pcchValue doesn't have enough room for NULL terminator */
10807     size = 8;
10808     lstrcpyA(val, "apple");
10809     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10810                             MSIINSTALLCONTEXT_USERMANAGED,
10811                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10812     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10813     ok(!lstrcmpA(val, "moreinf"),
10814        "Expected \"moreinf\", got \"%s\"\n", val);
10815     ok(size == 16, "Expected 16, got %d\n", size);
10816
10817     /* pcchValue has exactly enough room for NULL terminator */
10818     size = 9;
10819     lstrcpyA(val, "apple");
10820     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10821                             MSIINSTALLCONTEXT_USERMANAGED,
10822                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10823     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10824     ok(!lstrcmpA(val, "moreinfo"),
10825        "Expected \"moreinfo\", got \"%s\"\n", val);
10826     ok(size == 8, "Expected 8, got %d\n", size);
10827
10828     /* pcchValue is too small, lpValue is NULL */
10829     size = 0;
10830     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10831                             MSIINSTALLCONTEXT_USERMANAGED,
10832                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10833     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10834     ok(size == 16, "Expected 16, got %d\n", size);
10835
10836     RegDeleteValueA(prodpatches, patch_squashed);
10837     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
10838     RegCloseKey(prodpatches);
10839     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10840     RegCloseKey(prodkey);
10841
10842     /* UserData is sufficient for all properties
10843      * except INSTALLPROPERTY_TRANSFORMS
10844      */
10845     size = MAX_PATH;
10846     lstrcpyA(val, "apple");
10847     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10848                             MSIINSTALLCONTEXT_USERMANAGED,
10849                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10850     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10851     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10852     ok(size == 4, "Expected 4, got %d\n", size);
10853
10854     /* UserData is sufficient for all properties
10855      * except INSTALLPROPERTY_TRANSFORMS
10856      */
10857     size = MAX_PATH;
10858     lstrcpyA(val, "apple");
10859     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10860                             MSIINSTALLCONTEXT_USERMANAGED,
10861                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10862     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10863     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10864     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10865
10866     RegDeleteValueA(hpatch, "MoreInfoURL");
10867     RegDeleteValueA(hpatch, "Display");
10868     RegDeleteValueA(hpatch, "State");
10869     RegDeleteValueA(hpatch, "Uninstallable");
10870     RegDeleteValueA(hpatch, "Installed");
10871     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10872     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10873     RegCloseKey(udpatch);
10874     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10875     RegCloseKey(hpatch);
10876     delete_key(patches, "", access & KEY_WOW64_64KEY);
10877     RegCloseKey(patches);
10878     delete_key(props, "", access & KEY_WOW64_64KEY);
10879     RegCloseKey(props);
10880     delete_key(udprod, "", access & KEY_WOW64_64KEY);
10881     RegCloseKey(udprod);
10882
10883     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10884
10885     size = MAX_PATH;
10886     lstrcpyA(val, "apple");
10887     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10888                             MSIINSTALLCONTEXT_USERUNMANAGED,
10889                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10890     ok(r == ERROR_UNKNOWN_PRODUCT,
10891        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10892     ok(!lstrcmpA(val, "apple"),
10893        "Expected val to be unchanged, got \"%s\"\n", val);
10894     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10895
10896     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10897     lstrcatA(keypath, usersid);
10898     lstrcatA(keypath, "\\Products\\");
10899     lstrcatA(keypath, prod_squashed);
10900
10901     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10902     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10903
10904     /* local UserData product key exists */
10905     size = MAX_PATH;
10906     lstrcpyA(val, "apple");
10907     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10908                             MSIINSTALLCONTEXT_USERUNMANAGED,
10909                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10910     ok(r == ERROR_UNKNOWN_PRODUCT,
10911        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10912     ok(!lstrcmpA(val, "apple"),
10913        "Expected val to be unchanged, got \"%s\"\n", val);
10914     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10915
10916     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
10917     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10918
10919     /* InstallProperties key exists */
10920     size = MAX_PATH;
10921     lstrcpyA(val, "apple");
10922     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10923                             MSIINSTALLCONTEXT_USERUNMANAGED,
10924                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10925     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10926     ok(!lstrcmpA(val, "apple"),
10927        "Expected val to be unchanged, got \"%s\"\n", val);
10928     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10929
10930     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10931     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10932
10933     /* Patches key exists */
10934     size = MAX_PATH;
10935     lstrcpyA(val, "apple");
10936     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10937                             MSIINSTALLCONTEXT_USERUNMANAGED,
10938                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10939     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10940     ok(!lstrcmpA(val, "apple"),
10941        "Expected val to be unchanged, got \"%s\"\n", val);
10942     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10943
10944     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10945     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10946
10947     /* Patches key exists */
10948     size = MAX_PATH;
10949     lstrcpyA(val, "apple");
10950     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10951                             MSIINSTALLCONTEXT_USERUNMANAGED,
10952                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10953     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10954     ok(!lstrcmpA(val, "apple"),
10955        "Expected val to be unchanged, got \"%s\"\n", val);
10956     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10957
10958     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10959     lstrcatA(keypath, prod_squashed);
10960
10961     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10963
10964     /* current user product key exists */
10965     size = MAX_PATH;
10966     lstrcpyA(val, "apple");
10967     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10968                             MSIINSTALLCONTEXT_USERUNMANAGED,
10969                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10970     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10971     ok(!lstrcmpA(val, "apple"),
10972        "Expected val to be unchanged, got \"%s\"\n", val);
10973     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10974
10975     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10976     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10977
10978     /* Patches key exists */
10979     size = MAX_PATH;
10980     lstrcpyA(val, "apple");
10981     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10982                             MSIINSTALLCONTEXT_USERUNMANAGED,
10983                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10984     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10985     ok(!lstrcmpA(val, "apple"),
10986        "Expected val to be unchanged, got \"%s\"\n", val);
10987     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10988
10989     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10990                          (const BYTE *)"transforms", 11);
10991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10992
10993     /* specific patch value exists */
10994     size = MAX_PATH;
10995     lstrcpyA(val, "apple");
10996     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10997                             MSIINSTALLCONTEXT_USERUNMANAGED,
10998                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10999     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11000     ok(!lstrcmpA(val, "apple"),
11001        "Expected val to be unchanged, got \"%s\"\n", val);
11002     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11003
11004     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11005     lstrcatA(keypath, usersid);
11006     lstrcatA(keypath, "\\Patches\\");
11007     lstrcatA(keypath, patch_squashed);
11008
11009     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11010     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11011
11012     /* UserData Patches key exists */
11013     size = MAX_PATH;
11014     lstrcpyA(val, "apple");
11015     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11016                             MSIINSTALLCONTEXT_USERUNMANAGED,
11017                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11018     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11019     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11020     ok(size == 0, "Expected 0, got %d\n", size);
11021
11022     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11023                          (const BYTE *)"pack", 5);
11024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11025
11026     /* LocalPatch value exists */
11027     size = MAX_PATH;
11028     lstrcpyA(val, "apple");
11029     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11030                             MSIINSTALLCONTEXT_USERUNMANAGED,
11031                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11032     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11033     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11034     ok(size == 4, "Expected 4, got %d\n", size);
11035
11036     size = MAX_PATH;
11037     lstrcpyA(val, "apple");
11038     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11039                             MSIINSTALLCONTEXT_USERUNMANAGED,
11040                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11042     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11043     ok(size == 10, "Expected 10, got %d\n", size);
11044
11045     RegDeleteValueA(prodpatches, patch_squashed);
11046     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11047     RegCloseKey(prodpatches);
11048     RegDeleteKeyA(prodkey, "");
11049     RegCloseKey(prodkey);
11050
11051     /* UserData is sufficient for all properties
11052      * except INSTALLPROPERTY_TRANSFORMS
11053      */
11054     size = MAX_PATH;
11055     lstrcpyA(val, "apple");
11056     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11057                             MSIINSTALLCONTEXT_USERUNMANAGED,
11058                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11059     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11060     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11061     ok(size == 4, "Expected 4, got %d\n", size);
11062
11063     /* UserData is sufficient for all properties
11064      * except INSTALLPROPERTY_TRANSFORMS
11065      */
11066     size = MAX_PATH;
11067     lstrcpyA(val, "apple");
11068     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11069                             MSIINSTALLCONTEXT_USERUNMANAGED,
11070                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11071     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11072     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11073     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11074
11075     RegDeleteValueA(udpatch, "LocalPackage");
11076     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11077     RegCloseKey(udpatch);
11078     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11079     RegCloseKey(hpatch);
11080     delete_key(patches, "", access & KEY_WOW64_64KEY);
11081     RegCloseKey(patches);
11082     delete_key(props, "", access & KEY_WOW64_64KEY);
11083     RegCloseKey(props);
11084     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11085     RegCloseKey(udprod);
11086
11087     /* MSIINSTALLCONTEXT_MACHINE */
11088
11089     size = MAX_PATH;
11090     lstrcpyA(val, "apple");
11091     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11092                             MSIINSTALLCONTEXT_MACHINE,
11093                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11094     ok(r == ERROR_UNKNOWN_PRODUCT,
11095        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11096     ok(!lstrcmpA(val, "apple"),
11097        "Expected val to be unchanged, got \"%s\"\n", val);
11098     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11099
11100     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11101     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11102     lstrcatA(keypath, prod_squashed);
11103
11104     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11105     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11106
11107     /* local UserData product key exists */
11108     size = MAX_PATH;
11109     lstrcpyA(val, "apple");
11110     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11111                             MSIINSTALLCONTEXT_MACHINE,
11112                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11113     ok(r == ERROR_UNKNOWN_PRODUCT,
11114        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11115     ok(!lstrcmpA(val, "apple"),
11116        "Expected val to be unchanged, got \"%s\"\n", val);
11117     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11118
11119     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11120     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11121
11122     /* InstallProperties key exists */
11123     size = MAX_PATH;
11124     lstrcpyA(val, "apple");
11125     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11126                             MSIINSTALLCONTEXT_MACHINE,
11127                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11128     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11129     ok(!lstrcmpA(val, "apple"),
11130        "Expected val to be unchanged, got \"%s\"\n", val);
11131     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11132
11133     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11135
11136     /* Patches key exists */
11137     size = MAX_PATH;
11138     lstrcpyA(val, "apple");
11139     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11140                             MSIINSTALLCONTEXT_MACHINE,
11141                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11142     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11143     ok(!lstrcmpA(val, "apple"),
11144        "Expected val to be unchanged, got \"%s\"\n", val);
11145     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11146
11147     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11148     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11149
11150     /* Patches key exists */
11151     size = MAX_PATH;
11152     lstrcpyA(val, "apple");
11153     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11154                             MSIINSTALLCONTEXT_MACHINE,
11155                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11156     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11157     ok(!lstrcmpA(val, "apple"),
11158        "Expected val to be unchanged, got \"%s\"\n", val);
11159     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11160
11161     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11162     lstrcatA(keypath, prod_squashed);
11163
11164     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11166
11167     /* local product key exists */
11168     size = MAX_PATH;
11169     lstrcpyA(val, "apple");
11170     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11171                             MSIINSTALLCONTEXT_MACHINE,
11172                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11173     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11174     ok(!lstrcmpA(val, "apple"),
11175        "Expected val to be unchanged, got \"%s\"\n", val);
11176     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11177
11178     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11179     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11180
11181     /* Patches key exists */
11182     size = MAX_PATH;
11183     lstrcpyA(val, "apple");
11184     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11185                             MSIINSTALLCONTEXT_MACHINE,
11186                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11187     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11188     ok(!lstrcmpA(val, "apple"),
11189        "Expected val to be unchanged, got \"%s\"\n", val);
11190     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11191
11192     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11193                          (const BYTE *)"transforms", 11);
11194     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11195
11196     /* specific patch value exists */
11197     size = MAX_PATH;
11198     lstrcpyA(val, "apple");
11199     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11200                             MSIINSTALLCONTEXT_MACHINE,
11201                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11202     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11203     ok(!lstrcmpA(val, "apple"),
11204        "Expected val to be unchanged, got \"%s\"\n", val);
11205     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11206
11207     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11208     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11209     lstrcatA(keypath, patch_squashed);
11210
11211     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11213
11214     /* UserData Patches key exists */
11215     size = MAX_PATH;
11216     lstrcpyA(val, "apple");
11217     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11218                             MSIINSTALLCONTEXT_MACHINE,
11219                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11220     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11221     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11222     ok(size == 0, "Expected 0, got %d\n", size);
11223
11224     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11225                          (const BYTE *)"pack", 5);
11226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11227
11228     /* LocalPatch value exists */
11229     size = MAX_PATH;
11230     lstrcpyA(val, "apple");
11231     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11232                             MSIINSTALLCONTEXT_MACHINE,
11233                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11235     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11236     ok(size == 4, "Expected 4, got %d\n", size);
11237
11238     size = MAX_PATH;
11239     lstrcpyA(val, "apple");
11240     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11241                             MSIINSTALLCONTEXT_MACHINE,
11242                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11244     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11245     ok(size == 10, "Expected 10, got %d\n", size);
11246
11247     RegDeleteValueA(prodpatches, patch_squashed);
11248     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11249     RegCloseKey(prodpatches);
11250     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11251     RegCloseKey(prodkey);
11252
11253     /* UserData is sufficient for all properties
11254      * except INSTALLPROPERTY_TRANSFORMS
11255      */
11256     size = MAX_PATH;
11257     lstrcpyA(val, "apple");
11258     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11259                             MSIINSTALLCONTEXT_MACHINE,
11260                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11262     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11263     ok(size == 4, "Expected 4, got %d\n", size);
11264
11265     /* UserData is sufficient for all properties
11266      * except INSTALLPROPERTY_TRANSFORMS
11267      */
11268     size = MAX_PATH;
11269     lstrcpyA(val, "apple");
11270     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11271                             MSIINSTALLCONTEXT_MACHINE,
11272                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11273     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11274     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11275     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11276
11277     RegDeleteValueA(udpatch, "LocalPackage");
11278     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11279     RegCloseKey(udpatch);
11280     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11281     RegCloseKey(hpatch);
11282     delete_key(patches, "", access & KEY_WOW64_64KEY);
11283     RegCloseKey(patches);
11284     delete_key(props, "", access & KEY_WOW64_64KEY);
11285     RegCloseKey(props);
11286     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11287     RegCloseKey(udprod);
11288     LocalFree(usersid);
11289 }
11290
11291 static void test_MsiGetPatchInfo(void)
11292 {
11293     UINT r;
11294     char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
11295     char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
11296     WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
11297     HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
11298     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
11299     DWORD size;
11300     LONG res;
11301     REGSAM access = KEY_ALL_ACCESS;
11302     BOOL wow64;
11303
11304     create_test_guid(patch_code, patch_squashed);
11305     create_test_guid(prod_code, prod_squashed);
11306     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
11307
11308     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
11309         access |= KEY_WOW64_64KEY;
11310
11311     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
11312     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11313
11314     r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
11315     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11316
11317     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
11318     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
11319
11320     size = 0;
11321     r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
11322     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11323
11324     r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
11325     ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
11326
11327     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11328     lstrcatA(keypath, prod_squashed);
11329
11330     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
11331     if (res == ERROR_ACCESS_DENIED)
11332     {
11333         skip("Not enough rights to perform tests\n");
11334         return;
11335     }
11336     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11337
11338     /* product key exists */
11339     size = MAX_PATH;
11340     lstrcpyA(val, "apple");
11341     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11342     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11343     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11344     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11345
11346     res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
11347     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11348
11349     /* patches key exists */
11350     size = MAX_PATH;
11351     lstrcpyA(val, "apple");
11352     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11353     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11354     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11355     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11356
11357     res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
11358     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11359
11360     /* patch key exists */
11361     size = MAX_PATH;
11362     lstrcpyA(val, "apple");
11363     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11364     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11365     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11366     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11367
11368     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11369     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11370     lstrcatA(keypath, prod_squashed);
11371
11372     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
11373     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
11374
11375     /* UserData product key exists */
11376     size = MAX_PATH;
11377     lstrcpyA(val, "apple");
11378     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11379     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11380     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11381     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11382
11383     res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
11384     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11385
11386     /* InstallProperties key exists */
11387     size = MAX_PATH;
11388     lstrcpyA(val, "apple");
11389     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11390     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11391     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11392     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11393
11394     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
11395     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11396
11397     /* UserData Patches key exists */
11398     size = MAX_PATH;
11399     lstrcpyA(val, "apple");
11400     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11401     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11402     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11403     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11404
11405     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
11406     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11407
11408     res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
11409     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11410
11411     /* UserData product patch key exists */
11412     size = MAX_PATH;
11413     lstrcpyA(val, "apple");
11414     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11415     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11416     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11417     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11418
11419     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11420     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11421     lstrcatA(keypath, patch_squashed);
11422
11423     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
11424     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11425
11426     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11427     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11428
11429     /* UserData Patch key exists */
11430     size = 0;
11431     lstrcpyA(val, "apple");
11432     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11433     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11434     ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11435     ok(size == 11, "expected 11 got %u\n", size);
11436
11437     size = MAX_PATH;
11438     lstrcpyA(val, "apple");
11439     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11440     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11441     ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11442     ok(size == 11, "expected 11 got %u\n", size);
11443
11444     size = 0;
11445     valW[0] = 0;
11446     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11447     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA 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     size = MAX_PATH;
11452     valW[0] = 0;
11453     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11454     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11455     ok(valW[0], "expected > 0 got %u\n", valW[0]);
11456     ok(size == 11, "expected 11 got %u\n", size);
11457
11458     delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
11459     RegCloseKey(hkey_udproductpatch);
11460     delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
11461     RegCloseKey(hkey_udproductpatches);
11462     delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
11463     RegCloseKey(hkey_udpatch);
11464     delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
11465     RegCloseKey(hkey_patches);
11466     delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
11467     RegCloseKey(hkey_product);
11468     delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
11469     RegCloseKey(hkey_patch);
11470     delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
11471     RegCloseKey(hkey_udpatches);
11472     delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
11473     RegCloseKey(hkey_udprops);
11474     delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
11475     RegCloseKey(hkey_udproduct);
11476 }
11477
11478 static void test_MsiEnumProducts(void)
11479 {
11480     UINT r;
11481     int found1, found2, found3;
11482     DWORD index;
11483     char product1[39], product2[39], product3[39], guid[39];
11484     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11485     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11486     char *usersid;
11487     HKEY key1, key2, key3;
11488     REGSAM access = KEY_ALL_ACCESS;
11489     BOOL wow64;
11490
11491     create_test_guid(product1, product_squashed1);
11492     create_test_guid(product2, product_squashed2);
11493     create_test_guid(product3, product_squashed3);
11494     get_user_sid(&usersid);
11495
11496     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
11497         access |= KEY_WOW64_64KEY;
11498
11499     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11500     strcat(keypath1, product_squashed1);
11501
11502     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
11503     if (r == ERROR_ACCESS_DENIED)
11504     {
11505         skip("Not enough rights to perform tests\n");
11506         LocalFree(usersid);
11507         return;
11508     }
11509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11510
11511     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11512     strcat(keypath2, usersid);
11513     strcat(keypath2, "\\Installer\\Products\\");
11514     strcat(keypath2, product_squashed2);
11515
11516     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
11517     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11518
11519     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
11520     strcat(keypath3, product_squashed3);
11521
11522     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
11523     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11524
11525     index = 0;
11526     r = MsiEnumProductsA(index, guid);
11527     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11528
11529     r = MsiEnumProductsA(index, NULL);
11530     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11531
11532     index = 2;
11533     r = MsiEnumProductsA(index, guid);
11534     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11535
11536     index = 0;
11537     r = MsiEnumProductsA(index, guid);
11538     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11539
11540     found1 = found2 = found3 = 0;
11541     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
11542     {
11543         if (!strcmp(product1, guid)) found1 = 1;
11544         if (!strcmp(product2, guid)) found2 = 1;
11545         if (!strcmp(product3, guid)) found3 = 1;
11546         index++;
11547     }
11548     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
11549     ok(found1, "product1 not found\n");
11550     ok(found2, "product2 not found\n");
11551     ok(found3, "product3 not found\n");
11552
11553     delete_key(key1, "", access & KEY_WOW64_64KEY);
11554     delete_key(key2, "", access & KEY_WOW64_64KEY);
11555     RegDeleteKeyA(key3, "");
11556     RegCloseKey(key1);
11557     RegCloseKey(key2);
11558     RegCloseKey(key3);
11559     LocalFree(usersid);
11560 }
11561
11562 START_TEST(msi)
11563 {
11564     init_functionpointers();
11565
11566     test_usefeature();
11567     test_null();
11568     test_getcomponentpath();
11569     test_MsiGetFileHash();
11570
11571     if (!pConvertSidToStringSidA)
11572         win_skip("ConvertSidToStringSidA not implemented\n");
11573     else
11574     {
11575         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
11576         test_MsiQueryProductState();
11577         test_MsiQueryFeatureState();
11578         test_MsiQueryComponentState();
11579         test_MsiGetComponentPath();
11580         test_MsiGetProductCode();
11581         test_MsiEnumClients();
11582         test_MsiGetProductInfo();
11583         test_MsiGetProductInfoEx();
11584         test_MsiGetUserInfo();
11585         test_MsiOpenProduct();
11586         test_MsiEnumPatchesEx();
11587         test_MsiEnumPatches();
11588         test_MsiGetPatchInfoEx();
11589         test_MsiGetPatchInfo();
11590         test_MsiEnumProducts();
11591     }
11592
11593     test_MsiGetFileVersion();
11594 }