msi/tests: Move test coverage for standard actions to a separate module.
[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 BOOL is_wow64;
33 static const char msifile[] = "winetest.msi";
34
35 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
36 static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
37 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
38
39 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
40     (LPCSTR, LPCSTR, LPSTR, DWORD*);
41 static UINT (WINAPI *pMsiGetFileHashA)
42     (LPCSTR, DWORD, PMSIFILEHASHINFO);
43 static UINT (WINAPI *pMsiGetProductInfoExA)
44     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
45 static UINT (WINAPI *pMsiOpenPackageExA)
46     (LPCSTR, DWORD, MSIHANDLE*);
47 static UINT (WINAPI *pMsiOpenPackageExW)
48     (LPCWSTR, DWORD, MSIHANDLE*);
49 static UINT (WINAPI *pMsiEnumPatchesExA)
50     (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
51     MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
52 static UINT (WINAPI *pMsiQueryComponentStateA)
53     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
54 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
55     (LPCSTR, LPCSTR ,DWORD, DWORD);
56 static UINT (WINAPI *pMsiGetPatchInfoExA)
57     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
58
59 static void init_functionpointers(void)
60 {
61     HMODULE hmsi = GetModuleHandleA("msi.dll");
62     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
63     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
64
65 #define GET_PROC(dll, func) \
66     p ## func = (void *)GetProcAddress(dll, #func); \
67     if(!p ## func) \
68       trace("GetProcAddress(%s) failed\n", #func);
69
70     GET_PROC(hmsi, MsiGetComponentPathA)
71     GET_PROC(hmsi, MsiGetFileHashA)
72     GET_PROC(hmsi, MsiGetProductInfoExA)
73     GET_PROC(hmsi, MsiOpenPackageExA)
74     GET_PROC(hmsi, MsiOpenPackageExW)
75     GET_PROC(hmsi, MsiEnumPatchesExA)
76     GET_PROC(hmsi, MsiQueryComponentStateA)
77     GET_PROC(hmsi, MsiUseFeatureExA)
78     GET_PROC(hmsi, MsiGetPatchInfoExA)
79
80     GET_PROC(hadvapi32, ConvertSidToStringSidA)
81     GET_PROC(hadvapi32, RegDeleteKeyExA)
82     GET_PROC(hkernel32, IsWow64Process)
83
84 #undef GET_PROC
85 }
86
87 static UINT run_query(MSIHANDLE hdb, const char *query)
88 {
89     MSIHANDLE hview = 0;
90     UINT r;
91
92     r = MsiDatabaseOpenView(hdb, query, &hview);
93     if (r != ERROR_SUCCESS)
94         return r;
95
96     r = MsiViewExecute(hview, 0);
97     if (r == ERROR_SUCCESS)
98         r = MsiViewClose(hview);
99     MsiCloseHandle(hview);
100     return r;
101 }
102
103 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
104 {
105     UINT res;
106     MSIHANDLE suminfo;
107
108     /* build summary info */
109     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
110     ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
111
112     res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
113                                     "Installation Database");
114     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
115
116     res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
117                                     "Installation Database");
118     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
119
120     res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
121                                     "Wine Hackers");
122     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
123
124     res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
125                                     ";1033");
126     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
127
128     res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
129                                     "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
130     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
131
132     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
133     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
134
135     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
136     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
137
138     res = MsiSummaryInfoPersist(suminfo);
139     ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
140
141     res = MsiCloseHandle(suminfo);
142     ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
143
144     return res;
145 }
146
147 static MSIHANDLE create_package_db(LPSTR prodcode)
148 {
149     MSIHANDLE hdb = 0;
150     CHAR query[MAX_PATH];
151     UINT res;
152
153     DeleteFile(msifile);
154
155     /* create an empty database */
156     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
157     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
158     if (res != ERROR_SUCCESS)
159         return hdb;
160
161     res = MsiDatabaseCommit(hdb);
162     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
163
164     set_summary_info(hdb, prodcode);
165
166     res = run_query(hdb,
167             "CREATE TABLE `Directory` ( "
168             "`Directory` CHAR(255) NOT NULL, "
169             "`Directory_Parent` CHAR(255), "
170             "`DefaultDir` CHAR(255) NOT NULL "
171             "PRIMARY KEY `Directory`)");
172     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
173
174     res = run_query(hdb,
175             "CREATE TABLE `Property` ( "
176             "`Property` CHAR(72) NOT NULL, "
177             "`Value` CHAR(255) "
178             "PRIMARY KEY `Property`)");
179     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
180
181     sprintf(query, "INSERT INTO `Property` "
182             "(`Property`, `Value`) "
183             "VALUES( 'ProductCode', '%s' )", prodcode);
184     res = run_query(hdb, query);
185     ok(res == ERROR_SUCCESS , "Failed\n");
186
187     res = MsiDatabaseCommit(hdb);
188     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
189
190     return hdb;
191 }
192
193 static void test_usefeature(void)
194 {
195     INSTALLSTATE r;
196
197     if (!pMsiUseFeatureExA)
198     {
199         win_skip("MsiUseFeatureExA not implemented\n");
200         return;
201     }
202
203     r = MsiQueryFeatureState(NULL,NULL);
204     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
205
206     r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
207     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
208
209     r = pMsiUseFeatureExA(NULL,NULL,0,0);
210     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
211
212     r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
213     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
214
215     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
216                          NULL, -2, 0 );
217     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
218
219     r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}", 
220                          "WORDVIEWFiles", -2, 0 );
221     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
222
223     r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}", 
224                          "WORDVIEWFiles", -2, 0 );
225     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
226
227     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
228                          "WORDVIEWFiles", -2, 1 );
229     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
230 }
231
232 static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
233 {
234     if (pRegDeleteKeyExA)
235         return pRegDeleteKeyExA( key, subkey, access, 0 );
236     return RegDeleteKeyA( key, subkey );
237 }
238
239 static void test_null(void)
240 {
241     MSIHANDLE hpkg;
242     UINT r;
243     HKEY hkey;
244     DWORD dwType, cbData;
245     LPBYTE lpData = NULL;
246     INSTALLSTATE state;
247     REGSAM access = KEY_ALL_ACCESS;
248
249     if (is_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
579     create_test_guid(prodcode, prod_squashed);
580     get_user_sid(&usersid);
581
582     if (is_wow64)
583         access |= KEY_WOW64_64KEY;
584
585     /* NULL prodcode */
586     state = MsiQueryProductStateA(NULL);
587     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
588
589     /* empty prodcode */
590     state = MsiQueryProductStateA("");
591     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
592
593     /* garbage prodcode */
594     state = MsiQueryProductStateA("garbage");
595     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
596
597     /* guid without brackets */
598     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
599     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
600
601     /* guid with brackets */
602     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
603     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
604
605     /* same length as guid, but random */
606     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
607     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
608
609     /* MSIINSTALLCONTEXT_USERUNMANAGED */
610
611     state = MsiQueryProductStateA(prodcode);
612     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
613
614     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
615     lstrcatA(keypath, prod_squashed);
616
617     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
619
620     /* user product key exists */
621     state = MsiQueryProductStateA(prodcode);
622     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
623
624     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
625     lstrcatA(keypath, prodcode);
626
627     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
628     if (res == ERROR_ACCESS_DENIED)
629     {
630         skip("Not enough rights to perform tests\n");
631         RegDeleteKeyA(userkey, "");
632         LocalFree(usersid);
633         return;
634     }
635     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
636
637     /* local uninstall key exists */
638     state = MsiQueryProductStateA(prodcode);
639     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
640
641     data = 1;
642     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
643     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
644
645     /* WindowsInstaller value exists */
646     state = MsiQueryProductStateA(prodcode);
647     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
648
649     RegDeleteValueA(localkey, "WindowsInstaller");
650     delete_key(localkey, "", access & KEY_WOW64_64KEY);
651
652     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
653     lstrcatA(keypath, usersid);
654     lstrcatA(keypath, "\\Products\\");
655     lstrcatA(keypath, prod_squashed);
656
657     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
658     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
659
660     /* local product key exists */
661     state = MsiQueryProductStateA(prodcode);
662     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
663
664     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
665     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
666
667     /* install properties key exists */
668     state = MsiQueryProductStateA(prodcode);
669     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
670
671     data = 1;
672     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
673     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
674
675     /* WindowsInstaller value exists */
676     state = MsiQueryProductStateA(prodcode);
677     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
678
679     data = 2;
680     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
681     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
682
683     /* WindowsInstaller value is not 1 */
684     state = MsiQueryProductStateA(prodcode);
685     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
686
687     RegDeleteKeyA(userkey, "");
688
689     /* user product key does not exist */
690     state = MsiQueryProductStateA(prodcode);
691     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
692
693     RegDeleteValueA(props, "WindowsInstaller");
694     delete_key(props, "", access & KEY_WOW64_64KEY);
695     RegCloseKey(props);
696     delete_key(localkey, "", access & KEY_WOW64_64KEY);
697     RegCloseKey(localkey);
698     RegDeleteKeyA(userkey, "");
699     RegCloseKey(userkey);
700
701     /* MSIINSTALLCONTEXT_USERMANAGED */
702
703     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
704     lstrcatA(keypath, usersid);
705     lstrcatA(keypath, "\\Installer\\Products\\");
706     lstrcatA(keypath, prod_squashed);
707
708     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
709     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
710
711     state = MsiQueryProductStateA(prodcode);
712     ok(state == INSTALLSTATE_ADVERTISED,
713        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
714
715     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
716     lstrcatA(keypath, usersid);
717     lstrcatA(keypath, "\\Products\\");
718     lstrcatA(keypath, prod_squashed);
719
720     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
721     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
722
723     state = MsiQueryProductStateA(prodcode);
724     ok(state == INSTALLSTATE_ADVERTISED,
725        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
726
727     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
729
730     state = MsiQueryProductStateA(prodcode);
731     ok(state == INSTALLSTATE_ADVERTISED,
732        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
733
734     data = 1;
735     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
737
738     /* WindowsInstaller value exists */
739     state = MsiQueryProductStateA(prodcode);
740     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
741
742     RegDeleteValueA(props, "WindowsInstaller");
743     delete_key(props, "", access & KEY_WOW64_64KEY);
744     RegCloseKey(props);
745     delete_key(localkey, "", access & KEY_WOW64_64KEY);
746     RegCloseKey(localkey);
747     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
748     RegCloseKey(prodkey);
749
750     /* MSIINSTALLCONTEXT_MACHINE */
751
752     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
753     lstrcatA(keypath, prod_squashed);
754
755     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
756     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
757
758     state = MsiQueryProductStateA(prodcode);
759     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
760
761     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
762     lstrcatA(keypath, "S-1-5-18\\Products\\");
763     lstrcatA(keypath, prod_squashed);
764
765     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
767
768     state = MsiQueryProductStateA(prodcode);
769     ok(state == INSTALLSTATE_ADVERTISED,
770        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
771
772     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
773     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
774
775     state = MsiQueryProductStateA(prodcode);
776     ok(state == INSTALLSTATE_ADVERTISED,
777        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
778
779     data = 1;
780     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
781     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
782
783     /* WindowsInstaller value exists */
784     state = MsiQueryProductStateA(prodcode);
785     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
786
787     RegDeleteValueA(props, "WindowsInstaller");
788     delete_key(props, "", access & KEY_WOW64_64KEY);
789     RegCloseKey(props);
790     delete_key(localkey, "", access & KEY_WOW64_64KEY);
791     RegCloseKey(localkey);
792     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
793     RegCloseKey(prodkey);
794
795     LocalFree(usersid);
796 }
797
798 static const char table_enc85[] =
799 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
800 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
801 "yz{}~";
802
803 /*
804  *  Encodes a base85 guid given a GUID pointer
805  *  Caller should provide a 21 character buffer for the encoded string.
806  */
807 static void encode_base85_guid( GUID *guid, LPWSTR str )
808 {
809     unsigned int x, *p, i;
810
811     p = (unsigned int*) guid;
812     for( i=0; i<4; i++ )
813     {
814         x = p[i];
815         *str++ = table_enc85[x%85];
816         x = x/85;
817         *str++ = table_enc85[x%85];
818         x = x/85;
819         *str++ = table_enc85[x%85];
820         x = x/85;
821         *str++ = table_enc85[x%85];
822         x = x/85;
823         *str++ = table_enc85[x%85];
824     }
825     *str = 0;
826 }
827
828 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
829 {
830     WCHAR guidW[MAX_PATH];
831     WCHAR base85W[MAX_PATH];
832     WCHAR squashedW[MAX_PATH];
833     GUID guid;
834     HRESULT hr;
835     int size;
836
837     hr = CoCreateGuid(&guid);
838     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
839
840     size = StringFromGUID2(&guid, guidW, MAX_PATH);
841     ok(size == 39, "Expected 39, got %d\n", hr);
842
843     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
844     encode_base85_guid(&guid, base85W);
845     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
846     squash_guid(guidW, squashedW);
847     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
848 }
849
850 static void test_MsiQueryFeatureState(void)
851 {
852     HKEY userkey, localkey, compkey, compkey2;
853     CHAR prodcode[MAX_PATH];
854     CHAR prod_squashed[MAX_PATH];
855     CHAR component[MAX_PATH];
856     CHAR comp_base85[MAX_PATH];
857     CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
858     CHAR keypath[MAX_PATH*2];
859     INSTALLSTATE state;
860     LPSTR usersid;
861     LONG res;
862     REGSAM access = KEY_ALL_ACCESS;
863
864     create_test_guid(prodcode, prod_squashed);
865     compose_base85_guid(component, comp_base85, comp_squashed);
866     compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
867     get_user_sid(&usersid);
868
869     if (is_wow64)
870         access |= KEY_WOW64_64KEY;
871
872     /* NULL prodcode */
873     state = MsiQueryFeatureStateA(NULL, "feature");
874     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
875
876     /* empty prodcode */
877     state = MsiQueryFeatureStateA("", "feature");
878     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
879
880     /* garbage prodcode */
881     state = MsiQueryFeatureStateA("garbage", "feature");
882     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
883
884     /* guid without brackets */
885     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
886     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
887
888     /* guid with brackets */
889     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
890     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
891
892     /* same length as guid, but random */
893     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
894     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
895
896     /* NULL szFeature */
897     state = MsiQueryFeatureStateA(prodcode, NULL);
898     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
899
900     /* empty szFeature */
901     state = MsiQueryFeatureStateA(prodcode, "");
902     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
903
904     /* feature key does not exist yet */
905     state = MsiQueryFeatureStateA(prodcode, "feature");
906     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
907
908     /* MSIINSTALLCONTEXT_USERUNMANAGED */
909
910     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
911     lstrcatA(keypath, prod_squashed);
912
913     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
915
916     /* feature key exists */
917     state = MsiQueryFeatureStateA(prodcode, "feature");
918     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
919
920     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
921     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
922
923     /* feature value exists */
924     state = MsiQueryFeatureStateA(prodcode, "feature");
925     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
926
927     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
928     lstrcatA(keypath, usersid);
929     lstrcatA(keypath, "\\Products\\");
930     lstrcatA(keypath, prod_squashed);
931     lstrcatA(keypath, "\\Features");
932
933     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
934     if (res == ERROR_ACCESS_DENIED)
935     {
936         skip("Not enough rights to perform tests\n");
937         RegDeleteKeyA(userkey, "");
938         RegCloseKey(userkey);
939         LocalFree(usersid);
940         return;
941     }
942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
943
944     /* userdata features key exists */
945     state = MsiQueryFeatureStateA(prodcode, "feature");
946     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
947
948     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
949     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
950
951     state = MsiQueryFeatureStateA(prodcode, "feature");
952     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
953
954     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
955     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
956
957     state = MsiQueryFeatureStateA(prodcode, "feature");
958     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
959
960     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
962
963     state = MsiQueryFeatureStateA(prodcode, "feature");
964     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
965
966     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
967     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
968
969     state = MsiQueryFeatureStateA(prodcode, "feature");
970     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
971
972     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
973     lstrcatA(keypath, usersid);
974     lstrcatA(keypath, "\\Components\\");
975     lstrcatA(keypath, comp_squashed);
976
977     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
978     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
979
980     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
981     lstrcatA(keypath, usersid);
982     lstrcatA(keypath, "\\Components\\");
983     lstrcatA(keypath, comp_squashed2);
984
985     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
987
988     state = MsiQueryFeatureStateA(prodcode, "feature");
989     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
990
991     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
993
994     state = MsiQueryFeatureStateA(prodcode, "feature");
995     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
996
997     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
999
1000     state = MsiQueryFeatureStateA(prodcode, "feature");
1001     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1002
1003     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1005
1006     /* INSTALLSTATE_LOCAL */
1007     state = MsiQueryFeatureStateA(prodcode, "feature");
1008     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1009
1010     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1012
1013     /* INSTALLSTATE_SOURCE */
1014     state = MsiQueryFeatureStateA(prodcode, "feature");
1015     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1016
1017     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1019
1020     /* bad INSTALLSTATE_SOURCE */
1021     state = MsiQueryFeatureStateA(prodcode, "feature");
1022     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1023
1024     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1026
1027     /* INSTALLSTATE_SOURCE */
1028     state = MsiQueryFeatureStateA(prodcode, "feature");
1029     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1030
1031     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1032     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1033
1034     /* bad INSTALLSTATE_SOURCE */
1035     state = MsiQueryFeatureStateA(prodcode, "feature");
1036     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1037
1038     RegDeleteValueA(compkey, prod_squashed);
1039     RegDeleteValueA(compkey2, prod_squashed);
1040     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1041     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1042     RegDeleteValueA(localkey, "feature");
1043     RegDeleteValueA(userkey, "feature");
1044     RegDeleteKeyA(userkey, "");
1045     RegCloseKey(compkey);
1046     RegCloseKey(compkey2);
1047     RegCloseKey(localkey);
1048     RegCloseKey(userkey);
1049
1050     /* MSIINSTALLCONTEXT_USERMANAGED */
1051
1052     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1053     lstrcatA(keypath, usersid);
1054     lstrcatA(keypath, "\\Installer\\Features\\");
1055     lstrcatA(keypath, prod_squashed);
1056
1057     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1058     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1059
1060     /* feature key exists */
1061     state = MsiQueryFeatureStateA(prodcode, "feature");
1062     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1063
1064     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1065     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1066
1067     /* feature value exists */
1068     state = MsiQueryFeatureStateA(prodcode, "feature");
1069     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1070
1071     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1072     lstrcatA(keypath, usersid);
1073     lstrcatA(keypath, "\\Products\\");
1074     lstrcatA(keypath, prod_squashed);
1075     lstrcatA(keypath, "\\Features");
1076
1077     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1079
1080     /* userdata features key exists */
1081     state = MsiQueryFeatureStateA(prodcode, "feature");
1082     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1083
1084     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1085     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1086
1087     state = MsiQueryFeatureStateA(prodcode, "feature");
1088     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1089
1090     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1091     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1092
1093     state = MsiQueryFeatureStateA(prodcode, "feature");
1094     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1095
1096     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1097     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1098
1099     state = MsiQueryFeatureStateA(prodcode, "feature");
1100     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1101
1102     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1103     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1104
1105     state = MsiQueryFeatureStateA(prodcode, "feature");
1106     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1107
1108     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1109     lstrcatA(keypath, usersid);
1110     lstrcatA(keypath, "\\Components\\");
1111     lstrcatA(keypath, comp_squashed);
1112
1113     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1114     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1115
1116     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1117     lstrcatA(keypath, usersid);
1118     lstrcatA(keypath, "\\Components\\");
1119     lstrcatA(keypath, comp_squashed2);
1120
1121     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1122     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1123
1124     state = MsiQueryFeatureStateA(prodcode, "feature");
1125     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1126
1127     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1129
1130     state = MsiQueryFeatureStateA(prodcode, "feature");
1131     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1132
1133     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1135
1136     state = MsiQueryFeatureStateA(prodcode, "feature");
1137     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1138
1139     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1140     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1141
1142     state = MsiQueryFeatureStateA(prodcode, "feature");
1143     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1144
1145     RegDeleteValueA(compkey, prod_squashed);
1146     RegDeleteValueA(compkey2, prod_squashed);
1147     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1148     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1149     RegDeleteValueA(localkey, "feature");
1150     RegDeleteValueA(userkey, "feature");
1151     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1152     RegCloseKey(compkey);
1153     RegCloseKey(compkey2);
1154     RegCloseKey(localkey);
1155     RegCloseKey(userkey);
1156
1157     /* MSIINSTALLCONTEXT_MACHINE */
1158
1159     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1160     lstrcatA(keypath, prod_squashed);
1161
1162     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
1163     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1164
1165     /* feature key exists */
1166     state = MsiQueryFeatureStateA(prodcode, "feature");
1167     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1168
1169     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1170     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1171
1172     /* feature value exists */
1173     state = MsiQueryFeatureStateA(prodcode, "feature");
1174     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1175
1176     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1177     lstrcatA(keypath, "S-1-5-18\\Products\\");
1178     lstrcatA(keypath, prod_squashed);
1179     lstrcatA(keypath, "\\Features");
1180
1181     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
1182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1183
1184     /* userdata features key exists */
1185     state = MsiQueryFeatureStateA(prodcode, "feature");
1186     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1187
1188     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1190
1191     state = MsiQueryFeatureStateA(prodcode, "feature");
1192     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1193
1194     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1196
1197     state = MsiQueryFeatureStateA(prodcode, "feature");
1198     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1199
1200     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1201     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1202
1203     state = MsiQueryFeatureStateA(prodcode, "feature");
1204     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1205
1206     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1207     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1208
1209     state = MsiQueryFeatureStateA(prodcode, "feature");
1210     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1211
1212     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1213     lstrcatA(keypath, "S-1-5-18\\Components\\");
1214     lstrcatA(keypath, comp_squashed);
1215
1216     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1218
1219     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1220     lstrcatA(keypath, "S-1-5-18\\Components\\");
1221     lstrcatA(keypath, comp_squashed2);
1222
1223     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
1224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1225
1226     state = MsiQueryFeatureStateA(prodcode, "feature");
1227     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1228
1229     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1230     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1231
1232     state = MsiQueryFeatureStateA(prodcode, "feature");
1233     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1234
1235     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1236     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1237
1238     state = MsiQueryFeatureStateA(prodcode, "feature");
1239     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1240
1241     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1242     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1243
1244     state = MsiQueryFeatureStateA(prodcode, "feature");
1245     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1246
1247     RegDeleteValueA(compkey, prod_squashed);
1248     RegDeleteValueA(compkey2, prod_squashed);
1249     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1250     delete_key(compkey2, "", access & KEY_WOW64_64KEY);
1251     RegDeleteValueA(localkey, "feature");
1252     RegDeleteValueA(userkey, "feature");
1253     delete_key(userkey, "", access & KEY_WOW64_64KEY);
1254     RegCloseKey(compkey);
1255     RegCloseKey(compkey2);
1256     RegCloseKey(localkey);
1257     RegCloseKey(userkey);
1258     LocalFree(usersid);
1259 }
1260
1261 static void test_MsiQueryComponentState(void)
1262 {
1263     HKEY compkey, prodkey;
1264     CHAR prodcode[MAX_PATH];
1265     CHAR prod_squashed[MAX_PATH];
1266     CHAR component[MAX_PATH];
1267     CHAR comp_base85[MAX_PATH];
1268     CHAR comp_squashed[MAX_PATH];
1269     CHAR keypath[MAX_PATH];
1270     INSTALLSTATE state;
1271     LPSTR usersid;
1272     LONG res;
1273     UINT r;
1274     REGSAM access = KEY_ALL_ACCESS;
1275
1276     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1277
1278     if (!pMsiQueryComponentStateA)
1279     {
1280         win_skip("MsiQueryComponentStateA not implemented\n");
1281         return;
1282     }
1283
1284     create_test_guid(prodcode, prod_squashed);
1285     compose_base85_guid(component, comp_base85, comp_squashed);
1286     get_user_sid(&usersid);
1287
1288     if (is_wow64)
1289         access |= KEY_WOW64_64KEY;
1290
1291     /* NULL szProductCode */
1292     state = MAGIC_ERROR;
1293     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1294     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1295     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1296
1297     /* empty szProductCode */
1298     state = MAGIC_ERROR;
1299     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1300     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1301     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1302
1303     /* random szProductCode */
1304     state = MAGIC_ERROR;
1305     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1306     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1307     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1308
1309     /* GUID-length szProductCode */
1310     state = MAGIC_ERROR;
1311     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1312     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1313     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1314
1315     /* GUID-length with brackets */
1316     state = MAGIC_ERROR;
1317     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1318     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1319     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1320
1321     /* actual GUID */
1322     state = MAGIC_ERROR;
1323     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1324     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1325     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1326
1327     state = MAGIC_ERROR;
1328     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1329     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1330     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1331
1332     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1333     lstrcatA(keypath, prod_squashed);
1334
1335     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1336     if (res == ERROR_ACCESS_DENIED)
1337     {
1338         skip("Not enough rights to perform tests\n");
1339         LocalFree(usersid);
1340         return;
1341     }
1342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1343
1344     state = MAGIC_ERROR;
1345     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1346     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1347     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1348
1349     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1350     RegCloseKey(prodkey);
1351
1352     /* create local system product key */
1353     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1354     lstrcatA(keypath, prod_squashed);
1355     lstrcatA(keypath, "\\InstallProperties");
1356
1357     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1358     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1359
1360     /* local system product key exists */
1361     state = MAGIC_ERROR;
1362     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1363     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1364     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1365
1366     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1368
1369     /* LocalPackage value exists */
1370     state = MAGIC_ERROR;
1371     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1372     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1373     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1374
1375     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1376     lstrcatA(keypath, comp_squashed);
1377
1378     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1380
1381     /* component key exists */
1382     state = MAGIC_ERROR;
1383     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1384     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1385     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1386
1387     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1389
1390     /* component\product exists */
1391     state = MAGIC_ERROR;
1392     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1393     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1394     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1395        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1396
1397     /* NULL component, product exists */
1398     state = MAGIC_ERROR;
1399     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1400     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1401     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1402
1403     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1404     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1405
1406     /* INSTALLSTATE_LOCAL */
1407     state = MAGIC_ERROR;
1408     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1410     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1411
1412     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1413     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1414
1415     /* INSTALLSTATE_SOURCE */
1416     state = MAGIC_ERROR;
1417     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1418     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1419     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1420
1421     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1423
1424     /* bad INSTALLSTATE_SOURCE */
1425     state = MAGIC_ERROR;
1426     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1427     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1428     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1429
1430     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1431     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1432
1433     /* INSTALLSTATE_SOURCE */
1434     state = MAGIC_ERROR;
1435     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1436     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1437     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1438
1439     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1440     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1441
1442     /* bad INSTALLSTATE_SOURCE */
1443     state = MAGIC_ERROR;
1444     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1446     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1447
1448     RegDeleteValueA(prodkey, "LocalPackage");
1449     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1450     RegDeleteValueA(compkey, prod_squashed);
1451     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1452     RegCloseKey(prodkey);
1453     RegCloseKey(compkey);
1454
1455     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1456
1457     state = MAGIC_ERROR;
1458     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1459     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1460     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1461
1462     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1463     lstrcatA(keypath, prod_squashed);
1464
1465     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1466     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1467
1468     state = MAGIC_ERROR;
1469     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1470     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1471     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1472
1473     RegDeleteKeyA(prodkey, "");
1474     RegCloseKey(prodkey);
1475
1476     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1477     lstrcatA(keypath, usersid);
1478     lstrcatA(keypath, "\\Products\\");
1479     lstrcatA(keypath, prod_squashed);
1480     lstrcatA(keypath, "\\InstallProperties");
1481
1482     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1483     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1484
1485     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1486     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1487
1488     RegCloseKey(prodkey);
1489
1490     state = MAGIC_ERROR;
1491     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1492     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1493     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1494
1495     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1496     lstrcatA(keypath, usersid);
1497     lstrcatA(keypath, "\\Components\\");
1498     lstrcatA(keypath, comp_squashed);
1499
1500     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1501     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1502
1503     /* component key exists */
1504     state = MAGIC_ERROR;
1505     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1506     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1507     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1508
1509     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1510     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1511
1512     /* component\product exists */
1513     state = MAGIC_ERROR;
1514     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1515     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1516     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1517        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1518
1519     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1520     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1521
1522     state = MAGIC_ERROR;
1523     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1524     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1525     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1526
1527     /* MSIINSTALLCONTEXT_USERMANAGED */
1528
1529     state = MAGIC_ERROR;
1530     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1531     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1532     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1533
1534     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1535     lstrcatA(keypath, prod_squashed);
1536
1537     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1538     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1539
1540     state = MAGIC_ERROR;
1541     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1542     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1543     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1544
1545     RegDeleteKeyA(prodkey, "");
1546     RegCloseKey(prodkey);
1547
1548     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1549     lstrcatA(keypath, usersid);
1550     lstrcatA(keypath, "\\Installer\\Products\\");
1551     lstrcatA(keypath, prod_squashed);
1552
1553     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1555
1556     state = MAGIC_ERROR;
1557     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1558     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1559     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1560
1561     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1562     RegCloseKey(prodkey);
1563
1564     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1565     lstrcatA(keypath, usersid);
1566     lstrcatA(keypath, "\\Products\\");
1567     lstrcatA(keypath, prod_squashed);
1568     lstrcatA(keypath, "\\InstallProperties");
1569
1570     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1572
1573     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1574     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1575
1576     state = MAGIC_ERROR;
1577     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1578     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1579     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1580
1581     RegDeleteValueA(prodkey, "LocalPackage");
1582     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1583     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1584     RegDeleteValueA(compkey, prod_squashed);
1585     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1586     RegCloseKey(prodkey);
1587     RegCloseKey(compkey);
1588     LocalFree(usersid);
1589 }
1590
1591 static void test_MsiGetComponentPath(void)
1592 {
1593     HKEY compkey, prodkey, installprop;
1594     CHAR prodcode[MAX_PATH];
1595     CHAR prod_squashed[MAX_PATH];
1596     CHAR component[MAX_PATH];
1597     CHAR comp_base85[MAX_PATH];
1598     CHAR comp_squashed[MAX_PATH];
1599     CHAR keypath[MAX_PATH];
1600     CHAR path[MAX_PATH];
1601     INSTALLSTATE state;
1602     LPSTR usersid;
1603     DWORD size, val;
1604     REGSAM access = KEY_ALL_ACCESS;
1605     LONG res;
1606
1607     create_test_guid(prodcode, prod_squashed);
1608     compose_base85_guid(component, comp_base85, comp_squashed);
1609     get_user_sid(&usersid);
1610
1611     if (is_wow64)
1612         access |= KEY_WOW64_64KEY;
1613
1614     /* NULL szProduct */
1615     size = MAX_PATH;
1616     state = MsiGetComponentPathA(NULL, component, path, &size);
1617     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1618     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1619
1620     /* NULL szComponent */
1621     size = MAX_PATH;
1622     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1623     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1624     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1625
1626     size = MAX_PATH;
1627     state = MsiLocateComponentA(NULL, path, &size);
1628     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1629     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1630
1631     /* NULL lpPathBuf */
1632     size = MAX_PATH;
1633     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1634     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1635     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1636
1637     size = MAX_PATH;
1638     state = MsiLocateComponentA(component, NULL, &size);
1639     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1640     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1641
1642     /* NULL pcchBuf */
1643     size = MAX_PATH;
1644     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1645     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1646     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1647
1648     size = MAX_PATH;
1649     state = MsiLocateComponentA(component, path, NULL);
1650     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1651     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1652
1653     /* all params valid */
1654     size = MAX_PATH;
1655     state = MsiGetComponentPathA(prodcode, component, path, &size);
1656     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1657     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1658
1659     size = MAX_PATH;
1660     state = MsiLocateComponentA(component, path, &size);
1661     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1662     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1663
1664     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1665     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1666     lstrcatA(keypath, comp_squashed);
1667
1668     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1669     if (res == ERROR_ACCESS_DENIED)
1670     {
1671         skip("Not enough rights to perform tests\n");
1672         LocalFree(usersid);
1673         return;
1674     }
1675     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1676
1677     /* local system component key exists */
1678     size = MAX_PATH;
1679     state = MsiGetComponentPathA(prodcode, component, path, &size);
1680     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1681     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1682
1683     size = MAX_PATH;
1684     state = MsiLocateComponentA(component, path, &size);
1685     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1686     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1687
1688     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1690
1691     /* product value exists */
1692     path[0] = 0;
1693     size = MAX_PATH;
1694     state = MsiGetComponentPathA(prodcode, component, path, &size);
1695     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1696     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1697     ok(size == 10, "Expected 10, got %d\n", size);
1698
1699     path[0] = 0;
1700     size = MAX_PATH;
1701     state = MsiLocateComponentA(component, path, &size);
1702     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1703     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1704     ok(size == 10, "Expected 10, got %d\n", size);
1705
1706     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1707     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1708     lstrcatA(keypath, prod_squashed);
1709     lstrcatA(keypath, "\\InstallProperties");
1710
1711     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1713
1714     val = 1;
1715     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1717
1718     /* install properties key exists */
1719     path[0] = 0;
1720     size = MAX_PATH;
1721     state = MsiGetComponentPathA(prodcode, component, path, &size);
1722     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1723     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1724     ok(size == 10, "Expected 10, got %d\n", size);
1725
1726     path[0] = 0;
1727     size = MAX_PATH;
1728     state = MsiLocateComponentA(component, path, &size);
1729     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1730     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1731     ok(size == 10, "Expected 10, got %d\n", size);
1732
1733     create_file("C:\\imapath", "C:\\imapath", 11);
1734
1735     /* file exists */
1736     path[0] = 0;
1737     size = MAX_PATH;
1738     state = MsiGetComponentPathA(prodcode, component, path, &size);
1739     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1740     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1741     ok(size == 10, "Expected 10, got %d\n", size);
1742
1743     path[0] = 0;
1744     size = MAX_PATH;
1745     state = MsiLocateComponentA(component, path, &size);
1746     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1747     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1748     ok(size == 10, "Expected 10, got %d\n", size);
1749
1750     RegDeleteValueA(compkey, prod_squashed);
1751     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1752     RegDeleteValueA(installprop, "WindowsInstaller");
1753     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1754     RegCloseKey(compkey);
1755     RegCloseKey(installprop);
1756     DeleteFileA("C:\\imapath");
1757
1758     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1759     lstrcatA(keypath, "Installer\\UserData\\");
1760     lstrcatA(keypath, usersid);
1761     lstrcatA(keypath, "\\Components\\");
1762     lstrcatA(keypath, comp_squashed);
1763
1764     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1765     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1766
1767     /* user managed component key exists */
1768     size = MAX_PATH;
1769     state = MsiGetComponentPathA(prodcode, component, path, &size);
1770     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1771     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1772
1773     size = MAX_PATH;
1774     state = MsiLocateComponentA(component, path, &size);
1775     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1776     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1777
1778     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1780
1781     /* product value exists */
1782     path[0] = 0;
1783     size = MAX_PATH;
1784     state = MsiGetComponentPathA(prodcode, component, path, &size);
1785     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1786     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1787     ok(size == 10, "Expected 10, got %d\n", size);
1788
1789     path[0] = 0;
1790     size = MAX_PATH;
1791     state = MsiLocateComponentA(component, path, &size);
1792     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1793     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1794     ok(size == 10, "Expected 10, got %d\n", size);
1795
1796     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1797     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1798     lstrcatA(keypath, prod_squashed);
1799     lstrcatA(keypath, "\\InstallProperties");
1800
1801     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1803
1804     val = 1;
1805     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1806     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1807
1808     /* install properties key exists */
1809     path[0] = 0;
1810     size = MAX_PATH;
1811     state = MsiGetComponentPathA(prodcode, component, path, &size);
1812     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1813     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1814     ok(size == 10, "Expected 10, got %d\n", size);
1815
1816     path[0] = 0;
1817     size = MAX_PATH;
1818     state = MsiLocateComponentA(component, path, &size);
1819     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1820     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1821     ok(size == 10, "Expected 10, got %d\n", size);
1822
1823     create_file("C:\\imapath", "C:\\imapath", 11);
1824
1825     /* file exists */
1826     path[0] = 0;
1827     size = MAX_PATH;
1828     state = MsiGetComponentPathA(prodcode, component, path, &size);
1829     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1830     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1831     ok(size == 10, "Expected 10, got %d\n", size);
1832
1833     path[0] = 0;
1834     size = MAX_PATH;
1835     state = MsiLocateComponentA(component, path, &size);
1836     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1837     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1838     ok(size == 10, "Expected 10, got %d\n", size);
1839
1840     RegDeleteValueA(compkey, prod_squashed);
1841     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1842     RegDeleteValueA(installprop, "WindowsInstaller");
1843     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1844     RegCloseKey(compkey);
1845     RegCloseKey(installprop);
1846     DeleteFileA("C:\\imapath");
1847
1848     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1849     lstrcatA(keypath, "Installer\\Managed\\");
1850     lstrcatA(keypath, usersid);
1851     lstrcatA(keypath, "\\Installer\\Products\\");
1852     lstrcatA(keypath, prod_squashed);
1853
1854     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
1855     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1856
1857     /* user managed product key exists */
1858     size = MAX_PATH;
1859     state = MsiGetComponentPathA(prodcode, component, path, &size);
1860     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1861     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1862
1863     size = MAX_PATH;
1864     state = MsiLocateComponentA(component, path, &size);
1865     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1866     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1867
1868     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1869     lstrcatA(keypath, "Installer\\UserData\\");
1870     lstrcatA(keypath, usersid);
1871     lstrcatA(keypath, "\\Components\\");
1872     lstrcatA(keypath, comp_squashed);
1873
1874     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1875     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1876
1877     /* user managed component key exists */
1878     size = MAX_PATH;
1879     state = MsiGetComponentPathA(prodcode, component, path, &size);
1880     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1881     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1882
1883     size = MAX_PATH;
1884     state = MsiLocateComponentA(component, path, &size);
1885     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1886     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1887
1888     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1889     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1890
1891     /* product value exists */
1892     path[0] = 0;
1893     size = MAX_PATH;
1894     state = MsiGetComponentPathA(prodcode, component, path, &size);
1895     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1896     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1897     ok(size == 10, "Expected 10, got %d\n", size);
1898
1899     path[0] = 0;
1900     size = MAX_PATH;
1901     state = MsiLocateComponentA(component, path, &size);
1902     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1903     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1904     ok(size == 10, "Expected 10, got %d\n", size);
1905
1906     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1907     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1908     lstrcatA(keypath, prod_squashed);
1909     lstrcatA(keypath, "\\InstallProperties");
1910
1911     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
1912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1913
1914     val = 1;
1915     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1917
1918     /* install properties key exists */
1919     path[0] = 0;
1920     size = MAX_PATH;
1921     state = MsiGetComponentPathA(prodcode, component, path, &size);
1922     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1923     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1924     ok(size == 10, "Expected 10, got %d\n", size);
1925
1926     path[0] = 0;
1927     size = MAX_PATH;
1928     state = MsiLocateComponentA(component, path, &size);
1929     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1930     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1931     ok(size == 10, "Expected 10, got %d\n", size);
1932
1933     create_file("C:\\imapath", "C:\\imapath", 11);
1934
1935     /* file exists */
1936     path[0] = 0;
1937     size = MAX_PATH;
1938     state = MsiGetComponentPathA(prodcode, component, path, &size);
1939     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1940     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1941     ok(size == 10, "Expected 10, got %d\n", size);
1942
1943     path[0] = 0;
1944     size = MAX_PATH;
1945     state = MsiLocateComponentA(component, path, &size);
1946     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1947     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1948     ok(size == 10, "Expected 10, got %d\n", size);
1949
1950     RegDeleteValueA(compkey, prod_squashed);
1951     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
1952     delete_key(compkey, "", access & KEY_WOW64_64KEY);
1953     RegDeleteValueA(installprop, "WindowsInstaller");
1954     delete_key(installprop, "", access & KEY_WOW64_64KEY);
1955     RegCloseKey(prodkey);
1956     RegCloseKey(compkey);
1957     RegCloseKey(installprop);
1958     DeleteFileA("C:\\imapath");
1959
1960     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1961     lstrcatA(keypath, prod_squashed);
1962
1963     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1965
1966     /* user unmanaged product key exists */
1967     size = MAX_PATH;
1968     state = MsiGetComponentPathA(prodcode, component, path, &size);
1969     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1970     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1971
1972     size = MAX_PATH;
1973     state = MsiLocateComponentA(component, path, &size);
1974     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1975     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1976
1977     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1978     lstrcatA(keypath, "Installer\\UserData\\");
1979     lstrcatA(keypath, usersid);
1980     lstrcatA(keypath, "\\Components\\");
1981     lstrcatA(keypath, comp_squashed);
1982
1983     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
1984     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1985
1986     /* user unmanaged component key exists */
1987     size = MAX_PATH;
1988     state = MsiGetComponentPathA(prodcode, component, path, &size);
1989     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1990     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1991
1992     size = MAX_PATH;
1993     state = MsiLocateComponentA(component, path, &size);
1994     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1995     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1996
1997     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1999
2000     /* product value exists */
2001     path[0] = 0;
2002     size = MAX_PATH;
2003     state = MsiGetComponentPathA(prodcode, component, path, &size);
2004     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2005     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2006     ok(size == 10, "Expected 10, got %d\n", size);
2007
2008     path[0] = 0;
2009     size = MAX_PATH;
2010     state = MsiLocateComponentA(component, path, &size);
2011     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2012     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2013     ok(size == 10, "Expected 10, got %d\n", size);
2014
2015     create_file("C:\\imapath", "C:\\imapath", 11);
2016
2017     /* file exists */
2018     path[0] = 0;
2019     size = MAX_PATH;
2020     state = MsiGetComponentPathA(prodcode, component, path, &size);
2021     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2022     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2023     ok(size == 10, "Expected 10, got %d\n", size);
2024
2025     path[0] = 0;
2026     size = MAX_PATH;
2027     state = MsiLocateComponentA(component, path, &size);
2028     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2029     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2030     ok(size == 10, "Expected 10, got %d\n", size);
2031
2032     RegDeleteValueA(compkey, prod_squashed);
2033     RegDeleteKeyA(prodkey, "");
2034     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2035     RegCloseKey(prodkey);
2036     RegCloseKey(compkey);
2037     DeleteFileA("C:\\imapath");
2038
2039     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2040     lstrcatA(keypath, prod_squashed);
2041
2042     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2044
2045     /* local classes product key exists */
2046     size = MAX_PATH;
2047     state = MsiGetComponentPathA(prodcode, component, path, &size);
2048     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2049     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2050
2051     size = MAX_PATH;
2052     state = MsiLocateComponentA(component, path, &size);
2053     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2054     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2055
2056     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2057     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2058     lstrcatA(keypath, comp_squashed);
2059
2060     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2062
2063     /* local user component key exists */
2064     size = MAX_PATH;
2065     state = MsiGetComponentPathA(prodcode, component, path, &size);
2066     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2067     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2068
2069     size = MAX_PATH;
2070     state = MsiLocateComponentA(component, path, &size);
2071     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2072     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
2073
2074     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2076
2077     /* product value exists */
2078     path[0] = 0;
2079     size = MAX_PATH;
2080     state = MsiGetComponentPathA(prodcode, component, path, &size);
2081     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2082     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2083     ok(size == 10, "Expected 10, got %d\n", size);
2084
2085     path[0] = 0;
2086     size = MAX_PATH;
2087     state = MsiLocateComponentA(component, path, &size);
2088     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2089     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2090     ok(size == 10, "Expected 10, got %d\n", size);
2091
2092     create_file("C:\\imapath", "C:\\imapath", 11);
2093
2094     /* file exists */
2095     path[0] = 0;
2096     size = MAX_PATH;
2097     state = MsiGetComponentPathA(prodcode, component, path, &size);
2098     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2099     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2100     ok(size == 10, "Expected 10, got %d\n", size);
2101
2102     path[0] = 0;
2103     size = MAX_PATH;
2104     state = MsiLocateComponentA(component, path, &size);
2105     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2106     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2107     ok(size == 10, "Expected 10, got %d\n", size);
2108
2109     RegDeleteValueA(compkey, prod_squashed);
2110     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2111     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2112     RegCloseKey(prodkey);
2113     RegCloseKey(compkey);
2114     DeleteFileA("C:\\imapath");
2115     LocalFree(usersid);
2116 }
2117
2118 static void test_MsiGetProductCode(void)
2119 {
2120     HKEY compkey, prodkey;
2121     CHAR prodcode[MAX_PATH];
2122     CHAR prod_squashed[MAX_PATH];
2123     CHAR prodcode2[MAX_PATH];
2124     CHAR prod2_squashed[MAX_PATH];
2125     CHAR component[MAX_PATH];
2126     CHAR comp_base85[MAX_PATH];
2127     CHAR comp_squashed[MAX_PATH];
2128     CHAR keypath[MAX_PATH];
2129     CHAR product[MAX_PATH];
2130     LPSTR usersid;
2131     LONG res;
2132     UINT r;
2133     REGSAM access = KEY_ALL_ACCESS;
2134
2135     create_test_guid(prodcode, prod_squashed);
2136     create_test_guid(prodcode2, prod2_squashed);
2137     compose_base85_guid(component, comp_base85, comp_squashed);
2138     get_user_sid(&usersid);
2139
2140     if (is_wow64)
2141         access |= KEY_WOW64_64KEY;
2142
2143     /* szComponent is NULL */
2144     lstrcpyA(product, "prod");
2145     r = MsiGetProductCodeA(NULL, product);
2146     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2147     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2148
2149     /* szComponent is empty */
2150     lstrcpyA(product, "prod");
2151     r = MsiGetProductCodeA("", product);
2152     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2153     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2154
2155     /* garbage szComponent */
2156     lstrcpyA(product, "prod");
2157     r = MsiGetProductCodeA("garbage", product);
2158     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2159     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2160
2161     /* guid without brackets */
2162     lstrcpyA(product, "prod");
2163     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
2164     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2165     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2166
2167     /* guid with brackets */
2168     lstrcpyA(product, "prod");
2169     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
2170     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2171     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2172
2173     /* same length as guid, but random */
2174     lstrcpyA(product, "prod");
2175     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
2176     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2177     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2178
2179     /* all params correct, szComponent not published */
2180     lstrcpyA(product, "prod");
2181     r = MsiGetProductCodeA(component, product);
2182     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2183     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2184
2185     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2186     lstrcatA(keypath, "Installer\\UserData\\");
2187     lstrcatA(keypath, usersid);
2188     lstrcatA(keypath, "\\Components\\");
2189     lstrcatA(keypath, comp_squashed);
2190
2191     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2192     if (res == ERROR_ACCESS_DENIED)
2193     {
2194         skip("Not enough rights to perform tests\n");
2195         LocalFree(usersid);
2196         return;
2197     }
2198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2199
2200     /* user unmanaged component key exists */
2201     lstrcpyA(product, "prod");
2202     r = MsiGetProductCodeA(component, product);
2203     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2204     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2205
2206     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2207     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2208
2209     /* product value exists */
2210     lstrcpyA(product, "prod");
2211     r = MsiGetProductCodeA(component, product);
2212     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2213     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2214
2215     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2217
2218     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2219     lstrcatA(keypath, "Installer\\Managed\\");
2220     lstrcatA(keypath, usersid);
2221     lstrcatA(keypath, "\\Installer\\Products\\");
2222     lstrcatA(keypath, prod_squashed);
2223
2224     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2225     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2226
2227     /* user managed product key of first product exists */
2228     lstrcpyA(product, "prod");
2229     r = MsiGetProductCodeA(component, product);
2230     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2231     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2232
2233     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2234     RegCloseKey(prodkey);
2235
2236     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2237     lstrcatA(keypath, prod_squashed);
2238
2239     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2240     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2241
2242     /* user unmanaged product key exists */
2243     lstrcpyA(product, "prod");
2244     r = MsiGetProductCodeA(component, product);
2245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2246     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2247
2248     RegDeleteKeyA(prodkey, "");
2249     RegCloseKey(prodkey);
2250
2251     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2252     lstrcatA(keypath, prod_squashed);
2253
2254     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2255     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2256
2257     /* local classes product key exists */
2258     lstrcpyA(product, "prod");
2259     r = MsiGetProductCodeA(component, product);
2260     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2261     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2262
2263     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2264     RegCloseKey(prodkey);
2265
2266     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2267     lstrcatA(keypath, "Installer\\Managed\\");
2268     lstrcatA(keypath, usersid);
2269     lstrcatA(keypath, "\\Installer\\Products\\");
2270     lstrcatA(keypath, prod2_squashed);
2271
2272     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2274
2275     /* user managed product key of second product exists */
2276     lstrcpyA(product, "prod");
2277     r = MsiGetProductCodeA(component, product);
2278     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2279     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2280
2281     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2282     RegCloseKey(prodkey);
2283     RegDeleteValueA(compkey, prod_squashed);
2284     RegDeleteValueA(compkey, prod2_squashed);
2285     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2286     RegCloseKey(compkey);
2287
2288     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2289     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2290     lstrcatA(keypath, comp_squashed);
2291
2292     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2294
2295     /* local user component key exists */
2296     lstrcpyA(product, "prod");
2297     r = MsiGetProductCodeA(component, product);
2298     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2299     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2300
2301     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2303
2304     /* product value exists */
2305     lstrcpyA(product, "prod");
2306     r = MsiGetProductCodeA(component, product);
2307     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2308     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2309
2310     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2311     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2312
2313     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2314     lstrcatA(keypath, "Installer\\Managed\\");
2315     lstrcatA(keypath, usersid);
2316     lstrcatA(keypath, "\\Installer\\Products\\");
2317     lstrcatA(keypath, prod_squashed);
2318
2319     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2320     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2321
2322     /* user managed product key of first product exists */
2323     lstrcpyA(product, "prod");
2324     r = MsiGetProductCodeA(component, product);
2325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2326     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2327
2328     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2329     RegCloseKey(prodkey);
2330
2331     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2332     lstrcatA(keypath, prod_squashed);
2333
2334     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2335     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2336
2337     /* user unmanaged product key exists */
2338     lstrcpyA(product, "prod");
2339     r = MsiGetProductCodeA(component, product);
2340     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2341     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2342
2343     RegDeleteKeyA(prodkey, "");
2344     RegCloseKey(prodkey);
2345
2346     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2347     lstrcatA(keypath, prod_squashed);
2348
2349     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2351
2352     /* local classes product key exists */
2353     lstrcpyA(product, "prod");
2354     r = MsiGetProductCodeA(component, product);
2355     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2356     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2357
2358     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2359     RegCloseKey(prodkey);
2360
2361     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2362     lstrcatA(keypath, "Installer\\Managed\\");
2363     lstrcatA(keypath, usersid);
2364     lstrcatA(keypath, "\\Installer\\Products\\");
2365     lstrcatA(keypath, prod2_squashed);
2366
2367     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2369
2370     /* user managed product key of second product exists */
2371     lstrcpyA(product, "prod");
2372     r = MsiGetProductCodeA(component, product);
2373     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2374     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2375
2376     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2377     RegCloseKey(prodkey);
2378     RegDeleteValueA(compkey, prod_squashed);
2379     RegDeleteValueA(compkey, prod2_squashed);
2380     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2381     RegCloseKey(compkey);
2382     LocalFree(usersid);
2383 }
2384
2385 static void test_MsiEnumClients(void)
2386 {
2387     HKEY compkey;
2388     CHAR prodcode[MAX_PATH];
2389     CHAR prod_squashed[MAX_PATH];
2390     CHAR prodcode2[MAX_PATH];
2391     CHAR prod2_squashed[MAX_PATH];
2392     CHAR component[MAX_PATH];
2393     CHAR comp_base85[MAX_PATH];
2394     CHAR comp_squashed[MAX_PATH];
2395     CHAR product[MAX_PATH];
2396     CHAR keypath[MAX_PATH];
2397     LPSTR usersid;
2398     LONG res;
2399     UINT r;
2400     REGSAM access = KEY_ALL_ACCESS;
2401
2402     create_test_guid(prodcode, prod_squashed);
2403     create_test_guid(prodcode2, prod2_squashed);
2404     compose_base85_guid(component, comp_base85, comp_squashed);
2405     get_user_sid(&usersid);
2406
2407     if (is_wow64)
2408         access |= KEY_WOW64_64KEY;
2409
2410     /* NULL szComponent */
2411     product[0] = '\0';
2412     r = MsiEnumClientsA(NULL, 0, product);
2413     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2414     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2415
2416     /* empty szComponent */
2417     product[0] = '\0';
2418     r = MsiEnumClientsA("", 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     /* NULL lpProductBuf */
2423     r = MsiEnumClientsA(component, 0, NULL);
2424     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2425
2426     /* all params correct, component missing */
2427     product[0] = '\0';
2428     r = MsiEnumClientsA(component, 0, product);
2429     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2430     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2431
2432     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2433     lstrcatA(keypath, "Installer\\UserData\\");
2434     lstrcatA(keypath, usersid);
2435     lstrcatA(keypath, "\\Components\\");
2436     lstrcatA(keypath, comp_squashed);
2437
2438     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2439     if (res == ERROR_ACCESS_DENIED)
2440     {
2441         skip("Not enough rights to perform tests\n");
2442         LocalFree(usersid);
2443         return;
2444     }
2445     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2446
2447     /* user unmanaged component key exists */
2448     product[0] = '\0';
2449     r = MsiEnumClientsA(component, 0, product);
2450     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2451     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2452
2453     /* index > 0, no products exist */
2454     product[0] = '\0';
2455     r = MsiEnumClientsA(component, 1, product);
2456     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2457     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2458
2459     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2460     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2461
2462     /* product value exists */
2463     r = MsiEnumClientsA(component, 0, product);
2464     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2465     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2466
2467     /* try index 0 again */
2468     product[0] = '\0';
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 1, second product value does not exist */
2474     product[0] = '\0';
2475     r = MsiEnumClientsA(component, 1, product);
2476     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2477     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2478
2479     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2481
2482     /* try index 1, second product value does exist */
2483     product[0] = '\0';
2484     r = MsiEnumClientsA(component, 1, product);
2485     todo_wine
2486     {
2487         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2488         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2489     }
2490
2491     /* start the enumeration over */
2492     product[0] = '\0';
2493     r = MsiEnumClientsA(component, 0, product);
2494     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2495     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2496        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2497
2498     /* correctly query second product */
2499     product[0] = '\0';
2500     r = MsiEnumClientsA(component, 1, product);
2501     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2502     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2503        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2504
2505     RegDeleteValueA(compkey, prod_squashed);
2506     RegDeleteValueA(compkey, prod2_squashed);
2507     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2508     RegCloseKey(compkey);
2509
2510     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2511     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2512     lstrcatA(keypath, comp_squashed);
2513
2514     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
2515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2516
2517     /* user local component key exists */
2518     product[0] = '\0';
2519     r = MsiEnumClientsA(component, 0, product);
2520     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2521     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2522
2523     /* index > 0, no products exist */
2524     product[0] = '\0';
2525     r = MsiEnumClientsA(component, 1, product);
2526     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2527     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2528
2529     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2530     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2531
2532     /* product value exists */
2533     product[0] = '\0';
2534     r = MsiEnumClientsA(component, 0, product);
2535     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2536     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2537
2538     /* try index 0 again */
2539     product[0] = '\0';
2540     r = MsiEnumClientsA(component, 0, product);
2541     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2542
2543     /* try index 1, second product value does not exist */
2544     product[0] = '\0';
2545     r = MsiEnumClientsA(component, 1, product);
2546     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2547     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2548
2549     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2551
2552     /* try index 1, second product value does exist */
2553     product[0] = '\0';
2554     r = MsiEnumClientsA(component, 1, product);
2555     todo_wine
2556     {
2557         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2558         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2559     }
2560
2561     /* start the enumeration over */
2562     product[0] = '\0';
2563     r = MsiEnumClientsA(component, 0, product);
2564     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2565     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2566        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2567
2568     /* correctly query second product */
2569     product[0] = '\0';
2570     r = MsiEnumClientsA(component, 1, product);
2571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2572     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2573        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2574
2575     RegDeleteValueA(compkey, prod_squashed);
2576     RegDeleteValueA(compkey, prod2_squashed);
2577     delete_key(compkey, "", access & KEY_WOW64_64KEY);
2578     RegCloseKey(compkey);
2579     LocalFree(usersid);
2580 }
2581
2582 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2583                              LPSTR *langcheck, LPDWORD langchecksz)
2584 {
2585     LPSTR version;
2586     VS_FIXEDFILEINFO *ffi;
2587     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2588     USHORT *lang;
2589
2590     version = HeapAlloc(GetProcessHeap(), 0, size);
2591     GetFileVersionInfoA(path, 0, size, version);
2592
2593     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2594     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2595     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2596             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2597             LOWORD(ffi->dwFileVersionLS));
2598     *verchecksz = lstrlenA(*vercheck);
2599
2600     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2601     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2602     sprintf(*langcheck, "%d", *lang);
2603     *langchecksz = lstrlenA(*langcheck);
2604
2605     HeapFree(GetProcessHeap(), 0, version);
2606 }
2607
2608 static void test_MsiGetFileVersion(void)
2609 {
2610     UINT r;
2611     DWORD versz, langsz;
2612     char version[MAX_PATH];
2613     char lang[MAX_PATH];
2614     char path[MAX_PATH];
2615     LPSTR vercheck, langcheck;
2616     DWORD verchecksz, langchecksz;
2617
2618     /* NULL szFilePath */
2619     versz = MAX_PATH;
2620     langsz = MAX_PATH;
2621     lstrcpyA(version, "version");
2622     lstrcpyA(lang, "lang");
2623     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2624     ok(r == ERROR_INVALID_PARAMETER,
2625        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2626     ok(!lstrcmpA(version, "version"),
2627        "Expected version to be unchanged, got %s\n", version);
2628     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2629     ok(!lstrcmpA(lang, "lang"),
2630        "Expected lang to be unchanged, got %s\n", lang);
2631     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2632
2633     /* empty szFilePath */
2634     versz = MAX_PATH;
2635     langsz = MAX_PATH;
2636     lstrcpyA(version, "version");
2637     lstrcpyA(lang, "lang");
2638     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2639     ok(r == ERROR_FILE_NOT_FOUND,
2640        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2641     ok(!lstrcmpA(version, "version"),
2642        "Expected version to be unchanged, got %s\n", version);
2643     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2644     ok(!lstrcmpA(lang, "lang"),
2645        "Expected lang to be unchanged, got %s\n", lang);
2646     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2647
2648     /* nonexistent szFilePath */
2649     versz = MAX_PATH;
2650     langsz = MAX_PATH;
2651     lstrcpyA(version, "version");
2652     lstrcpyA(lang, "lang");
2653     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2654     ok(r == ERROR_FILE_NOT_FOUND,
2655        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2656     ok(!lstrcmpA(version, "version"),
2657        "Expected version to be unchanged, got %s\n", version);
2658     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2659     ok(!lstrcmpA(lang, "lang"),
2660        "Expected lang to be unchanged, got %s\n", lang);
2661     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2662
2663     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2664     versz = MAX_PATH;
2665     langsz = MAX_PATH;
2666     lstrcpyA(version, "version");
2667     lstrcpyA(lang, "lang");
2668     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2669     ok(r == ERROR_INVALID_PARAMETER,
2670        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2671     ok(!lstrcmpA(version, "version"),
2672        "Expected version to be unchanged, got %s\n", version);
2673     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2674     ok(!lstrcmpA(lang, "lang"),
2675        "Expected lang to be unchanged, got %s\n", lang);
2676     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2677
2678     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2679     versz = MAX_PATH;
2680     langsz = MAX_PATH;
2681     lstrcpyA(version, "version");
2682     lstrcpyA(lang, "lang");
2683     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2684     ok(r == ERROR_INVALID_PARAMETER,
2685        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2686     ok(!lstrcmpA(version, "version"),
2687        "Expected version to be unchanged, got %s\n", version);
2688     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2689     ok(!lstrcmpA(lang, "lang"),
2690        "Expected lang to be unchanged, got %s\n", lang);
2691     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2692
2693     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2694     versz = 0;
2695     langsz = MAX_PATH;
2696     lstrcpyA(version, "version");
2697     lstrcpyA(lang, "lang");
2698     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2699     ok(r == ERROR_FILE_NOT_FOUND,
2700        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2701     ok(!lstrcmpA(version, "version"),
2702        "Expected version to be unchanged, got %s\n", version);
2703     ok(versz == 0, "Expected 0, got %d\n", versz);
2704     ok(!lstrcmpA(lang, "lang"),
2705        "Expected lang to be unchanged, got %s\n", lang);
2706     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2707
2708     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2709     versz = MAX_PATH;
2710     langsz = 0;
2711     lstrcpyA(version, "version");
2712     lstrcpyA(lang, "lang");
2713     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2714     ok(r == ERROR_FILE_NOT_FOUND,
2715        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2716     ok(!lstrcmpA(version, "version"),
2717        "Expected version to be unchanged, got %s\n", version);
2718     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2719     ok(!lstrcmpA(lang, "lang"),
2720        "Expected lang to be unchanged, got %s\n", lang);
2721     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2722
2723     /* nonexistent szFilePath, rest NULL */
2724     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2725     ok(r == ERROR_FILE_NOT_FOUND,
2726        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2727
2728     create_file("ver.txt", "ver.txt", 20);
2729
2730     /* file exists, no version information */
2731     versz = MAX_PATH;
2732     langsz = MAX_PATH;
2733     lstrcpyA(version, "version");
2734     lstrcpyA(lang, "lang");
2735     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2736     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2737     ok(!lstrcmpA(version, "version"),
2738        "Expected version to be unchanged, got %s\n", version);
2739     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2740     ok(!lstrcmpA(lang, "lang"),
2741        "Expected lang to be unchanged, got %s\n", lang);
2742     ok(r == ERROR_FILE_INVALID,
2743        "Expected ERROR_FILE_INVALID, got %d\n", r);
2744
2745     DeleteFileA("ver.txt");
2746
2747     /* relative path, has version information */
2748     versz = MAX_PATH;
2749     langsz = MAX_PATH;
2750     lstrcpyA(version, "version");
2751     lstrcpyA(lang, "lang");
2752     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2753     todo_wine
2754     {
2755         ok(r == ERROR_FILE_NOT_FOUND,
2756            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2757         ok(!lstrcmpA(version, "version"),
2758            "Expected version to be unchanged, got %s\n", version);
2759         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2760         ok(!lstrcmpA(lang, "lang"),
2761            "Expected lang to be unchanged, got %s\n", lang);
2762         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2763     }
2764
2765     GetSystemDirectoryA(path, MAX_PATH);
2766     lstrcatA(path, "\\kernel32.dll");
2767
2768     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2769
2770     /* absolute path, has version information */
2771     versz = MAX_PATH;
2772     langsz = MAX_PATH;
2773     lstrcpyA(version, "version");
2774     lstrcpyA(lang, "lang");
2775     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2776     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2777     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2778     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2779     ok(!lstrcmpA(version, vercheck),
2780         "Expected %s, got %s\n", vercheck, version);
2781
2782     /* only check version */
2783     versz = MAX_PATH;
2784     lstrcpyA(version, "version");
2785     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2786     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2787     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2788     ok(!lstrcmpA(version, vercheck),
2789        "Expected %s, got %s\n", vercheck, version);
2790
2791     /* only check language */
2792     langsz = MAX_PATH;
2793     lstrcpyA(lang, "lang");
2794     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2795     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2796     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2797
2798     /* check neither version nor language */
2799     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2801
2802     /* get pcchVersionBuf */
2803     versz = MAX_PATH;
2804     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2805     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2806     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2807
2808     /* get pcchLangBuf */
2809     langsz = MAX_PATH;
2810     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2811     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2812     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
2813
2814     /* pcchVersionBuf not big enough */
2815     versz = 5;
2816     lstrcpyA(version, "version");
2817     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2818     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2819     ok(!strncmp(version, vercheck, 4),
2820        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2821     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2822
2823     /* pcchLangBuf not big enough */
2824     langsz = 3;
2825     lstrcpyA(lang, "lang");
2826     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2827     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2828     ok(!strncmp(lang, langcheck, 2),
2829        "Expected first character of %s, got %s\n", langcheck, lang);
2830     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
2831
2832     HeapFree(GetProcessHeap(), 0, vercheck);
2833     HeapFree(GetProcessHeap(), 0, langcheck);
2834 }
2835
2836 static void test_MsiGetProductInfo(void)
2837 {
2838     UINT r;
2839     LONG res;
2840     HKEY propkey, source;
2841     HKEY prodkey, localkey;
2842     CHAR prodcode[MAX_PATH];
2843     CHAR prod_squashed[MAX_PATH];
2844     CHAR packcode[MAX_PATH];
2845     CHAR pack_squashed[MAX_PATH];
2846     CHAR buf[MAX_PATH];
2847     CHAR keypath[MAX_PATH];
2848     LPSTR usersid;
2849     DWORD sz, val = 42;
2850     REGSAM access = KEY_ALL_ACCESS;
2851
2852     create_test_guid(prodcode, prod_squashed);
2853     create_test_guid(packcode, pack_squashed);
2854     get_user_sid(&usersid);
2855
2856     if (is_wow64)
2857         access |= KEY_WOW64_64KEY;
2858
2859     /* NULL szProduct */
2860     sz = MAX_PATH;
2861     lstrcpyA(buf, "apple");
2862     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2863     ok(r == ERROR_INVALID_PARAMETER,
2864        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2865     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2866     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2867
2868     /* empty szProduct */
2869     sz = MAX_PATH;
2870     lstrcpyA(buf, "apple");
2871     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2872     ok(r == ERROR_INVALID_PARAMETER,
2873        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2874     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2875     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2876
2877     /* garbage szProduct */
2878     sz = MAX_PATH;
2879     lstrcpyA(buf, "apple");
2880     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2881     ok(r == ERROR_INVALID_PARAMETER,
2882        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2883     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2884     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2885
2886     /* guid without brackets */
2887     sz = MAX_PATH;
2888     lstrcpyA(buf, "apple");
2889     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2890                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2891     ok(r == ERROR_INVALID_PARAMETER,
2892        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2893     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2894     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2895
2896     /* guid with brackets */
2897     sz = MAX_PATH;
2898     lstrcpyA(buf, "apple");
2899     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2900                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2901     ok(r == ERROR_UNKNOWN_PRODUCT,
2902        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2903     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2904     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2905
2906     /* same length as guid, but random */
2907     sz = MAX_PATH;
2908     lstrcpyA(buf, "apple");
2909     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2910                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2911     ok(r == ERROR_INVALID_PARAMETER,
2912        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2913     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2914     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2915
2916     /* not installed, NULL szAttribute */
2917     sz = MAX_PATH;
2918     lstrcpyA(buf, "apple");
2919     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2920     ok(r == ERROR_INVALID_PARAMETER,
2921        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2922     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2923     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2924
2925     /* not installed, NULL lpValueBuf */
2926     sz = MAX_PATH;
2927     lstrcpyA(buf, "apple");
2928     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2929     ok(r == ERROR_UNKNOWN_PRODUCT,
2930        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2931     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2932     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2933
2934     /* not installed, NULL pcchValueBuf */
2935     sz = MAX_PATH;
2936     lstrcpyA(buf, "apple");
2937     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2938     ok(r == ERROR_INVALID_PARAMETER,
2939        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2940     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2941     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2942
2943     /* created guid cannot possibly be an installed product code */
2944     sz = MAX_PATH;
2945     lstrcpyA(buf, "apple");
2946     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2947     ok(r == ERROR_UNKNOWN_PRODUCT,
2948        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2949     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2950     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2951
2952     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2953     lstrcatA(keypath, usersid);
2954     lstrcatA(keypath, "\\Installer\\Products\\");
2955     lstrcatA(keypath, prod_squashed);
2956
2957     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
2958     if (res == ERROR_ACCESS_DENIED)
2959     {
2960         skip("Not enough rights to perform tests\n");
2961         LocalFree(usersid);
2962         return;
2963     }
2964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2965
2966     /* managed product code exists */
2967     sz = MAX_PATH;
2968     lstrcpyA(buf, "apple");
2969     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2970     ok(r == ERROR_UNKNOWN_PROPERTY,
2971        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2972     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2973     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2974
2975     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
2976     RegCloseKey(prodkey);
2977
2978     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2979     lstrcatA(keypath, usersid);
2980     lstrcatA(keypath, "\\Products\\");
2981     lstrcatA(keypath, prod_squashed);
2982
2983     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
2984     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2985
2986     /* local user product code exists */
2987     sz = MAX_PATH;
2988     lstrcpyA(buf, "apple");
2989     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2990     ok(r == ERROR_UNKNOWN_PRODUCT,
2991        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2992     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2993     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2994
2995     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2996     lstrcatA(keypath, usersid);
2997     lstrcatA(keypath, "\\Installer\\Products\\");
2998     lstrcatA(keypath, prod_squashed);
2999
3000     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3001     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3002
3003     /* both local and managed product code exist */
3004     sz = MAX_PATH;
3005     lstrcpyA(buf, "apple");
3006     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3007     ok(r == ERROR_UNKNOWN_PROPERTY,
3008        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3009     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3010     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3011
3012     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3014
3015     /* InstallProperties key exists */
3016     sz = MAX_PATH;
3017     lstrcpyA(buf, "apple");
3018     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3019     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3020     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3021     ok(sz == 0, "Expected 0, got %d\n", sz);
3022
3023     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3025
3026     /* HelpLink value exists */
3027     sz = MAX_PATH;
3028     lstrcpyA(buf, "apple");
3029     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3030     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3031     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3032     ok(sz == 4, "Expected 4, got %d\n", sz);
3033
3034     /* pcchBuf is NULL */
3035     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
3036     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3037
3038     /* lpValueBuf is NULL */
3039     sz = MAX_PATH;
3040     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3042     ok(sz == 4, "Expected 4, got %d\n", sz);
3043
3044     /* lpValueBuf is NULL, pcchValueBuf is too small */
3045     sz = 2;
3046     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
3047     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3048     ok(sz == 4, "Expected 4, got %d\n", sz);
3049
3050     /* lpValueBuf is non-NULL, pcchValueBuf is too small */
3051     sz = 2;
3052     lstrcpyA(buf, "apple");
3053     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3054     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
3055     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3056     ok(sz == 4, "Expected 4, got %d\n", sz);
3057
3058     /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
3059     sz = 4;
3060     lstrcpyA(buf, "apple");
3061     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3062     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
3063     ok(!lstrcmpA(buf, "apple"),
3064        "Expected buf to remain unchanged, got \"%s\"\n", buf);
3065     ok(sz == 4, "Expected 4, got %d\n", sz);
3066
3067     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
3068     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3069
3070     /* random property not supported by MSI, value exists */
3071     sz = MAX_PATH;
3072     lstrcpyA(buf, "apple");
3073     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
3074     ok(r == ERROR_UNKNOWN_PROPERTY,
3075        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3076     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3077     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3078
3079     RegDeleteValueA(propkey, "IMadeThis");
3080     RegDeleteValueA(propkey, "HelpLink");
3081     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3082     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3083     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
3084     RegCloseKey(propkey);
3085     RegCloseKey(localkey);
3086     RegCloseKey(prodkey);
3087
3088     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
3089     lstrcatA(keypath, prod_squashed);
3090
3091     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
3092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3093
3094     /* user product key exists */
3095     sz = MAX_PATH;
3096     lstrcpyA(buf, "apple");
3097     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3098     ok(r == ERROR_UNKNOWN_PROPERTY,
3099        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3100     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3101     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3102
3103     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3104     lstrcatA(keypath, usersid);
3105     lstrcatA(keypath, "\\Products\\");
3106     lstrcatA(keypath, prod_squashed);
3107
3108     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3110
3111     /* local user product key exists */
3112     sz = MAX_PATH;
3113     lstrcpyA(buf, "apple");
3114     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3115     ok(r == ERROR_UNKNOWN_PROPERTY,
3116        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3117     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3118     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3119
3120     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3121     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3122
3123     /* InstallProperties key exists */
3124     sz = MAX_PATH;
3125     lstrcpyA(buf, "apple");
3126     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3127     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3128     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3129     ok(sz == 0, "Expected 0, got %d\n", sz);
3130
3131     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3133
3134     /* HelpLink value exists */
3135     sz = MAX_PATH;
3136     lstrcpyA(buf, "apple");
3137     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3138     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3139     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3140     ok(sz == 4, "Expected 4, got %d\n", sz);
3141
3142     RegDeleteValueA(propkey, "HelpLink");
3143     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3144     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3145     RegDeleteKeyA(prodkey, "");
3146     RegCloseKey(propkey);
3147     RegCloseKey(localkey);
3148     RegCloseKey(prodkey);
3149
3150     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3151     lstrcatA(keypath, prod_squashed);
3152
3153     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
3154     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3155
3156     /* classes product key exists */
3157     sz = MAX_PATH;
3158     lstrcpyA(buf, "apple");
3159     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3160     ok(r == ERROR_UNKNOWN_PROPERTY,
3161        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3162     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3163     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3164
3165     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3166     lstrcatA(keypath, usersid);
3167     lstrcatA(keypath, "\\Products\\");
3168     lstrcatA(keypath, prod_squashed);
3169
3170     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3171     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3172
3173     /* local user product key exists */
3174     sz = MAX_PATH;
3175     lstrcpyA(buf, "apple");
3176     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3177     ok(r == ERROR_UNKNOWN_PROPERTY,
3178        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3179     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3180     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3181
3182     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3183     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3184
3185     /* InstallProperties key exists */
3186     sz = MAX_PATH;
3187     lstrcpyA(buf, "apple");
3188     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3189     ok(r == ERROR_UNKNOWN_PROPERTY,
3190        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3191     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3192     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3193
3194     delete_key(propkey, "", access & KEY_WOW64_64KEY);
3195     delete_key(localkey, "", access & KEY_WOW64_64KEY);
3196     RegCloseKey(propkey);
3197     RegCloseKey(localkey);
3198
3199     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3200     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
3201     lstrcatA(keypath, prod_squashed);
3202
3203     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
3204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3205
3206     /* Local System product key exists */
3207     sz = MAX_PATH;
3208     lstrcpyA(buf, "apple");
3209     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3210     ok(r == ERROR_UNKNOWN_PROPERTY,
3211         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3212     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3213     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3214
3215     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
3216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3217
3218     /* InstallProperties key exists */
3219     sz = MAX_PATH;
3220     lstrcpyA(buf, "apple");
3221     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3223     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3224     ok(sz == 0, "Expected 0, got %d\n", sz);
3225
3226     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3228
3229     /* HelpLink value exists */
3230     sz = MAX_PATH;
3231     lstrcpyA(buf, "apple");
3232     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3234     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3235     ok(sz == 4, "Expected 4, got %d\n", sz);
3236
3237     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
3238                          (const BYTE *)&val, sizeof(DWORD));
3239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3240
3241     /* HelpLink type is REG_DWORD */
3242     sz = MAX_PATH;
3243     lstrcpyA(buf, "apple");
3244     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3246     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3247     ok(sz == 2, "Expected 2, got %d\n", sz);
3248
3249     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
3250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3251
3252     /* DisplayName value exists */
3253     sz = MAX_PATH;
3254     lstrcpyA(buf, "apple");
3255     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3257     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3258     ok(sz == 4, "Expected 4, got %d\n", sz);
3259
3260     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
3261                          (const BYTE *)&val, sizeof(DWORD));
3262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3263
3264     /* DisplayName type is REG_DWORD */
3265     sz = MAX_PATH;
3266     lstrcpyA(buf, "apple");
3267     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3268     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3269     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3270     ok(sz == 2, "Expected 2, got %d\n", sz);
3271
3272     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3274
3275     /* DisplayVersion value exists */
3276     sz = MAX_PATH;
3277     lstrcpyA(buf, "apple");
3278     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3280     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3281     ok(sz == 5, "Expected 5, got %d\n", sz);
3282
3283     res = RegSetValueExA(propkey, "DisplayVersion", 0,
3284                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3286
3287     /* DisplayVersion type is REG_DWORD */
3288     sz = MAX_PATH;
3289     lstrcpyA(buf, "apple");
3290     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3291     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3292     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3293     ok(sz == 2, "Expected 2, got %d\n", sz);
3294
3295     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3297
3298     /* HelpTelephone value exists */
3299     sz = MAX_PATH;
3300     lstrcpyA(buf, "apple");
3301     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3303     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3304     ok(sz == 4, "Expected 4, got %d\n", sz);
3305
3306     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3307                          (const BYTE *)&val, sizeof(DWORD));
3308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3309
3310     /* HelpTelephone type is REG_DWORD */
3311     sz = MAX_PATH;
3312     lstrcpyA(buf, "apple");
3313     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3315     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3316     ok(sz == 2, "Expected 2, got %d\n", sz);
3317
3318     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3320
3321     /* InstallLocation value exists */
3322     sz = MAX_PATH;
3323     lstrcpyA(buf, "apple");
3324     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3326     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3327     ok(sz == 3, "Expected 3, got %d\n", sz);
3328
3329     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3330                          (const BYTE *)&val, sizeof(DWORD));
3331     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3332
3333     /* InstallLocation type is REG_DWORD */
3334     sz = MAX_PATH;
3335     lstrcpyA(buf, "apple");
3336     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3338     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3339     ok(sz == 2, "Expected 2, got %d\n", sz);
3340
3341     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3343
3344     /* InstallSource value exists */
3345     sz = MAX_PATH;
3346     lstrcpyA(buf, "apple");
3347     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3349     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3350     ok(sz == 6, "Expected 6, got %d\n", sz);
3351
3352     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3353                          (const BYTE *)&val, sizeof(DWORD));
3354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3355
3356     /* InstallSource type is REG_DWORD */
3357     sz = MAX_PATH;
3358     lstrcpyA(buf, "apple");
3359     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3360     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3361     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3362     ok(sz == 2, "Expected 2, got %d\n", sz);
3363
3364     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3366
3367     /* InstallDate value exists */
3368     sz = MAX_PATH;
3369     lstrcpyA(buf, "apple");
3370     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3372     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3373     ok(sz == 4, "Expected 4, got %d\n", sz);
3374
3375     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3376                          (const BYTE *)&val, sizeof(DWORD));
3377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3378
3379     /* InstallDate type is REG_DWORD */
3380     sz = MAX_PATH;
3381     lstrcpyA(buf, "apple");
3382     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3384     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3385     ok(sz == 2, "Expected 2, got %d\n", sz);
3386
3387     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3389
3390     /* Publisher value exists */
3391     sz = MAX_PATH;
3392     lstrcpyA(buf, "apple");
3393     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3394     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3395     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3396     ok(sz == 3, "Expected 3, got %d\n", sz);
3397
3398     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3399                          (const BYTE *)&val, sizeof(DWORD));
3400     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3401
3402     /* Publisher type is REG_DWORD */
3403     sz = MAX_PATH;
3404     lstrcpyA(buf, "apple");
3405     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3406     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3407     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3408     ok(sz == 2, "Expected 2, got %d\n", sz);
3409
3410     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3412
3413     /* LocalPackage value exists */
3414     sz = MAX_PATH;
3415     lstrcpyA(buf, "apple");
3416     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3417     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3418     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3419     ok(sz == 4, "Expected 4, got %d\n", sz);
3420
3421     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3422                          (const BYTE *)&val, sizeof(DWORD));
3423     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3424
3425     /* LocalPackage type is REG_DWORD */
3426     sz = MAX_PATH;
3427     lstrcpyA(buf, "apple");
3428     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3429     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3430     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3431     ok(sz == 2, "Expected 2, got %d\n", sz);
3432
3433     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3435
3436     /* UrlInfoAbout value exists */
3437     sz = MAX_PATH;
3438     lstrcpyA(buf, "apple");
3439     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3441     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3442     ok(sz == 5, "Expected 5, got %d\n", sz);
3443
3444     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3445                          (const BYTE *)&val, sizeof(DWORD));
3446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3447
3448     /* UrlInfoAbout type is REG_DWORD */
3449     sz = MAX_PATH;
3450     lstrcpyA(buf, "apple");
3451     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3452     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3453     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3454     ok(sz == 2, "Expected 2, got %d\n", sz);
3455
3456     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3457     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3458
3459     /* UrlUpdateInfo value exists */
3460     sz = MAX_PATH;
3461     lstrcpyA(buf, "apple");
3462     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3464     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3465     ok(sz == 4, "Expected 4, got %d\n", sz);
3466
3467     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3468                          (const BYTE *)&val, sizeof(DWORD));
3469     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3470
3471     /* UrlUpdateInfo type is REG_DWORD */
3472     sz = MAX_PATH;
3473     lstrcpyA(buf, "apple");
3474     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3475     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3476     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3477     ok(sz == 2, "Expected 2, got %d\n", sz);
3478
3479     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3481
3482     /* VersionMinor value exists */
3483     sz = MAX_PATH;
3484     lstrcpyA(buf, "apple");
3485     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3486     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3487     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3488     ok(sz == 1, "Expected 1, got %d\n", sz);
3489
3490     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3491                          (const BYTE *)&val, sizeof(DWORD));
3492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3493
3494     /* VersionMinor type is REG_DWORD */
3495     sz = MAX_PATH;
3496     lstrcpyA(buf, "apple");
3497     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3498     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3499     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3500     ok(sz == 2, "Expected 2, got %d\n", sz);
3501
3502     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3504
3505     /* VersionMajor value exists */
3506     sz = MAX_PATH;
3507     lstrcpyA(buf, "apple");
3508     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3510     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3511     ok(sz == 1, "Expected 1, got %d\n", sz);
3512
3513     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3514                          (const BYTE *)&val, sizeof(DWORD));
3515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3516
3517     /* VersionMajor type is REG_DWORD */
3518     sz = MAX_PATH;
3519     lstrcpyA(buf, "apple");
3520     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3522     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3523     ok(sz == 2, "Expected 2, got %d\n", sz);
3524
3525     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3527
3528     /* ProductID value exists */
3529     sz = MAX_PATH;
3530     lstrcpyA(buf, "apple");
3531     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3532     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3533     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3534     ok(sz == 2, "Expected 2, got %d\n", sz);
3535
3536     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3537                          (const BYTE *)&val, sizeof(DWORD));
3538     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3539
3540     /* ProductID type is REG_DWORD */
3541     sz = MAX_PATH;
3542     lstrcpyA(buf, "apple");
3543     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3545     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3546     ok(sz == 2, "Expected 2, got %d\n", sz);
3547
3548     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3549     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3550
3551     /* RegCompany value exists */
3552     sz = MAX_PATH;
3553     lstrcpyA(buf, "apple");
3554     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3556     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3557     ok(sz == 4, "Expected 4, got %d\n", sz);
3558
3559     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3560                          (const BYTE *)&val, sizeof(DWORD));
3561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3562
3563     /* RegCompany type is REG_DWORD */
3564     sz = MAX_PATH;
3565     lstrcpyA(buf, "apple");
3566     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3567     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3568     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3569     ok(sz == 2, "Expected 2, got %d\n", sz);
3570
3571     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3572     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3573
3574     /* RegOwner value exists */
3575     sz = MAX_PATH;
3576     lstrcpyA(buf, "apple");
3577     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3578     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3579     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3580     ok(sz == 3, "Expected 3, got %d\n", sz);
3581
3582     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3583                          (const BYTE *)&val, sizeof(DWORD));
3584     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3585
3586     /* RegOwner type is REG_DWORD */
3587     sz = MAX_PATH;
3588     lstrcpyA(buf, "apple");
3589     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3590     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3591     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3592     ok(sz == 2, "Expected 2, got %d\n", sz);
3593
3594     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3595     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3596
3597     /* InstanceType value exists */
3598     sz = MAX_PATH;
3599     lstrcpyA(buf, "apple");
3600     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3601     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3602     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3603     ok(sz == 0, "Expected 0, got %d\n", sz);
3604
3605     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3606                          (const BYTE *)&val, sizeof(DWORD));
3607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3608
3609     /* InstanceType type is REG_DWORD */
3610     sz = MAX_PATH;
3611     lstrcpyA(buf, "apple");
3612     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3613     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3614     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3615     ok(sz == 0, "Expected 0, got %d\n", sz);
3616
3617     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3619
3620     /* InstanceType value exists */
3621     sz = MAX_PATH;
3622     lstrcpyA(buf, "apple");
3623     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3624     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3625     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3626     ok(sz == 4, "Expected 4, got %d\n", sz);
3627
3628     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3629                          (const BYTE *)&val, sizeof(DWORD));
3630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3631
3632     /* InstanceType type is REG_DWORD */
3633     sz = MAX_PATH;
3634     lstrcpyA(buf, "apple");
3635     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3636     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3637     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3638     ok(sz == 2, "Expected 2, got %d\n", sz);
3639
3640     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3642
3643     /* Transforms value exists */
3644     sz = MAX_PATH;
3645     lstrcpyA(buf, "apple");
3646     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3647     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3648     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3649     ok(sz == 0, "Expected 0, got %d\n", sz);
3650
3651     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3652                          (const BYTE *)&val, sizeof(DWORD));
3653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3654
3655     /* Transforms type is REG_DWORD */
3656     sz = MAX_PATH;
3657     lstrcpyA(buf, "apple");
3658     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3659     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3660     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3661     ok(sz == 0, "Expected 0, got %d\n", sz);
3662
3663     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3664     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3665
3666     /* Transforms value exists */
3667     sz = MAX_PATH;
3668     lstrcpyA(buf, "apple");
3669     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3670     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3671     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3672     ok(sz == 6, "Expected 6, got %d\n", sz);
3673
3674     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3675                          (const BYTE *)&val, sizeof(DWORD));
3676     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3677
3678     /* Transforms type is REG_DWORD */
3679     sz = MAX_PATH;
3680     lstrcpyA(buf, "apple");
3681     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3682     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3683     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3684     ok(sz == 2, "Expected 2, got %d\n", sz);
3685
3686     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3688
3689     /* Language value exists */
3690     sz = MAX_PATH;
3691     lstrcpyA(buf, "apple");
3692     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3693     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3694     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3695     ok(sz == 0, "Expected 0, got %d\n", sz);
3696
3697     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3698                          (const BYTE *)&val, sizeof(DWORD));
3699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3700
3701     /* Language type is REG_DWORD */
3702     sz = MAX_PATH;
3703     lstrcpyA(buf, "apple");
3704     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3705     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3706     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3707     ok(sz == 0, "Expected 0, got %d\n", sz);
3708
3709     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3711
3712     /* Language value exists */
3713     sz = MAX_PATH;
3714     lstrcpyA(buf, "apple");
3715     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3716     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3717     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3718     ok(sz == 4, "Expected 4, got %d\n", sz);
3719
3720     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3721                          (const BYTE *)&val, sizeof(DWORD));
3722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3723
3724     /* Language type is REG_DWORD */
3725     sz = MAX_PATH;
3726     lstrcpyA(buf, "apple");
3727     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3728     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3729     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3730     ok(sz == 2, "Expected 2, got %d\n", sz);
3731
3732     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3733     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3734
3735     /* ProductName value exists */
3736     sz = MAX_PATH;
3737     lstrcpyA(buf, "apple");
3738     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3739     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3740     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3741     ok(sz == 0, "Expected 0, got %d\n", sz);
3742
3743     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3744                          (const BYTE *)&val, sizeof(DWORD));
3745     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3746
3747     /* ProductName type is REG_DWORD */
3748     sz = MAX_PATH;
3749     lstrcpyA(buf, "apple");
3750     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3751     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3752     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3753     ok(sz == 0, "Expected 0, got %d\n", sz);
3754
3755     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3756     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3757
3758     /* ProductName value exists */
3759     sz = MAX_PATH;
3760     lstrcpyA(buf, "apple");
3761     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3762     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3763     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3764     ok(sz == 4, "Expected 4, got %d\n", sz);
3765
3766     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3767                          (const BYTE *)&val, sizeof(DWORD));
3768     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3769
3770     /* ProductName type is REG_DWORD */
3771     sz = MAX_PATH;
3772     lstrcpyA(buf, "apple");
3773     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3774     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3775     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3776     ok(sz == 2, "Expected 2, got %d\n", sz);
3777
3778     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3780
3781     /* Assignment value exists */
3782     sz = MAX_PATH;
3783     lstrcpyA(buf, "apple");
3784     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3786     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3787     ok(sz == 0, "Expected 0, got %d\n", sz);
3788
3789     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3790                          (const BYTE *)&val, sizeof(DWORD));
3791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3792
3793     /* Assignment type is REG_DWORD */
3794     sz = MAX_PATH;
3795     lstrcpyA(buf, "apple");
3796     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3797     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3798     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3799     ok(sz == 0, "Expected 0, got %d\n", sz);
3800
3801     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3803
3804     /* Assignment value exists */
3805     sz = MAX_PATH;
3806     lstrcpyA(buf, "apple");
3807     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3808     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3809     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3810     ok(sz == 2, "Expected 2, got %d\n", sz);
3811
3812     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3813                          (const BYTE *)&val, sizeof(DWORD));
3814     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3815
3816     /* Assignment type is REG_DWORD */
3817     sz = MAX_PATH;
3818     lstrcpyA(buf, "apple");
3819     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3821     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3822     ok(sz == 2, "Expected 2, got %d\n", sz);
3823
3824     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3825     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3826
3827     /* PackageCode value exists */
3828     sz = MAX_PATH;
3829     lstrcpyA(buf, "apple");
3830     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3831     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3832     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3833     ok(sz == 0, "Expected 0, got %d\n", sz);
3834
3835     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3836                          (const BYTE *)&val, sizeof(DWORD));
3837     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3838
3839     /* PackageCode type is REG_DWORD */
3840     sz = MAX_PATH;
3841     lstrcpyA(buf, "apple");
3842     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3843     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3844     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3845     ok(sz == 0, "Expected 0, got %d\n", sz);
3846
3847     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3848     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3849
3850     /* PackageCode value exists */
3851     sz = MAX_PATH;
3852     lstrcpyA(buf, "apple");
3853     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3854     ok(r == ERROR_BAD_CONFIGURATION,
3855        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3856     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3857     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3858
3859     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3860                          (const BYTE *)&val, sizeof(DWORD));
3861     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3862
3863     /* PackageCode type is REG_DWORD */
3864     sz = MAX_PATH;
3865     lstrcpyA(buf, "apple");
3866     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3867     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3868     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3869     ok(sz == 2, "Expected 2, got %d\n", sz);
3870
3871     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3872     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3873
3874     /* PackageCode value exists */
3875     sz = MAX_PATH;
3876     lstrcpyA(buf, "apple");
3877     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3878     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3879     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3880     ok(sz == 38, "Expected 38, got %d\n", sz);
3881
3882     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3883     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3884
3885     /* Version value exists */
3886     sz = MAX_PATH;
3887     lstrcpyA(buf, "apple");
3888     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3889     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3890     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3891     ok(sz == 0, "Expected 0, got %d\n", sz);
3892
3893     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3894                          (const BYTE *)&val, sizeof(DWORD));
3895     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3896
3897     /* Version type is REG_DWORD */
3898     sz = MAX_PATH;
3899     lstrcpyA(buf, "apple");
3900     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3901     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3902     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3903     ok(sz == 0, "Expected 0, got %d\n", sz);
3904
3905     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3907
3908     /* Version value exists */
3909     sz = MAX_PATH;
3910     lstrcpyA(buf, "apple");
3911     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3912     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3913     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3914     ok(sz == 3, "Expected 3, got %d\n", sz);
3915
3916     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3917                          (const BYTE *)&val, sizeof(DWORD));
3918     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3919
3920     /* Version type is REG_DWORD */
3921     sz = MAX_PATH;
3922     lstrcpyA(buf, "apple");
3923     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3924     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3925     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3926     ok(sz == 2, "Expected 2, got %d\n", sz);
3927
3928     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3930
3931     /* ProductIcon value exists */
3932     sz = MAX_PATH;
3933     lstrcpyA(buf, "apple");
3934     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3935     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3936     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3937     ok(sz == 0, "Expected 0, got %d\n", sz);
3938
3939     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3940                          (const BYTE *)&val, sizeof(DWORD));
3941     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3942
3943     /* ProductIcon type is REG_DWORD */
3944     sz = MAX_PATH;
3945     lstrcpyA(buf, "apple");
3946     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3947     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3948     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3949     ok(sz == 0, "Expected 0, got %d\n", sz);
3950
3951     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3952     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3953
3954     /* ProductIcon value exists */
3955     sz = MAX_PATH;
3956     lstrcpyA(buf, "apple");
3957     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3958     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3959     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3960     ok(sz == 3, "Expected 3, got %d\n", sz);
3961
3962     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3963                          (const BYTE *)&val, sizeof(DWORD));
3964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3965
3966     /* ProductIcon type is REG_DWORD */
3967     sz = MAX_PATH;
3968     lstrcpyA(buf, "apple");
3969     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3970     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3971     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3972     ok(sz == 2, "Expected 2, got %d\n", sz);
3973
3974     /* SourceList key does not exist */
3975     sz = MAX_PATH;
3976     lstrcpyA(buf, "apple");
3977     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3978     ok(r == ERROR_UNKNOWN_PRODUCT,
3979        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3980     ok(!lstrcmpA(buf, "apple"),
3981        "Expected buf to be unchanged, got \"%s\"\n", buf);
3982     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
3983
3984     res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
3985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3986
3987     /* SourceList key exists, but PackageName val does not exist */
3988     sz = MAX_PATH;
3989     lstrcpyA(buf, "apple");
3990     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3991     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3992     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3993     ok(sz == 0, "Expected 0, got %d\n", sz);
3994
3995     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3997
3998     /* PackageName val exists */
3999     sz = MAX_PATH;
4000     lstrcpyA(buf, "apple");
4001     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4002     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4003     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
4004     ok(sz == 8, "Expected 8, got %d\n", sz);
4005
4006     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
4007                          (const BYTE *)&val, sizeof(DWORD));
4008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4009
4010     /* PackageName type is REG_DWORD */
4011     sz = MAX_PATH;
4012     lstrcpyA(buf, "apple");
4013     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4014     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4015     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4016     ok(sz == 2, "Expected 2, got %d\n", sz);
4017
4018     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4020
4021     /* Authorized value exists */
4022     sz = MAX_PATH;
4023     lstrcpyA(buf, "apple");
4024     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4025     if (r != ERROR_UNKNOWN_PROPERTY)
4026     {
4027         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4028         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4029         ok(sz == 0, "Expected 0, got %d\n", sz);
4030     }
4031
4032     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
4033                          (const BYTE *)&val, sizeof(DWORD));
4034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4035
4036     /* AuthorizedLUAApp type is REG_DWORD */
4037     sz = MAX_PATH;
4038     lstrcpyA(buf, "apple");
4039     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4040     if (r != ERROR_UNKNOWN_PROPERTY)
4041     {
4042         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4043         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4044         ok(sz == 0, "Expected 0, got %d\n", sz);
4045     }
4046
4047     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4049
4050     /* Authorized value exists */
4051     sz = MAX_PATH;
4052     lstrcpyA(buf, "apple");
4053     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4054     if (r != ERROR_UNKNOWN_PROPERTY)
4055     {
4056         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4057         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4058         ok(sz == 4, "Expected 4, got %d\n", sz);
4059     }
4060
4061     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
4062                          (const BYTE *)&val, sizeof(DWORD));
4063     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4064
4065     /* AuthorizedLUAApp type is REG_DWORD */
4066     sz = MAX_PATH;
4067     lstrcpyA(buf, "apple");
4068     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4069     if (r != ERROR_UNKNOWN_PROPERTY)
4070     {
4071         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4072         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
4073         ok(sz == 2, "Expected 2, got %d\n", sz);
4074     }
4075
4076     RegDeleteValueA(propkey, "HelpLink");
4077     RegDeleteValueA(propkey, "DisplayName");
4078     RegDeleteValueA(propkey, "DisplayVersion");
4079     RegDeleteValueA(propkey, "HelpTelephone");
4080     RegDeleteValueA(propkey, "InstallLocation");
4081     RegDeleteValueA(propkey, "InstallSource");
4082     RegDeleteValueA(propkey, "InstallDate");
4083     RegDeleteValueA(propkey, "Publisher");
4084     RegDeleteValueA(propkey, "LocalPackage");
4085     RegDeleteValueA(propkey, "UrlInfoAbout");
4086     RegDeleteValueA(propkey, "UrlUpdateInfo");
4087     RegDeleteValueA(propkey, "VersionMinor");
4088     RegDeleteValueA(propkey, "VersionMajor");
4089     RegDeleteValueA(propkey, "ProductID");
4090     RegDeleteValueA(propkey, "RegCompany");
4091     RegDeleteValueA(propkey, "RegOwner");
4092     RegDeleteValueA(propkey, "InstanceType");
4093     RegDeleteValueA(propkey, "Transforms");
4094     RegDeleteValueA(propkey, "Language");
4095     RegDeleteValueA(propkey, "ProductName");
4096     RegDeleteValueA(propkey, "Assignment");
4097     RegDeleteValueA(propkey, "PackageCode");
4098     RegDeleteValueA(propkey, "Version");
4099     RegDeleteValueA(propkey, "ProductIcon");
4100     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4101     delete_key(propkey, "", access & KEY_WOW64_64KEY);
4102     delete_key(localkey, "", access & KEY_WOW64_64KEY);
4103     RegDeleteValueA(prodkey, "InstanceType");
4104     RegDeleteValueA(prodkey, "Transforms");
4105     RegDeleteValueA(prodkey, "Language");
4106     RegDeleteValueA(prodkey, "ProductName");
4107     RegDeleteValueA(prodkey, "Assignment");
4108     RegDeleteValueA(prodkey, "PackageCode");
4109     RegDeleteValueA(prodkey, "Version");
4110     RegDeleteValueA(prodkey, "ProductIcon");
4111     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4112     RegDeleteValueA(source, "PackageName");
4113     delete_key(source, "", access & KEY_WOW64_64KEY);
4114     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
4115     RegCloseKey(propkey);
4116     RegCloseKey(localkey);
4117     RegCloseKey(source);
4118     RegCloseKey(prodkey);
4119     LocalFree(usersid);
4120 }
4121
4122 static void test_MsiGetProductInfoEx(void)
4123 {
4124     UINT r;
4125     LONG res;
4126     HKEY propkey, userkey;
4127     HKEY prodkey, localkey;
4128     CHAR prodcode[MAX_PATH];
4129     CHAR prod_squashed[MAX_PATH];
4130     CHAR packcode[MAX_PATH];
4131     CHAR pack_squashed[MAX_PATH];
4132     CHAR buf[MAX_PATH];
4133     CHAR keypath[MAX_PATH];
4134     LPSTR usersid;
4135     DWORD sz;
4136     REGSAM access = KEY_ALL_ACCESS;
4137
4138     if (!pMsiGetProductInfoExA)
4139     {
4140         win_skip("MsiGetProductInfoExA is not available\n");
4141         return;
4142     }
4143
4144     create_test_guid(prodcode, prod_squashed);
4145     create_test_guid(packcode, pack_squashed);
4146     get_user_sid(&usersid);
4147
4148     if (is_wow64)
4149         access |= KEY_WOW64_64KEY;
4150
4151     /* NULL szProductCode */
4152     sz = MAX_PATH;
4153     lstrcpyA(buf, "apple");
4154     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4155                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4156     ok(r == ERROR_INVALID_PARAMETER,
4157        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4158     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4159     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4160
4161     /* empty szProductCode */
4162     sz = MAX_PATH;
4163     lstrcpyA(buf, "apple");
4164     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4165                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4166     ok(r == ERROR_INVALID_PARAMETER,
4167        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4168     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4169     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4170
4171     /* garbage szProductCode */
4172     sz = MAX_PATH;
4173     lstrcpyA(buf, "apple");
4174     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4175                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4176     ok(r == ERROR_INVALID_PARAMETER,
4177        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4178     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4179     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4180
4181     /* guid without brackets */
4182     sz = MAX_PATH;
4183     lstrcpyA(buf, "apple");
4184     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
4185                               MSIINSTALLCONTEXT_USERUNMANAGED,
4186                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4187     ok(r == ERROR_INVALID_PARAMETER,
4188        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4189     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4190     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4191
4192     /* guid with brackets */
4193     sz = MAX_PATH;
4194     lstrcpyA(buf, "apple");
4195     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
4196                               MSIINSTALLCONTEXT_USERUNMANAGED,
4197                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4198     ok(r == ERROR_UNKNOWN_PRODUCT,
4199        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4200     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4201     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4202
4203     /* szValue is non-NULL while pcchValue is NULL */
4204     lstrcpyA(buf, "apple");
4205     r = pMsiGetProductInfoExA(prodcode, usersid,
4206                               MSIINSTALLCONTEXT_USERUNMANAGED,
4207                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
4208     ok(r == ERROR_INVALID_PARAMETER,
4209        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4210     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4211
4212     /* dwContext is out of range */
4213     sz = MAX_PATH;
4214     lstrcpyA(buf, "apple");
4215     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
4216                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4217     ok(r == ERROR_INVALID_PARAMETER,
4218        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4219     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4220     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4221
4222     /* szProperty is NULL */
4223     sz = MAX_PATH;
4224     lstrcpyA(buf, "apple");
4225     r = pMsiGetProductInfoExA(prodcode, usersid,
4226                               MSIINSTALLCONTEXT_USERUNMANAGED,
4227                               NULL, buf, &sz);
4228     ok(r == ERROR_INVALID_PARAMETER,
4229        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4230     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4231     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4232
4233     /* szProperty is empty */
4234     sz = MAX_PATH;
4235     lstrcpyA(buf, "apple");
4236     r = pMsiGetProductInfoExA(prodcode, usersid,
4237                               MSIINSTALLCONTEXT_USERUNMANAGED,
4238                               "", buf, &sz);
4239     ok(r == ERROR_INVALID_PARAMETER,
4240        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4241     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4242     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4243
4244     /* szProperty is not a valid property */
4245     sz = MAX_PATH;
4246     lstrcpyA(buf, "apple");
4247     r = pMsiGetProductInfoExA(prodcode, usersid,
4248                               MSIINSTALLCONTEXT_USERUNMANAGED,
4249                               "notvalid", buf, &sz);
4250     ok(r == ERROR_UNKNOWN_PRODUCT,
4251        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4252     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4253     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4254
4255     /* same length as guid, but random */
4256     sz = MAX_PATH;
4257     lstrcpyA(buf, "apple");
4258     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
4259                               MSIINSTALLCONTEXT_USERUNMANAGED,
4260                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4261     ok(r == ERROR_INVALID_PARAMETER,
4262        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4263     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4264     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4265
4266     /* MSIINSTALLCONTEXT_USERUNMANAGED */
4267
4268     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4269     lstrcatA(keypath, usersid);
4270     lstrcatA(keypath, "\\Products\\");
4271     lstrcatA(keypath, prod_squashed);
4272
4273     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
4274     if (res == ERROR_ACCESS_DENIED)
4275     {
4276         skip("Not enough rights to perform tests\n");
4277         LocalFree(usersid);
4278         return;
4279     }
4280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4281
4282     /* local user product key exists */
4283     sz = MAX_PATH;
4284     lstrcpyA(buf, "apple");
4285     r = pMsiGetProductInfoExA(prodcode, usersid,
4286                               MSIINSTALLCONTEXT_USERUNMANAGED,
4287                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4288     ok(r == ERROR_UNKNOWN_PRODUCT,
4289        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4290     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4291     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4292
4293     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
4294     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4295
4296     /* InstallProperties key exists */
4297     sz = MAX_PATH;
4298     lstrcpyA(buf, "apple");
4299     r = pMsiGetProductInfoExA(prodcode, usersid,
4300                               MSIINSTALLCONTEXT_USERUNMANAGED,
4301                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4302     ok(r == ERROR_UNKNOWN_PRODUCT,
4303        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4304     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4305     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4306
4307     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4309
4310     /* LocalPackage value exists */
4311     sz = MAX_PATH;
4312     lstrcpyA(buf, "apple");
4313     r = pMsiGetProductInfoExA(prodcode, usersid,
4314                               MSIINSTALLCONTEXT_USERUNMANAGED,
4315                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4316     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4317     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4318     ok(sz == 1, "Expected 1, got %d\n", sz);
4319
4320     RegDeleteValueA(propkey, "LocalPackage");
4321
4322     /* LocalPackage value must exist */
4323     sz = MAX_PATH;
4324     lstrcpyA(buf, "apple");
4325     r = pMsiGetProductInfoExA(prodcode, usersid,
4326                               MSIINSTALLCONTEXT_USERUNMANAGED,
4327                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4328     ok(r == ERROR_UNKNOWN_PRODUCT,
4329        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4330     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4331     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4332
4333     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4334     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4335
4336     /* LocalPackage exists, but HelpLink does not exist */
4337     sz = MAX_PATH;
4338     lstrcpyA(buf, "apple");
4339     r = pMsiGetProductInfoExA(prodcode, usersid,
4340                               MSIINSTALLCONTEXT_USERUNMANAGED,
4341                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4342     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4343     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4344     ok(sz == 0, "Expected 0, got %d\n", sz);
4345
4346     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4347     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4348
4349     /* HelpLink value exists */
4350     sz = MAX_PATH;
4351     lstrcpyA(buf, "apple");
4352     r = pMsiGetProductInfoExA(prodcode, usersid,
4353                               MSIINSTALLCONTEXT_USERUNMANAGED,
4354                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4355     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4356     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4357     ok(sz == 4, "Expected 4, got %d\n", sz);
4358
4359     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4361
4362     /* HelpTelephone value exists */
4363     sz = MAX_PATH;
4364     lstrcpyA(buf, "apple");
4365     r = pMsiGetProductInfoExA(prodcode, usersid,
4366                               MSIINSTALLCONTEXT_USERUNMANAGED,
4367                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4368     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4369     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4370     ok(sz == 5, "Expected 5, got %d\n", sz);
4371
4372     /* szValue and pcchValue are NULL */
4373     r = pMsiGetProductInfoExA(prodcode, usersid,
4374                               MSIINSTALLCONTEXT_USERUNMANAGED,
4375                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4376     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4377
4378     /* pcchValue is exactly 5 */
4379     sz = 5;
4380     lstrcpyA(buf, "apple");
4381     r = pMsiGetProductInfoExA(prodcode, usersid,
4382                               MSIINSTALLCONTEXT_USERUNMANAGED,
4383                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4384     ok(r == ERROR_MORE_DATA,
4385        "Expected ERROR_MORE_DATA, got %d\n", r);
4386     ok(sz == 10, "Expected 10, got %d\n", sz);
4387
4388     /* szValue is NULL, pcchValue is exactly 5 */
4389     sz = 5;
4390     r = pMsiGetProductInfoExA(prodcode, usersid,
4391                               MSIINSTALLCONTEXT_USERUNMANAGED,
4392                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4393     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4394     ok(sz == 10, "Expected 10, got %d\n", sz);
4395
4396     /* szValue is NULL, pcchValue is MAX_PATH */
4397     sz = MAX_PATH;
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     /* pcchValue is exactly 0 */
4405     sz = 0;
4406     lstrcpyA(buf, "apple");
4407     r = pMsiGetProductInfoExA(prodcode, usersid,
4408                               MSIINSTALLCONTEXT_USERUNMANAGED,
4409                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4410     ok(r == ERROR_MORE_DATA,
4411        "Expected ERROR_MORE_DATA, got %d\n", r);
4412     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4413     ok(sz == 10, "Expected 10, got %d\n", sz);
4414
4415     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4417
4418     /* szProperty is not a valid property */
4419     sz = MAX_PATH;
4420     lstrcpyA(buf, "apple");
4421     r = pMsiGetProductInfoExA(prodcode, usersid,
4422                               MSIINSTALLCONTEXT_USERUNMANAGED,
4423                               "notvalid", buf, &sz);
4424     ok(r == ERROR_UNKNOWN_PROPERTY,
4425        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4426     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4427     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4428
4429     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4431
4432     /* InstallDate value exists */
4433     sz = MAX_PATH;
4434     lstrcpyA(buf, "apple");
4435     r = pMsiGetProductInfoExA(prodcode, usersid,
4436                               MSIINSTALLCONTEXT_USERUNMANAGED,
4437                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4438     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4439     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4440     ok(sz == 4, "Expected 4, got %d\n", sz);
4441
4442     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4443     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4444
4445     /* DisplayName value exists */
4446     sz = MAX_PATH;
4447     lstrcpyA(buf, "apple");
4448     r = pMsiGetProductInfoExA(prodcode, usersid,
4449                               MSIINSTALLCONTEXT_USERUNMANAGED,
4450                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4452     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4453     ok(sz == 4, "Expected 4, got %d\n", sz);
4454
4455     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4457
4458     /* InstallLocation value exists */
4459     sz = MAX_PATH;
4460     lstrcpyA(buf, "apple");
4461     r = pMsiGetProductInfoExA(prodcode, usersid,
4462                               MSIINSTALLCONTEXT_USERUNMANAGED,
4463                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4464     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4465     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4466     ok(sz == 3, "Expected 3, got %d\n", sz);
4467
4468     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4469     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4470
4471     /* InstallSource value exists */
4472     sz = MAX_PATH;
4473     lstrcpyA(buf, "apple");
4474     r = pMsiGetProductInfoExA(prodcode, usersid,
4475                               MSIINSTALLCONTEXT_USERUNMANAGED,
4476                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4477     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4478     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4479     ok(sz == 6, "Expected 6, got %d\n", sz);
4480
4481     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4482     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4483
4484     /* LocalPackage value exists */
4485     sz = MAX_PATH;
4486     lstrcpyA(buf, "apple");
4487     r = pMsiGetProductInfoExA(prodcode, usersid,
4488                               MSIINSTALLCONTEXT_USERUNMANAGED,
4489                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4490     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4491     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4492     ok(sz == 5, "Expected 5, got %d\n", sz);
4493
4494     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4495     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4496
4497     /* Publisher value exists */
4498     sz = MAX_PATH;
4499     lstrcpyA(buf, "apple");
4500     r = pMsiGetProductInfoExA(prodcode, usersid,
4501                               MSIINSTALLCONTEXT_USERUNMANAGED,
4502                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4503     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4504     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4505     ok(sz == 3, "Expected 3, got %d\n", sz);
4506
4507     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4508     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4509
4510     /* URLInfoAbout value exists */
4511     sz = MAX_PATH;
4512     lstrcpyA(buf, "apple");
4513     r = pMsiGetProductInfoExA(prodcode, usersid,
4514                               MSIINSTALLCONTEXT_USERUNMANAGED,
4515                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4516     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4517     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4518     ok(sz == 5, "Expected 5, got %d\n", sz);
4519
4520     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4521     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4522
4523     /* URLUpdateInfo value exists */
4524     sz = MAX_PATH;
4525     lstrcpyA(buf, "apple");
4526     r = pMsiGetProductInfoExA(prodcode, usersid,
4527                               MSIINSTALLCONTEXT_USERUNMANAGED,
4528                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4529     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4530     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4531     ok(sz == 6, "Expected 6, got %d\n", sz);
4532
4533     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4534     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4535
4536     /* VersionMinor value exists */
4537     sz = MAX_PATH;
4538     lstrcpyA(buf, "apple");
4539     r = pMsiGetProductInfoExA(prodcode, usersid,
4540                               MSIINSTALLCONTEXT_USERUNMANAGED,
4541                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4542     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4543     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4544     ok(sz == 1, "Expected 1, got %d\n", sz);
4545
4546     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4547     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4548
4549     /* VersionMajor value exists */
4550     sz = MAX_PATH;
4551     lstrcpyA(buf, "apple");
4552     r = pMsiGetProductInfoExA(prodcode, usersid,
4553                               MSIINSTALLCONTEXT_USERUNMANAGED,
4554                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4556     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4557     ok(sz == 1, "Expected 1, got %d\n", sz);
4558
4559     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4560     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4561
4562     /* DisplayVersion value exists */
4563     sz = MAX_PATH;
4564     lstrcpyA(buf, "apple");
4565     r = pMsiGetProductInfoExA(prodcode, usersid,
4566                               MSIINSTALLCONTEXT_USERUNMANAGED,
4567                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4568     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4569     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4570     ok(sz == 5, "Expected 5, got %d\n", sz);
4571
4572     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4574
4575     /* ProductID value exists */
4576     sz = MAX_PATH;
4577     lstrcpyA(buf, "apple");
4578     r = pMsiGetProductInfoExA(prodcode, usersid,
4579                               MSIINSTALLCONTEXT_USERUNMANAGED,
4580                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4581     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4582     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4583     ok(sz == 2, "Expected 2, got %d\n", sz);
4584
4585     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4586     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4587
4588     /* RegCompany value exists */
4589     sz = MAX_PATH;
4590     lstrcpyA(buf, "apple");
4591     r = pMsiGetProductInfoExA(prodcode, usersid,
4592                               MSIINSTALLCONTEXT_USERUNMANAGED,
4593                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4594     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4595     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4596     ok(sz == 4, "Expected 4, got %d\n", sz);
4597
4598     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4599     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4600
4601     /* RegOwner value exists */
4602     sz = MAX_PATH;
4603     lstrcpyA(buf, "apple");
4604     r = pMsiGetProductInfoExA(prodcode, usersid,
4605                               MSIINSTALLCONTEXT_USERUNMANAGED,
4606                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4607     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4608     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4609     ok(sz == 5, "Expected 5, got %d\n", sz);
4610
4611     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4612     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4613
4614     /* Transforms value exists */
4615     sz = MAX_PATH;
4616     lstrcpyA(buf, "apple");
4617     r = pMsiGetProductInfoExA(prodcode, usersid,
4618                               MSIINSTALLCONTEXT_USERUNMANAGED,
4619                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4620     ok(r == ERROR_UNKNOWN_PRODUCT,
4621        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4622     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4623     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4624
4625     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4626     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4627
4628     /* Language value exists */
4629     sz = MAX_PATH;
4630     lstrcpyA(buf, "apple");
4631     r = pMsiGetProductInfoExA(prodcode, usersid,
4632                               MSIINSTALLCONTEXT_USERUNMANAGED,
4633                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4634     ok(r == ERROR_UNKNOWN_PRODUCT,
4635        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4636     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4637     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4638
4639     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4640     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4641
4642     /* ProductName value exists */
4643     sz = MAX_PATH;
4644     lstrcpyA(buf, "apple");
4645     r = pMsiGetProductInfoExA(prodcode, usersid,
4646                               MSIINSTALLCONTEXT_USERUNMANAGED,
4647                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4648     ok(r == ERROR_UNKNOWN_PRODUCT,
4649        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4650     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4651     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4652
4653     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4654     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4655
4656     /* FIXME */
4657
4658     /* AssignmentType value exists */
4659     sz = MAX_PATH;
4660     lstrcpyA(buf, "apple");
4661     r = pMsiGetProductInfoExA(prodcode, usersid,
4662                               MSIINSTALLCONTEXT_USERUNMANAGED,
4663                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4664     ok(r == ERROR_UNKNOWN_PRODUCT,
4665        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4666     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4667     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4668
4669     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4670     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4671
4672     /* PackageCode value exists */
4673     sz = MAX_PATH;
4674     lstrcpyA(buf, "apple");
4675     r = pMsiGetProductInfoExA(prodcode, usersid,
4676                               MSIINSTALLCONTEXT_USERUNMANAGED,
4677                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4678     ok(r == ERROR_UNKNOWN_PRODUCT,
4679        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4680     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4681     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4682
4683     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4685
4686     /* Version value exists */
4687     sz = MAX_PATH;
4688     lstrcpyA(buf, "apple");
4689     r = pMsiGetProductInfoExA(prodcode, usersid,
4690                               MSIINSTALLCONTEXT_USERUNMANAGED,
4691                               INSTALLPROPERTY_VERSION, buf, &sz);
4692     ok(r == ERROR_UNKNOWN_PRODUCT,
4693        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4694     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4695     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4696
4697     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4698     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4699
4700     /* ProductIcon value exists */
4701     sz = MAX_PATH;
4702     lstrcpyA(buf, "apple");
4703     r = pMsiGetProductInfoExA(prodcode, usersid,
4704                               MSIINSTALLCONTEXT_USERUNMANAGED,
4705                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4706     ok(r == ERROR_UNKNOWN_PRODUCT,
4707        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4708     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4709     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4710
4711     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4713
4714     /* PackageName value exists */
4715     sz = MAX_PATH;
4716     lstrcpyA(buf, "apple");
4717     r = pMsiGetProductInfoExA(prodcode, usersid,
4718                               MSIINSTALLCONTEXT_USERUNMANAGED,
4719                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4720     ok(r == ERROR_UNKNOWN_PRODUCT,
4721        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4722     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4723     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4724
4725     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4727
4728     /* AuthorizedLUAApp value exists */
4729     sz = MAX_PATH;
4730     lstrcpyA(buf, "apple");
4731     r = pMsiGetProductInfoExA(prodcode, usersid,
4732                               MSIINSTALLCONTEXT_USERUNMANAGED,
4733                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4734     ok(r == ERROR_UNKNOWN_PRODUCT,
4735        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4736     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4737     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4738
4739     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4740     RegDeleteValueA(propkey, "PackageName");
4741     RegDeleteValueA(propkey, "ProductIcon");
4742     RegDeleteValueA(propkey, "Version");
4743     RegDeleteValueA(propkey, "PackageCode");
4744     RegDeleteValueA(propkey, "AssignmentType");
4745     RegDeleteValueA(propkey, "ProductName");
4746     RegDeleteValueA(propkey, "Language");
4747     RegDeleteValueA(propkey, "Transforms");
4748     RegDeleteValueA(propkey, "RegOwner");
4749     RegDeleteValueA(propkey, "RegCompany");
4750     RegDeleteValueA(propkey, "ProductID");
4751     RegDeleteValueA(propkey, "DisplayVersion");
4752     RegDeleteValueA(propkey, "VersionMajor");
4753     RegDeleteValueA(propkey, "VersionMinor");
4754     RegDeleteValueA(propkey, "URLUpdateInfo");
4755     RegDeleteValueA(propkey, "URLInfoAbout");
4756     RegDeleteValueA(propkey, "Publisher");
4757     RegDeleteValueA(propkey, "LocalPackage");
4758     RegDeleteValueA(propkey, "InstallSource");
4759     RegDeleteValueA(propkey, "InstallLocation");
4760     RegDeleteValueA(propkey, "DisplayName");
4761     RegDeleteValueA(propkey, "InstallDate");
4762     RegDeleteValueA(propkey, "HelpTelephone");
4763     RegDeleteValueA(propkey, "HelpLink");
4764     RegDeleteValueA(propkey, "LocalPackage");
4765     RegDeleteKeyA(propkey, "");
4766     RegCloseKey(propkey);
4767     RegDeleteKeyA(localkey, "");
4768     RegCloseKey(localkey);
4769
4770     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4771     lstrcatA(keypath, usersid);
4772     lstrcatA(keypath, "\\Installer\\Products\\");
4773     lstrcatA(keypath, prod_squashed);
4774
4775     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
4776     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4777
4778     /* user product key exists */
4779     sz = MAX_PATH;
4780     lstrcpyA(buf, "apple");
4781     r = pMsiGetProductInfoExA(prodcode, usersid,
4782                               MSIINSTALLCONTEXT_USERUNMANAGED,
4783                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4784     ok(r == ERROR_UNKNOWN_PRODUCT,
4785        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4786     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4787     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4788
4789     RegDeleteKeyA(userkey, "");
4790     RegCloseKey(userkey);
4791
4792     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4793     lstrcatA(keypath, prod_squashed);
4794
4795     res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
4796     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4797
4798     sz = MAX_PATH;
4799     lstrcpyA(buf, "apple");
4800     r = pMsiGetProductInfoExA(prodcode, usersid,
4801                               MSIINSTALLCONTEXT_USERUNMANAGED,
4802                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4803     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4804     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4805     ok(sz == 1, "Expected 1, got %d\n", sz);
4806
4807     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4808     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4809
4810     /* HelpLink value exists */
4811     sz = MAX_PATH;
4812     lstrcpyA(buf, "apple");
4813     r = pMsiGetProductInfoExA(prodcode, usersid,
4814                               MSIINSTALLCONTEXT_USERUNMANAGED,
4815                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4816     ok(r == ERROR_UNKNOWN_PROPERTY,
4817        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4818     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4819     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4820
4821     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4822     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4823
4824     /* HelpTelephone value exists */
4825     sz = MAX_PATH;
4826     lstrcpyA(buf, "apple");
4827     r = pMsiGetProductInfoExA(prodcode, usersid,
4828                               MSIINSTALLCONTEXT_USERUNMANAGED,
4829                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4830     ok(r == ERROR_UNKNOWN_PROPERTY,
4831        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4832     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4833     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4834
4835     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4836     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4837
4838     /* InstallDate value exists */
4839     sz = MAX_PATH;
4840     lstrcpyA(buf, "apple");
4841     r = pMsiGetProductInfoExA(prodcode, usersid,
4842                               MSIINSTALLCONTEXT_USERUNMANAGED,
4843                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4844     ok(r == ERROR_UNKNOWN_PROPERTY,
4845        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4846     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4847     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4848
4849     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4850     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4851
4852     /* DisplayName value exists */
4853     sz = MAX_PATH;
4854     lstrcpyA(buf, "apple");
4855     r = pMsiGetProductInfoExA(prodcode, usersid,
4856                               MSIINSTALLCONTEXT_USERUNMANAGED,
4857                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4858     ok(r == ERROR_UNKNOWN_PROPERTY,
4859        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4860     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4861     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4862
4863     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4864     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4865
4866     /* InstallLocation value exists */
4867     sz = MAX_PATH;
4868     lstrcpyA(buf, "apple");
4869     r = pMsiGetProductInfoExA(prodcode, usersid,
4870                               MSIINSTALLCONTEXT_USERUNMANAGED,
4871                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4872     ok(r == ERROR_UNKNOWN_PROPERTY,
4873        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4874     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4875     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4876
4877     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4878     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4879
4880     /* InstallSource value exists */
4881     sz = MAX_PATH;
4882     lstrcpyA(buf, "apple");
4883     r = pMsiGetProductInfoExA(prodcode, usersid,
4884                               MSIINSTALLCONTEXT_USERUNMANAGED,
4885                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4886     ok(r == ERROR_UNKNOWN_PROPERTY,
4887        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4888     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4889     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4890
4891     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4892     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4893
4894     /* LocalPackage value exists */
4895     sz = MAX_PATH;
4896     lstrcpyA(buf, "apple");
4897     r = pMsiGetProductInfoExA(prodcode, usersid,
4898                               MSIINSTALLCONTEXT_USERUNMANAGED,
4899                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4900     ok(r == ERROR_UNKNOWN_PROPERTY,
4901        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4902     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4903     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4904
4905     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4907
4908     /* Publisher value exists */
4909     sz = MAX_PATH;
4910     lstrcpyA(buf, "apple");
4911     r = pMsiGetProductInfoExA(prodcode, usersid,
4912                               MSIINSTALLCONTEXT_USERUNMANAGED,
4913                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4914     ok(r == ERROR_UNKNOWN_PROPERTY,
4915        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4916     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4917     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4918
4919     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4920     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4921
4922     /* URLInfoAbout value exists */
4923     sz = MAX_PATH;
4924     lstrcpyA(buf, "apple");
4925     r = pMsiGetProductInfoExA(prodcode, usersid,
4926                               MSIINSTALLCONTEXT_USERUNMANAGED,
4927                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4928     ok(r == ERROR_UNKNOWN_PROPERTY,
4929        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4930     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4931     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4932
4933     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4934     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4935
4936     /* URLUpdateInfo value exists */
4937     sz = MAX_PATH;
4938     lstrcpyA(buf, "apple");
4939     r = pMsiGetProductInfoExA(prodcode, usersid,
4940                               MSIINSTALLCONTEXT_USERUNMANAGED,
4941                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4942     ok(r == ERROR_UNKNOWN_PROPERTY,
4943        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4944     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4945     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4946
4947     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4948     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4949
4950     /* VersionMinor value exists */
4951     sz = MAX_PATH;
4952     lstrcpyA(buf, "apple");
4953     r = pMsiGetProductInfoExA(prodcode, usersid,
4954                               MSIINSTALLCONTEXT_USERUNMANAGED,
4955                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4956     ok(r == ERROR_UNKNOWN_PROPERTY,
4957        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4958     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4959     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4960
4961     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4963
4964     /* VersionMajor value exists */
4965     sz = MAX_PATH;
4966     lstrcpyA(buf, "apple");
4967     r = pMsiGetProductInfoExA(prodcode, usersid,
4968                               MSIINSTALLCONTEXT_USERUNMANAGED,
4969                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4970     ok(r == ERROR_UNKNOWN_PROPERTY,
4971        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4972     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4973     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4974
4975     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4976     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4977
4978     /* DisplayVersion value exists */
4979     sz = MAX_PATH;
4980     lstrcpyA(buf, "apple");
4981     r = pMsiGetProductInfoExA(prodcode, usersid,
4982                               MSIINSTALLCONTEXT_USERUNMANAGED,
4983                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4984     ok(r == ERROR_UNKNOWN_PROPERTY,
4985        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4986     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4987     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4988
4989     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4990     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4991
4992     /* ProductID value exists */
4993     sz = MAX_PATH;
4994     lstrcpyA(buf, "apple");
4995     r = pMsiGetProductInfoExA(prodcode, usersid,
4996                               MSIINSTALLCONTEXT_USERUNMANAGED,
4997                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4998     ok(r == ERROR_UNKNOWN_PROPERTY,
4999        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5000     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5001     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5002
5003     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5005
5006     /* RegCompany value exists */
5007     sz = MAX_PATH;
5008     lstrcpyA(buf, "apple");
5009     r = pMsiGetProductInfoExA(prodcode, usersid,
5010                               MSIINSTALLCONTEXT_USERUNMANAGED,
5011                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5012     ok(r == ERROR_UNKNOWN_PROPERTY,
5013        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5014     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5015     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5016
5017     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5019
5020     /* RegOwner value exists */
5021     sz = MAX_PATH;
5022     lstrcpyA(buf, "apple");
5023     r = pMsiGetProductInfoExA(prodcode, usersid,
5024                               MSIINSTALLCONTEXT_USERUNMANAGED,
5025                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5026     ok(r == ERROR_UNKNOWN_PROPERTY,
5027        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5028     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5029     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5030
5031     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5032     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5033
5034     /* Transforms value exists */
5035     sz = MAX_PATH;
5036     lstrcpyA(buf, "apple");
5037     r = pMsiGetProductInfoExA(prodcode, usersid,
5038                               MSIINSTALLCONTEXT_USERUNMANAGED,
5039                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5040     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5041     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5042     ok(sz == 5, "Expected 5, got %d\n", sz);
5043
5044     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5045     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5046
5047     /* Language value exists */
5048     sz = MAX_PATH;
5049     lstrcpyA(buf, "apple");
5050     r = pMsiGetProductInfoExA(prodcode, usersid,
5051                               MSIINSTALLCONTEXT_USERUNMANAGED,
5052                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5053     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5054     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5055     ok(sz == 4, "Expected 4, got %d\n", sz);
5056
5057     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5058     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5059
5060     /* ProductName value exists */
5061     sz = MAX_PATH;
5062     lstrcpyA(buf, "apple");
5063     r = pMsiGetProductInfoExA(prodcode, usersid,
5064                               MSIINSTALLCONTEXT_USERUNMANAGED,
5065                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5066     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5067     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5068     ok(sz == 4, "Expected 4, got %d\n", sz);
5069
5070     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5071     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5072
5073     /* FIXME */
5074
5075     /* AssignmentType value exists */
5076     sz = MAX_PATH;
5077     lstrcpyA(buf, "apple");
5078     r = pMsiGetProductInfoExA(prodcode, usersid,
5079                               MSIINSTALLCONTEXT_USERUNMANAGED,
5080                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5081     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5082     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5083     ok(sz == 0, "Expected 0, got %d\n", sz);
5084
5085     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5087
5088     /* FIXME */
5089
5090     /* PackageCode value exists */
5091     sz = MAX_PATH;
5092     lstrcpyA(buf, "apple");
5093     r = pMsiGetProductInfoExA(prodcode, usersid,
5094                               MSIINSTALLCONTEXT_USERUNMANAGED,
5095                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5096     todo_wine
5097     {
5098         ok(r == ERROR_BAD_CONFIGURATION,
5099            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5100         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5101         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5102     }
5103
5104     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5105     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5106
5107     /* Version value exists */
5108     sz = MAX_PATH;
5109     lstrcpyA(buf, "apple");
5110     r = pMsiGetProductInfoExA(prodcode, usersid,
5111                               MSIINSTALLCONTEXT_USERUNMANAGED,
5112                               INSTALLPROPERTY_VERSION, buf, &sz);
5113     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5114     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5115     ok(sz == 3, "Expected 3, got %d\n", sz);
5116
5117     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5119
5120     /* ProductIcon value exists */
5121     sz = MAX_PATH;
5122     lstrcpyA(buf, "apple");
5123     r = pMsiGetProductInfoExA(prodcode, usersid,
5124                               MSIINSTALLCONTEXT_USERUNMANAGED,
5125                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5126     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5127     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5128     ok(sz == 4, "Expected 4, got %d\n", sz);
5129
5130     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5131     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5132
5133     /* PackageName value exists */
5134     sz = MAX_PATH;
5135     lstrcpyA(buf, "apple");
5136     r = pMsiGetProductInfoExA(prodcode, usersid,
5137                               MSIINSTALLCONTEXT_USERUNMANAGED,
5138                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5139     todo_wine
5140     {
5141         ok(r == ERROR_UNKNOWN_PRODUCT,
5142            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5143         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5144         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5145     }
5146
5147     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5148     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5149
5150     /* AuthorizedLUAApp value exists */
5151     sz = MAX_PATH;
5152     lstrcpyA(buf, "apple");
5153     r = pMsiGetProductInfoExA(prodcode, usersid,
5154                               MSIINSTALLCONTEXT_USERUNMANAGED,
5155                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5156     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5157     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5158     ok(sz == 4, "Expected 4, got %d\n", sz);
5159
5160     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5161     RegDeleteValueA(prodkey, "PackageName");
5162     RegDeleteValueA(prodkey, "ProductIcon");
5163     RegDeleteValueA(prodkey, "Version");
5164     RegDeleteValueA(prodkey, "PackageCode");
5165     RegDeleteValueA(prodkey, "AssignmentType");
5166     RegDeleteValueA(prodkey, "ProductName");
5167     RegDeleteValueA(prodkey, "Language");
5168     RegDeleteValueA(prodkey, "Transforms");
5169     RegDeleteValueA(prodkey, "RegOwner");
5170     RegDeleteValueA(prodkey, "RegCompany");
5171     RegDeleteValueA(prodkey, "ProductID");
5172     RegDeleteValueA(prodkey, "DisplayVersion");
5173     RegDeleteValueA(prodkey, "VersionMajor");
5174     RegDeleteValueA(prodkey, "VersionMinor");
5175     RegDeleteValueA(prodkey, "URLUpdateInfo");
5176     RegDeleteValueA(prodkey, "URLInfoAbout");
5177     RegDeleteValueA(prodkey, "Publisher");
5178     RegDeleteValueA(prodkey, "LocalPackage");
5179     RegDeleteValueA(prodkey, "InstallSource");
5180     RegDeleteValueA(prodkey, "InstallLocation");
5181     RegDeleteValueA(prodkey, "DisplayName");
5182     RegDeleteValueA(prodkey, "InstallDate");
5183     RegDeleteValueA(prodkey, "HelpTelephone");
5184     RegDeleteValueA(prodkey, "HelpLink");
5185     RegDeleteValueA(prodkey, "LocalPackage");
5186     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
5187     RegCloseKey(prodkey);
5188
5189     /* MSIINSTALLCONTEXT_USERMANAGED */
5190
5191     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5192     lstrcatA(keypath, usersid);
5193     lstrcatA(keypath, "\\Products\\");
5194     lstrcatA(keypath, prod_squashed);
5195
5196     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
5197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5198
5199     /* local user product key exists */
5200     sz = MAX_PATH;
5201     lstrcpyA(buf, "apple");
5202     r = pMsiGetProductInfoExA(prodcode, usersid,
5203                               MSIINSTALLCONTEXT_USERMANAGED,
5204                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5205     ok(r == ERROR_UNKNOWN_PRODUCT,
5206        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5207     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5208     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5209
5210     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
5211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5212
5213     /* InstallProperties key exists */
5214     sz = MAX_PATH;
5215     lstrcpyA(buf, "apple");
5216     r = pMsiGetProductInfoExA(prodcode, usersid,
5217                               MSIINSTALLCONTEXT_USERMANAGED,
5218                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5219     ok(r == ERROR_UNKNOWN_PRODUCT,
5220        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5221     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5222     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5223
5224     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5225     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5226
5227     /* ManagedLocalPackage value exists */
5228     sz = MAX_PATH;
5229     lstrcpyA(buf, "apple");
5230     r = pMsiGetProductInfoExA(prodcode, usersid,
5231                               MSIINSTALLCONTEXT_USERMANAGED,
5232                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5234     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5235     ok(sz == 1, "Expected 1, got %d\n", sz);
5236
5237     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5239
5240     /* HelpLink value exists */
5241     sz = MAX_PATH;
5242     lstrcpyA(buf, "apple");
5243     r = pMsiGetProductInfoExA(prodcode, usersid,
5244                               MSIINSTALLCONTEXT_USERMANAGED,
5245                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5246     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5247     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5248     ok(sz == 4, "Expected 4, got %d\n", sz);
5249
5250     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5251     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5252
5253     /* HelpTelephone value exists */
5254     sz = MAX_PATH;
5255     lstrcpyA(buf, "apple");
5256     r = pMsiGetProductInfoExA(prodcode, usersid,
5257                               MSIINSTALLCONTEXT_USERMANAGED,
5258                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5259     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5260     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5261     ok(sz == 5, "Expected 5, got %d\n", sz);
5262
5263     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5264     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5265
5266     /* InstallDate value exists */
5267     sz = MAX_PATH;
5268     lstrcpyA(buf, "apple");
5269     r = pMsiGetProductInfoExA(prodcode, usersid,
5270                               MSIINSTALLCONTEXT_USERMANAGED,
5271                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5272     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5273     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5274     ok(sz == 4, "Expected 4, got %d\n", sz);
5275
5276     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5277     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5278
5279     /* DisplayName value exists */
5280     sz = MAX_PATH;
5281     lstrcpyA(buf, "apple");
5282     r = pMsiGetProductInfoExA(prodcode, usersid,
5283                               MSIINSTALLCONTEXT_USERMANAGED,
5284                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5285     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5286     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5287     ok(sz == 4, "Expected 4, got %d\n", sz);
5288
5289     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5290     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5291
5292     /* InstallLocation value exists */
5293     sz = MAX_PATH;
5294     lstrcpyA(buf, "apple");
5295     r = pMsiGetProductInfoExA(prodcode, usersid,
5296                               MSIINSTALLCONTEXT_USERMANAGED,
5297                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5298     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5299     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5300     ok(sz == 3, "Expected 3, got %d\n", sz);
5301
5302     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5304
5305     /* InstallSource value exists */
5306     sz = MAX_PATH;
5307     lstrcpyA(buf, "apple");
5308     r = pMsiGetProductInfoExA(prodcode, usersid,
5309                               MSIINSTALLCONTEXT_USERMANAGED,
5310                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5311     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5312     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5313     ok(sz == 6, "Expected 6, got %d\n", sz);
5314
5315     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5317
5318     /* LocalPackage value exists */
5319     sz = MAX_PATH;
5320     lstrcpyA(buf, "apple");
5321     r = pMsiGetProductInfoExA(prodcode, usersid,
5322                               MSIINSTALLCONTEXT_USERMANAGED,
5323                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5324     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5325     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5326     ok(sz == 5, "Expected 5, got %d\n", sz);
5327
5328     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5330
5331     /* Publisher value exists */
5332     sz = MAX_PATH;
5333     lstrcpyA(buf, "apple");
5334     r = pMsiGetProductInfoExA(prodcode, usersid,
5335                               MSIINSTALLCONTEXT_USERMANAGED,
5336                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5338     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5339     ok(sz == 3, "Expected 3, got %d\n", sz);
5340
5341     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5343
5344     /* URLInfoAbout value exists */
5345     sz = MAX_PATH;
5346     lstrcpyA(buf, "apple");
5347     r = pMsiGetProductInfoExA(prodcode, usersid,
5348                               MSIINSTALLCONTEXT_USERMANAGED,
5349                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5350     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5351     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5352     ok(sz == 5, "Expected 5, got %d\n", sz);
5353
5354     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5356
5357     /* URLUpdateInfo value exists */
5358     sz = MAX_PATH;
5359     lstrcpyA(buf, "apple");
5360     r = pMsiGetProductInfoExA(prodcode, usersid,
5361                               MSIINSTALLCONTEXT_USERMANAGED,
5362                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5364     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5365     ok(sz == 6, "Expected 6, got %d\n", sz);
5366
5367     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5369
5370     /* VersionMinor value exists */
5371     sz = MAX_PATH;
5372     lstrcpyA(buf, "apple");
5373     r = pMsiGetProductInfoExA(prodcode, usersid,
5374                               MSIINSTALLCONTEXT_USERMANAGED,
5375                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5376     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5377     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5378     ok(sz == 1, "Expected 1, got %d\n", sz);
5379
5380     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5381     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5382
5383     /* VersionMajor value exists */
5384     sz = MAX_PATH;
5385     lstrcpyA(buf, "apple");
5386     r = pMsiGetProductInfoExA(prodcode, usersid,
5387                               MSIINSTALLCONTEXT_USERMANAGED,
5388                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5390     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5391     ok(sz == 1, "Expected 1, got %d\n", sz);
5392
5393     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5395
5396     /* DisplayVersion value exists */
5397     sz = MAX_PATH;
5398     lstrcpyA(buf, "apple");
5399     r = pMsiGetProductInfoExA(prodcode, usersid,
5400                               MSIINSTALLCONTEXT_USERMANAGED,
5401                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5402     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5403     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5404     ok(sz == 5, "Expected 5, got %d\n", sz);
5405
5406     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5407     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5408
5409     /* ProductID value exists */
5410     sz = MAX_PATH;
5411     lstrcpyA(buf, "apple");
5412     r = pMsiGetProductInfoExA(prodcode, usersid,
5413                               MSIINSTALLCONTEXT_USERMANAGED,
5414                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5415     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5416     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5417     ok(sz == 2, "Expected 2, got %d\n", sz);
5418
5419     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5420     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5421
5422     /* RegCompany value exists */
5423     sz = MAX_PATH;
5424     lstrcpyA(buf, "apple");
5425     r = pMsiGetProductInfoExA(prodcode, usersid,
5426                               MSIINSTALLCONTEXT_USERMANAGED,
5427                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5428     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5429     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5430     ok(sz == 4, "Expected 4, got %d\n", sz);
5431
5432     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5434
5435     /* RegOwner value exists */
5436     sz = MAX_PATH;
5437     lstrcpyA(buf, "apple");
5438     r = pMsiGetProductInfoExA(prodcode, usersid,
5439                               MSIINSTALLCONTEXT_USERMANAGED,
5440                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5442     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5443     ok(sz == 5, "Expected 5, got %d\n", sz);
5444
5445     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5447
5448     /* Transforms value exists */
5449     sz = MAX_PATH;
5450     lstrcpyA(buf, "apple");
5451     r = pMsiGetProductInfoExA(prodcode, usersid,
5452                               MSIINSTALLCONTEXT_USERMANAGED,
5453                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5454     ok(r == ERROR_UNKNOWN_PRODUCT,
5455        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5456     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5457     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5458
5459     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5460     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5461
5462     /* Language value exists */
5463     sz = MAX_PATH;
5464     lstrcpyA(buf, "apple");
5465     r = pMsiGetProductInfoExA(prodcode, usersid,
5466                               MSIINSTALLCONTEXT_USERMANAGED,
5467                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5468     ok(r == ERROR_UNKNOWN_PRODUCT,
5469        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5470     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5471     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5472
5473     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5474     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5475
5476     /* ProductName value exists */
5477     sz = MAX_PATH;
5478     lstrcpyA(buf, "apple");
5479     r = pMsiGetProductInfoExA(prodcode, usersid,
5480                               MSIINSTALLCONTEXT_USERMANAGED,
5481                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5482     ok(r == ERROR_UNKNOWN_PRODUCT,
5483        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5484     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5485     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5486
5487     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5488     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5489
5490     /* FIXME */
5491
5492     /* AssignmentType value exists */
5493     sz = MAX_PATH;
5494     lstrcpyA(buf, "apple");
5495     r = pMsiGetProductInfoExA(prodcode, usersid,
5496                               MSIINSTALLCONTEXT_USERMANAGED,
5497                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5498     ok(r == ERROR_UNKNOWN_PRODUCT,
5499        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5500     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5501     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5502
5503     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5504     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5505
5506     /* PackageCode value exists */
5507     sz = MAX_PATH;
5508     lstrcpyA(buf, "apple");
5509     r = pMsiGetProductInfoExA(prodcode, usersid,
5510                               MSIINSTALLCONTEXT_USERMANAGED,
5511                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5512     ok(r == ERROR_UNKNOWN_PRODUCT,
5513        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5514     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5515     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5516
5517     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5518     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5519
5520     /* Version value exists */
5521     sz = MAX_PATH;
5522     lstrcpyA(buf, "apple");
5523     r = pMsiGetProductInfoExA(prodcode, usersid,
5524                               MSIINSTALLCONTEXT_USERMANAGED,
5525                               INSTALLPROPERTY_VERSION, buf, &sz);
5526     ok(r == ERROR_UNKNOWN_PRODUCT,
5527        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5528     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5529     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5530
5531     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5532     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5533
5534     /* ProductIcon value exists */
5535     sz = MAX_PATH;
5536     lstrcpyA(buf, "apple");
5537     r = pMsiGetProductInfoExA(prodcode, usersid,
5538                               MSIINSTALLCONTEXT_USERMANAGED,
5539                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5540     ok(r == ERROR_UNKNOWN_PRODUCT,
5541        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5542     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5543     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5544
5545     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5546     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5547
5548     /* PackageName value exists */
5549     sz = MAX_PATH;
5550     lstrcpyA(buf, "apple");
5551     r = pMsiGetProductInfoExA(prodcode, usersid,
5552                               MSIINSTALLCONTEXT_USERMANAGED,
5553                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5554     ok(r == ERROR_UNKNOWN_PRODUCT,
5555        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5556     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5557     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5558
5559     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5560     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5561
5562     /* AuthorizedLUAApp value exists */
5563     sz = MAX_PATH;
5564     lstrcpyA(buf, "apple");
5565     r = pMsiGetProductInfoExA(prodcode, usersid,
5566                               MSIINSTALLCONTEXT_USERMANAGED,
5567                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5568     ok(r == ERROR_UNKNOWN_PRODUCT,
5569        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5570     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5571     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5572
5573     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5574     RegDeleteValueA(propkey, "PackageName");
5575     RegDeleteValueA(propkey, "ProductIcon");
5576     RegDeleteValueA(propkey, "Version");
5577     RegDeleteValueA(propkey, "PackageCode");
5578     RegDeleteValueA(propkey, "AssignmentType");
5579     RegDeleteValueA(propkey, "ProductName");
5580     RegDeleteValueA(propkey, "Language");
5581     RegDeleteValueA(propkey, "Transforms");
5582     RegDeleteValueA(propkey, "RegOwner");
5583     RegDeleteValueA(propkey, "RegCompany");
5584     RegDeleteValueA(propkey, "ProductID");
5585     RegDeleteValueA(propkey, "DisplayVersion");
5586     RegDeleteValueA(propkey, "VersionMajor");
5587     RegDeleteValueA(propkey, "VersionMinor");
5588     RegDeleteValueA(propkey, "URLUpdateInfo");
5589     RegDeleteValueA(propkey, "URLInfoAbout");
5590     RegDeleteValueA(propkey, "Publisher");
5591     RegDeleteValueA(propkey, "LocalPackage");
5592     RegDeleteValueA(propkey, "InstallSource");
5593     RegDeleteValueA(propkey, "InstallLocation");
5594     RegDeleteValueA(propkey, "DisplayName");
5595     RegDeleteValueA(propkey, "InstallDate");
5596     RegDeleteValueA(propkey, "HelpTelephone");
5597     RegDeleteValueA(propkey, "HelpLink");
5598     RegDeleteValueA(propkey, "ManagedLocalPackage");
5599     delete_key(propkey, "", access & KEY_WOW64_64KEY);
5600     RegCloseKey(propkey);
5601     delete_key(localkey, "", access & KEY_WOW64_64KEY);
5602     RegCloseKey(localkey);
5603
5604     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5605     lstrcatA(keypath, usersid);
5606     lstrcatA(keypath, "\\Installer\\Products\\");
5607     lstrcatA(keypath, prod_squashed);
5608
5609     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5611
5612     /* user product key exists */
5613     sz = MAX_PATH;
5614     lstrcpyA(buf, "apple");
5615     r = pMsiGetProductInfoExA(prodcode, usersid,
5616                               MSIINSTALLCONTEXT_USERMANAGED,
5617                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5619     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5620     ok(sz == 1, "Expected 1, got %d\n", sz);
5621
5622     delete_key(userkey, "", access & KEY_WOW64_64KEY);
5623     RegCloseKey(userkey);
5624
5625     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5626     lstrcatA(keypath, prod_squashed);
5627
5628     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5629     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5630
5631     /* current user product key exists */
5632     sz = MAX_PATH;
5633     lstrcpyA(buf, "apple");
5634     r = pMsiGetProductInfoExA(prodcode, usersid,
5635                               MSIINSTALLCONTEXT_USERMANAGED,
5636                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5637     ok(r == ERROR_UNKNOWN_PRODUCT,
5638        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5639     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5640     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5641
5642     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5643     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5644
5645     /* HelpLink value exists, user product key does not exist */
5646     sz = MAX_PATH;
5647     lstrcpyA(buf, "apple");
5648     r = pMsiGetProductInfoExA(prodcode, usersid,
5649                               MSIINSTALLCONTEXT_USERMANAGED,
5650                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5651     ok(r == ERROR_UNKNOWN_PRODUCT,
5652        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5653     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5654     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5655
5656     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5657     lstrcatA(keypath, usersid);
5658     lstrcatA(keypath, "\\Installer\\Products\\");
5659     lstrcatA(keypath, prod_squashed);
5660
5661     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
5662     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5663
5664     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5665     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5666
5667     /* HelpLink value exists, user product key does exist */
5668     sz = MAX_PATH;
5669     lstrcpyA(buf, "apple");
5670     r = pMsiGetProductInfoExA(prodcode, usersid,
5671                               MSIINSTALLCONTEXT_USERMANAGED,
5672                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5673     ok(r == ERROR_UNKNOWN_PROPERTY,
5674        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5675     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5676     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5677
5678     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5680
5681     /* HelpTelephone value exists */
5682     sz = MAX_PATH;
5683     lstrcpyA(buf, "apple");
5684     r = pMsiGetProductInfoExA(prodcode, usersid,
5685                               MSIINSTALLCONTEXT_USERMANAGED,
5686                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5687     ok(r == ERROR_UNKNOWN_PROPERTY,
5688        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5689     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5690     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5691
5692     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5694
5695     /* InstallDate value exists */
5696     sz = MAX_PATH;
5697     lstrcpyA(buf, "apple");
5698     r = pMsiGetProductInfoExA(prodcode, usersid,
5699                               MSIINSTALLCONTEXT_USERMANAGED,
5700                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5701     ok(r == ERROR_UNKNOWN_PROPERTY,
5702        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5703     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5704     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5705
5706     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5707     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5708
5709     /* DisplayName value exists */
5710     sz = MAX_PATH;
5711     lstrcpyA(buf, "apple");
5712     r = pMsiGetProductInfoExA(prodcode, usersid,
5713                               MSIINSTALLCONTEXT_USERMANAGED,
5714                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5715     ok(r == ERROR_UNKNOWN_PROPERTY,
5716        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5717     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5718     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5719
5720     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5721     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5722
5723     /* InstallLocation value exists */
5724     sz = MAX_PATH;
5725     lstrcpyA(buf, "apple");
5726     r = pMsiGetProductInfoExA(prodcode, usersid,
5727                               MSIINSTALLCONTEXT_USERMANAGED,
5728                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5729     ok(r == ERROR_UNKNOWN_PROPERTY,
5730        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5731     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5732     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5733
5734     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5735     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5736
5737     /* InstallSource value exists */
5738     sz = MAX_PATH;
5739     lstrcpyA(buf, "apple");
5740     r = pMsiGetProductInfoExA(prodcode, usersid,
5741                               MSIINSTALLCONTEXT_USERMANAGED,
5742                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5743     ok(r == ERROR_UNKNOWN_PROPERTY,
5744        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5745     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5746     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5747
5748     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5749     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5750
5751     /* LocalPackage value exists */
5752     sz = MAX_PATH;
5753     lstrcpyA(buf, "apple");
5754     r = pMsiGetProductInfoExA(prodcode, usersid,
5755                               MSIINSTALLCONTEXT_USERMANAGED,
5756                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5757     ok(r == ERROR_UNKNOWN_PROPERTY,
5758        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5759     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5760     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5761
5762     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5763     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5764
5765     /* Publisher value exists */
5766     sz = MAX_PATH;
5767     lstrcpyA(buf, "apple");
5768     r = pMsiGetProductInfoExA(prodcode, usersid,
5769                               MSIINSTALLCONTEXT_USERMANAGED,
5770                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5771     ok(r == ERROR_UNKNOWN_PROPERTY,
5772        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5773     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5774     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5775
5776     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5778
5779     /* URLInfoAbout value exists */
5780     sz = MAX_PATH;
5781     lstrcpyA(buf, "apple");
5782     r = pMsiGetProductInfoExA(prodcode, usersid,
5783                               MSIINSTALLCONTEXT_USERMANAGED,
5784                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5785     ok(r == ERROR_UNKNOWN_PROPERTY,
5786        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5787     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5788     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5789
5790     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5792
5793     /* URLUpdateInfo value exists */
5794     sz = MAX_PATH;
5795     lstrcpyA(buf, "apple");
5796     r = pMsiGetProductInfoExA(prodcode, usersid,
5797                               MSIINSTALLCONTEXT_USERMANAGED,
5798                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5799     ok(r == ERROR_UNKNOWN_PROPERTY,
5800        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5801     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5802     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5803
5804     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5805     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5806
5807     /* VersionMinor value exists */
5808     sz = MAX_PATH;
5809     lstrcpyA(buf, "apple");
5810     r = pMsiGetProductInfoExA(prodcode, usersid,
5811                               MSIINSTALLCONTEXT_USERMANAGED,
5812                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5813     ok(r == ERROR_UNKNOWN_PROPERTY,
5814        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5815     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5816     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5817
5818     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5819     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5820
5821     /* VersionMajor value exists */
5822     sz = MAX_PATH;
5823     lstrcpyA(buf, "apple");
5824     r = pMsiGetProductInfoExA(prodcode, usersid,
5825                               MSIINSTALLCONTEXT_USERMANAGED,
5826                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5827     ok(r == ERROR_UNKNOWN_PROPERTY,
5828        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5829     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5830     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5831
5832     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5833     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5834
5835     /* DisplayVersion value exists */
5836     sz = MAX_PATH;
5837     lstrcpyA(buf, "apple");
5838     r = pMsiGetProductInfoExA(prodcode, usersid,
5839                               MSIINSTALLCONTEXT_USERMANAGED,
5840                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5841     ok(r == ERROR_UNKNOWN_PROPERTY,
5842        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5843     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5844     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5845
5846     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5847     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5848
5849     /* ProductID value exists */
5850     sz = MAX_PATH;
5851     lstrcpyA(buf, "apple");
5852     r = pMsiGetProductInfoExA(prodcode, usersid,
5853                               MSIINSTALLCONTEXT_USERMANAGED,
5854                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5855     ok(r == ERROR_UNKNOWN_PROPERTY,
5856        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5857     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5858     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5859
5860     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5861     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5862
5863     /* RegCompany value exists */
5864     sz = MAX_PATH;
5865     lstrcpyA(buf, "apple");
5866     r = pMsiGetProductInfoExA(prodcode, usersid,
5867                               MSIINSTALLCONTEXT_USERMANAGED,
5868                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5869     ok(r == ERROR_UNKNOWN_PROPERTY,
5870        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5871     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5872     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5873
5874     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5875     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5876
5877     /* RegOwner value exists */
5878     sz = MAX_PATH;
5879     lstrcpyA(buf, "apple");
5880     r = pMsiGetProductInfoExA(prodcode, usersid,
5881                               MSIINSTALLCONTEXT_USERMANAGED,
5882                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5883     ok(r == ERROR_UNKNOWN_PROPERTY,
5884        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5885     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5886     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5887
5888     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5889     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5890
5891     /* Transforms value exists */
5892     sz = MAX_PATH;
5893     lstrcpyA(buf, "apple");
5894     r = pMsiGetProductInfoExA(prodcode, usersid,
5895                               MSIINSTALLCONTEXT_USERMANAGED,
5896                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5897     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5898     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5899     ok(sz == 5, "Expected 5, got %d\n", sz);
5900
5901     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5902     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5903
5904     /* Language value exists */
5905     sz = MAX_PATH;
5906     lstrcpyA(buf, "apple");
5907     r = pMsiGetProductInfoExA(prodcode, usersid,
5908                               MSIINSTALLCONTEXT_USERMANAGED,
5909                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5910     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5911     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5912     ok(sz == 4, "Expected 4, got %d\n", sz);
5913
5914     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5915     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5916
5917     /* ProductName value exists */
5918     sz = MAX_PATH;
5919     lstrcpyA(buf, "apple");
5920     r = pMsiGetProductInfoExA(prodcode, usersid,
5921                               MSIINSTALLCONTEXT_USERMANAGED,
5922                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5923     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5924     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5925     ok(sz == 4, "Expected 4, got %d\n", sz);
5926
5927     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5929
5930     /* FIXME */
5931
5932     /* AssignmentType value exists */
5933     sz = MAX_PATH;
5934     lstrcpyA(buf, "apple");
5935     r = pMsiGetProductInfoExA(prodcode, usersid,
5936                               MSIINSTALLCONTEXT_USERMANAGED,
5937                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5938     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5939     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5940     ok(sz == 0, "Expected 0, got %d\n", sz);
5941
5942     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5943     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5944
5945     /* FIXME */
5946
5947     /* PackageCode value exists */
5948     sz = MAX_PATH;
5949     lstrcpyA(buf, "apple");
5950     r = pMsiGetProductInfoExA(prodcode, usersid,
5951                               MSIINSTALLCONTEXT_USERMANAGED,
5952                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5953     todo_wine
5954     {
5955         ok(r == ERROR_BAD_CONFIGURATION,
5956            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5957         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5958         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5959     }
5960
5961     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5963
5964     /* Version value exists */
5965     sz = MAX_PATH;
5966     lstrcpyA(buf, "apple");
5967     r = pMsiGetProductInfoExA(prodcode, usersid,
5968                               MSIINSTALLCONTEXT_USERMANAGED,
5969                               INSTALLPROPERTY_VERSION, buf, &sz);
5970     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5971     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5972     ok(sz == 3, "Expected 3, got %d\n", sz);
5973
5974     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5975     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5976
5977     /* ProductIcon value exists */
5978     sz = MAX_PATH;
5979     lstrcpyA(buf, "apple");
5980     r = pMsiGetProductInfoExA(prodcode, usersid,
5981                               MSIINSTALLCONTEXT_USERMANAGED,
5982                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5984     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5985     ok(sz == 4, "Expected 4, got %d\n", sz);
5986
5987     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5988     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5989
5990     /* PackageName value exists */
5991     sz = MAX_PATH;
5992     lstrcpyA(buf, "apple");
5993     r = pMsiGetProductInfoExA(prodcode, usersid,
5994                               MSIINSTALLCONTEXT_USERMANAGED,
5995                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5996     todo_wine
5997     {
5998         ok(r == ERROR_UNKNOWN_PRODUCT,
5999            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6000         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6001         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6002     }
6003
6004     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6006
6007     /* AuthorizedLUAApp value exists */
6008     sz = MAX_PATH;
6009     lstrcpyA(buf, "apple");
6010     r = pMsiGetProductInfoExA(prodcode, usersid,
6011                               MSIINSTALLCONTEXT_USERMANAGED,
6012                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6013     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6014     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6015     ok(sz == 4, "Expected 4, got %d\n", sz);
6016
6017     RegDeleteValueA(userkey, "AuthorizedLUAApp");
6018     RegDeleteValueA(userkey, "PackageName");
6019     RegDeleteValueA(userkey, "ProductIcon");
6020     RegDeleteValueA(userkey, "Version");
6021     RegDeleteValueA(userkey, "PackageCode");
6022     RegDeleteValueA(userkey, "AssignmentType");
6023     RegDeleteValueA(userkey, "ProductName");
6024     RegDeleteValueA(userkey, "Language");
6025     RegDeleteValueA(userkey, "Transforms");
6026     RegDeleteValueA(userkey, "RegOwner");
6027     RegDeleteValueA(userkey, "RegCompany");
6028     RegDeleteValueA(userkey, "ProductID");
6029     RegDeleteValueA(userkey, "DisplayVersion");
6030     RegDeleteValueA(userkey, "VersionMajor");
6031     RegDeleteValueA(userkey, "VersionMinor");
6032     RegDeleteValueA(userkey, "URLUpdateInfo");
6033     RegDeleteValueA(userkey, "URLInfoAbout");
6034     RegDeleteValueA(userkey, "Publisher");
6035     RegDeleteValueA(userkey, "LocalPackage");
6036     RegDeleteValueA(userkey, "InstallSource");
6037     RegDeleteValueA(userkey, "InstallLocation");
6038     RegDeleteValueA(userkey, "DisplayName");
6039     RegDeleteValueA(userkey, "InstallDate");
6040     RegDeleteValueA(userkey, "HelpTelephone");
6041     RegDeleteValueA(userkey, "HelpLink");
6042     delete_key(userkey, "", access & KEY_WOW64_64KEY);
6043     RegCloseKey(userkey);
6044     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6045     RegCloseKey(prodkey);
6046
6047     /* MSIINSTALLCONTEXT_MACHINE */
6048
6049     /* szUserSid is non-NULL */
6050     sz = MAX_PATH;
6051     lstrcpyA(buf, "apple");
6052     r = pMsiGetProductInfoExA(prodcode, usersid,
6053                               MSIINSTALLCONTEXT_MACHINE,
6054                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6055     ok(r == ERROR_INVALID_PARAMETER,
6056        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
6057     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6058     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6059
6060     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
6061     lstrcatA(keypath, prod_squashed);
6062
6063     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
6064     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6065
6066     /* local system product key exists */
6067     sz = MAX_PATH;
6068     lstrcpyA(buf, "apple");
6069     r = pMsiGetProductInfoExA(prodcode, NULL,
6070                               MSIINSTALLCONTEXT_MACHINE,
6071                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6072     ok(r == ERROR_UNKNOWN_PRODUCT,
6073        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6074     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6075     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6076
6077     res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
6078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6079
6080     /* InstallProperties key exists */
6081     sz = MAX_PATH;
6082     lstrcpyA(buf, "apple");
6083     r = pMsiGetProductInfoExA(prodcode, NULL,
6084                               MSIINSTALLCONTEXT_MACHINE,
6085                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6086     ok(r == ERROR_UNKNOWN_PRODUCT,
6087        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6088     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6089     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6090
6091     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6093
6094     /* LocalPackage value exists */
6095     sz = MAX_PATH;
6096     lstrcpyA(buf, "apple");
6097     r = pMsiGetProductInfoExA(prodcode, NULL,
6098                               MSIINSTALLCONTEXT_MACHINE,
6099                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6100     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6101     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
6102     ok(sz == 1, "Expected 1, got %d\n", sz);
6103
6104     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6105     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6106
6107     /* HelpLink value exists */
6108     sz = MAX_PATH;
6109     lstrcpyA(buf, "apple");
6110     r = pMsiGetProductInfoExA(prodcode, NULL,
6111                               MSIINSTALLCONTEXT_MACHINE,
6112                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6113     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6114     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6115     ok(sz == 4, "Expected 4, got %d\n", sz);
6116
6117     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6119
6120     /* HelpTelephone value exists */
6121     sz = MAX_PATH;
6122     lstrcpyA(buf, "apple");
6123     r = pMsiGetProductInfoExA(prodcode, NULL,
6124                               MSIINSTALLCONTEXT_MACHINE,
6125                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6126     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6127     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6128     ok(sz == 5, "Expected 5, got %d\n", sz);
6129
6130     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6131     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6132
6133     /* InstallDate value exists */
6134     sz = MAX_PATH;
6135     lstrcpyA(buf, "apple");
6136     r = pMsiGetProductInfoExA(prodcode, NULL,
6137                               MSIINSTALLCONTEXT_MACHINE,
6138                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6139     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6140     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6141     ok(sz == 4, "Expected 4, got %d\n", sz);
6142
6143     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6144     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6145
6146     /* DisplayName value exists */
6147     sz = MAX_PATH;
6148     lstrcpyA(buf, "apple");
6149     r = pMsiGetProductInfoExA(prodcode, NULL,
6150                               MSIINSTALLCONTEXT_MACHINE,
6151                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6152     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6153     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6154     ok(sz == 4, "Expected 4, got %d\n", sz);
6155
6156     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6157     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6158
6159     /* InstallLocation value exists */
6160     sz = MAX_PATH;
6161     lstrcpyA(buf, "apple");
6162     r = pMsiGetProductInfoExA(prodcode, NULL,
6163                               MSIINSTALLCONTEXT_MACHINE,
6164                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6165     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6166     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6167     ok(sz == 3, "Expected 3, got %d\n", sz);
6168
6169     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6170     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6171
6172     /* InstallSource value exists */
6173     sz = MAX_PATH;
6174     lstrcpyA(buf, "apple");
6175     r = pMsiGetProductInfoExA(prodcode, NULL,
6176                               MSIINSTALLCONTEXT_MACHINE,
6177                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6178     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6179     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6180     ok(sz == 6, "Expected 6, got %d\n", sz);
6181
6182     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6183     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6184
6185     /* LocalPackage value exists */
6186     sz = MAX_PATH;
6187     lstrcpyA(buf, "apple");
6188     r = pMsiGetProductInfoExA(prodcode, NULL,
6189                               MSIINSTALLCONTEXT_MACHINE,
6190                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6191     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6192     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6193     ok(sz == 5, "Expected 5, got %d\n", sz);
6194
6195     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6197
6198     /* Publisher value exists */
6199     sz = MAX_PATH;
6200     lstrcpyA(buf, "apple");
6201     r = pMsiGetProductInfoExA(prodcode, NULL,
6202                               MSIINSTALLCONTEXT_MACHINE,
6203                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6204     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6205     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6206     ok(sz == 3, "Expected 3, got %d\n", sz);
6207
6208     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6209     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6210
6211     /* URLInfoAbout value exists */
6212     sz = MAX_PATH;
6213     lstrcpyA(buf, "apple");
6214     r = pMsiGetProductInfoExA(prodcode, NULL,
6215                               MSIINSTALLCONTEXT_MACHINE,
6216                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6217     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6218     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6219     ok(sz == 5, "Expected 5, got %d\n", sz);
6220
6221     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6222     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6223
6224     /* URLUpdateInfo value exists */
6225     sz = MAX_PATH;
6226     lstrcpyA(buf, "apple");
6227     r = pMsiGetProductInfoExA(prodcode, NULL,
6228                               MSIINSTALLCONTEXT_MACHINE,
6229                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6230     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6231     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6232     ok(sz == 6, "Expected 6, got %d\n", sz);
6233
6234     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6235     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6236
6237     /* VersionMinor value exists */
6238     sz = MAX_PATH;
6239     lstrcpyA(buf, "apple");
6240     r = pMsiGetProductInfoExA(prodcode, NULL,
6241                               MSIINSTALLCONTEXT_MACHINE,
6242                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6244     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6245     ok(sz == 1, "Expected 1, got %d\n", sz);
6246
6247     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6248     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6249
6250     /* VersionMajor value exists */
6251     sz = MAX_PATH;
6252     lstrcpyA(buf, "apple");
6253     r = pMsiGetProductInfoExA(prodcode, NULL,
6254                               MSIINSTALLCONTEXT_MACHINE,
6255                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6257     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6258     ok(sz == 1, "Expected 1, got %d\n", sz);
6259
6260     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6261     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6262
6263     /* DisplayVersion value exists */
6264     sz = MAX_PATH;
6265     lstrcpyA(buf, "apple");
6266     r = pMsiGetProductInfoExA(prodcode, NULL,
6267                               MSIINSTALLCONTEXT_MACHINE,
6268                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6269     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6270     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6271     ok(sz == 5, "Expected 5, got %d\n", sz);
6272
6273     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6274     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6275
6276     /* ProductID value exists */
6277     sz = MAX_PATH;
6278     lstrcpyA(buf, "apple");
6279     r = pMsiGetProductInfoExA(prodcode, NULL,
6280                               MSIINSTALLCONTEXT_MACHINE,
6281                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6282     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6283     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6284     ok(sz == 2, "Expected 2, got %d\n", sz);
6285
6286     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6287     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6288
6289     /* RegCompany value exists */
6290     sz = MAX_PATH;
6291     lstrcpyA(buf, "apple");
6292     r = pMsiGetProductInfoExA(prodcode, NULL,
6293                               MSIINSTALLCONTEXT_MACHINE,
6294                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6295     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6296     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6297     ok(sz == 4, "Expected 4, got %d\n", sz);
6298
6299     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6300     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6301
6302     /* RegOwner value exists */
6303     sz = MAX_PATH;
6304     lstrcpyA(buf, "apple");
6305     r = pMsiGetProductInfoExA(prodcode, NULL,
6306                               MSIINSTALLCONTEXT_MACHINE,
6307                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6308     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6309     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6310     ok(sz == 5, "Expected 5, got %d\n", sz);
6311
6312     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6313     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6314
6315     /* Transforms value exists */
6316     sz = MAX_PATH;
6317     lstrcpyA(buf, "apple");
6318     r = pMsiGetProductInfoExA(prodcode, NULL,
6319                               MSIINSTALLCONTEXT_MACHINE,
6320                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6321     ok(r == ERROR_UNKNOWN_PRODUCT,
6322        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6323     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6324     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6325
6326     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6327     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6328
6329     /* Language value exists */
6330     sz = MAX_PATH;
6331     lstrcpyA(buf, "apple");
6332     r = pMsiGetProductInfoExA(prodcode, NULL,
6333                               MSIINSTALLCONTEXT_MACHINE,
6334                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6335     ok(r == ERROR_UNKNOWN_PRODUCT,
6336        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6337     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6338     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6339
6340     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6341     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6342
6343     /* ProductName value exists */
6344     sz = MAX_PATH;
6345     lstrcpyA(buf, "apple");
6346     r = pMsiGetProductInfoExA(prodcode, NULL,
6347                               MSIINSTALLCONTEXT_MACHINE,
6348                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6349     ok(r == ERROR_UNKNOWN_PRODUCT,
6350        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6351     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6352     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6353
6354     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6356
6357     /* FIXME */
6358
6359     /* AssignmentType value exists */
6360     sz = MAX_PATH;
6361     lstrcpyA(buf, "apple");
6362     r = pMsiGetProductInfoExA(prodcode, NULL,
6363                               MSIINSTALLCONTEXT_MACHINE,
6364                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6365     ok(r == ERROR_UNKNOWN_PRODUCT,
6366        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6367     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6368     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6369
6370     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6371     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6372
6373     /* PackageCode value exists */
6374     sz = MAX_PATH;
6375     lstrcpyA(buf, "apple");
6376     r = pMsiGetProductInfoExA(prodcode, NULL,
6377                               MSIINSTALLCONTEXT_MACHINE,
6378                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6379     ok(r == ERROR_UNKNOWN_PRODUCT,
6380        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6381     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6382     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6383
6384     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6385     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6386
6387     /* Version value exists */
6388     sz = MAX_PATH;
6389     lstrcpyA(buf, "apple");
6390     r = pMsiGetProductInfoExA(prodcode, NULL,
6391                               MSIINSTALLCONTEXT_MACHINE,
6392                               INSTALLPROPERTY_VERSION, buf, &sz);
6393     ok(r == ERROR_UNKNOWN_PRODUCT,
6394        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6395     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6396     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6397
6398     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6399     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6400
6401     /* ProductIcon value exists */
6402     sz = MAX_PATH;
6403     lstrcpyA(buf, "apple");
6404     r = pMsiGetProductInfoExA(prodcode, NULL,
6405                               MSIINSTALLCONTEXT_MACHINE,
6406                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6407     ok(r == ERROR_UNKNOWN_PRODUCT,
6408        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6409     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6410     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6411
6412     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6413     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6414
6415     /* PackageName value exists */
6416     sz = MAX_PATH;
6417     lstrcpyA(buf, "apple");
6418     r = pMsiGetProductInfoExA(prodcode, NULL,
6419                               MSIINSTALLCONTEXT_MACHINE,
6420                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6421     ok(r == ERROR_UNKNOWN_PRODUCT,
6422        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6423     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6424     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6425
6426     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6427     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6428
6429     /* AuthorizedLUAApp value exists */
6430     sz = MAX_PATH;
6431     lstrcpyA(buf, "apple");
6432     r = pMsiGetProductInfoExA(prodcode, NULL,
6433                               MSIINSTALLCONTEXT_MACHINE,
6434                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6435     ok(r == ERROR_UNKNOWN_PRODUCT,
6436        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6437     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6438     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6439
6440     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6441     RegDeleteValueA(propkey, "PackageName");
6442     RegDeleteValueA(propkey, "ProductIcon");
6443     RegDeleteValueA(propkey, "Version");
6444     RegDeleteValueA(propkey, "PackageCode");
6445     RegDeleteValueA(propkey, "AssignmentType");
6446     RegDeleteValueA(propkey, "ProductName");
6447     RegDeleteValueA(propkey, "Language");
6448     RegDeleteValueA(propkey, "Transforms");
6449     RegDeleteValueA(propkey, "RegOwner");
6450     RegDeleteValueA(propkey, "RegCompany");
6451     RegDeleteValueA(propkey, "ProductID");
6452     RegDeleteValueA(propkey, "DisplayVersion");
6453     RegDeleteValueA(propkey, "VersionMajor");
6454     RegDeleteValueA(propkey, "VersionMinor");
6455     RegDeleteValueA(propkey, "URLUpdateInfo");
6456     RegDeleteValueA(propkey, "URLInfoAbout");
6457     RegDeleteValueA(propkey, "Publisher");
6458     RegDeleteValueA(propkey, "LocalPackage");
6459     RegDeleteValueA(propkey, "InstallSource");
6460     RegDeleteValueA(propkey, "InstallLocation");
6461     RegDeleteValueA(propkey, "DisplayName");
6462     RegDeleteValueA(propkey, "InstallDate");
6463     RegDeleteValueA(propkey, "HelpTelephone");
6464     RegDeleteValueA(propkey, "HelpLink");
6465     RegDeleteValueA(propkey, "LocalPackage");
6466     delete_key(propkey, "", access & KEY_WOW64_64KEY);
6467     RegCloseKey(propkey);
6468     delete_key(localkey, "", access & KEY_WOW64_64KEY);
6469     RegCloseKey(localkey);
6470
6471     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6472     lstrcatA(keypath, prod_squashed);
6473
6474     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
6475     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6476
6477     /* local classes product key exists */
6478     sz = MAX_PATH;
6479     lstrcpyA(buf, "apple");
6480     r = pMsiGetProductInfoExA(prodcode, NULL,
6481                               MSIINSTALLCONTEXT_MACHINE,
6482                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6483     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6484     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6485     ok(sz == 1, "Expected 1, got %d\n", sz);
6486
6487     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6488     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6489
6490     /* HelpLink value exists */
6491     sz = MAX_PATH;
6492     lstrcpyA(buf, "apple");
6493     r = pMsiGetProductInfoExA(prodcode, NULL,
6494                               MSIINSTALLCONTEXT_MACHINE,
6495                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6496     ok(r == ERROR_UNKNOWN_PROPERTY,
6497        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6498     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6499     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6500
6501     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6502     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6503
6504     /* HelpTelephone value exists */
6505     sz = MAX_PATH;
6506     lstrcpyA(buf, "apple");
6507     r = pMsiGetProductInfoExA(prodcode, NULL,
6508                               MSIINSTALLCONTEXT_MACHINE,
6509                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6510     ok(r == ERROR_UNKNOWN_PROPERTY,
6511        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6512     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6513     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6514
6515     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6516     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6517
6518     /* InstallDate value exists */
6519     sz = MAX_PATH;
6520     lstrcpyA(buf, "apple");
6521     r = pMsiGetProductInfoExA(prodcode, NULL,
6522                               MSIINSTALLCONTEXT_MACHINE,
6523                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6524     ok(r == ERROR_UNKNOWN_PROPERTY,
6525        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6526     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6527     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6528
6529     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6530     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6531
6532     /* DisplayName value exists */
6533     sz = MAX_PATH;
6534     lstrcpyA(buf, "apple");
6535     r = pMsiGetProductInfoExA(prodcode, NULL,
6536                               MSIINSTALLCONTEXT_MACHINE,
6537                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6538     ok(r == ERROR_UNKNOWN_PROPERTY,
6539        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6540     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6541     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6542
6543     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6544     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6545
6546     /* InstallLocation value exists */
6547     sz = MAX_PATH;
6548     lstrcpyA(buf, "apple");
6549     r = pMsiGetProductInfoExA(prodcode, NULL,
6550                               MSIINSTALLCONTEXT_MACHINE,
6551                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6552     ok(r == ERROR_UNKNOWN_PROPERTY,
6553        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6554     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6555     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6556
6557     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6558     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6559
6560     /* InstallSource value exists */
6561     sz = MAX_PATH;
6562     lstrcpyA(buf, "apple");
6563     r = pMsiGetProductInfoExA(prodcode, NULL,
6564                               MSIINSTALLCONTEXT_MACHINE,
6565                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6566     ok(r == ERROR_UNKNOWN_PROPERTY,
6567        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6568     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6569     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6570
6571     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6572     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6573
6574     /* LocalPackage value exists */
6575     sz = MAX_PATH;
6576     lstrcpyA(buf, "apple");
6577     r = pMsiGetProductInfoExA(prodcode, NULL,
6578                               MSIINSTALLCONTEXT_MACHINE,
6579                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6580     ok(r == ERROR_UNKNOWN_PROPERTY,
6581        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6582     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6583     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6584
6585     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6586     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6587
6588     /* Publisher value exists */
6589     sz = MAX_PATH;
6590     lstrcpyA(buf, "apple");
6591     r = pMsiGetProductInfoExA(prodcode, NULL,
6592                               MSIINSTALLCONTEXT_MACHINE,
6593                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6594     ok(r == ERROR_UNKNOWN_PROPERTY,
6595        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6596     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6597     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6598
6599     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6600     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6601
6602     /* URLInfoAbout value exists */
6603     sz = MAX_PATH;
6604     lstrcpyA(buf, "apple");
6605     r = pMsiGetProductInfoExA(prodcode, NULL,
6606                               MSIINSTALLCONTEXT_MACHINE,
6607                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6608     ok(r == ERROR_UNKNOWN_PROPERTY,
6609        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6610     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6611     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6612
6613     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6614     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6615
6616     /* URLUpdateInfo value exists */
6617     sz = MAX_PATH;
6618     lstrcpyA(buf, "apple");
6619     r = pMsiGetProductInfoExA(prodcode, NULL,
6620                               MSIINSTALLCONTEXT_MACHINE,
6621                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6622     ok(r == ERROR_UNKNOWN_PROPERTY,
6623        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6624     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6625     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6626
6627     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6628     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6629
6630     /* VersionMinor value exists */
6631     sz = MAX_PATH;
6632     lstrcpyA(buf, "apple");
6633     r = pMsiGetProductInfoExA(prodcode, NULL,
6634                               MSIINSTALLCONTEXT_MACHINE,
6635                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6636     ok(r == ERROR_UNKNOWN_PROPERTY,
6637        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6638     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6639     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6640
6641     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6643
6644     /* VersionMajor value exists */
6645     sz = MAX_PATH;
6646     lstrcpyA(buf, "apple");
6647     r = pMsiGetProductInfoExA(prodcode, NULL,
6648                               MSIINSTALLCONTEXT_MACHINE,
6649                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6650     ok(r == ERROR_UNKNOWN_PROPERTY,
6651        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6652     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6653     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6654
6655     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6657
6658     /* DisplayVersion value exists */
6659     sz = MAX_PATH;
6660     lstrcpyA(buf, "apple");
6661     r = pMsiGetProductInfoExA(prodcode, NULL,
6662                               MSIINSTALLCONTEXT_MACHINE,
6663                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6664     ok(r == ERROR_UNKNOWN_PROPERTY,
6665        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6666     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6667     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6668
6669     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6670     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6671
6672     /* ProductID value exists */
6673     sz = MAX_PATH;
6674     lstrcpyA(buf, "apple");
6675     r = pMsiGetProductInfoExA(prodcode, NULL,
6676                               MSIINSTALLCONTEXT_MACHINE,
6677                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6678     ok(r == ERROR_UNKNOWN_PROPERTY,
6679        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6680     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6681     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6682
6683     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6685
6686     /* RegCompany value exists */
6687     sz = MAX_PATH;
6688     lstrcpyA(buf, "apple");
6689     r = pMsiGetProductInfoExA(prodcode, NULL,
6690                               MSIINSTALLCONTEXT_MACHINE,
6691                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6692     ok(r == ERROR_UNKNOWN_PROPERTY,
6693        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6694     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6695     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6696
6697     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6698     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6699
6700     /* RegOwner value exists */
6701     sz = MAX_PATH;
6702     lstrcpyA(buf, "apple");
6703     r = pMsiGetProductInfoExA(prodcode, NULL,
6704                               MSIINSTALLCONTEXT_MACHINE,
6705                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6706     ok(r == ERROR_UNKNOWN_PROPERTY,
6707        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6708     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6709     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6710
6711     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6713
6714     /* Transforms value exists */
6715     sz = MAX_PATH;
6716     lstrcpyA(buf, "apple");
6717     r = pMsiGetProductInfoExA(prodcode, NULL,
6718                               MSIINSTALLCONTEXT_MACHINE,
6719                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6720     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6721     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6722     ok(sz == 5, "Expected 5, got %d\n", sz);
6723
6724     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6726
6727     /* Language value exists */
6728     sz = MAX_PATH;
6729     lstrcpyA(buf, "apple");
6730     r = pMsiGetProductInfoExA(prodcode, NULL,
6731                               MSIINSTALLCONTEXT_MACHINE,
6732                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6733     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6734     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6735     ok(sz == 4, "Expected 4, got %d\n", sz);
6736
6737     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6738     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6739
6740     /* ProductName value exists */
6741     sz = MAX_PATH;
6742     lstrcpyA(buf, "apple");
6743     r = pMsiGetProductInfoExA(prodcode, NULL,
6744                               MSIINSTALLCONTEXT_MACHINE,
6745                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6746     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6747     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6748     ok(sz == 4, "Expected 4, got %d\n", sz);
6749
6750     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6752
6753     /* FIXME */
6754
6755     /* AssignmentType value exists */
6756     sz = MAX_PATH;
6757     lstrcpyA(buf, "apple");
6758     r = pMsiGetProductInfoExA(prodcode, NULL,
6759                               MSIINSTALLCONTEXT_MACHINE,
6760                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6762     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6763     ok(sz == 0, "Expected 0, got %d\n", sz);
6764
6765     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6767
6768     /* FIXME */
6769
6770     /* PackageCode value exists */
6771     sz = MAX_PATH;
6772     lstrcpyA(buf, "apple");
6773     r = pMsiGetProductInfoExA(prodcode, NULL,
6774                               MSIINSTALLCONTEXT_MACHINE,
6775                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6776     todo_wine
6777     {
6778         ok(r == ERROR_BAD_CONFIGURATION,
6779            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6780         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6781         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6782     }
6783
6784     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6786
6787     /* Version value exists */
6788     sz = MAX_PATH;
6789     lstrcpyA(buf, "apple");
6790     r = pMsiGetProductInfoExA(prodcode, NULL,
6791                               MSIINSTALLCONTEXT_MACHINE,
6792                               INSTALLPROPERTY_VERSION, buf, &sz);
6793     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6794     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6795     ok(sz == 3, "Expected 3, got %d\n", sz);
6796
6797     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6798     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6799
6800     /* ProductIcon value exists */
6801     sz = MAX_PATH;
6802     lstrcpyA(buf, "apple");
6803     r = pMsiGetProductInfoExA(prodcode, NULL,
6804                               MSIINSTALLCONTEXT_MACHINE,
6805                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6806     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6807     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6808     ok(sz == 4, "Expected 4, got %d\n", sz);
6809
6810     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6811     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6812
6813     /* PackageName value exists */
6814     sz = MAX_PATH;
6815     lstrcpyA(buf, "apple");
6816     r = pMsiGetProductInfoExA(prodcode, NULL,
6817                               MSIINSTALLCONTEXT_MACHINE,
6818                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6819     todo_wine
6820     {
6821         ok(r == ERROR_UNKNOWN_PRODUCT,
6822            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6823         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6824         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6825     }
6826
6827     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6828     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6829
6830     /* AuthorizedLUAApp value exists */
6831     sz = MAX_PATH;
6832     lstrcpyA(buf, "apple");
6833     r = pMsiGetProductInfoExA(prodcode, NULL,
6834                               MSIINSTALLCONTEXT_MACHINE,
6835                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6836     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6837     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6838     ok(sz == 4, "Expected 4, got %d\n", sz);
6839
6840     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6841     RegDeleteValueA(prodkey, "PackageName");
6842     RegDeleteValueA(prodkey, "ProductIcon");
6843     RegDeleteValueA(prodkey, "Version");
6844     RegDeleteValueA(prodkey, "PackageCode");
6845     RegDeleteValueA(prodkey, "AssignmentType");
6846     RegDeleteValueA(prodkey, "ProductName");
6847     RegDeleteValueA(prodkey, "Language");
6848     RegDeleteValueA(prodkey, "Transforms");
6849     RegDeleteValueA(prodkey, "RegOwner");
6850     RegDeleteValueA(prodkey, "RegCompany");
6851     RegDeleteValueA(prodkey, "ProductID");
6852     RegDeleteValueA(prodkey, "DisplayVersion");
6853     RegDeleteValueA(prodkey, "VersionMajor");
6854     RegDeleteValueA(prodkey, "VersionMinor");
6855     RegDeleteValueA(prodkey, "URLUpdateInfo");
6856     RegDeleteValueA(prodkey, "URLInfoAbout");
6857     RegDeleteValueA(prodkey, "Publisher");
6858     RegDeleteValueA(prodkey, "LocalPackage");
6859     RegDeleteValueA(prodkey, "InstallSource");
6860     RegDeleteValueA(prodkey, "InstallLocation");
6861     RegDeleteValueA(prodkey, "DisplayName");
6862     RegDeleteValueA(prodkey, "InstallDate");
6863     RegDeleteValueA(prodkey, "HelpTelephone");
6864     RegDeleteValueA(prodkey, "HelpLink");
6865     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
6866     RegCloseKey(prodkey);
6867     LocalFree(usersid);
6868 }
6869
6870 #define INIT_USERINFO() \
6871     lstrcpyA(user, "apple"); \
6872     lstrcpyA(org, "orange"); \
6873     lstrcpyA(serial, "banana"); \
6874     usersz = orgsz = serialsz = MAX_PATH;
6875
6876 static void test_MsiGetUserInfo(void)
6877 {
6878     USERINFOSTATE state;
6879     CHAR user[MAX_PATH];
6880     CHAR org[MAX_PATH];
6881     CHAR serial[MAX_PATH];
6882     DWORD usersz, orgsz, serialsz;
6883     CHAR keypath[MAX_PATH * 2];
6884     CHAR prodcode[MAX_PATH];
6885     CHAR prod_squashed[MAX_PATH];
6886     HKEY prodkey, userprod, props;
6887     LPSTR usersid;
6888     LONG res;
6889     REGSAM access = KEY_ALL_ACCESS;
6890
6891     create_test_guid(prodcode, prod_squashed);
6892     get_user_sid(&usersid);
6893
6894     if (is_wow64)
6895         access |= KEY_WOW64_64KEY;
6896
6897     /* NULL szProduct */
6898     INIT_USERINFO();
6899     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6900     ok(state == USERINFOSTATE_INVALIDARG,
6901        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6902     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6903     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6904     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6905     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6906     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6907     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6908
6909     /* empty szProductCode */
6910     INIT_USERINFO();
6911     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6912     ok(state == USERINFOSTATE_INVALIDARG,
6913        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6914     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6915     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6916     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6917     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6918     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6919     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6920
6921     /* garbage szProductCode */
6922     INIT_USERINFO();
6923     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6924     ok(state == USERINFOSTATE_INVALIDARG,
6925        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6926     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6927     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6928     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6929     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6930     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6931     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6932
6933     /* guid without brackets */
6934     INIT_USERINFO();
6935     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6936                             user, &usersz, org, &orgsz, serial, &serialsz);
6937     ok(state == USERINFOSTATE_INVALIDARG,
6938        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6939     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6940     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6941     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6942     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6943     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6944     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6945
6946     /* guid with brackets */
6947     INIT_USERINFO();
6948     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6949                             user, &usersz, org, &orgsz, serial, &serialsz);
6950     ok(state == USERINFOSTATE_UNKNOWN,
6951        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6952     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6953     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6954     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6955     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6956     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6957     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6958
6959     /* NULL lpUserNameBuf */
6960     INIT_USERINFO();
6961     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6962     ok(state == USERINFOSTATE_UNKNOWN,
6963        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6964     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6965     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6966     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6967     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6968     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6969
6970     /* NULL pcchUserNameBuf */
6971     INIT_USERINFO();
6972     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6973     ok(state == USERINFOSTATE_INVALIDARG,
6974        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6975     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6976     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6977     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6978     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6979     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6980
6981     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6982     INIT_USERINFO();
6983     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6984     ok(state == USERINFOSTATE_UNKNOWN,
6985        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6986     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6987     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6988     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6989     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6990
6991     /* NULL lpOrgNameBuf */
6992     INIT_USERINFO();
6993     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6994     ok(state == USERINFOSTATE_UNKNOWN,
6995        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6996     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6997     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6998     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6999     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7000     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7001
7002     /* NULL pcchOrgNameBuf */
7003     INIT_USERINFO();
7004     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
7005     ok(state == USERINFOSTATE_INVALIDARG,
7006        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7007     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7008     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7009     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7010     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7011     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7012
7013     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
7014     INIT_USERINFO();
7015     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
7016     ok(state == USERINFOSTATE_UNKNOWN,
7017        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7018     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7019     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7020     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7021     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7022
7023     /* NULL lpSerialBuf */
7024     INIT_USERINFO();
7025     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
7026     ok(state == USERINFOSTATE_UNKNOWN,
7027        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7028     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7029     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7030     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7031     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7032     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7033
7034     /* NULL pcchSerialBuf */
7035     INIT_USERINFO();
7036     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
7037     ok(state == USERINFOSTATE_INVALIDARG,
7038        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
7039     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7040     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7041     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7042     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7043     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7044
7045     /* both lpSerialBuf and pcchSerialBuf NULL */
7046     INIT_USERINFO();
7047     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
7048     ok(state == USERINFOSTATE_UNKNOWN,
7049        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
7050     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7051     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7052     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7053     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7054
7055     /* MSIINSTALLCONTEXT_USERMANAGED */
7056
7057     /* create local system product key */
7058     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7059     lstrcatA(keypath, usersid);
7060     lstrcatA(keypath, "\\Installer\\Products\\");
7061     lstrcatA(keypath, prod_squashed);
7062
7063     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7064     if (res == ERROR_ACCESS_DENIED)
7065     {
7066         skip("Not enough rights to perform tests\n");
7067         LocalFree(usersid);
7068         return;
7069     }
7070     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7071
7072     /* managed product key exists */
7073     INIT_USERINFO();
7074     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7075     ok(state == USERINFOSTATE_ABSENT,
7076        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7077     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7078     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7079     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7080     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7081     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7082     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7083
7084     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7085     lstrcatA(keypath, "Installer\\UserData\\");
7086     lstrcatA(keypath, usersid);
7087     lstrcatA(keypath, "\\Products\\");
7088     lstrcatA(keypath, prod_squashed);
7089
7090     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7091     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7092
7093     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7094     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7095
7096     /* InstallProperties key exists */
7097     INIT_USERINFO();
7098     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7099     ok(state == USERINFOSTATE_ABSENT,
7100        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7101     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7102     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7103     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7104     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7105     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7106     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7107
7108     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7109     INIT_USERINFO();
7110     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7111     ok(state == USERINFOSTATE_ABSENT,
7112        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7113     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7114     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7115     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7116     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7117
7118     /* RegOwner, RegCompany don't exist, out params are NULL */
7119     INIT_USERINFO();
7120     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7121     ok(state == USERINFOSTATE_ABSENT,
7122        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7123     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7124     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7125
7126     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7127     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7128
7129     /* RegOwner value exists */
7130     INIT_USERINFO();
7131     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7132     ok(state == USERINFOSTATE_ABSENT,
7133        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7134     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7135     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7136     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7137     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7138     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7139     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7140
7141     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7142     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7143
7144     /* RegCompany value exists */
7145     INIT_USERINFO();
7146     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7147     ok(state == USERINFOSTATE_ABSENT,
7148        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7149     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7150     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7151     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7152     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7153     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7154     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7155
7156     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7157     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7158
7159     /* ProductID value exists */
7160     INIT_USERINFO();
7161     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7162     ok(state == USERINFOSTATE_PRESENT,
7163        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7164     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7165     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7166     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7167     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7168     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7169     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7170
7171     /* pcchUserNameBuf is too small */
7172     INIT_USERINFO();
7173     usersz = 0;
7174     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7175     ok(state == USERINFOSTATE_MOREDATA,
7176        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7177     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7178     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7179     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7180     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7181     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7182     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7183
7184     /* pcchUserNameBuf has no room for NULL terminator */
7185     INIT_USERINFO();
7186     usersz = 5;
7187     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7188     ok(state == USERINFOSTATE_MOREDATA,
7189        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7190     todo_wine
7191     {
7192         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7193     }
7194     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7195     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7196     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7197     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7198     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7199
7200     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
7201     INIT_USERINFO();
7202     usersz = 0;
7203     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7204     ok(state == USERINFOSTATE_PRESENT,
7205        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7206     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7207     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7208     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7209     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7210     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7211     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7212
7213     RegDeleteValueA(props, "ProductID");
7214     RegDeleteValueA(props, "RegCompany");
7215     RegDeleteValueA(props, "RegOwner");
7216     delete_key(props, "", access & KEY_WOW64_64KEY);
7217     RegCloseKey(props);
7218     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7219     RegCloseKey(userprod);
7220     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7221     RegCloseKey(prodkey);
7222
7223     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7224
7225     /* create local system product key */
7226     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7227     lstrcatA(keypath, prod_squashed);
7228
7229     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7230     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7231
7232     /* product key exists */
7233     INIT_USERINFO();
7234     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7235     ok(state == USERINFOSTATE_ABSENT,
7236        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7237     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7238     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7239     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7240     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7241     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7242     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7243
7244     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7245     lstrcatA(keypath, "Installer\\UserData\\");
7246     lstrcatA(keypath, usersid);
7247     lstrcatA(keypath, "\\Products\\");
7248     lstrcatA(keypath, prod_squashed);
7249
7250     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7251     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7252
7253     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7255
7256     /* InstallProperties key exists */
7257     INIT_USERINFO();
7258     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7259     ok(state == USERINFOSTATE_ABSENT,
7260        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7261     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7262     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7263     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7264     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7265     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7266     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7267
7268     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7269     INIT_USERINFO();
7270     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7271     ok(state == USERINFOSTATE_ABSENT,
7272        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7273     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7274     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7275     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7276     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7277
7278     /* RegOwner, RegCompany don't exist, out params are NULL */
7279     INIT_USERINFO();
7280     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7281     ok(state == USERINFOSTATE_ABSENT,
7282        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7283     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7284     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7285
7286     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7287     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7288
7289     /* RegOwner value exists */
7290     INIT_USERINFO();
7291     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7292     ok(state == USERINFOSTATE_ABSENT,
7293        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7294     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7295     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7296     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7297     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7298     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7299     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7300
7301     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7303
7304     /* RegCompany value exists */
7305     INIT_USERINFO();
7306     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7307     ok(state == USERINFOSTATE_ABSENT,
7308        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7309     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7310     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7311     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7312     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7313     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7314     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7315
7316     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7317     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7318
7319     /* ProductID value exists */
7320     INIT_USERINFO();
7321     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7322     ok(state == USERINFOSTATE_PRESENT,
7323        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7324     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7325     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7326     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7327     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7328     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7329     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7330
7331     RegDeleteValueA(props, "ProductID");
7332     RegDeleteValueA(props, "RegCompany");
7333     RegDeleteValueA(props, "RegOwner");
7334     delete_key(props, "", access & KEY_WOW64_64KEY);
7335     RegCloseKey(props);
7336     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7337     RegCloseKey(userprod);
7338     RegDeleteKeyA(prodkey, "");
7339     RegCloseKey(prodkey);
7340
7341     /* MSIINSTALLCONTEXT_MACHINE */
7342
7343     /* create local system product key */
7344     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7345     lstrcatA(keypath, prod_squashed);
7346
7347     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7349
7350     /* product key exists */
7351     INIT_USERINFO();
7352     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7353     ok(state == USERINFOSTATE_ABSENT,
7354        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7355     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7356     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7357     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7358     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7359     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7360     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7361
7362     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7363     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7364     lstrcatA(keypath, "\\Products\\");
7365     lstrcatA(keypath, prod_squashed);
7366
7367     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
7368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7369
7370     res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7371     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7372
7373     /* InstallProperties key exists */
7374     INIT_USERINFO();
7375     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7376     ok(state == USERINFOSTATE_ABSENT,
7377        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7378     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7379     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7380     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7381     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7382     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7383     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7384
7385     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7386     INIT_USERINFO();
7387     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7388     ok(state == USERINFOSTATE_ABSENT,
7389        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7390     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7391     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7392     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7393     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7394
7395     /* RegOwner, RegCompany don't exist, out params are NULL */
7396     INIT_USERINFO();
7397     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7398     ok(state == USERINFOSTATE_ABSENT,
7399        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7400     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7401     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7402
7403     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7404     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7405
7406     /* RegOwner value exists */
7407     INIT_USERINFO();
7408     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7409     ok(state == USERINFOSTATE_ABSENT,
7410        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7411     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7412     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7413     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7414     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7415     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7416     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7417
7418     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7419     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7420
7421     /* RegCompany value exists */
7422     INIT_USERINFO();
7423     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7424     ok(state == USERINFOSTATE_ABSENT,
7425        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7426     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7427     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7428     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7429     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7430     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7431     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7432
7433     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7435
7436     /* ProductID value exists */
7437     INIT_USERINFO();
7438     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7439     ok(state == USERINFOSTATE_PRESENT,
7440        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7441     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7442     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7443     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7444     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7445     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7446     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7447
7448     RegDeleteValueA(props, "ProductID");
7449     RegDeleteValueA(props, "RegCompany");
7450     RegDeleteValueA(props, "RegOwner");
7451     delete_key(props, "", access & KEY_WOW64_64KEY);
7452     RegCloseKey(props);
7453     delete_key(userprod, "", access & KEY_WOW64_64KEY);
7454     RegCloseKey(userprod);
7455     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7456     RegCloseKey(prodkey);
7457     LocalFree(usersid);
7458 }
7459
7460 static void test_MsiOpenProduct(void)
7461 {
7462     MSIHANDLE hprod, hdb;
7463     CHAR val[MAX_PATH];
7464     CHAR path[MAX_PATH];
7465     CHAR keypath[MAX_PATH*2];
7466     CHAR prodcode[MAX_PATH];
7467     CHAR prod_squashed[MAX_PATH];
7468     HKEY prodkey, userkey, props;
7469     LPSTR usersid;
7470     DWORD size;
7471     LONG res;
7472     UINT r;
7473     REGSAM access = KEY_ALL_ACCESS;
7474
7475     GetCurrentDirectoryA(MAX_PATH, path);
7476     lstrcatA(path, "\\");
7477
7478     create_test_guid(prodcode, prod_squashed);
7479     get_user_sid(&usersid);
7480
7481     if (is_wow64)
7482         access |= KEY_WOW64_64KEY;
7483
7484     hdb = create_package_db(prodcode);
7485     MsiCloseHandle(hdb);
7486
7487     /* NULL szProduct */
7488     hprod = 0xdeadbeef;
7489     r = MsiOpenProductA(NULL, &hprod);
7490     ok(r == ERROR_INVALID_PARAMETER,
7491        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7492     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7493
7494     /* empty szProduct */
7495     hprod = 0xdeadbeef;
7496     r = MsiOpenProductA("", &hprod);
7497     ok(r == ERROR_INVALID_PARAMETER,
7498        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7499     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7500
7501     /* garbage szProduct */
7502     hprod = 0xdeadbeef;
7503     r = MsiOpenProductA("garbage", &hprod);
7504     ok(r == ERROR_INVALID_PARAMETER,
7505        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7506     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7507
7508     /* guid without brackets */
7509     hprod = 0xdeadbeef;
7510     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7511     ok(r == ERROR_INVALID_PARAMETER,
7512        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7513     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7514
7515     /* guid with brackets */
7516     hprod = 0xdeadbeef;
7517     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7518     ok(r == ERROR_UNKNOWN_PRODUCT,
7519        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7520     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7521
7522     /* same length as guid, but random */
7523     hprod = 0xdeadbeef;
7524     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7525     ok(r == ERROR_INVALID_PARAMETER,
7526        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7527     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7528
7529     /* hProduct is NULL */
7530     hprod = 0xdeadbeef;
7531     r = MsiOpenProductA(prodcode, NULL);
7532     ok(r == ERROR_INVALID_PARAMETER,
7533        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7534     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7535
7536     /* MSIINSTALLCONTEXT_USERMANAGED */
7537
7538     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7539     lstrcatA(keypath, "Installer\\Managed\\");
7540     lstrcatA(keypath, usersid);
7541     lstrcatA(keypath, "\\Installer\\Products\\");
7542     lstrcatA(keypath, prod_squashed);
7543
7544     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7545     if (res == ERROR_ACCESS_DENIED)
7546     {
7547         skip("Not enough rights to perform tests\n");
7548         LocalFree(usersid);
7549         return;
7550     }
7551     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7552
7553     /* managed product key exists */
7554     hprod = 0xdeadbeef;
7555     r = MsiOpenProductA(prodcode, &hprod);
7556     ok(r == ERROR_UNKNOWN_PRODUCT,
7557        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7558     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7559
7560     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7561     lstrcatA(keypath, "Installer\\UserData\\");
7562     lstrcatA(keypath, usersid);
7563     lstrcatA(keypath, "\\Products\\");
7564     lstrcatA(keypath, prod_squashed);
7565
7566     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7567     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7568
7569     /* user product key exists */
7570     hprod = 0xdeadbeef;
7571     r = MsiOpenProductA(prodcode, &hprod);
7572     ok(r == ERROR_UNKNOWN_PRODUCT,
7573        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7574     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7575
7576     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7578
7579     /* InstallProperties 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     lstrcpyA(val, path);
7587     lstrcatA(val, "\\winetest.msi");
7588     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7589                          (const BYTE *)val, lstrlenA(val) + 1);
7590     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7591
7592     /* ManagedLocalPackage value exists */
7593     hprod = 0xdeadbeef;
7594     r = MsiOpenProductA(prodcode, &hprod);
7595     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7596     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7597
7598     size = MAX_PATH;
7599     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7600     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7601     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7602     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7603
7604     MsiCloseHandle(hprod);
7605
7606     RegDeleteValueA(props, "ManagedLocalPackage");
7607     delete_key(props, "", access & KEY_WOW64_64KEY);
7608     RegCloseKey(props);
7609     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7610     RegCloseKey(userkey);
7611     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7612     RegCloseKey(prodkey);
7613
7614     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7615
7616     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7617     lstrcatA(keypath, prod_squashed);
7618
7619     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7620     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7621
7622     /* unmanaged product key exists */
7623     hprod = 0xdeadbeef;
7624     r = MsiOpenProductA(prodcode, &hprod);
7625     ok(r == ERROR_UNKNOWN_PRODUCT,
7626        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7627     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7628
7629     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7630     lstrcatA(keypath, "Installer\\UserData\\");
7631     lstrcatA(keypath, usersid);
7632     lstrcatA(keypath, "\\Products\\");
7633     lstrcatA(keypath, prod_squashed);
7634
7635     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7637
7638     /* user product key exists */
7639     hprod = 0xdeadbeef;
7640     r = MsiOpenProductA(prodcode, &hprod);
7641     ok(r == ERROR_UNKNOWN_PRODUCT,
7642        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7643     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7644
7645     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7646     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7647
7648     /* InstallProperties 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     lstrcpyA(val, path);
7656     lstrcatA(val, "\\winetest.msi");
7657     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7658                          (const BYTE *)val, lstrlenA(val) + 1);
7659     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7660
7661     /* LocalPackage value exists */
7662     hprod = 0xdeadbeef;
7663     r = MsiOpenProductA(prodcode, &hprod);
7664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7665     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7666
7667     size = MAX_PATH;
7668     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7669     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7670     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7671     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7672
7673     MsiCloseHandle(hprod);
7674
7675     RegDeleteValueA(props, "LocalPackage");
7676     delete_key(props, "", access & KEY_WOW64_64KEY);
7677     RegCloseKey(props);
7678     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7679     RegCloseKey(userkey);
7680     RegDeleteKeyA(prodkey, "");
7681     RegCloseKey(prodkey);
7682
7683     /* MSIINSTALLCONTEXT_MACHINE */
7684
7685     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7686     lstrcatA(keypath, prod_squashed);
7687
7688     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7690
7691     /* managed product key exists */
7692     hprod = 0xdeadbeef;
7693     r = MsiOpenProductA(prodcode, &hprod);
7694     ok(r == ERROR_UNKNOWN_PRODUCT,
7695        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7696     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7697
7698     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7699     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7700     lstrcatA(keypath, prod_squashed);
7701
7702     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
7703     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7704
7705     /* user product key exists */
7706     hprod = 0xdeadbeef;
7707     r = MsiOpenProductA(prodcode, &hprod);
7708     ok(r == ERROR_UNKNOWN_PRODUCT,
7709        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7710     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7711
7712     res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
7713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7714
7715     /* InstallProperties 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     lstrcpyA(val, path);
7723     lstrcatA(val, "\\winetest.msi");
7724     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7725                          (const BYTE *)val, lstrlenA(val) + 1);
7726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7727
7728     /* LocalPackage value exists */
7729     hprod = 0xdeadbeef;
7730     r = MsiOpenProductA(prodcode, &hprod);
7731     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7732     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7733
7734     size = MAX_PATH;
7735     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7736     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7737     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7738     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7739
7740     MsiCloseHandle(hprod);
7741
7742     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7743                          (const BYTE *)"winetest.msi", 13);
7744     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7745
7746     /* LocalPackage has just the package name */
7747     hprod = 0xdeadbeef;
7748     r = MsiOpenProductA(prodcode, &hprod);
7749     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7750        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7751     if (r == ERROR_SUCCESS)
7752         MsiCloseHandle(hprod);
7753     else
7754         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7755
7756     lstrcpyA(val, path);
7757     lstrcatA(val, "\\winetest.msi");
7758     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7759                          (const BYTE *)val, lstrlenA(val) + 1);
7760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7761
7762     DeleteFileA(msifile);
7763
7764     /* local package does not exist */
7765     hprod = 0xdeadbeef;
7766     r = MsiOpenProductA(prodcode, &hprod);
7767     ok(r == ERROR_UNKNOWN_PRODUCT,
7768        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7769     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7770
7771     RegDeleteValueA(props, "LocalPackage");
7772     delete_key(props, "", access & KEY_WOW64_64KEY);
7773     RegCloseKey(props);
7774     delete_key(userkey, "", access & KEY_WOW64_64KEY);
7775     RegCloseKey(userkey);
7776     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
7777     RegCloseKey(prodkey);
7778
7779     DeleteFileA(msifile);
7780     LocalFree(usersid);
7781 }
7782
7783 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7784 {
7785     MSIINSTALLCONTEXT context;
7786     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7787     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7788     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7789     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7790     HKEY prodkey, patches, udprod, udpatch, hpatch;
7791     DWORD size, data;
7792     LONG res;
7793     UINT r;
7794     REGSAM access = KEY_ALL_ACCESS;
7795
7796     create_test_guid(prodcode, prod_squashed);
7797     create_test_guid(patch, patch_squashed);
7798
7799     if (is_wow64)
7800         access |= KEY_WOW64_64KEY;
7801
7802     /* MSIPATCHSTATE_APPLIED */
7803
7804     lstrcpyA(patchcode, "apple");
7805     lstrcpyA(targetprod, "banana");
7806     context = 0xdeadbeef;
7807     lstrcpyA(targetsid, "kiwi");
7808     size = MAX_PATH;
7809     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7810                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7811                            &context, targetsid, &size);
7812     if (r == ERROR_ACCESS_DENIED)
7813     {
7814         skip("Not enough rights to perform tests\n");
7815         return;
7816     }
7817     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7818     ok(!lstrcmpA(patchcode, "apple"),
7819        "Expected patchcode to be unchanged, got %s\n", patchcode);
7820     ok(!lstrcmpA(targetprod, "banana"),
7821        "Expected targetprod to be unchanged, got %s\n", targetprod);
7822     ok(context == 0xdeadbeef,
7823        "Expected context to be unchanged, got %d\n", context);
7824     ok(!lstrcmpA(targetsid, "kiwi"),
7825        "Expected targetsid to be unchanged, got %s\n", targetsid);
7826     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7827
7828     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7829     lstrcatA(keypath, expectedsid);
7830     lstrcatA(keypath, "\\Installer\\Products\\");
7831     lstrcatA(keypath, prod_squashed);
7832
7833     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
7834     if (res == ERROR_ACCESS_DENIED)
7835     {
7836         skip("Not enough rights to perform tests\n");
7837         return;
7838     }
7839     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7840
7841     /* managed product key exists */
7842     lstrcpyA(patchcode, "apple");
7843     lstrcpyA(targetprod, "banana");
7844     context = 0xdeadbeef;
7845     lstrcpyA(targetsid, "kiwi");
7846     size = MAX_PATH;
7847     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7848                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7849                            &context, targetsid, &size);
7850     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7851     ok(!lstrcmpA(patchcode, "apple"),
7852        "Expected patchcode to be unchanged, got %s\n", patchcode);
7853     ok(!lstrcmpA(targetprod, "banana"),
7854        "Expected targetprod to be unchanged, got %s\n", targetprod);
7855     ok(context == 0xdeadbeef,
7856        "Expected context to be unchanged, got %d\n", context);
7857     ok(!lstrcmpA(targetsid, "kiwi"),
7858        "Expected targetsid to be unchanged, got %s\n", targetsid);
7859     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7860
7861     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
7862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7863
7864     /* patches key exists */
7865     lstrcpyA(patchcode, "apple");
7866     lstrcpyA(targetprod, "banana");
7867     context = 0xdeadbeef;
7868     lstrcpyA(targetsid, "kiwi");
7869     size = MAX_PATH;
7870     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7871                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7872                            &context, targetsid, &size);
7873     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7874     ok(!lstrcmpA(patchcode, "apple"),
7875        "Expected patchcode to be unchanged, got %s\n", patchcode);
7876     ok(!lstrcmpA(targetprod, "banana"),
7877        "Expected targetprod to be unchanged, got %s\n", targetprod);
7878     ok(context == 0xdeadbeef,
7879        "Expected context to be unchanged, got %d\n", context);
7880     ok(!lstrcmpA(targetsid, "kiwi"),
7881        "Expected targetsid to be unchanged, got %s\n", targetsid);
7882     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7883
7884     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7885                          (const BYTE *)patch_squashed,
7886                          lstrlenA(patch_squashed) + 1);
7887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7888
7889     /* Patches value exists, is not REG_MULTI_SZ */
7890     lstrcpyA(patchcode, "apple");
7891     lstrcpyA(targetprod, "banana");
7892     context = 0xdeadbeef;
7893     lstrcpyA(targetsid, "kiwi");
7894     size = MAX_PATH;
7895     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7896                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7897                            &context, targetsid, &size);
7898     ok(r == ERROR_BAD_CONFIGURATION,
7899        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7900     ok(!lstrcmpA(patchcode, "apple"),
7901        "Expected patchcode to be unchanged, got %s\n", patchcode);
7902     ok(!lstrcmpA(targetprod, "banana"),
7903        "Expected targetprod to be unchanged, got %s\n", targetprod);
7904     ok(context == 0xdeadbeef,
7905        "Expected context to be unchanged, got %d\n", context);
7906     ok(!lstrcmpA(targetsid, "kiwi"),
7907        "Expected targetsid to be unchanged, got %s\n", targetsid);
7908     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7909
7910     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7911                          (const BYTE *)"a\0b\0c\0\0", 7);
7912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7913
7914     /* Patches value exists, is not a squashed guid */
7915     lstrcpyA(patchcode, "apple");
7916     lstrcpyA(targetprod, "banana");
7917     context = 0xdeadbeef;
7918     lstrcpyA(targetsid, "kiwi");
7919     size = MAX_PATH;
7920     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7921                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7922                            &context, targetsid, &size);
7923     ok(r == ERROR_BAD_CONFIGURATION,
7924        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7925     ok(!lstrcmpA(patchcode, "apple"),
7926        "Expected patchcode to be unchanged, got %s\n", patchcode);
7927     ok(!lstrcmpA(targetprod, "banana"),
7928        "Expected targetprod to be unchanged, got %s\n", targetprod);
7929     ok(context == 0xdeadbeef,
7930        "Expected context to be unchanged, got %d\n", context);
7931     ok(!lstrcmpA(targetsid, "kiwi"),
7932        "Expected targetsid to be unchanged, got %s\n", targetsid);
7933     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7934
7935     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
7936     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7937                          (const BYTE *)patch_squashed,
7938                          lstrlenA(patch_squashed) + 2);
7939     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7940
7941     /* Patches value exists */
7942     lstrcpyA(patchcode, "apple");
7943     lstrcpyA(targetprod, "banana");
7944     context = 0xdeadbeef;
7945     lstrcpyA(targetsid, "kiwi");
7946     size = MAX_PATH;
7947     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7948                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7949                            &context, targetsid, &size);
7950     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7951     ok(!lstrcmpA(patchcode, "apple"),
7952        "Expected patchcode to be unchanged, got %s\n", patchcode);
7953     ok(!lstrcmpA(targetprod, "banana"),
7954        "Expected targetprod to be unchanged, got %s\n", targetprod);
7955     ok(context == 0xdeadbeef,
7956        "Expected context to be unchanged, got %d\n", context);
7957     ok(!lstrcmpA(targetsid, "kiwi"),
7958        "Expected targetsid to be unchanged, got %s\n", targetsid);
7959     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7960
7961     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7962                          (const BYTE *)"whatever", 9);
7963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7964
7965     /* patch squashed value exists */
7966     lstrcpyA(patchcode, "apple");
7967     lstrcpyA(targetprod, "banana");
7968     context = 0xdeadbeef;
7969     lstrcpyA(targetsid, "kiwi");
7970     size = MAX_PATH;
7971     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7972                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7973                            &context, targetsid, &size);
7974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7975     ok(!lstrcmpA(patchcode, patch),
7976        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7977     ok(!lstrcmpA(targetprod, prodcode),
7978        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7979     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7980        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7981     ok(!lstrcmpA(targetsid, expectedsid),
7982        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7983     ok(size == lstrlenA(expectedsid),
7984        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7985
7986     /* increase the index */
7987     lstrcpyA(patchcode, "apple");
7988     lstrcpyA(targetprod, "banana");
7989     context = 0xdeadbeef;
7990     lstrcpyA(targetsid, "kiwi");
7991     size = MAX_PATH;
7992     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7993                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7994                            &context, targetsid, &size);
7995     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7996     ok(!lstrcmpA(patchcode, "apple"),
7997        "Expected patchcode to be unchanged, got %s\n", patchcode);
7998     ok(!lstrcmpA(targetprod, "banana"),
7999        "Expected targetprod to be unchanged, got %s\n", targetprod);
8000     ok(context == 0xdeadbeef,
8001        "Expected context to be unchanged, got %d\n", context);
8002     ok(!lstrcmpA(targetsid, "kiwi"),
8003        "Expected targetsid to be unchanged, got %s\n", targetsid);
8004     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8005
8006     /* increase again */
8007     lstrcpyA(patchcode, "apple");
8008     lstrcpyA(targetprod, "banana");
8009     context = 0xdeadbeef;
8010     lstrcpyA(targetsid, "kiwi");
8011     size = MAX_PATH;
8012     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8013                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
8014                            &context, targetsid, &size);
8015     ok(r == ERROR_INVALID_PARAMETER,
8016        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8017     ok(!lstrcmpA(patchcode, "apple"),
8018        "Expected patchcode to be unchanged, got %s\n", patchcode);
8019     ok(!lstrcmpA(targetprod, "banana"),
8020        "Expected targetprod to be unchanged, got %s\n", targetprod);
8021     ok(context == 0xdeadbeef,
8022        "Expected context to be unchanged, got %d\n", context);
8023     ok(!lstrcmpA(targetsid, "kiwi"),
8024        "Expected targetsid to be unchanged, got %s\n", targetsid);
8025     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8026
8027     /* szPatchCode is NULL */
8028     lstrcpyA(targetprod, "banana");
8029     context = 0xdeadbeef;
8030     lstrcpyA(targetsid, "kiwi");
8031     size = MAX_PATH;
8032     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8033                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
8034                            &context, targetsid, &size);
8035     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8036     ok(!lstrcmpA(targetprod, prodcode),
8037        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8038     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8039        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8040     ok(!lstrcmpA(targetsid, expectedsid),
8041        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8042     ok(size == lstrlenA(expectedsid),
8043        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8044
8045     /* szTargetProductCode is NULL */
8046     lstrcpyA(patchcode, "apple");
8047     context = 0xdeadbeef;
8048     lstrcpyA(targetsid, "kiwi");
8049     size = MAX_PATH;
8050     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8051                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
8052                            &context, targetsid, &size);
8053     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8054     ok(!lstrcmpA(patchcode, patch),
8055        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8056     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8057        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8058     ok(!lstrcmpA(targetsid, expectedsid),
8059        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8060     ok(size == lstrlenA(expectedsid),
8061        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8062
8063     /* pdwTargetProductContext is NULL */
8064     lstrcpyA(patchcode, "apple");
8065     lstrcpyA(targetprod, "banana");
8066     lstrcpyA(targetsid, "kiwi");
8067     size = MAX_PATH;
8068     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8069                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8070                            NULL, targetsid, &size);
8071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8072     ok(!lstrcmpA(patchcode, patch),
8073        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8074     ok(!lstrcmpA(targetprod, prodcode),
8075        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8076     ok(!lstrcmpA(targetsid, expectedsid),
8077        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8078     ok(size == lstrlenA(expectedsid),
8079        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8080
8081     /* szTargetUserSid is NULL */
8082     lstrcpyA(patchcode, "apple");
8083     lstrcpyA(targetprod, "banana");
8084     context = 0xdeadbeef;
8085     size = MAX_PATH;
8086     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8087                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8088                            &context, NULL, &size);
8089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8090     ok(!lstrcmpA(patchcode, patch),
8091        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8092     ok(!lstrcmpA(targetprod, prodcode),
8093        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8094     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8095        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8096     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8097        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8098
8099     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
8100     lstrcpyA(patchcode, "apple");
8101     lstrcpyA(targetprod, "banana");
8102     context = 0xdeadbeef;
8103     lstrcpyA(targetsid, "kiwi");
8104     size = lstrlenA(expectedsid);
8105     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8106                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8107                            &context, targetsid, &size);
8108     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
8109     ok(!lstrcmpA(patchcode, patch),
8110        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8111     ok(!lstrcmpA(targetprod, prodcode),
8112        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8113     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8114        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8115     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
8116        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8117     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
8118        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
8119
8120     /* pcchTargetUserSid has enough room for NULL terminator */
8121     lstrcpyA(patchcode, "apple");
8122     lstrcpyA(targetprod, "banana");
8123     context = 0xdeadbeef;
8124     lstrcpyA(targetsid, "kiwi");
8125     size = lstrlenA(expectedsid) + 1;
8126     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8127                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8128                            &context, targetsid, &size);
8129     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8130     ok(!lstrcmpA(patchcode, patch),
8131        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8132     ok(!lstrcmpA(targetprod, prodcode),
8133        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8134     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8135        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8136     ok(!lstrcmpA(targetsid, expectedsid),
8137        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8138     ok(size == lstrlenA(expectedsid),
8139        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8140
8141     /* both szTargetuserSid and pcchTargetUserSid are NULL */
8142     lstrcpyA(patchcode, "apple");
8143     lstrcpyA(targetprod, "banana");
8144     context = 0xdeadbeef;
8145     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8146                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8147                            &context, NULL, NULL);
8148     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8149     ok(!lstrcmpA(patchcode, patch),
8150        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8151     ok(!lstrcmpA(targetprod, prodcode),
8152        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8153     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8154        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8155
8156     /* MSIPATCHSTATE_SUPERSEDED */
8157
8158     lstrcpyA(patchcode, "apple");
8159     lstrcpyA(targetprod, "banana");
8160     context = 0xdeadbeef;
8161     lstrcpyA(targetsid, "kiwi");
8162     size = MAX_PATH;
8163     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8164                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8165                            &context, targetsid, &size);
8166     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8167     ok(!lstrcmpA(patchcode, "apple"),
8168        "Expected patchcode to be unchanged, got %s\n", patchcode);
8169     ok(!lstrcmpA(targetprod, "banana"),
8170        "Expected targetprod to be unchanged, got %s\n", targetprod);
8171     ok(context == 0xdeadbeef,
8172        "Expected context to be unchanged, got %d\n", context);
8173     ok(!lstrcmpA(targetsid, "kiwi"),
8174        "Expected targetsid to be unchanged, got %s\n", targetsid);
8175     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8176
8177     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8178     lstrcatA(keypath, expectedsid);
8179     lstrcatA(keypath, "\\Products\\");
8180     lstrcatA(keypath, prod_squashed);
8181
8182     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8183     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8184
8185     /* UserData product key exists */
8186     lstrcpyA(patchcode, "apple");
8187     lstrcpyA(targetprod, "banana");
8188     context = 0xdeadbeef;
8189     lstrcpyA(targetsid, "kiwi");
8190     size = MAX_PATH;
8191     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8192                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8193                            &context, targetsid, &size);
8194     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8195     ok(!lstrcmpA(patchcode, "apple"),
8196        "Expected patchcode to be unchanged, got %s\n", patchcode);
8197     ok(!lstrcmpA(targetprod, "banana"),
8198        "Expected targetprod to be unchanged, got %s\n", targetprod);
8199     ok(context == 0xdeadbeef,
8200        "Expected context to be unchanged, got %d\n", context);
8201     ok(!lstrcmpA(targetsid, "kiwi"),
8202        "Expected targetsid to be unchanged, got %s\n", targetsid);
8203     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8204
8205     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8206     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8207
8208     /* UserData patches key exists */
8209     lstrcpyA(patchcode, "apple");
8210     lstrcpyA(targetprod, "banana");
8211     context = 0xdeadbeef;
8212     lstrcpyA(targetsid, "kiwi");
8213     size = MAX_PATH;
8214     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8215                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8216                            &context, targetsid, &size);
8217     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8218     ok(!lstrcmpA(patchcode, "apple"),
8219        "Expected patchcode to be unchanged, got %s\n", patchcode);
8220     ok(!lstrcmpA(targetprod, "banana"),
8221        "Expected targetprod to be unchanged, got %s\n", targetprod);
8222     ok(context == 0xdeadbeef,
8223        "Expected context to be unchanged, got %d\n", context);
8224     ok(!lstrcmpA(targetsid, "kiwi"),
8225        "Expected targetsid to be unchanged, got %s\n", targetsid);
8226     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8227
8228     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8229     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8230
8231     /* specific UserData patch key exists */
8232     lstrcpyA(patchcode, "apple");
8233     lstrcpyA(targetprod, "banana");
8234     context = 0xdeadbeef;
8235     lstrcpyA(targetsid, "kiwi");
8236     size = MAX_PATH;
8237     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8238                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8239                            &context, targetsid, &size);
8240     ok(r == ERROR_BAD_CONFIGURATION,
8241        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8242     ok(!lstrcmpA(patchcode, "apple"),
8243        "Expected patchcode to be unchanged, got %s\n", patchcode);
8244     ok(!lstrcmpA(targetprod, "banana"),
8245        "Expected targetprod to be unchanged, got %s\n", targetprod);
8246     ok(context == 0xdeadbeef,
8247        "Expected context to be unchanged, got %d\n", context);
8248     ok(!lstrcmpA(targetsid, "kiwi"),
8249        "Expected targetsid to be unchanged, got %s\n", targetsid);
8250     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8251
8252     data = MSIPATCHSTATE_SUPERSEDED;
8253     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8254                          (const BYTE *)&data, sizeof(DWORD));
8255     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8256
8257     /* State value exists */
8258     lstrcpyA(patchcode, "apple");
8259     lstrcpyA(targetprod, "banana");
8260     context = 0xdeadbeef;
8261     lstrcpyA(targetsid, "kiwi");
8262     size = MAX_PATH;
8263     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8264                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8265                            &context, targetsid, &size);
8266     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8267     ok(!lstrcmpA(patchcode, patch),
8268        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8269     ok(!lstrcmpA(targetprod, prodcode),
8270        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8271     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8272        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8273     ok(!lstrcmpA(targetsid, expectedsid),
8274        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8275     ok(size == lstrlenA(expectedsid),
8276        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8277
8278     /* MSIPATCHSTATE_OBSOLETED */
8279
8280     lstrcpyA(patchcode, "apple");
8281     lstrcpyA(targetprod, "banana");
8282     context = 0xdeadbeef;
8283     lstrcpyA(targetsid, "kiwi");
8284     size = MAX_PATH;
8285     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8286                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8287                            &context, targetsid, &size);
8288     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8289     ok(!lstrcmpA(patchcode, "apple"),
8290        "Expected patchcode to be unchanged, got %s\n", patchcode);
8291     ok(!lstrcmpA(targetprod, "banana"),
8292        "Expected targetprod to be unchanged, got %s\n", targetprod);
8293     ok(context == 0xdeadbeef,
8294        "Expected context to be unchanged, got %d\n", context);
8295     ok(!lstrcmpA(targetsid, "kiwi"),
8296        "Expected targetsid to be unchanged, got %s\n", targetsid);
8297     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8298
8299     data = MSIPATCHSTATE_OBSOLETED;
8300     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8301                          (const BYTE *)&data, sizeof(DWORD));
8302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8303
8304     /* State value is obsoleted */
8305     lstrcpyA(patchcode, "apple");
8306     lstrcpyA(targetprod, "banana");
8307     context = 0xdeadbeef;
8308     lstrcpyA(targetsid, "kiwi");
8309     size = MAX_PATH;
8310     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8311                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8312                            &context, targetsid, &size);
8313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8314     ok(!lstrcmpA(patchcode, patch),
8315        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8316     ok(!lstrcmpA(targetprod, prodcode),
8317        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8318     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8319        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8320     ok(!lstrcmpA(targetsid, expectedsid),
8321        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8322     ok(size == lstrlenA(expectedsid),
8323        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8324
8325     /* MSIPATCHSTATE_REGISTERED */
8326     /* FIXME */
8327
8328     /* MSIPATCHSTATE_ALL */
8329
8330     /* 1st */
8331     lstrcpyA(patchcode, "apple");
8332     lstrcpyA(targetprod, "banana");
8333     context = 0xdeadbeef;
8334     lstrcpyA(targetsid, "kiwi");
8335     size = MAX_PATH;
8336     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8337                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8338                            &context, targetsid, &size);
8339     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8340     ok(!lstrcmpA(patchcode, patch),
8341        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8342     ok(!lstrcmpA(targetprod, prodcode),
8343        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8344     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8345        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8346     ok(!lstrcmpA(targetsid, expectedsid),
8347        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8348     ok(size == lstrlenA(expectedsid),
8349        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8350
8351     /* same patch in multiple places, only one is enumerated */
8352     lstrcpyA(patchcode, "apple");
8353     lstrcpyA(targetprod, "banana");
8354     context = 0xdeadbeef;
8355     lstrcpyA(targetsid, "kiwi");
8356     size = MAX_PATH;
8357     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8358                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8359                            &context, targetsid, &size);
8360     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8361     ok(!lstrcmpA(patchcode, "apple"),
8362        "Expected patchcode to be unchanged, got %s\n", patchcode);
8363     ok(!lstrcmpA(targetprod, "banana"),
8364        "Expected targetprod to be unchanged, got %s\n", targetprod);
8365     ok(context == 0xdeadbeef,
8366        "Expected context to be unchanged, got %d\n", context);
8367     ok(!lstrcmpA(targetsid, "kiwi"),
8368        "Expected targetsid to be unchanged, got %s\n", targetsid);
8369     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8370
8371     RegDeleteValueA(hpatch, "State");
8372     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8373     RegCloseKey(hpatch);
8374     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8375     RegCloseKey(udpatch);
8376     delete_key(udprod, "", access & KEY_WOW64_64KEY);
8377     RegCloseKey(udprod);
8378     RegDeleteValueA(patches, "Patches");
8379     delete_key(patches, "", access & KEY_WOW64_64KEY);
8380     RegCloseKey(patches);
8381     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
8382     RegCloseKey(prodkey);
8383 }
8384
8385 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8386 {
8387     MSIINSTALLCONTEXT context;
8388     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8389     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8390     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8391     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8392     HKEY prodkey, patches, udprod, udpatch;
8393     HKEY userkey, hpatch;
8394     DWORD size, data;
8395     LONG res;
8396     UINT r;
8397     REGSAM access = KEY_ALL_ACCESS;
8398
8399     create_test_guid(prodcode, prod_squashed);
8400     create_test_guid(patch, patch_squashed);
8401
8402     if (is_wow64)
8403         access |= KEY_WOW64_64KEY;
8404
8405     /* MSIPATCHSTATE_APPLIED */
8406
8407     lstrcpyA(patchcode, "apple");
8408     lstrcpyA(targetprod, "banana");
8409     context = 0xdeadbeef;
8410     lstrcpyA(targetsid, "kiwi");
8411     size = MAX_PATH;
8412     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8413                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8414                            &context, targetsid, &size);
8415     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8416     ok(!lstrcmpA(patchcode, "apple"),
8417        "Expected patchcode to be unchanged, got %s\n", patchcode);
8418     ok(!lstrcmpA(targetprod, "banana"),
8419        "Expected targetprod to be unchanged, got %s\n", targetprod);
8420     ok(context == 0xdeadbeef,
8421        "Expected context to be unchanged, got %d\n", context);
8422     ok(!lstrcmpA(targetsid, "kiwi"),
8423        "Expected targetsid to be unchanged, got %s\n", targetsid);
8424     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8425
8426     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8427     lstrcatA(keypath, prod_squashed);
8428
8429     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8431
8432     /* current user product key exists */
8433     lstrcpyA(patchcode, "apple");
8434     lstrcpyA(targetprod, "banana");
8435     context = 0xdeadbeef;
8436     lstrcpyA(targetsid, "kiwi");
8437     size = MAX_PATH;
8438     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8439                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8440                            &context, targetsid, &size);
8441     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8442     ok(!lstrcmpA(patchcode, "apple"),
8443        "Expected patchcode to be unchanged, got %s\n", patchcode);
8444     ok(!lstrcmpA(targetprod, "banana"),
8445        "Expected targetprod to be unchanged, got %s\n", targetprod);
8446     ok(context == 0xdeadbeef,
8447        "Expected context to be unchanged, got %d\n", context);
8448     ok(!lstrcmpA(targetsid, "kiwi"),
8449        "Expected targetsid to be unchanged, got %s\n", targetsid);
8450     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8451
8452     res = RegCreateKeyA(prodkey, "Patches", &patches);
8453     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8454
8455     /* Patches key exists */
8456     lstrcpyA(patchcode, "apple");
8457     lstrcpyA(targetprod, "banana");
8458     context = 0xdeadbeef;
8459     lstrcpyA(targetsid, "kiwi");
8460     size = MAX_PATH;
8461     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8462                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8463                            &context, targetsid, &size);
8464     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8465     ok(!lstrcmpA(patchcode, "apple"),
8466        "Expected patchcode to be unchanged, got %s\n", patchcode);
8467     ok(!lstrcmpA(targetprod, "banana"),
8468        "Expected targetprod to be unchanged, got %s\n", targetprod);
8469     ok(context == 0xdeadbeef,
8470        "Expected context to be unchanged, got %d\n", context);
8471     ok(!lstrcmpA(targetsid, "kiwi"),
8472        "Expected targetsid to be unchanged, got %s\n", targetsid);
8473     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8474
8475     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8476                          (const BYTE *)patch_squashed,
8477                          lstrlenA(patch_squashed) + 1);
8478     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8479
8480     /* Patches value exists, is not REG_MULTI_SZ */
8481     lstrcpyA(patchcode, "apple");
8482     lstrcpyA(targetprod, "banana");
8483     context = 0xdeadbeef;
8484     lstrcpyA(targetsid, "kiwi");
8485     size = MAX_PATH;
8486     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8487                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8488                            &context, targetsid, &size);
8489     ok(r == ERROR_BAD_CONFIGURATION,
8490        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8491     ok(!lstrcmpA(patchcode, "apple"),
8492        "Expected patchcode to be unchanged, got %s\n", patchcode);
8493     ok(!lstrcmpA(targetprod, "banana"),
8494        "Expected targetprod to be unchanged, got %s\n", targetprod);
8495     ok(context == 0xdeadbeef,
8496        "Expected context to be unchanged, got %d\n", context);
8497     ok(!lstrcmpA(targetsid, "kiwi"),
8498        "Expected targetsid to be unchanged, got %s\n", targetsid);
8499     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8500
8501     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8502                          (const BYTE *)"a\0b\0c\0\0", 7);
8503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8504
8505     /* Patches value exists, is not a squashed guid */
8506     lstrcpyA(patchcode, "apple");
8507     lstrcpyA(targetprod, "banana");
8508     context = 0xdeadbeef;
8509     lstrcpyA(targetsid, "kiwi");
8510     size = MAX_PATH;
8511     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8512                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8513                            &context, targetsid, &size);
8514     ok(r == ERROR_BAD_CONFIGURATION,
8515        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8516     ok(!lstrcmpA(patchcode, "apple"),
8517        "Expected patchcode to be unchanged, got %s\n", patchcode);
8518     ok(!lstrcmpA(targetprod, "banana"),
8519        "Expected targetprod to be unchanged, got %s\n", targetprod);
8520     ok(context == 0xdeadbeef,
8521        "Expected context to be unchanged, got %d\n", context);
8522     ok(!lstrcmpA(targetsid, "kiwi"),
8523        "Expected targetsid to be unchanged, got %s\n", targetsid);
8524     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8525
8526     patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
8527     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8528                          (const BYTE *)patch_squashed,
8529                          lstrlenA(patch_squashed) + 2);
8530     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8531
8532     /* Patches value exists */
8533     lstrcpyA(patchcode, "apple");
8534     lstrcpyA(targetprod, "banana");
8535     context = 0xdeadbeef;
8536     lstrcpyA(targetsid, "kiwi");
8537     size = MAX_PATH;
8538     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8539                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8540                            &context, targetsid, &size);
8541     ok(r == ERROR_NO_MORE_ITEMS ||
8542        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8543        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8544     ok(!lstrcmpA(patchcode, "apple"),
8545        "Expected patchcode to be unchanged, got %s\n", patchcode);
8546     ok(!lstrcmpA(targetprod, "banana"),
8547        "Expected targetprod to be unchanged, got %s\n", targetprod);
8548     ok(context == 0xdeadbeef,
8549        "Expected context to be unchanged, got %d\n", context);
8550     ok(!lstrcmpA(targetsid, "kiwi"),
8551        "Expected targetsid to be unchanged, got %s\n", targetsid);
8552     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8553
8554     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8555                          (const BYTE *)"whatever", 9);
8556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8557
8558     /* patch code value exists */
8559     lstrcpyA(patchcode, "apple");
8560     lstrcpyA(targetprod, "banana");
8561     context = 0xdeadbeef;
8562     lstrcpyA(targetsid, "kiwi");
8563     size = MAX_PATH;
8564     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8565                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8566                            &context, targetsid, &size);
8567     ok(r == ERROR_NO_MORE_ITEMS ||
8568        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8569        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8570     ok(!lstrcmpA(patchcode, "apple"),
8571        "Expected patchcode to be unchanged, got %s\n", patchcode);
8572     ok(!lstrcmpA(targetprod, "banana"),
8573        "Expected targetprod to be unchanged, got %s\n", targetprod);
8574     ok(context == 0xdeadbeef,
8575        "Expected context to be unchanged, got %d\n", context);
8576     ok(!lstrcmpA(targetsid, "kiwi"),
8577        "Expected targetsid to be unchanged, got %s\n", targetsid);
8578     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8579
8580     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8581     lstrcatA(keypath, expectedsid);
8582     lstrcatA(keypath, "\\Patches\\");
8583     lstrcatA(keypath, patch_squashed);
8584
8585     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
8586     if (res == ERROR_ACCESS_DENIED)
8587     {
8588         skip("Not enough rights to perform tests\n");
8589         goto error;
8590     }
8591     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8592
8593     /* userdata patch key exists */
8594     lstrcpyA(patchcode, "apple");
8595     lstrcpyA(targetprod, "banana");
8596     context = 0xdeadbeef;
8597     lstrcpyA(targetsid, "kiwi");
8598     size = MAX_PATH;
8599     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8600                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8601                            &context, targetsid, &size);
8602     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8603     ok(!lstrcmpA(patchcode, patch),
8604        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8605     ok(!lstrcmpA(targetprod, prodcode),
8606        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8607     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8608        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8609     ok(!lstrcmpA(targetsid, expectedsid),
8610        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8611     ok(size == lstrlenA(expectedsid),
8612        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8613
8614     /* MSIPATCHSTATE_SUPERSEDED */
8615
8616     lstrcpyA(patchcode, "apple");
8617     lstrcpyA(targetprod, "banana");
8618     context = 0xdeadbeef;
8619     lstrcpyA(targetsid, "kiwi");
8620     size = MAX_PATH;
8621     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8622                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8623                            &context, targetsid, &size);
8624     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8625     ok(!lstrcmpA(patchcode, "apple"),
8626        "Expected patchcode to be unchanged, got %s\n", patchcode);
8627     ok(!lstrcmpA(targetprod, "banana"),
8628        "Expected targetprod to be unchanged, got %s\n", targetprod);
8629     ok(context == 0xdeadbeef,
8630        "Expected context to be unchanged, got %d\n", context);
8631     ok(!lstrcmpA(targetsid, "kiwi"),
8632        "Expected targetsid to be unchanged, got %s\n", targetsid);
8633     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8634
8635     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8636     lstrcatA(keypath, expectedsid);
8637     lstrcatA(keypath, "\\Products\\");
8638     lstrcatA(keypath, prod_squashed);
8639
8640     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
8641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8642
8643     /* UserData product key exists */
8644     lstrcpyA(patchcode, "apple");
8645     lstrcpyA(targetprod, "banana");
8646     context = 0xdeadbeef;
8647     lstrcpyA(targetsid, "kiwi");
8648     size = MAX_PATH;
8649     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8650                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8651                            &context, targetsid, &size);
8652     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8653     ok(!lstrcmpA(patchcode, "apple"),
8654        "Expected patchcode to be unchanged, got %s\n", patchcode);
8655     ok(!lstrcmpA(targetprod, "banana"),
8656        "Expected targetprod to be unchanged, got %s\n", targetprod);
8657     ok(context == 0xdeadbeef,
8658        "Expected context to be unchanged, got %d\n", context);
8659     ok(!lstrcmpA(targetsid, "kiwi"),
8660        "Expected targetsid to be unchanged, got %s\n", targetsid);
8661     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8662
8663     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
8664     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8665
8666     /* UserData patches key exists */
8667     lstrcpyA(patchcode, "apple");
8668     lstrcpyA(targetprod, "banana");
8669     context = 0xdeadbeef;
8670     lstrcpyA(targetsid, "kiwi");
8671     size = MAX_PATH;
8672     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8673                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8674                            &context, targetsid, &size);
8675     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8676     ok(!lstrcmpA(patchcode, "apple"),
8677        "Expected patchcode to be unchanged, got %s\n", patchcode);
8678     ok(!lstrcmpA(targetprod, "banana"),
8679        "Expected targetprod to be unchanged, got %s\n", targetprod);
8680     ok(context == 0xdeadbeef,
8681        "Expected context to be unchanged, got %d\n", context);
8682     ok(!lstrcmpA(targetsid, "kiwi"),
8683        "Expected targetsid to be unchanged, got %s\n", targetsid);
8684     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8685
8686     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
8687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8688
8689     /* specific UserData patch key exists */
8690     lstrcpyA(patchcode, "apple");
8691     lstrcpyA(targetprod, "banana");
8692     context = 0xdeadbeef;
8693     lstrcpyA(targetsid, "kiwi");
8694     size = MAX_PATH;
8695     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8696                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8697                            &context, targetsid, &size);
8698     ok(r == ERROR_BAD_CONFIGURATION,
8699        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8700     ok(!lstrcmpA(patchcode, "apple"),
8701        "Expected patchcode to be unchanged, got %s\n", patchcode);
8702     ok(!lstrcmpA(targetprod, "banana"),
8703        "Expected targetprod to be unchanged, got %s\n", targetprod);
8704     ok(context == 0xdeadbeef,
8705        "Expected context to be unchanged, got %d\n", context);
8706     ok(!lstrcmpA(targetsid, "kiwi"),
8707        "Expected targetsid to be unchanged, got %s\n", targetsid);
8708     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8709
8710     data = MSIPATCHSTATE_SUPERSEDED;
8711     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8712                          (const BYTE *)&data, sizeof(DWORD));
8713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8714
8715     /* State value exists */
8716     lstrcpyA(patchcode, "apple");
8717     lstrcpyA(targetprod, "banana");
8718     context = 0xdeadbeef;
8719     lstrcpyA(targetsid, "kiwi");
8720     size = MAX_PATH;
8721     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8722                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8723                            &context, targetsid, &size);
8724     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8725     ok(!lstrcmpA(patchcode, patch),
8726        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8727     ok(!lstrcmpA(targetprod, prodcode),
8728        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8729     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8730        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8731     ok(!lstrcmpA(targetsid, expectedsid),
8732        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8733     ok(size == lstrlenA(expectedsid),
8734        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8735
8736     /* MSIPATCHSTATE_OBSOLETED */
8737
8738     lstrcpyA(patchcode, "apple");
8739     lstrcpyA(targetprod, "banana");
8740     context = 0xdeadbeef;
8741     lstrcpyA(targetsid, "kiwi");
8742     size = MAX_PATH;
8743     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8744                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8745                            &context, targetsid, &size);
8746     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8747     ok(!lstrcmpA(patchcode, "apple"),
8748        "Expected patchcode to be unchanged, got %s\n", patchcode);
8749     ok(!lstrcmpA(targetprod, "banana"),
8750        "Expected targetprod to be unchanged, got %s\n", targetprod);
8751     ok(context == 0xdeadbeef,
8752        "Expected context to be unchanged, got %d\n", context);
8753     ok(!lstrcmpA(targetsid, "kiwi"),
8754        "Expected targetsid to be unchanged, got %s\n", targetsid);
8755     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8756
8757     data = MSIPATCHSTATE_OBSOLETED;
8758     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8759                          (const BYTE *)&data, sizeof(DWORD));
8760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8761
8762     /* State value is obsoleted */
8763     lstrcpyA(patchcode, "apple");
8764     lstrcpyA(targetprod, "banana");
8765     context = 0xdeadbeef;
8766     lstrcpyA(targetsid, "kiwi");
8767     size = MAX_PATH;
8768     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8769                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8770                            &context, targetsid, &size);
8771     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8772     ok(!lstrcmpA(patchcode, patch),
8773        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8774     ok(!lstrcmpA(targetprod, prodcode),
8775        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8776     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8777        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8778     ok(!lstrcmpA(targetsid, expectedsid),
8779        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8780     ok(size == lstrlenA(expectedsid),
8781        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8782
8783     /* MSIPATCHSTATE_REGISTERED */
8784     /* FIXME */
8785
8786     /* MSIPATCHSTATE_ALL */
8787
8788     /* 1st */
8789     lstrcpyA(patchcode, "apple");
8790     lstrcpyA(targetprod, "banana");
8791     context = 0xdeadbeef;
8792     lstrcpyA(targetsid, "kiwi");
8793     size = MAX_PATH;
8794     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8795                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8796                            &context, targetsid, &size);
8797     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8798     ok(!lstrcmpA(patchcode, patch),
8799        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8800     ok(!lstrcmpA(targetprod, prodcode),
8801        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8802     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8803        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8804     ok(!lstrcmpA(targetsid, expectedsid),
8805        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8806     ok(size == lstrlenA(expectedsid),
8807        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8808
8809     /* same patch in multiple places, only one is enumerated */
8810     lstrcpyA(patchcode, "apple");
8811     lstrcpyA(targetprod, "banana");
8812     context = 0xdeadbeef;
8813     lstrcpyA(targetsid, "kiwi");
8814     size = MAX_PATH;
8815     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8816                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8817                            &context, targetsid, &size);
8818     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8819     ok(!lstrcmpA(patchcode, "apple"),
8820        "Expected patchcode to be unchanged, got %s\n", patchcode);
8821     ok(!lstrcmpA(targetprod, "banana"),
8822        "Expected targetprod to be unchanged, got %s\n", targetprod);
8823     ok(context == 0xdeadbeef,
8824        "Expected context to be unchanged, got %d\n", context);
8825     ok(!lstrcmpA(targetsid, "kiwi"),
8826        "Expected targetsid to be unchanged, got %s\n", targetsid);
8827     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8828
8829     RegDeleteValueA(hpatch, "State");
8830     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
8831     RegCloseKey(hpatch);
8832     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
8833     RegCloseKey(udpatch);
8834     delete_key(udprod, "", access & KEY_WOW64_64KEY);
8835     RegCloseKey(udprod);
8836     delete_key(userkey, "", access & KEY_WOW64_64KEY);
8837     RegCloseKey(userkey);
8838     RegDeleteValueA(patches, patch_squashed);
8839     RegDeleteValueA(patches, "Patches");
8840
8841 error:
8842     RegDeleteKeyA(patches, "");
8843     RegCloseKey(patches);
8844     RegDeleteKeyA(prodkey, "");
8845     RegCloseKey(prodkey);
8846 }
8847
8848 static void test_MsiEnumPatchesEx_machine(void)
8849 {
8850     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8851     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8852     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8853     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8854     HKEY prodkey, patches, udprod, udpatch;
8855     HKEY hpatch;
8856     MSIINSTALLCONTEXT context;
8857     DWORD size, data;
8858     LONG res;
8859     UINT r;
8860     REGSAM access = KEY_ALL_ACCESS;
8861
8862     create_test_guid(prodcode, prod_squashed);
8863     create_test_guid(patch, patch_squashed);
8864
8865     if (is_wow64)
8866         access |= KEY_WOW64_64KEY;
8867
8868     /* MSIPATCHSTATE_APPLIED */
8869
8870     lstrcpyA(patchcode, "apple");
8871     lstrcpyA(targetprod, "banana");
8872     context = 0xdeadbeef;
8873     lstrcpyA(targetsid, "kiwi");
8874     size = MAX_PATH;
8875     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8876                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8877                            &context, targetsid, &size);
8878     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8879     ok(!lstrcmpA(patchcode, "apple"),
8880        "Expected patchcode to be unchanged, got %s\n", patchcode);
8881     ok(!lstrcmpA(targetprod, "banana"),
8882        "Expected targetprod to be unchanged, got %s\n", targetprod);
8883     ok(context == 0xdeadbeef,
8884        "Expected context to be unchanged, got %d\n", context);
8885     ok(!lstrcmpA(targetsid, "kiwi"),
8886        "Expected targetsid to be unchanged, got %s\n", targetsid);
8887     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8888
8889     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8890     lstrcatA(keypath, prod_squashed);
8891
8892     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
8893     if (res == ERROR_ACCESS_DENIED)
8894     {
8895         skip("Not enough rights to perform tests\n");
8896         return;
8897     }
8898     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8899
8900     /* local product key exists */
8901     lstrcpyA(patchcode, "apple");
8902     lstrcpyA(targetprod, "banana");
8903     context = 0xdeadbeef;
8904     lstrcpyA(targetsid, "kiwi");
8905     size = MAX_PATH;
8906     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8907                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8908                            &context, targetsid, &size);
8909     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8910     ok(!lstrcmpA(patchcode, "apple"),
8911        "Expected patchcode to be unchanged, got %s\n", patchcode);
8912     ok(!lstrcmpA(targetprod, "banana"),
8913        "Expected targetprod to be unchanged, got %s\n", targetprod);
8914     ok(context == 0xdeadbeef,
8915        "Expected context to be unchanged, got %d\n", context);
8916     ok(!lstrcmpA(targetsid, "kiwi"),
8917        "Expected targetsid to be unchanged, got %s\n", targetsid);
8918     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8919
8920     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
8921     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8922
8923     /* Patches key exists */
8924     lstrcpyA(patchcode, "apple");
8925     lstrcpyA(targetprod, "banana");
8926     context = 0xdeadbeef;
8927     lstrcpyA(targetsid, "kiwi");
8928     size = MAX_PATH;
8929     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8930                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8931                            &context, targetsid, &size);
8932     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8933     ok(!lstrcmpA(patchcode, "apple"),
8934        "Expected patchcode to be unchanged, got %s\n", patchcode);
8935     ok(!lstrcmpA(targetprod, "banana"),
8936        "Expected targetprod to be unchanged, got %s\n", targetprod);
8937     ok(context == 0xdeadbeef,
8938        "Expected context to be unchanged, got %d\n", context);
8939     ok(!lstrcmpA(targetsid, "kiwi"),
8940        "Expected targetsid to be unchanged, got %s\n", targetsid);
8941     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8942
8943     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8944                          (const BYTE *)patch_squashed,
8945                          lstrlenA(patch_squashed) + 1);
8946     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8947
8948     /* Patches value exists, is not REG_MULTI_SZ */
8949     lstrcpyA(patchcode, "apple");
8950     lstrcpyA(targetprod, "banana");
8951     context = 0xdeadbeef;
8952     lstrcpyA(targetsid, "kiwi");
8953     size = MAX_PATH;
8954     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8955                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8956                            &context, targetsid, &size);
8957     ok(r == ERROR_BAD_CONFIGURATION,
8958        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8959     ok(!lstrcmpA(patchcode, "apple"),
8960        "Expected patchcode to be unchanged, got %s\n", patchcode);
8961     ok(!lstrcmpA(targetprod, "banana"),
8962        "Expected targetprod to be unchanged, got %s\n", targetprod);
8963     ok(context == 0xdeadbeef,
8964        "Expected context to be unchanged, got %d\n", context);
8965     ok(!lstrcmpA(targetsid, "kiwi"),
8966        "Expected targetsid to be unchanged, got %s\n", targetsid);
8967     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8968
8969     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8970                          (const BYTE *)"a\0b\0c\0\0", 7);
8971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8972
8973     /* Patches value exists, is not a squashed guid */
8974     lstrcpyA(patchcode, "apple");
8975     lstrcpyA(targetprod, "banana");
8976     context = 0xdeadbeef;
8977     lstrcpyA(targetsid, "kiwi");
8978     size = MAX_PATH;
8979     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8980                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8981                            &context, targetsid, &size);
8982     ok(r == ERROR_BAD_CONFIGURATION,
8983        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8984     ok(!lstrcmpA(patchcode, "apple"),
8985        "Expected patchcode to be unchanged, got %s\n", patchcode);
8986     ok(!lstrcmpA(targetprod, "banana"),
8987        "Expected targetprod to be unchanged, got %s\n", targetprod);
8988     ok(context == 0xdeadbeef,
8989        "Expected context to be unchanged, got %d\n", context);
8990     ok(!lstrcmpA(targetsid, "kiwi"),
8991        "Expected targetsid to be unchanged, got %s\n", targetsid);
8992     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8993
8994     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8995     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8996                          (const BYTE *)patch_squashed,
8997                          lstrlenA(patch_squashed) + 2);
8998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8999
9000     /* Patches value exists */
9001     lstrcpyA(patchcode, "apple");
9002     lstrcpyA(targetprod, "banana");
9003     context = 0xdeadbeef;
9004     lstrcpyA(targetsid, "kiwi");
9005     size = MAX_PATH;
9006     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9007                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9008                            &context, targetsid, &size);
9009     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9010     ok(!lstrcmpA(patchcode, "apple"),
9011        "Expected patchcode to be unchanged, got %s\n", patchcode);
9012     ok(!lstrcmpA(targetprod, "banana"),
9013        "Expected targetprod to be unchanged, got %s\n", targetprod);
9014     ok(context == 0xdeadbeef,
9015        "Expected context to be unchanged, got %d\n", context);
9016     ok(!lstrcmpA(targetsid, "kiwi"),
9017        "Expected targetsid to be unchanged, got %s\n", targetsid);
9018     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9019
9020     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9021                          (const BYTE *)"whatever", 9);
9022     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9023
9024     /* patch code value exists */
9025     lstrcpyA(patchcode, "apple");
9026     lstrcpyA(targetprod, "banana");
9027     context = 0xdeadbeef;
9028     lstrcpyA(targetsid, "kiwi");
9029     size = MAX_PATH;
9030     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9031                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9032                            &context, targetsid, &size);
9033     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9034     ok(!lstrcmpA(patchcode, patch),
9035        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9036     ok(!lstrcmpA(targetprod, prodcode),
9037        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9038     ok(context == MSIINSTALLCONTEXT_MACHINE,
9039        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9040     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9041     ok(size == 0, "Expected 0, got %d\n", size);
9042
9043     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9044     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9045     lstrcatA(keypath, prod_squashed);
9046
9047     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
9048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9049
9050     /* local UserData product key exists */
9051     lstrcpyA(patchcode, "apple");
9052     lstrcpyA(targetprod, "banana");
9053     context = 0xdeadbeef;
9054     lstrcpyA(targetsid, "kiwi");
9055     size = MAX_PATH;
9056     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9057                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9058                            &context, targetsid, &size);
9059     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9060     ok(!lstrcmpA(patchcode, patch),
9061        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9062     ok(!lstrcmpA(targetprod, prodcode),
9063        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9064     ok(context == MSIINSTALLCONTEXT_MACHINE,
9065        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9066     ok(!lstrcmpA(targetsid, ""),
9067        "Expected \"\", got \"%s\"\n", targetsid);
9068     ok(size == 0, "Expected 0, got %d\n", size);
9069
9070     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
9071     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9072
9073     /* local UserData Patches key exists */
9074     lstrcpyA(patchcode, "apple");
9075     lstrcpyA(targetprod, "banana");
9076     context = 0xdeadbeef;
9077     lstrcpyA(targetsid, "kiwi");
9078     size = MAX_PATH;
9079     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9080                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9081                            &context, targetsid, &size);
9082     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9083     ok(!lstrcmpA(patchcode, patch),
9084        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9085     ok(!lstrcmpA(targetprod, prodcode),
9086        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9087     ok(context == MSIINSTALLCONTEXT_MACHINE,
9088        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9089     ok(!lstrcmpA(targetsid, ""),
9090        "Expected \"\", got \"%s\"\n", targetsid);
9091     ok(size == 0, "Expected 0, got %d\n", size);
9092
9093     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
9094     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9095
9096     /* local UserData Product patch key exists */
9097     lstrcpyA(patchcode, "apple");
9098     lstrcpyA(targetprod, "banana");
9099     context = 0xdeadbeef;
9100     lstrcpyA(targetsid, "kiwi");
9101     size = MAX_PATH;
9102     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9103                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9104                            &context, targetsid, &size);
9105     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9106     ok(!lstrcmpA(patchcode, "apple"),
9107        "Expected patchcode to be unchanged, got %s\n", patchcode);
9108     ok(!lstrcmpA(targetprod, "banana"),
9109        "Expected targetprod to be unchanged, got %s\n", targetprod);
9110     ok(context == 0xdeadbeef,
9111        "Expected context to be unchanged, got %d\n", context);
9112     ok(!lstrcmpA(targetsid, "kiwi"),
9113        "Expected targetsid to be unchanged, got %s\n", targetsid);
9114     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9115
9116     data = MSIPATCHSTATE_APPLIED;
9117     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9118                          (const BYTE *)&data, sizeof(DWORD));
9119     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9120
9121     /* State value exists */
9122     lstrcpyA(patchcode, "apple");
9123     lstrcpyA(targetprod, "banana");
9124     context = 0xdeadbeef;
9125     lstrcpyA(targetsid, "kiwi");
9126     size = MAX_PATH;
9127     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9128                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
9129                            &context, targetsid, &size);
9130     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9131     ok(!lstrcmpA(patchcode, patch),
9132        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9133     ok(!lstrcmpA(targetprod, prodcode),
9134        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9135     ok(context == MSIINSTALLCONTEXT_MACHINE,
9136        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9137     ok(!lstrcmpA(targetsid, ""),
9138        "Expected \"\", got \"%s\"\n", targetsid);
9139     ok(size == 0, "Expected 0, got %d\n", size);
9140
9141     /* MSIPATCHSTATE_SUPERSEDED */
9142
9143     lstrcpyA(patchcode, "apple");
9144     lstrcpyA(targetprod, "banana");
9145     context = 0xdeadbeef;
9146     lstrcpyA(targetsid, "kiwi");
9147     size = MAX_PATH;
9148     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9149                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9150                            &context, targetsid, &size);
9151     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9152     ok(!lstrcmpA(patchcode, "apple"),
9153        "Expected patchcode to be unchanged, got %s\n", patchcode);
9154     ok(!lstrcmpA(targetprod, "banana"),
9155        "Expected targetprod to be unchanged, got %s\n", targetprod);
9156     ok(context == 0xdeadbeef,
9157        "Expected context to be unchanged, got %d\n", context);
9158     ok(!lstrcmpA(targetsid, "kiwi"),
9159        "Expected targetsid to be unchanged, got %s\n", targetsid);
9160     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9161
9162     data = MSIPATCHSTATE_SUPERSEDED;
9163     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9164                          (const BYTE *)&data, sizeof(DWORD));
9165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9166
9167     /* State value is MSIPATCHSTATE_SUPERSEDED */
9168     lstrcpyA(patchcode, "apple");
9169     lstrcpyA(targetprod, "banana");
9170     context = 0xdeadbeef;
9171     lstrcpyA(targetsid, "kiwi");
9172     size = MAX_PATH;
9173     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9174                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9175                            &context, targetsid, &size);
9176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9177     ok(!lstrcmpA(patchcode, patch),
9178        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9179     ok(!lstrcmpA(targetprod, prodcode),
9180        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9181     ok(context == MSIINSTALLCONTEXT_MACHINE,
9182        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9183     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9184     ok(size == 0, "Expected 0, got %d\n", size);
9185
9186     /* MSIPATCHSTATE_OBSOLETED */
9187
9188     lstrcpyA(patchcode, "apple");
9189     lstrcpyA(targetprod, "banana");
9190     context = 0xdeadbeef;
9191     lstrcpyA(targetsid, "kiwi");
9192     size = MAX_PATH;
9193     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9194                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9195                            &context, targetsid, &size);
9196     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9197     ok(!lstrcmpA(patchcode, "apple"),
9198        "Expected patchcode to be unchanged, got %s\n", patchcode);
9199     ok(!lstrcmpA(targetprod, "banana"),
9200        "Expected targetprod to be unchanged, got %s\n", targetprod);
9201     ok(context == 0xdeadbeef,
9202        "Expected context to be unchanged, got %d\n", context);
9203     ok(!lstrcmpA(targetsid, "kiwi"),
9204        "Expected targetsid to be unchanged, got %s\n", targetsid);
9205     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9206
9207     data = MSIPATCHSTATE_OBSOLETED;
9208     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9209                          (const BYTE *)&data, sizeof(DWORD));
9210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9211
9212     /* State value is obsoleted */
9213     lstrcpyA(patchcode, "apple");
9214     lstrcpyA(targetprod, "banana");
9215     context = 0xdeadbeef;
9216     lstrcpyA(targetsid, "kiwi");
9217     size = MAX_PATH;
9218     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9219                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9220                            &context, targetsid, &size);
9221     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9222     ok(!lstrcmpA(patchcode, patch),
9223        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9224     ok(!lstrcmpA(targetprod, prodcode),
9225        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9226     ok(context == MSIINSTALLCONTEXT_MACHINE,
9227        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9228     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9229     ok(size == 0, "Expected 0, got %d\n", size);
9230
9231     /* MSIPATCHSTATE_REGISTERED */
9232     /* FIXME */
9233
9234     /* MSIPATCHSTATE_ALL */
9235
9236     /* 1st */
9237     lstrcpyA(patchcode, "apple");
9238     lstrcpyA(targetprod, "banana");
9239     context = 0xdeadbeef;
9240     lstrcpyA(targetsid, "kiwi");
9241     size = MAX_PATH;
9242     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9243                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9244                            &context, targetsid, &size);
9245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9246     ok(!lstrcmpA(patchcode, patch),
9247        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9248     ok(!lstrcmpA(targetprod, prodcode),
9249        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9250     ok(context == MSIINSTALLCONTEXT_MACHINE,
9251        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9252     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9253     ok(size == 0, "Expected 0, got %d\n", size);
9254
9255     /* same patch in multiple places, only one is enumerated */
9256     lstrcpyA(patchcode, "apple");
9257     lstrcpyA(targetprod, "banana");
9258     context = 0xdeadbeef;
9259     lstrcpyA(targetsid, "kiwi");
9260     size = MAX_PATH;
9261     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9262                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9263                            &context, targetsid, &size);
9264     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9265     ok(!lstrcmpA(patchcode, "apple"),
9266        "Expected patchcode to be unchanged, got %s\n", patchcode);
9267     ok(!lstrcmpA(targetprod, "banana"),
9268        "Expected targetprod to be unchanged, got %s\n", targetprod);
9269     ok(context == 0xdeadbeef,
9270        "Expected context to be unchanged, got %d\n", context);
9271     ok(!lstrcmpA(targetsid, "kiwi"),
9272        "Expected targetsid to be unchanged, got %s\n", targetsid);
9273     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9274
9275     RegDeleteValueA(patches, patch_squashed);
9276     RegDeleteValueA(patches, "Patches");
9277     delete_key(patches, "", access & KEY_WOW64_64KEY);
9278     RegCloseKey(patches);
9279     RegDeleteValueA(hpatch, "State");
9280     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
9281     RegCloseKey(hpatch);
9282     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
9283     RegCloseKey(udpatch);
9284     delete_key(udprod, "", access & KEY_WOW64_64KEY);
9285     RegCloseKey(udprod);
9286     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9287     RegCloseKey(prodkey);
9288 }
9289
9290 static void test_MsiEnumPatchesEx(void)
9291 {
9292     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9293     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9294     CHAR patchcode[MAX_PATH];
9295     MSIINSTALLCONTEXT context;
9296     LPSTR usersid;
9297     DWORD size;
9298     UINT r;
9299
9300     if (!pMsiEnumPatchesExA)
9301     {
9302         win_skip("MsiEnumPatchesExA not implemented\n");
9303         return;
9304     }
9305
9306     create_test_guid(prodcode, prod_squashed);
9307     get_user_sid(&usersid);
9308
9309     /* empty szProductCode */
9310     lstrcpyA(patchcode, "apple");
9311     lstrcpyA(targetprod, "banana");
9312     context = 0xdeadbeef;
9313     lstrcpyA(targetsid, "kiwi");
9314     size = MAX_PATH;
9315     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9316                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9317                            targetsid, &size);
9318     ok(r == ERROR_INVALID_PARAMETER,
9319        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9320     ok(!lstrcmpA(patchcode, "apple"),
9321        "Expected patchcode to be unchanged, got %s\n", patchcode);
9322     ok(!lstrcmpA(targetprod, "banana"),
9323        "Expected targetprod to be unchanged, got %s\n", targetprod);
9324     ok(context == 0xdeadbeef,
9325        "Expected context to be unchanged, got %d\n", context);
9326     ok(!lstrcmpA(targetsid, "kiwi"),
9327        "Expected targetsid to be unchanged, got %s\n", targetsid);
9328     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9329
9330     /* garbage szProductCode */
9331     lstrcpyA(patchcode, "apple");
9332     lstrcpyA(targetprod, "banana");
9333     context = 0xdeadbeef;
9334     lstrcpyA(targetsid, "kiwi");
9335     size = MAX_PATH;
9336     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9337                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9338                            targetsid, &size);
9339     ok(r == ERROR_INVALID_PARAMETER,
9340        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9341     ok(!lstrcmpA(patchcode, "apple"),
9342        "Expected patchcode to be unchanged, got %s\n", patchcode);
9343     ok(!lstrcmpA(targetprod, "banana"),
9344        "Expected targetprod to be unchanged, got %s\n", targetprod);
9345     ok(context == 0xdeadbeef,
9346        "Expected context to be unchanged, got %d\n", context);
9347     ok(!lstrcmpA(targetsid, "kiwi"),
9348        "Expected targetsid to be unchanged, got %s\n", targetsid);
9349     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9350
9351     /* guid without brackets */
9352     lstrcpyA(patchcode, "apple");
9353     lstrcpyA(targetprod, "banana");
9354     context = 0xdeadbeef;
9355     lstrcpyA(targetsid, "kiwi");
9356     size = MAX_PATH;
9357     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9358                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9359                            0, patchcode, targetprod, &context,
9360                            targetsid, &size);
9361     ok(r == ERROR_INVALID_PARAMETER,
9362        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9363     ok(!lstrcmpA(patchcode, "apple"),
9364        "Expected patchcode to be unchanged, got %s\n", patchcode);
9365     ok(!lstrcmpA(targetprod, "banana"),
9366        "Expected targetprod to be unchanged, got %s\n", targetprod);
9367     ok(context == 0xdeadbeef,
9368        "Expected context to be unchanged, got %d\n", context);
9369     ok(!lstrcmpA(targetsid, "kiwi"),
9370        "Expected targetsid to be unchanged, got %s\n", targetsid);
9371     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9372
9373     /* guid with brackets */
9374     lstrcpyA(patchcode, "apple");
9375     lstrcpyA(targetprod, "banana");
9376     context = 0xdeadbeef;
9377     lstrcpyA(targetsid, "kiwi");
9378     size = MAX_PATH;
9379     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9380                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9381                            0, patchcode, targetprod, &context,
9382                            targetsid, &size);
9383     ok(r == ERROR_NO_MORE_ITEMS,
9384        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9385     ok(!lstrcmpA(patchcode, "apple"),
9386        "Expected patchcode to be unchanged, got %s\n", patchcode);
9387     ok(!lstrcmpA(targetprod, "banana"),
9388        "Expected targetprod to be unchanged, got %s\n", targetprod);
9389     ok(context == 0xdeadbeef,
9390        "Expected context to be unchanged, got %d\n", context);
9391     ok(!lstrcmpA(targetsid, "kiwi"),
9392        "Expected targetsid to be unchanged, got %s\n", targetsid);
9393     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9394
9395     /* szUserSid is S-1-5-18 */
9396     lstrcpyA(patchcode, "apple");
9397     lstrcpyA(targetprod, "banana");
9398     context = 0xdeadbeef;
9399     lstrcpyA(targetsid, "kiwi");
9400     size = MAX_PATH;
9401     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9402                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9403                            0, patchcode, targetprod, &context,
9404                            targetsid, &size);
9405     ok(r == ERROR_INVALID_PARAMETER,
9406        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9407     ok(!lstrcmpA(patchcode, "apple"),
9408        "Expected patchcode to be unchanged, got %s\n", patchcode);
9409     ok(!lstrcmpA(targetprod, "banana"),
9410        "Expected targetprod to be unchanged, got %s\n", targetprod);
9411     ok(context == 0xdeadbeef,
9412        "Expected context to be unchanged, got %d\n", context);
9413     ok(!lstrcmpA(targetsid, "kiwi"),
9414        "Expected targetsid to be unchanged, got %s\n", targetsid);
9415     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9416
9417     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9418     lstrcpyA(patchcode, "apple");
9419     lstrcpyA(targetprod, "banana");
9420     context = 0xdeadbeef;
9421     lstrcpyA(targetsid, "kiwi");
9422     size = MAX_PATH;
9423     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9424                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9425                            &context, targetsid, &size);
9426     ok(r == ERROR_INVALID_PARAMETER,
9427        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9428     ok(!lstrcmpA(patchcode, "apple"),
9429        "Expected patchcode to be unchanged, got %s\n", patchcode);
9430     ok(!lstrcmpA(targetprod, "banana"),
9431        "Expected targetprod to be unchanged, got %s\n", targetprod);
9432     ok(context == 0xdeadbeef,
9433        "Expected context to be unchanged, got %d\n", context);
9434     ok(!lstrcmpA(targetsid, "kiwi"),
9435        "Expected targetsid to be unchanged, got %s\n", targetsid);
9436     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9437
9438     /* dwContext is out of bounds */
9439     lstrcpyA(patchcode, "apple");
9440     lstrcpyA(targetprod, "banana");
9441     context = 0xdeadbeef;
9442     lstrcpyA(targetsid, "kiwi");
9443     size = MAX_PATH;
9444     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9445                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9446                            &context, targetsid, &size);
9447     ok(r == ERROR_INVALID_PARAMETER,
9448        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9449     ok(!lstrcmpA(patchcode, "apple"),
9450        "Expected patchcode to be unchanged, got %s\n", patchcode);
9451     ok(!lstrcmpA(targetprod, "banana"),
9452        "Expected targetprod to be unchanged, got %s\n", targetprod);
9453     ok(context == 0xdeadbeef,
9454        "Expected context to be unchanged, got %d\n", context);
9455     ok(!lstrcmpA(targetsid, "kiwi"),
9456        "Expected targetsid to be unchanged, got %s\n", targetsid);
9457     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9458
9459     /* dwContext is out of bounds */
9460     lstrcpyA(patchcode, "apple");
9461     lstrcpyA(targetprod, "banana");
9462     context = 0xdeadbeef;
9463     lstrcpyA(targetsid, "kiwi");
9464     size = MAX_PATH;
9465     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9466                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9467                            &context, targetsid, &size);
9468     ok(r == ERROR_INVALID_PARAMETER,
9469        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9470     ok(!lstrcmpA(patchcode, "apple"),
9471        "Expected patchcode to be unchanged, got %s\n", patchcode);
9472     ok(!lstrcmpA(targetprod, "banana"),
9473        "Expected targetprod to be unchanged, got %s\n", targetprod);
9474     ok(context == 0xdeadbeef,
9475        "Expected context to be unchanged, got %d\n", context);
9476     ok(!lstrcmpA(targetsid, "kiwi"),
9477        "Expected targetsid to be unchanged, got %s\n", targetsid);
9478     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9479
9480     /* dwFilter is out of bounds */
9481     lstrcpyA(patchcode, "apple");
9482     lstrcpyA(targetprod, "banana");
9483     context = 0xdeadbeef;
9484     lstrcpyA(targetsid, "kiwi");
9485     size = MAX_PATH;
9486     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9487                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9488                            &context, targetsid, &size);
9489     ok(r == ERROR_INVALID_PARAMETER,
9490        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9491     ok(!lstrcmpA(patchcode, "apple"),
9492        "Expected patchcode to be unchanged, got %s\n", patchcode);
9493     ok(!lstrcmpA(targetprod, "banana"),
9494        "Expected targetprod to be unchanged, got %s\n", targetprod);
9495     ok(context == 0xdeadbeef,
9496        "Expected context to be unchanged, got %d\n", context);
9497     ok(!lstrcmpA(targetsid, "kiwi"),
9498        "Expected targetsid to be unchanged, got %s\n", targetsid);
9499     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9500
9501     /* dwFilter is out of bounds */
9502     lstrcpyA(patchcode, "apple");
9503     lstrcpyA(targetprod, "banana");
9504     context = 0xdeadbeef;
9505     lstrcpyA(targetsid, "kiwi");
9506     size = MAX_PATH;
9507     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9508                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9509                            &context, targetsid, &size);
9510     ok(r == ERROR_INVALID_PARAMETER,
9511        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9512     ok(!lstrcmpA(patchcode, "apple"),
9513        "Expected patchcode to be unchanged, got %s\n", patchcode);
9514     ok(!lstrcmpA(targetprod, "banana"),
9515        "Expected targetprod to be unchanged, got %s\n", targetprod);
9516     ok(context == 0xdeadbeef,
9517        "Expected context to be unchanged, got %d\n", context);
9518     ok(!lstrcmpA(targetsid, "kiwi"),
9519        "Expected targetsid to be unchanged, got %s\n", targetsid);
9520     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9521
9522     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9523     lstrcpyA(patchcode, "apple");
9524     lstrcpyA(targetprod, "banana");
9525     context = 0xdeadbeef;
9526     lstrcpyA(targetsid, "kiwi");
9527     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9528                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9529                            &context, targetsid, NULL);
9530     ok(r == ERROR_INVALID_PARAMETER,
9531        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9532     ok(!lstrcmpA(patchcode, "apple"),
9533        "Expected patchcode to be unchanged, got %s\n", patchcode);
9534     ok(!lstrcmpA(targetprod, "banana"),
9535        "Expected targetprod to be unchanged, got %s\n", targetprod);
9536     ok(context == 0xdeadbeef,
9537        "Expected context to be unchanged, got %d\n", context);
9538     ok(!lstrcmpA(targetsid, "kiwi"),
9539        "Expected targetsid to be unchanged, got %s\n", targetsid);
9540
9541     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9542     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9543     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9544     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9545     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9546     /* FIXME: Successfully test userunmanaged with a different user */
9547     test_MsiEnumPatchesEx_machine();
9548     LocalFree(usersid);
9549 }
9550
9551 static void test_MsiEnumPatches(void)
9552 {
9553     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9554     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9555     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9556     CHAR transforms[MAX_PATH];
9557     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9558     HKEY prodkey, patches, udprod;
9559     HKEY userkey, hpatch, udpatch;
9560     DWORD size, data;
9561     LPSTR usersid;
9562     LONG res;
9563     UINT r;
9564     REGSAM access = KEY_ALL_ACCESS;
9565
9566     create_test_guid(prodcode, prod_squashed);
9567     create_test_guid(patchcode, patch_squashed);
9568     get_user_sid(&usersid);
9569
9570     if (is_wow64)
9571         access |= KEY_WOW64_64KEY;
9572
9573     /* NULL szProduct */
9574     size = MAX_PATH;
9575     lstrcpyA(patch, "apple");
9576     lstrcpyA(transforms, "banana");
9577     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9578     ok(r == ERROR_INVALID_PARAMETER,
9579        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9580     ok(!lstrcmpA(patch, "apple"),
9581        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9582     ok(!lstrcmpA(transforms, "banana"),
9583        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9584     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9585
9586     /* empty szProduct */
9587     size = MAX_PATH;
9588     lstrcpyA(patch, "apple");
9589     lstrcpyA(transforms, "banana");
9590     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9591     ok(r == ERROR_INVALID_PARAMETER,
9592        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9593     ok(!lstrcmpA(patch, "apple"),
9594        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9595     ok(!lstrcmpA(transforms, "banana"),
9596        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9597     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9598
9599     /* garbage szProduct */
9600     size = MAX_PATH;
9601     lstrcpyA(patch, "apple");
9602     lstrcpyA(transforms, "banana");
9603     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9604     ok(r == ERROR_INVALID_PARAMETER,
9605        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9606     ok(!lstrcmpA(patch, "apple"),
9607        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9608     ok(!lstrcmpA(transforms, "banana"),
9609        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9610     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9611
9612     /* guid without brackets */
9613     size = MAX_PATH;
9614     lstrcpyA(patch, "apple");
9615     lstrcpyA(transforms, "banana");
9616     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9617                         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 with 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_UNKNOWN_PRODUCT,
9633        "Expected ERROR_UNKNOWN_PRODUCT, 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     /* same length as guid, but random */
9641     size = MAX_PATH;
9642     lstrcpyA(patch, "apple");
9643     lstrcpyA(transforms, "banana");
9644     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9645                         transforms, &size);
9646     ok(r == ERROR_INVALID_PARAMETER,
9647        "Expected ERROR_INVALID_PARAMETER, 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     /* MSIINSTALLCONTEXT_USERMANAGED */
9655
9656     size = MAX_PATH;
9657     lstrcpyA(patch, "apple");
9658     lstrcpyA(transforms, "banana");
9659     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9660     ok(r == ERROR_UNKNOWN_PRODUCT,
9661        "Expected ERROR_UNKNOWN_PRODUCT, 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     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9669     lstrcatA(keypath, usersid);
9670     lstrcatA(keypath, "\\Installer\\Products\\");
9671     lstrcatA(keypath, prod_squashed);
9672
9673     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
9674     if (res == ERROR_ACCESS_DENIED)
9675     {
9676         skip("Not enough rights to perform tests\n");
9677         LocalFree(usersid);
9678         return;
9679     }
9680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9681
9682     /* managed product key exists */
9683     size = MAX_PATH;
9684     lstrcpyA(patch, "apple");
9685     lstrcpyA(transforms, "banana");
9686     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9687     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9688     ok(!lstrcmpA(patch, "apple"),
9689        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9690     ok(!lstrcmpA(transforms, "banana"),
9691        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9692     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9693
9694     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
9695     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9696
9697     /* patches key exists */
9698     size = MAX_PATH;
9699     lstrcpyA(patch, "apple");
9700     lstrcpyA(transforms, "banana");
9701     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9702     ok(r == ERROR_NO_MORE_ITEMS ||
9703        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9704        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9705     ok(!lstrcmpA(patch, "apple"),
9706        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9707     ok(!lstrcmpA(transforms, "banana"),
9708        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9709     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9710
9711     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9712                          (const BYTE *)patch_squashed,
9713                          lstrlenA(patch_squashed) + 1);
9714     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9715
9716     /* Patches value exists, is not REG_MULTI_SZ */
9717     size = MAX_PATH;
9718     lstrcpyA(patch, "apple");
9719     lstrcpyA(transforms, "banana");
9720     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9721     ok(r == ERROR_BAD_CONFIGURATION ||
9722        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9723        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9724     ok(!lstrcmpA(patch, "apple"),
9725        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9726     ok(!lstrcmpA(transforms, "banana"),
9727        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9728     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9729
9730     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9731                          (const BYTE *)"a\0b\0c\0\0", 7);
9732     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9733
9734     /* Patches value exists, is not a squashed guid */
9735     size = MAX_PATH;
9736     lstrcpyA(patch, "apple");
9737     lstrcpyA(transforms, "banana");
9738     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9739     ok(r == ERROR_BAD_CONFIGURATION,
9740        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9741     ok(!lstrcmpA(patch, "apple"),
9742        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9743     ok(!lstrcmpA(transforms, "banana"),
9744        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9745     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9746
9747     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9748     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9749                          (const BYTE *)patch_squashed,
9750                          lstrlenA(patch_squashed) + 2);
9751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9752
9753     /* Patches value exists */
9754     size = MAX_PATH;
9755     lstrcpyA(patch, "apple");
9756     lstrcpyA(transforms, "banana");
9757     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9758     ok(r == ERROR_NO_MORE_ITEMS ||
9759        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9760        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9761     ok(!lstrcmpA(patch, "apple") ||
9762        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9763        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9764     ok(!lstrcmpA(transforms, "banana"),
9765        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9766     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9767
9768     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9769                          (const BYTE *)"whatever", 9);
9770     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9771
9772     /* patch squashed value exists */
9773     size = MAX_PATH;
9774     lstrcpyA(patch, "apple");
9775     lstrcpyA(transforms, "banana");
9776     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9778     ok(!lstrcmpA(patch, patchcode),
9779        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9780     ok(!lstrcmpA(transforms, "whatever"),
9781        "Expected \"whatever\", got \"%s\"\n", transforms);
9782     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9783
9784     /* lpPatchBuf is NULL */
9785     size = MAX_PATH;
9786     lstrcpyA(transforms, "banana");
9787     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9788     ok(r == ERROR_INVALID_PARAMETER,
9789        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9790     ok(!lstrcmpA(transforms, "banana"),
9791        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9792     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9793
9794     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9795     size = MAX_PATH;
9796     lstrcpyA(patch, "apple");
9797     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9798     ok(r == ERROR_INVALID_PARAMETER,
9799        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9800     ok(!lstrcmpA(patch, "apple"),
9801        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9802     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9803
9804     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9805     lstrcpyA(patch, "apple");
9806     lstrcpyA(transforms, "banana");
9807     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9808     ok(r == ERROR_INVALID_PARAMETER,
9809        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9810     ok(!lstrcmpA(patch, "apple"),
9811        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9812     ok(!lstrcmpA(transforms, "banana"),
9813        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9814
9815     /* pcchTransformsBuf is too small */
9816     size = 6;
9817     lstrcpyA(patch, "apple");
9818     lstrcpyA(transforms, "banana");
9819     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9820     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9821     ok(!lstrcmpA(patch, patchcode),
9822        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9823     ok(!lstrcmpA(transforms, "whate") ||
9824        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
9825        "Expected \"whate\", got \"%s\"\n", transforms);
9826     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
9827
9828     /* increase the index */
9829     size = MAX_PATH;
9830     lstrcpyA(patch, "apple");
9831     lstrcpyA(transforms, "banana");
9832     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9833     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9834     ok(!lstrcmpA(patch, "apple"),
9835        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9836     ok(!lstrcmpA(transforms, "banana"),
9837        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9838     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9839
9840     /* increase again */
9841     size = MAX_PATH;
9842     lstrcpyA(patch, "apple");
9843     lstrcpyA(transforms, "banana");
9844     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9845     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9846     ok(!lstrcmpA(patch, "apple"),
9847        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9848     ok(!lstrcmpA(transforms, "banana"),
9849        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9850     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9851
9852     RegDeleteValueA(patches, "Patches");
9853     delete_key(patches, "", access & KEY_WOW64_64KEY);
9854     RegCloseKey(patches);
9855     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
9856     RegCloseKey(prodkey);
9857
9858     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9859
9860     size = MAX_PATH;
9861     lstrcpyA(patch, "apple");
9862     lstrcpyA(transforms, "banana");
9863     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9864     ok(r == ERROR_UNKNOWN_PRODUCT,
9865        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9866     ok(!lstrcmpA(patch, "apple"),
9867        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9868     ok(!lstrcmpA(transforms, "banana"),
9869        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9870     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9871
9872     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9873     lstrcatA(keypath, prod_squashed);
9874
9875     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9876     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9877
9878     /* current user product key exists */
9879     size = MAX_PATH;
9880     lstrcpyA(patch, "apple");
9881     lstrcpyA(transforms, "banana");
9882     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9883     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9884     ok(!lstrcmpA(patch, "apple"),
9885        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9886     ok(!lstrcmpA(transforms, "banana"),
9887        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9888     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9889
9890     res = RegCreateKeyA(prodkey, "Patches", &patches);
9891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9892
9893     /* Patches key exists */
9894     size = MAX_PATH;
9895     lstrcpyA(patch, "apple");
9896     lstrcpyA(transforms, "banana");
9897     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9898     ok(r == ERROR_NO_MORE_ITEMS ||
9899        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9900        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9901     ok(!lstrcmpA(patch, "apple"),
9902        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9903     ok(!lstrcmpA(transforms, "banana"),
9904        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9905     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9906
9907     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9908                          (const BYTE *)patch_squashed,
9909                          lstrlenA(patch_squashed) + 1);
9910     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9911
9912     /* Patches value exists, is not REG_MULTI_SZ */
9913     size = MAX_PATH;
9914     lstrcpyA(patch, "apple");
9915     lstrcpyA(transforms, "banana");
9916     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9917     ok(r == ERROR_BAD_CONFIGURATION ||
9918        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9919        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9920     ok(!lstrcmpA(patch, "apple"),
9921        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9922     ok(!lstrcmpA(transforms, "banana"),
9923        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9924     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9925
9926     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9927                          (const BYTE *)"a\0b\0c\0\0", 7);
9928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9929
9930     /* Patches value exists, is not a squashed guid */
9931     size = MAX_PATH;
9932     lstrcpyA(patch, "apple");
9933     lstrcpyA(transforms, "banana");
9934     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9935     ok(r == ERROR_BAD_CONFIGURATION,
9936        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9937     ok(!lstrcmpA(patch, "apple"),
9938        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9939     ok(!lstrcmpA(transforms, "banana"),
9940        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9941     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9942
9943     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9944     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9945                          (const BYTE *)patch_squashed,
9946                          lstrlenA(patch_squashed) + 2);
9947     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9948
9949     /* Patches value exists */
9950     size = MAX_PATH;
9951     lstrcpyA(patch, "apple");
9952     lstrcpyA(transforms, "banana");
9953     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9954     ok(r == ERROR_NO_MORE_ITEMS ||
9955        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9956        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9957     ok(!lstrcmpA(patch, "apple") ||
9958        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9959        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9960     ok(!lstrcmpA(transforms, "banana"),
9961        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9962     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9963
9964     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9965                          (const BYTE *)"whatever", 9);
9966     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9967
9968     /* patch code value exists */
9969     size = MAX_PATH;
9970     lstrcpyA(patch, "apple");
9971     lstrcpyA(transforms, "banana");
9972     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9973     ok(r == ERROR_NO_MORE_ITEMS ||
9974        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9975        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9976     ok(!lstrcmpA(patch, "apple") ||
9977        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9978        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9979     ok(!lstrcmpA(transforms, "banana") ||
9980        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
9981        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9982     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9983
9984     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9985     lstrcatA(keypath, usersid);
9986     lstrcatA(keypath, "\\Patches\\");
9987     lstrcatA(keypath, patch_squashed);
9988
9989     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
9990     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9991
9992     /* userdata patch key exists */
9993     size = MAX_PATH;
9994     lstrcpyA(patch, "apple");
9995     lstrcpyA(transforms, "banana");
9996     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9997     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9998     ok(!lstrcmpA(patch, patchcode),
9999        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10000     ok(!lstrcmpA(transforms, "whatever"),
10001        "Expected \"whatever\", got \"%s\"\n", transforms);
10002     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10003
10004     delete_key(userkey, "", access & KEY_WOW64_64KEY);
10005     RegCloseKey(userkey);
10006     RegDeleteValueA(patches, patch_squashed);
10007     RegDeleteValueA(patches, "Patches");
10008     RegDeleteKeyA(patches, "");
10009     RegCloseKey(patches);
10010     RegDeleteKeyA(prodkey, "");
10011     RegCloseKey(prodkey);
10012
10013     /* MSIINSTALLCONTEXT_MACHINE */
10014
10015     size = MAX_PATH;
10016     lstrcpyA(patch, "apple");
10017     lstrcpyA(transforms, "banana");
10018     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10019     ok(r == ERROR_UNKNOWN_PRODUCT,
10020        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10021     ok(!lstrcmpA(patch, "apple"),
10022        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10023     ok(!lstrcmpA(transforms, "banana"),
10024        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10025     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10026
10027     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10028     lstrcatA(keypath, prod_squashed);
10029
10030     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10032
10033     /* local product key exists */
10034     size = MAX_PATH;
10035     lstrcpyA(patch, "apple");
10036     lstrcpyA(transforms, "banana");
10037     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10038     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10039     ok(!lstrcmpA(patch, "apple"),
10040        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10041     ok(!lstrcmpA(transforms, "banana"),
10042        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10043     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10044
10045     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10046     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10047
10048     /* Patches key exists */
10049     size = MAX_PATH;
10050     lstrcpyA(patch, "apple");
10051     lstrcpyA(transforms, "banana");
10052     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10053     ok(r == ERROR_NO_MORE_ITEMS ||
10054        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10055        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10056     ok(!lstrcmpA(patch, "apple"),
10057        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10058     ok(!lstrcmpA(transforms, "banana"),
10059        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10060     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10061
10062     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10063                          (const BYTE *)patch_squashed,
10064                          lstrlenA(patch_squashed) + 1);
10065     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10066
10067     /* Patches value exists, is not REG_MULTI_SZ */
10068     size = MAX_PATH;
10069     lstrcpyA(patch, "apple");
10070     lstrcpyA(transforms, "banana");
10071     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10072     ok(r == ERROR_BAD_CONFIGURATION ||
10073        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10074        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10075     ok(!lstrcmpA(patch, "apple"),
10076        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10077     ok(!lstrcmpA(transforms, "banana"),
10078        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10079     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10080
10081     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10082                          (const BYTE *)"a\0b\0c\0\0", 7);
10083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10084
10085     /* Patches value exists, is not a squashed guid */
10086     size = MAX_PATH;
10087     lstrcpyA(patch, "apple");
10088     lstrcpyA(transforms, "banana");
10089     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10090     ok(r == ERROR_BAD_CONFIGURATION,
10091        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10092     ok(!lstrcmpA(patch, "apple"),
10093        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10094     ok(!lstrcmpA(transforms, "banana"),
10095        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10096     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10097
10098     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10099     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10100                          (const BYTE *)patch_squashed,
10101                          lstrlenA(patch_squashed) + 2);
10102     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10103
10104     /* Patches value exists */
10105     size = MAX_PATH;
10106     lstrcpyA(patch, "apple");
10107     lstrcpyA(transforms, "banana");
10108     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10109     ok(r == ERROR_NO_MORE_ITEMS ||
10110        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
10111        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10112     ok(!lstrcmpA(patch, "apple") ||
10113        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10114        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10115     ok(!lstrcmpA(transforms, "banana"),
10116        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10117     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10118
10119     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10120                          (const BYTE *)"whatever", 9);
10121     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10122
10123     /* patch code value exists */
10124     size = MAX_PATH;
10125     lstrcpyA(patch, "apple");
10126     lstrcpyA(transforms, "banana");
10127     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10128     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10129     ok(!lstrcmpA(patch, patchcode),
10130        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10131     ok(!lstrcmpA(transforms, "whatever"),
10132        "Expected \"whatever\", got \"%s\"\n", transforms);
10133     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10134
10135     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10136     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10137     lstrcatA(keypath, prod_squashed);
10138
10139     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10140     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10141
10142     /* local UserData product key exists */
10143     size = MAX_PATH;
10144     lstrcpyA(patch, "apple");
10145     lstrcpyA(transforms, "banana");
10146     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10147     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10148     ok(!lstrcmpA(patch, patchcode),
10149        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10150     ok(!lstrcmpA(transforms, "whatever"),
10151        "Expected \"whatever\", got \"%s\"\n", transforms);
10152     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10153
10154     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10155     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10156
10157     /* local UserData Patches key exists */
10158     size = MAX_PATH;
10159     lstrcpyA(patch, "apple");
10160     lstrcpyA(transforms, "banana");
10161     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10162     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10163     ok(!lstrcmpA(patch, patchcode),
10164        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10165     ok(!lstrcmpA(transforms, "whatever"),
10166        "Expected \"whatever\", got \"%s\"\n", transforms);
10167     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10168
10169     res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10170     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10171
10172     /* local UserData Product patch key exists */
10173     size = MAX_PATH;
10174     lstrcpyA(patch, "apple");
10175     lstrcpyA(transforms, "banana");
10176     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10177     ok(r == ERROR_NO_MORE_ITEMS ||
10178        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10179        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10180     ok(!lstrcmpA(patch, "apple") ||
10181        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10182        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10183     ok(!lstrcmpA(transforms, "banana") ||
10184        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10185        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10186     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10187
10188     data = MSIPATCHSTATE_APPLIED;
10189     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10190                          (const BYTE *)&data, sizeof(DWORD));
10191     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10192
10193     /* State value exists */
10194     size = MAX_PATH;
10195     lstrcpyA(patch, "apple");
10196     lstrcpyA(transforms, "banana");
10197     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10198     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10199     ok(!lstrcmpA(patch, patchcode),
10200        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10201     ok(!lstrcmpA(transforms, "whatever"),
10202        "Expected \"whatever\", got \"%s\"\n", transforms);
10203     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10204
10205     /* now duplicate some of the tests for the W version */
10206
10207     /* pcchTransformsBuf is too small */
10208     size = 6;
10209     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
10210     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10211     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10212     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10213     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10214     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10215     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10216     ok(!lstrcmpA(patch, patchcode),
10217        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10218     ok(!lstrcmpA(transforms, "whate") ||
10219        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10220        "Expected \"whate\", got \"%s\"\n", transforms);
10221     ok(size == 8, "Expected 8, got %d\n", size);
10222
10223     /* patch code value exists */
10224     size = MAX_PATH;
10225     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10226     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10227     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10229     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10230     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10231     ok(!lstrcmpA(patch, patchcode),
10232        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10233     ok(!lstrcmpA(transforms, "whatever"),
10234        "Expected \"whatever\", got \"%s\"\n", transforms);
10235     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10236
10237     RegDeleteValueA(patches, patch_squashed);
10238     RegDeleteValueA(patches, "Patches");
10239     delete_key(patches, "", access & KEY_WOW64_64KEY);
10240     RegCloseKey(patches);
10241     RegDeleteValueA(hpatch, "State");
10242     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10243     RegCloseKey(hpatch);
10244     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10245     RegCloseKey(udpatch);
10246     delete_key(udprod, "", access & KEY_WOW64_64KEY);
10247     RegCloseKey(udprod);
10248     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10249     RegCloseKey(prodkey);
10250     LocalFree(usersid);
10251 }
10252
10253 static void test_MsiGetPatchInfoEx(void)
10254 {
10255     CHAR keypath[MAX_PATH], val[MAX_PATH];
10256     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10257     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10258     HKEY prodkey, patches, udprod, props;
10259     HKEY hpatch, udpatch, prodpatches;
10260     LPSTR usersid;
10261     DWORD size;
10262     LONG res;
10263     UINT r;
10264     REGSAM access = KEY_ALL_ACCESS;
10265
10266     if (!pMsiGetPatchInfoExA)
10267     {
10268         win_skip("MsiGetPatchInfoEx not implemented\n");
10269         return;
10270     }
10271
10272     create_test_guid(prodcode, prod_squashed);
10273     create_test_guid(patchcode, patch_squashed);
10274     get_user_sid(&usersid);
10275
10276     if (is_wow64)
10277         access |= KEY_WOW64_64KEY;
10278
10279     /* NULL szPatchCode */
10280     lstrcpyA(val, "apple");
10281     size = MAX_PATH;
10282     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10283                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10284     ok(r == ERROR_INVALID_PARAMETER,
10285        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10286     ok(!lstrcmpA(val, "apple"),
10287        "Expected val to be unchanged, got \"%s\"\n", val);
10288     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10289
10290     /* empty szPatchCode */
10291     size = MAX_PATH;
10292     lstrcpyA(val, "apple");
10293     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10294                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10295     ok(r == ERROR_INVALID_PARAMETER,
10296        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10297     ok(!lstrcmpA(val, "apple"),
10298        "Expected val to be unchanged, got \"%s\"\n", val);
10299     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10300
10301     /* garbage szPatchCode */
10302     size = MAX_PATH;
10303     lstrcpyA(val, "apple");
10304     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
10305                             MSIINSTALLCONTEXT_USERMANAGED,
10306                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10307     ok(r == ERROR_INVALID_PARAMETER,
10308        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10309     ok(!lstrcmpA(val, "apple"),
10310        "Expected val to be unchanged, got \"%s\"\n", val);
10311     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10312
10313     /* guid without brackets */
10314     size = MAX_PATH;
10315     lstrcpyA(val, "apple");
10316     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
10317                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10318                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10319     ok(r == ERROR_INVALID_PARAMETER,
10320        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10321     ok(!lstrcmpA(val, "apple"),
10322        "Expected val to be unchanged, got \"%s\"\n", val);
10323     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10324
10325     /* guid with brackets */
10326     size = MAX_PATH;
10327     lstrcpyA(val, "apple");
10328     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
10329                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10330                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10331     ok(r == ERROR_UNKNOWN_PRODUCT,
10332        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10333     ok(!lstrcmpA(val, "apple"),
10334        "Expected val to be unchanged, got \"%s\"\n", val);
10335     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10336
10337     /* same length as guid, but random */
10338     size = MAX_PATH;
10339     lstrcpyA(val, "apple");
10340     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
10341                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10342                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10343     ok(r == ERROR_INVALID_PARAMETER,
10344        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10345     ok(!lstrcmpA(val, "apple"),
10346        "Expected val to be unchanged, got \"%s\"\n", val);
10347     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10348
10349     /* NULL szProductCode */
10350     lstrcpyA(val, "apple");
10351     size = MAX_PATH;
10352     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10353                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10354     ok(r == ERROR_INVALID_PARAMETER,
10355        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10356     ok(!lstrcmpA(val, "apple"),
10357        "Expected val to be unchanged, got \"%s\"\n", val);
10358     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10359
10360     /* empty szProductCode */
10361     size = MAX_PATH;
10362     lstrcpyA(val, "apple");
10363     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10364                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10365     ok(r == ERROR_INVALID_PARAMETER,
10366        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10367     ok(!lstrcmpA(val, "apple"),
10368        "Expected val to be unchanged, got \"%s\"\n", val);
10369     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10370
10371     /* garbage szProductCode */
10372     size = MAX_PATH;
10373     lstrcpyA(val, "apple");
10374     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
10375                             MSIINSTALLCONTEXT_USERMANAGED,
10376                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10377     ok(r == ERROR_INVALID_PARAMETER,
10378        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10379     ok(!lstrcmpA(val, "apple"),
10380        "Expected val to be unchanged, got \"%s\"\n", val);
10381     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10382
10383     /* guid without brackets */
10384     size = MAX_PATH;
10385     lstrcpyA(val, "apple");
10386     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10387                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10388                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10389     ok(r == ERROR_INVALID_PARAMETER,
10390        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10391     ok(!lstrcmpA(val, "apple"),
10392        "Expected val to be unchanged, got \"%s\"\n", val);
10393     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10394
10395     /* guid with brackets */
10396     size = MAX_PATH;
10397     lstrcpyA(val, "apple");
10398     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10399                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10400                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10401     ok(r == ERROR_UNKNOWN_PRODUCT,
10402        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10403     ok(!lstrcmpA(val, "apple"),
10404        "Expected val to be unchanged, got \"%s\"\n", val);
10405     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10406
10407     /* same length as guid, but random */
10408     size = MAX_PATH;
10409     lstrcpyA(val, "apple");
10410     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10411                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10412                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10413     ok(r == ERROR_INVALID_PARAMETER,
10414        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10415     ok(!lstrcmpA(val, "apple"),
10416        "Expected val to be unchanged, got \"%s\"\n", val);
10417     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10418
10419     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10420     size = MAX_PATH;
10421     lstrcpyA(val, "apple");
10422     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10423                             MSIINSTALLCONTEXT_USERMANAGED,
10424                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10425     ok(r == ERROR_INVALID_PARAMETER,
10426        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10427     ok(!lstrcmpA(val, "apple"),
10428        "Expected val to be unchanged, got \"%s\"\n", val);
10429     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10430
10431     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10432     size = MAX_PATH;
10433     lstrcpyA(val, "apple");
10434     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10435                             MSIINSTALLCONTEXT_USERUNMANAGED,
10436                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10437     ok(r == ERROR_INVALID_PARAMETER,
10438        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10439     ok(!lstrcmpA(val, "apple"),
10440        "Expected val to be unchanged, got \"%s\"\n", val);
10441     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10442
10443     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10444     size = MAX_PATH;
10445     lstrcpyA(val, "apple");
10446     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10447                             MSIINSTALLCONTEXT_MACHINE,
10448                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10449     ok(r == ERROR_INVALID_PARAMETER,
10450        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10451     ok(!lstrcmpA(val, "apple"),
10452        "Expected val to be unchanged, got \"%s\"\n", val);
10453     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10454
10455     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10456     size = MAX_PATH;
10457     lstrcpyA(val, "apple");
10458     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10459                             MSIINSTALLCONTEXT_MACHINE,
10460                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10461     ok(r == ERROR_INVALID_PARAMETER,
10462        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10463     ok(!lstrcmpA(val, "apple"),
10464        "Expected val to be unchanged, got \"%s\"\n", val);
10465     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10466
10467     /* dwContext is out of range */
10468     size = MAX_PATH;
10469     lstrcpyA(val, "apple");
10470     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10471                             MSIINSTALLCONTEXT_NONE,
10472                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10473     ok(r == ERROR_INVALID_PARAMETER,
10474        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10475     ok(!lstrcmpA(val, "apple"),
10476        "Expected val to be unchanged, got \"%s\"\n", val);
10477     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10478
10479     /* dwContext is out of range */
10480     size = MAX_PATH;
10481     lstrcpyA(val, "apple");
10482     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10483                             MSIINSTALLCONTEXT_ALL,
10484                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10485     ok(r == ERROR_INVALID_PARAMETER,
10486        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10487     ok(!lstrcmpA(val, "apple"),
10488        "Expected val to be unchanged, got \"%s\"\n", val);
10489     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10490
10491     /* dwContext is invalid */
10492     size = MAX_PATH;
10493     lstrcpyA(val, "apple");
10494     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10495                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10496     ok(r == ERROR_INVALID_PARAMETER,
10497        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10498     ok(!lstrcmpA(val, "apple"),
10499        "Expected val to be unchanged, got \"%s\"\n", val);
10500     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10501
10502     /* MSIINSTALLCONTEXT_USERMANAGED */
10503
10504     size = MAX_PATH;
10505     lstrcpyA(val, "apple");
10506     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10507                             MSIINSTALLCONTEXT_USERMANAGED,
10508                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10509     ok(r == ERROR_UNKNOWN_PRODUCT,
10510        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10511     ok(!lstrcmpA(val, "apple"),
10512        "Expected val to be unchanged, got \"%s\"\n", val);
10513     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10514
10515     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10516     lstrcatA(keypath, usersid);
10517     lstrcatA(keypath, "\\Products\\");
10518     lstrcatA(keypath, prod_squashed);
10519
10520     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10521     if (res == ERROR_ACCESS_DENIED)
10522     {
10523         skip("Not enough rights to perform tests\n");
10524         LocalFree(usersid);
10525         return;
10526     }
10527     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10528
10529     /* local UserData product key exists */
10530     size = MAX_PATH;
10531     lstrcpyA(val, "apple");
10532     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10533                             MSIINSTALLCONTEXT_USERMANAGED,
10534                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10535     ok(r == ERROR_UNKNOWN_PRODUCT,
10536        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10537     ok(!lstrcmpA(val, "apple"),
10538        "Expected val to be unchanged, got \"%s\"\n", val);
10539     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10540
10541     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
10542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10543
10544     /* InstallProperties 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_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10551     ok(!lstrcmpA(val, "apple"),
10552        "Expected val to be unchanged, got \"%s\"\n", val);
10553     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10554
10555     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10557
10558     /* Patches key exists */
10559     size = MAX_PATH;
10560     lstrcpyA(val, "apple");
10561     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10562                             MSIINSTALLCONTEXT_USERMANAGED,
10563                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10564     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10565     ok(!lstrcmpA(val, "apple"),
10566        "Expected val to be unchanged, got \"%s\"\n", val);
10567     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10568
10569     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10570     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10571
10572     /* Patches key exists */
10573     size = MAX_PATH;
10574     lstrcpyA(val, "apple");
10575     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10576                             MSIINSTALLCONTEXT_USERMANAGED,
10577                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10578     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10579     ok(!lstrcmpA(val, "apple"),
10580        "Expected val to be unchanged, got \"%s\"\n", val);
10581     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10582
10583     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10584     lstrcatA(keypath, usersid);
10585     lstrcatA(keypath, "\\Installer\\Products\\");
10586     lstrcatA(keypath, prod_squashed);
10587
10588     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10590
10591     /* managed product key exists */
10592     size = MAX_PATH;
10593     lstrcpyA(val, "apple");
10594     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10595                             MSIINSTALLCONTEXT_USERMANAGED,
10596                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10597     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10598     ok(!lstrcmpA(val, "apple"),
10599        "Expected val to be unchanged, got \"%s\"\n", val);
10600     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10601
10602     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
10603     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10604
10605     /* Patches key exists */
10606     size = MAX_PATH;
10607     lstrcpyA(val, "apple");
10608     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10609                             MSIINSTALLCONTEXT_USERMANAGED,
10610                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10611     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10612     ok(!lstrcmpA(val, "apple"),
10613        "Expected val to be unchanged, got \"%s\"\n", val);
10614     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10615
10616     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10617                          (const BYTE *)"transforms", 11);
10618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10619
10620     /* specific patch value 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     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10632     lstrcatA(keypath, usersid);
10633     lstrcatA(keypath, "\\Patches\\");
10634     lstrcatA(keypath, patch_squashed);
10635
10636     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
10637     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10638
10639     /* UserData Patches key exists */
10640     size = MAX_PATH;
10641     lstrcpyA(val, "apple");
10642     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10643                             MSIINSTALLCONTEXT_USERMANAGED,
10644                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10645     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10646     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10647     ok(size == 0, "Expected 0, got %d\n", size);
10648
10649     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10650                          (const BYTE *)"pack", 5);
10651     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10652
10653     /* ManagedLocalPatch value exists */
10654     size = MAX_PATH;
10655     lstrcpyA(val, "apple");
10656     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10657                             MSIINSTALLCONTEXT_USERMANAGED,
10658                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10659     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10660     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10661     ok(size == 4, "Expected 4, got %d\n", size);
10662
10663     size = MAX_PATH;
10664     lstrcpyA(val, "apple");
10665     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10666                             MSIINSTALLCONTEXT_USERMANAGED,
10667                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10668     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10669     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10670     ok(size == 10, "Expected 10, got %d\n", size);
10671
10672     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10673                          (const BYTE *)"mydate", 7);
10674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10675
10676     /* Installed value exists */
10677     size = MAX_PATH;
10678     lstrcpyA(val, "apple");
10679     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10680                             MSIINSTALLCONTEXT_USERMANAGED,
10681                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10682     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10683     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10684     ok(size == 6, "Expected 6, got %d\n", size);
10685
10686     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10687                          (const BYTE *)"yes", 4);
10688     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10689
10690     /* Uninstallable value exists */
10691     size = MAX_PATH;
10692     lstrcpyA(val, "apple");
10693     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10694                             MSIINSTALLCONTEXT_USERMANAGED,
10695                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10696     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10697     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10698     ok(size == 3, "Expected 3, got %d\n", size);
10699
10700     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10701                          (const BYTE *)"good", 5);
10702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10703
10704     /* State value exists */
10705     size = MAX_PATH;
10706     lstrcpyA(val, "apple");
10707     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10708                             MSIINSTALLCONTEXT_USERMANAGED,
10709                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10710     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10711     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10712     ok(size == 4, "Expected 4, got %d\n", size);
10713
10714     size = 1;
10715     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10716                          (const BYTE *)&size, sizeof(DWORD));
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     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10727     ok(size == 1, "Expected 1, got %d\n", size);
10728
10729     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10730                          (const BYTE *)"display", 8);
10731     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10732
10733     /* DisplayName value exists */
10734     size = MAX_PATH;
10735     lstrcpyA(val, "apple");
10736     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10737                             MSIINSTALLCONTEXT_USERMANAGED,
10738                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10739     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10740     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10741     ok(size == 7, "Expected 7, got %d\n", size);
10742
10743     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10744                          (const BYTE *)"moreinfo", 9);
10745     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10746
10747     /* MoreInfoURL value exists */
10748     size = MAX_PATH;
10749     lstrcpyA(val, "apple");
10750     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10751                             MSIINSTALLCONTEXT_USERMANAGED,
10752                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10753     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10754     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10755     ok(size == 8, "Expected 8, got %d\n", size);
10756
10757     /* szProperty is invalid */
10758     size = MAX_PATH;
10759     lstrcpyA(val, "apple");
10760     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10761                             MSIINSTALLCONTEXT_USERMANAGED,
10762                             "IDontExist", val, &size);
10763     ok(r == ERROR_UNKNOWN_PROPERTY,
10764        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10765     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10766     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10767
10768     /* lpValue is NULL, while pcchValue is non-NULL */
10769     size = MAX_PATH;
10770     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10771                             MSIINSTALLCONTEXT_USERMANAGED,
10772                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10773     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10774     ok(size == 16, "Expected 16, got %d\n", size);
10775
10776     /* pcchValue is NULL, while lpValue is non-NULL */
10777     lstrcpyA(val, "apple");
10778     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10779                             MSIINSTALLCONTEXT_USERMANAGED,
10780                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10781     ok(r == ERROR_INVALID_PARAMETER,
10782        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10783     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10784
10785     /* both lpValue and pcchValue are NULL */
10786     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10787                             MSIINSTALLCONTEXT_USERMANAGED,
10788                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10789     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10790
10791     /* pcchValue doesn't have enough room for NULL terminator */
10792     size = 8;
10793     lstrcpyA(val, "apple");
10794     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10795                             MSIINSTALLCONTEXT_USERMANAGED,
10796                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10797     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10798     ok(!lstrcmpA(val, "moreinf"),
10799        "Expected \"moreinf\", got \"%s\"\n", val);
10800     ok(size == 16, "Expected 16, got %d\n", size);
10801
10802     /* pcchValue has exactly enough room for NULL terminator */
10803     size = 9;
10804     lstrcpyA(val, "apple");
10805     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10806                             MSIINSTALLCONTEXT_USERMANAGED,
10807                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10808     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10809     ok(!lstrcmpA(val, "moreinfo"),
10810        "Expected \"moreinfo\", got \"%s\"\n", val);
10811     ok(size == 8, "Expected 8, got %d\n", size);
10812
10813     /* pcchValue is too small, lpValue is NULL */
10814     size = 0;
10815     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10816                             MSIINSTALLCONTEXT_USERMANAGED,
10817                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10818     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10819     ok(size == 16, "Expected 16, got %d\n", size);
10820
10821     RegDeleteValueA(prodpatches, patch_squashed);
10822     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
10823     RegCloseKey(prodpatches);
10824     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
10825     RegCloseKey(prodkey);
10826
10827     /* UserData is sufficient for all properties
10828      * except INSTALLPROPERTY_TRANSFORMS
10829      */
10830     size = MAX_PATH;
10831     lstrcpyA(val, "apple");
10832     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10833                             MSIINSTALLCONTEXT_USERMANAGED,
10834                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10835     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10836     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10837     ok(size == 4, "Expected 4, got %d\n", size);
10838
10839     /* UserData is sufficient for all properties
10840      * except INSTALLPROPERTY_TRANSFORMS
10841      */
10842     size = MAX_PATH;
10843     lstrcpyA(val, "apple");
10844     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10845                             MSIINSTALLCONTEXT_USERMANAGED,
10846                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10847     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10848     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10849     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10850
10851     RegDeleteValueA(hpatch, "MoreInfoURL");
10852     RegDeleteValueA(hpatch, "Display");
10853     RegDeleteValueA(hpatch, "State");
10854     RegDeleteValueA(hpatch, "Uninstallable");
10855     RegDeleteValueA(hpatch, "Installed");
10856     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10857     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
10858     RegCloseKey(udpatch);
10859     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
10860     RegCloseKey(hpatch);
10861     delete_key(patches, "", access & KEY_WOW64_64KEY);
10862     RegCloseKey(patches);
10863     delete_key(props, "", access & KEY_WOW64_64KEY);
10864     RegCloseKey(props);
10865     delete_key(udprod, "", access & KEY_WOW64_64KEY);
10866     RegCloseKey(udprod);
10867
10868     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10869
10870     size = MAX_PATH;
10871     lstrcpyA(val, "apple");
10872     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10873                             MSIINSTALLCONTEXT_USERUNMANAGED,
10874                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10875     ok(r == ERROR_UNKNOWN_PRODUCT,
10876        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10877     ok(!lstrcmpA(val, "apple"),
10878        "Expected val to be unchanged, got \"%s\"\n", val);
10879     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10880
10881     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10882     lstrcatA(keypath, usersid);
10883     lstrcatA(keypath, "\\Products\\");
10884     lstrcatA(keypath, prod_squashed);
10885
10886     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10888
10889     /* local UserData product key exists */
10890     size = MAX_PATH;
10891     lstrcpyA(val, "apple");
10892     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10893                             MSIINSTALLCONTEXT_USERUNMANAGED,
10894                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10895     ok(r == ERROR_UNKNOWN_PRODUCT,
10896        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10897     ok(!lstrcmpA(val, "apple"),
10898        "Expected val to be unchanged, got \"%s\"\n", val);
10899     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10900
10901     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
10902     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10903
10904     /* InstallProperties 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_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10911     ok(!lstrcmpA(val, "apple"),
10912        "Expected val to be unchanged, got \"%s\"\n", val);
10913     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10914
10915     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10917
10918     /* Patches key exists */
10919     size = MAX_PATH;
10920     lstrcpyA(val, "apple");
10921     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10922                             MSIINSTALLCONTEXT_USERUNMANAGED,
10923                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10924     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10925     ok(!lstrcmpA(val, "apple"),
10926        "Expected val to be unchanged, got \"%s\"\n", val);
10927     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10928
10929     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10930     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10931
10932     /* Patches key exists */
10933     size = MAX_PATH;
10934     lstrcpyA(val, "apple");
10935     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10936                             MSIINSTALLCONTEXT_USERUNMANAGED,
10937                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10938     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10939     ok(!lstrcmpA(val, "apple"),
10940        "Expected val to be unchanged, got \"%s\"\n", val);
10941     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10942
10943     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10944     lstrcatA(keypath, prod_squashed);
10945
10946     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10947     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10948
10949     /* current user product key exists */
10950     size = MAX_PATH;
10951     lstrcpyA(val, "apple");
10952     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10953                             MSIINSTALLCONTEXT_USERUNMANAGED,
10954                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10955     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10956     ok(!lstrcmpA(val, "apple"),
10957        "Expected val to be unchanged, got \"%s\"\n", val);
10958     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10959
10960     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10962
10963     /* Patches key exists */
10964     size = MAX_PATH;
10965     lstrcpyA(val, "apple");
10966     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10967                             MSIINSTALLCONTEXT_USERUNMANAGED,
10968                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10969     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10970     ok(!lstrcmpA(val, "apple"),
10971        "Expected val to be unchanged, got \"%s\"\n", val);
10972     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10973
10974     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10975                          (const BYTE *)"transforms", 11);
10976     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10977
10978     /* specific patch value 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     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10990     lstrcatA(keypath, usersid);
10991     lstrcatA(keypath, "\\Patches\\");
10992     lstrcatA(keypath, patch_squashed);
10993
10994     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
10995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10996
10997     /* UserData Patches key exists */
10998     size = MAX_PATH;
10999     lstrcpyA(val, "apple");
11000     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11001                             MSIINSTALLCONTEXT_USERUNMANAGED,
11002                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11004     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11005     ok(size == 0, "Expected 0, got %d\n", size);
11006
11007     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11008                          (const BYTE *)"pack", 5);
11009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11010
11011     /* LocalPatch value exists */
11012     size = MAX_PATH;
11013     lstrcpyA(val, "apple");
11014     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11015                             MSIINSTALLCONTEXT_USERUNMANAGED,
11016                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11017     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11018     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11019     ok(size == 4, "Expected 4, got %d\n", size);
11020
11021     size = MAX_PATH;
11022     lstrcpyA(val, "apple");
11023     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11024                             MSIINSTALLCONTEXT_USERUNMANAGED,
11025                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11027     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11028     ok(size == 10, "Expected 10, got %d\n", size);
11029
11030     RegDeleteValueA(prodpatches, patch_squashed);
11031     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11032     RegCloseKey(prodpatches);
11033     RegDeleteKeyA(prodkey, "");
11034     RegCloseKey(prodkey);
11035
11036     /* UserData is sufficient for all properties
11037      * except INSTALLPROPERTY_TRANSFORMS
11038      */
11039     size = MAX_PATH;
11040     lstrcpyA(val, "apple");
11041     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11042                             MSIINSTALLCONTEXT_USERUNMANAGED,
11043                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11044     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11045     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11046     ok(size == 4, "Expected 4, got %d\n", size);
11047
11048     /* UserData is sufficient for all properties
11049      * except INSTALLPROPERTY_TRANSFORMS
11050      */
11051     size = MAX_PATH;
11052     lstrcpyA(val, "apple");
11053     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
11054                             MSIINSTALLCONTEXT_USERUNMANAGED,
11055                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11056     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11057     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11058     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11059
11060     RegDeleteValueA(udpatch, "LocalPackage");
11061     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11062     RegCloseKey(udpatch);
11063     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11064     RegCloseKey(hpatch);
11065     delete_key(patches, "", access & KEY_WOW64_64KEY);
11066     RegCloseKey(patches);
11067     delete_key(props, "", access & KEY_WOW64_64KEY);
11068     RegCloseKey(props);
11069     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11070     RegCloseKey(udprod);
11071
11072     /* MSIINSTALLCONTEXT_MACHINE */
11073
11074     size = MAX_PATH;
11075     lstrcpyA(val, "apple");
11076     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11077                             MSIINSTALLCONTEXT_MACHINE,
11078                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11079     ok(r == ERROR_UNKNOWN_PRODUCT,
11080        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11081     ok(!lstrcmpA(val, "apple"),
11082        "Expected val to be unchanged, got \"%s\"\n", val);
11083     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11084
11085     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11086     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11087     lstrcatA(keypath, prod_squashed);
11088
11089     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11090     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11091
11092     /* local UserData product key exists */
11093     size = MAX_PATH;
11094     lstrcpyA(val, "apple");
11095     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11096                             MSIINSTALLCONTEXT_MACHINE,
11097                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11098     ok(r == ERROR_UNKNOWN_PRODUCT,
11099        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11100     ok(!lstrcmpA(val, "apple"),
11101        "Expected val to be unchanged, got \"%s\"\n", val);
11102     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11103
11104     res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
11105     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11106
11107     /* InstallProperties 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_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11114     ok(!lstrcmpA(val, "apple"),
11115        "Expected val to be unchanged, got \"%s\"\n", val);
11116     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11117
11118     res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11119     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11120
11121     /* Patches key exists */
11122     size = MAX_PATH;
11123     lstrcpyA(val, "apple");
11124     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11125                             MSIINSTALLCONTEXT_MACHINE,
11126                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11127     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11128     ok(!lstrcmpA(val, "apple"),
11129        "Expected val to be unchanged, got \"%s\"\n", val);
11130     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11131
11132     res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11133     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11134
11135     /* Patches key exists */
11136     size = MAX_PATH;
11137     lstrcpyA(val, "apple");
11138     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11139                             MSIINSTALLCONTEXT_MACHINE,
11140                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11141     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11142     ok(!lstrcmpA(val, "apple"),
11143        "Expected val to be unchanged, got \"%s\"\n", val);
11144     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11145
11146     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11147     lstrcatA(keypath, prod_squashed);
11148
11149     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11151
11152     /* local product key exists */
11153     size = MAX_PATH;
11154     lstrcpyA(val, "apple");
11155     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11156                             MSIINSTALLCONTEXT_MACHINE,
11157                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11158     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11159     ok(!lstrcmpA(val, "apple"),
11160        "Expected val to be unchanged, got \"%s\"\n", val);
11161     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11162
11163     res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
11164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11165
11166     /* Patches key exists */
11167     size = MAX_PATH;
11168     lstrcpyA(val, "apple");
11169     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11170                             MSIINSTALLCONTEXT_MACHINE,
11171                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11172     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11173     ok(!lstrcmpA(val, "apple"),
11174        "Expected val to be unchanged, got \"%s\"\n", val);
11175     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11176
11177     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
11178                          (const BYTE *)"transforms", 11);
11179     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11180
11181     /* specific patch value 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     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11193     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11194     lstrcatA(keypath, patch_squashed);
11195
11196     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
11197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11198
11199     /* UserData Patches key exists */
11200     size = MAX_PATH;
11201     lstrcpyA(val, "apple");
11202     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11203                             MSIINSTALLCONTEXT_MACHINE,
11204                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11205     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11206     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11207     ok(size == 0, "Expected 0, got %d\n", size);
11208
11209     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11210                          (const BYTE *)"pack", 5);
11211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11212
11213     /* LocalPatch value exists */
11214     size = MAX_PATH;
11215     lstrcpyA(val, "apple");
11216     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11217                             MSIINSTALLCONTEXT_MACHINE,
11218                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11219     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11220     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11221     ok(size == 4, "Expected 4, got %d\n", size);
11222
11223     size = MAX_PATH;
11224     lstrcpyA(val, "apple");
11225     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11226                             MSIINSTALLCONTEXT_MACHINE,
11227                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11229     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11230     ok(size == 10, "Expected 10, got %d\n", size);
11231
11232     RegDeleteValueA(prodpatches, patch_squashed);
11233     delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
11234     RegCloseKey(prodpatches);
11235     delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11236     RegCloseKey(prodkey);
11237
11238     /* UserData is sufficient for all properties
11239      * except INSTALLPROPERTY_TRANSFORMS
11240      */
11241     size = MAX_PATH;
11242     lstrcpyA(val, "apple");
11243     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11244                             MSIINSTALLCONTEXT_MACHINE,
11245                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11246     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11247     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11248     ok(size == 4, "Expected 4, got %d\n", size);
11249
11250     /* UserData is sufficient for all properties
11251      * except INSTALLPROPERTY_TRANSFORMS
11252      */
11253     size = MAX_PATH;
11254     lstrcpyA(val, "apple");
11255     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11256                             MSIINSTALLCONTEXT_MACHINE,
11257                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11258     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11259     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11260     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11261
11262     RegDeleteValueA(udpatch, "LocalPackage");
11263     delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11264     RegCloseKey(udpatch);
11265     delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11266     RegCloseKey(hpatch);
11267     delete_key(patches, "", access & KEY_WOW64_64KEY);
11268     RegCloseKey(patches);
11269     delete_key(props, "", access & KEY_WOW64_64KEY);
11270     RegCloseKey(props);
11271     delete_key(udprod, "", access & KEY_WOW64_64KEY);
11272     RegCloseKey(udprod);
11273     LocalFree(usersid);
11274 }
11275
11276 static void test_MsiGetPatchInfo(void)
11277 {
11278     UINT r;
11279     char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
11280     char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
11281     WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
11282     HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
11283     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
11284     DWORD size;
11285     LONG res;
11286     REGSAM access = KEY_ALL_ACCESS;
11287
11288     create_test_guid(patch_code, patch_squashed);
11289     create_test_guid(prod_code, prod_squashed);
11290     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
11291
11292     if (is_wow64)
11293         access |= KEY_WOW64_64KEY;
11294
11295     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
11296     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11297
11298     r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
11299     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11300
11301     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
11302     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
11303
11304     size = 0;
11305     r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
11306     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11307
11308     r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
11309     ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
11310
11311     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11312     lstrcatA(keypath, prod_squashed);
11313
11314     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
11315     if (res == ERROR_ACCESS_DENIED)
11316     {
11317         skip("Not enough rights to perform tests\n");
11318         return;
11319     }
11320     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11321
11322     /* product key exists */
11323     size = MAX_PATH;
11324     lstrcpyA(val, "apple");
11325     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11326     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11327     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11328     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11329
11330     res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
11331     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11332
11333     /* patches key exists */
11334     size = MAX_PATH;
11335     lstrcpyA(val, "apple");
11336     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11337     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11338     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11339     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11340
11341     res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
11342     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11343
11344     /* patch key exists */
11345     size = MAX_PATH;
11346     lstrcpyA(val, "apple");
11347     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11348     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11349     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11350     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11351
11352     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11353     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11354     lstrcatA(keypath, prod_squashed);
11355
11356     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
11357     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
11358
11359     /* UserData product key exists */
11360     size = MAX_PATH;
11361     lstrcpyA(val, "apple");
11362     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11363     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11364     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11365     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11366
11367     res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
11368     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11369
11370     /* InstallProperties key exists */
11371     size = MAX_PATH;
11372     lstrcpyA(val, "apple");
11373     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11374     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11375     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11376     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11377
11378     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
11379     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11380
11381     /* UserData Patches key exists */
11382     size = MAX_PATH;
11383     lstrcpyA(val, "apple");
11384     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11385     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11386     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11387     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11388
11389     res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
11390     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11391
11392     res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
11393     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11394
11395     /* UserData product patch key exists */
11396     size = MAX_PATH;
11397     lstrcpyA(val, "apple");
11398     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11399     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11400     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11401     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11402
11403     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11404     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11405     lstrcatA(keypath, patch_squashed);
11406
11407     res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
11408     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11409
11410     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11411     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11412
11413     /* UserData Patch key exists */
11414     size = 0;
11415     lstrcpyA(val, "apple");
11416     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11417     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11418     ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11419     ok(size == 11, "expected 11 got %u\n", size);
11420
11421     size = MAX_PATH;
11422     lstrcpyA(val, "apple");
11423     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11424     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11425     ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11426     ok(size == 11, "expected 11 got %u\n", size);
11427
11428     size = 0;
11429     valW[0] = 0;
11430     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11431     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11432     ok(!valW[0], "expected 0 got %u\n", valW[0]);
11433     ok(size == 11, "expected 11 got %u\n", size);
11434
11435     size = MAX_PATH;
11436     valW[0] = 0;
11437     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11438     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11439     ok(valW[0], "expected > 0 got %u\n", valW[0]);
11440     ok(size == 11, "expected 11 got %u\n", size);
11441
11442     delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
11443     RegCloseKey(hkey_udproductpatch);
11444     delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
11445     RegCloseKey(hkey_udproductpatches);
11446     delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
11447     RegCloseKey(hkey_udpatch);
11448     delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
11449     RegCloseKey(hkey_patches);
11450     delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
11451     RegCloseKey(hkey_product);
11452     delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
11453     RegCloseKey(hkey_patch);
11454     delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
11455     RegCloseKey(hkey_udpatches);
11456     delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
11457     RegCloseKey(hkey_udprops);
11458     delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
11459     RegCloseKey(hkey_udproduct);
11460 }
11461
11462 static void test_MsiEnumProducts(void)
11463 {
11464     UINT r;
11465     int found1, found2, found3;
11466     DWORD index;
11467     char product1[39], product2[39], product3[39], guid[39];
11468     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11469     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11470     char *usersid;
11471     HKEY key1, key2, key3;
11472     REGSAM access = KEY_ALL_ACCESS;
11473
11474     create_test_guid(product1, product_squashed1);
11475     create_test_guid(product2, product_squashed2);
11476     create_test_guid(product3, product_squashed3);
11477     get_user_sid(&usersid);
11478
11479     if (is_wow64)
11480         access |= KEY_WOW64_64KEY;
11481
11482     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11483     strcat(keypath1, product_squashed1);
11484
11485     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
11486     if (r == ERROR_ACCESS_DENIED)
11487     {
11488         skip("Not enough rights to perform tests\n");
11489         LocalFree(usersid);
11490         return;
11491     }
11492     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11493
11494     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11495     strcat(keypath2, usersid);
11496     strcat(keypath2, "\\Installer\\Products\\");
11497     strcat(keypath2, product_squashed2);
11498
11499     r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
11500     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11501
11502     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
11503     strcat(keypath3, product_squashed3);
11504
11505     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
11506     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11507
11508     index = 0;
11509     r = MsiEnumProductsA(index, guid);
11510     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11511
11512     r = MsiEnumProductsA(index, NULL);
11513     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11514
11515     index = 2;
11516     r = MsiEnumProductsA(index, guid);
11517     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11518
11519     index = 0;
11520     r = MsiEnumProductsA(index, guid);
11521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11522
11523     found1 = found2 = found3 = 0;
11524     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
11525     {
11526         if (!strcmp(product1, guid)) found1 = 1;
11527         if (!strcmp(product2, guid)) found2 = 1;
11528         if (!strcmp(product3, guid)) found3 = 1;
11529         index++;
11530     }
11531     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
11532     ok(found1, "product1 not found\n");
11533     ok(found2, "product2 not found\n");
11534     ok(found3, "product3 not found\n");
11535
11536     delete_key(key1, "", access & KEY_WOW64_64KEY);
11537     delete_key(key2, "", access & KEY_WOW64_64KEY);
11538     RegDeleteKeyA(key3, "");
11539     RegCloseKey(key1);
11540     RegCloseKey(key2);
11541     RegCloseKey(key3);
11542     LocalFree(usersid);
11543 }
11544
11545 START_TEST(msi)
11546 {
11547     init_functionpointers();
11548
11549     if (pIsWow64Process)
11550         pIsWow64Process(GetCurrentProcess(), &is_wow64);
11551
11552     test_usefeature();
11553     test_null();
11554     test_getcomponentpath();
11555     test_MsiGetFileHash();
11556
11557     if (!pConvertSidToStringSidA)
11558         win_skip("ConvertSidToStringSidA not implemented\n");
11559     else
11560     {
11561         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
11562         test_MsiQueryProductState();
11563         test_MsiQueryFeatureState();
11564         test_MsiQueryComponentState();
11565         test_MsiGetComponentPath();
11566         test_MsiGetProductCode();
11567         test_MsiEnumClients();
11568         test_MsiGetProductInfo();
11569         test_MsiGetProductInfoEx();
11570         test_MsiGetUserInfo();
11571         test_MsiOpenProduct();
11572         test_MsiEnumPatchesEx();
11573         test_MsiEnumPatches();
11574         test_MsiGetPatchInfoEx();
11575         test_MsiGetPatchInfo();
11576         test_MsiEnumProducts();
11577     }
11578
11579     test_MsiGetFileVersion();
11580 }