msi: Factor out the MsiEnumPatchesEx tests and test the NULL szUserSid and an szUserS...
[wine] / dlls / msi / tests / msi.c
1 /*
2  * tests for Microsoft Installer functionality
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_MSI 300
22
23 #include <stdio.h>
24 #include <windows.h>
25 #include <msi.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <sddl.h>
29
30 #include "wine/test.h"
31
32 static const char msifile[] = "winetest.msi";
33
34 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
35
36 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
37     (LPCSTR, LPCSTR, LPSTR, DWORD*);
38 static UINT (WINAPI *pMsiGetFileHashA)
39     (LPCSTR, DWORD, PMSIFILEHASHINFO);
40 static UINT (WINAPI *pMsiGetProductInfoExA)
41     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
42 static UINT (WINAPI *pMsiOpenPackageExA)
43     (LPCSTR, DWORD, MSIHANDLE*);
44 static UINT (WINAPI *pMsiOpenPackageExW)
45     (LPCWSTR, DWORD, MSIHANDLE*);
46 static UINT (WINAPI *pMsiEnumPatchesExA)
47     (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
48     MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
49 static UINT (WINAPI *pMsiQueryComponentStateA)
50     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
51 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
52     (LPCSTR, LPCSTR ,DWORD, DWORD);
53 static UINT (WINAPI *pMsiGetPatchInfoExA)
54     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
55
56 static void init_functionpointers(void)
57 {
58     HMODULE hmsi = GetModuleHandleA("msi.dll");
59     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
60
61 #define GET_PROC(dll, func) \
62     p ## func = (void *)GetProcAddress(dll, #func); \
63     if(!p ## func) \
64       trace("GetProcAddress(%s) failed\n", #func);
65
66     GET_PROC(hmsi, MsiGetComponentPathA)
67     GET_PROC(hmsi, MsiGetFileHashA)
68     GET_PROC(hmsi, MsiGetProductInfoExA)
69     GET_PROC(hmsi, MsiOpenPackageExA)
70     GET_PROC(hmsi, MsiOpenPackageExW)
71     GET_PROC(hmsi, MsiEnumPatchesExA)
72     GET_PROC(hmsi, MsiQueryComponentStateA)
73     GET_PROC(hmsi, MsiUseFeatureExA)
74     GET_PROC(hmsi, MsiGetPatchInfoExA)
75
76     GET_PROC(hadvapi32, ConvertSidToStringSidA)
77
78 #undef GET_PROC
79 }
80
81 static UINT run_query(MSIHANDLE hdb, const char *query)
82 {
83     MSIHANDLE hview = 0;
84     UINT r;
85
86     r = MsiDatabaseOpenView(hdb, query, &hview);
87     if (r != ERROR_SUCCESS)
88         return r;
89
90     r = MsiViewExecute(hview, 0);
91     if (r == ERROR_SUCCESS)
92         r = MsiViewClose(hview);
93     MsiCloseHandle(hview);
94     return r;
95 }
96
97 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
98 {
99     UINT res;
100     MSIHANDLE suminfo;
101
102     /* build summary info */
103     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
104     ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
105
106     res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
107                                     "Installation Database");
108     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
109
110     res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
111                                     "Installation Database");
112     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
113
114     res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
115                                     "Wine Hackers");
116     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
117
118     res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
119                                     ";1033");
120     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
121
122     res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
123                                     "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
124     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
125
126     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
127     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
128
129     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
130     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
131
132     res = MsiSummaryInfoPersist(suminfo);
133     ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
134
135     res = MsiCloseHandle(suminfo);
136     ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
137
138     return res;
139 }
140
141 static MSIHANDLE create_package_db(LPSTR prodcode)
142 {
143     MSIHANDLE hdb = 0;
144     CHAR query[MAX_PATH];
145     UINT res;
146
147     DeleteFile(msifile);
148
149     /* create an empty database */
150     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
151     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
152     if (res != ERROR_SUCCESS)
153         return hdb;
154
155     res = MsiDatabaseCommit(hdb);
156     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
157
158     set_summary_info(hdb, prodcode);
159
160     res = run_query(hdb,
161             "CREATE TABLE `Directory` ( "
162             "`Directory` CHAR(255) NOT NULL, "
163             "`Directory_Parent` CHAR(255), "
164             "`DefaultDir` CHAR(255) NOT NULL "
165             "PRIMARY KEY `Directory`)");
166     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
167
168     res = run_query(hdb,
169             "CREATE TABLE `Property` ( "
170             "`Property` CHAR(72) NOT NULL, "
171             "`Value` CHAR(255) "
172             "PRIMARY KEY `Property`)");
173     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
174
175     sprintf(query, "INSERT INTO `Property` "
176             "(`Property`, `Value`) "
177             "VALUES( 'ProductCode', '%s' )", prodcode);
178     res = run_query(hdb, query);
179     ok(res == ERROR_SUCCESS , "Failed\n");
180
181     res = MsiDatabaseCommit(hdb);
182     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
183
184     return hdb;
185 }
186
187 static void test_usefeature(void)
188 {
189     INSTALLSTATE r;
190
191     if (!pMsiUseFeatureExA)
192     {
193         skip("MsiUseFeatureExA not implemented\n");
194         return;
195     }
196
197     r = MsiQueryFeatureState(NULL,NULL);
198     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
199
200     r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
201     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
202
203     r = pMsiUseFeatureExA(NULL,NULL,0,0);
204     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
205
206     r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
207     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
208
209     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
210                          NULL, -2, 0 );
211     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
212
213     r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}", 
214                          "WORDVIEWFiles", -2, 0 );
215     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
216
217     r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}", 
218                          "WORDVIEWFiles", -2, 0 );
219     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
220
221     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
222                          "WORDVIEWFiles", -2, 1 );
223     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
224 }
225
226 static void test_null(void)
227 {
228     MSIHANDLE hpkg;
229     UINT r;
230     HKEY hkey;
231     DWORD dwType, cbData;
232     LPBYTE lpData = NULL;
233     INSTALLSTATE state;
234
235     r = pMsiOpenPackageExW(NULL, 0, &hpkg);
236     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
237
238     state = MsiQueryProductStateW(NULL);
239     ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
240
241     r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
242     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
243
244     r = MsiConfigureFeatureW(NULL, NULL, 0);
245     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
246
247     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
248     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
249
250     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", 0);
251     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
252
253     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", INSTALLSTATE_DEFAULT);
254     ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
255
256     /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
257      * necessary registry values */
258
259     /* empty product string */
260     r = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", &hkey);
261     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
262
263     r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
264     ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
265     if ( r == ERROR_SUCCESS )
266     {
267         lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
268         if (!lpData)
269             skip("Out of memory\n");
270         else
271         {
272             r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
273             ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
274         }
275     }
276
277     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
278     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
279
280     r = MsiGetProductInfoA("", "", NULL, NULL);
281     ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
282
283     if (lpData)
284     {
285         r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
286         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
287
288         HeapFree(GetProcessHeap(), 0, lpData);
289     }
290     else
291     {
292         r = RegDeleteValueA(hkey, NULL);
293         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
294     }
295
296     r = RegCloseKey(hkey);
297     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
298
299     /* empty attribute */
300     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", &hkey);
301     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
302
303     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
304     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
305
306     r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
307     ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
308
309     r = RegCloseKey(hkey);
310     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
311
312     r = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}");
313     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
314 }
315
316 static void test_getcomponentpath(void)
317 {
318     INSTALLSTATE r;
319     char buffer[0x100];
320     DWORD sz;
321
322     if(!pMsiGetComponentPathA)
323         return;
324
325     r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
326     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
327
328     r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
329     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
330
331     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
332     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
333
334     sz = sizeof buffer;
335     buffer[0]=0;
336     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
337     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
338
339     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
340         "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
341     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
342
343     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
344         "{00000000-0000-0000-0000-00000000}", buffer, &sz );
345     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
346
347     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
348         "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
349     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
350
351     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
352                             "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
353     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
354 }
355
356 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
357 {
358     HANDLE file;
359     DWORD written;
360
361     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
362     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
363     WriteFile(file, data, strlen(data), &written, NULL);
364
365     if (size)
366     {
367         SetFilePointer(file, size, NULL, FILE_BEGIN);
368         SetEndOfFile(file);
369     }
370
371     CloseHandle(file);
372 }
373
374 #define HASHSIZE sizeof(MSIFILEHASHINFO)
375
376 static const struct
377 {
378     LPCSTR data;
379     DWORD size;
380     MSIFILEHASHINFO hash;
381 } hash_data[] =
382 {
383     { "abc", 0,
384       { HASHSIZE,
385         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
386       },
387     },
388
389     { "C:\\Program Files\\msitest\\caesar\n", 0,
390       { HASHSIZE,
391         { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
392       },
393     },
394
395     { "C:\\Program Files\\msitest\\caesar\n", 500,
396       { HASHSIZE,
397         { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
398       },
399     },
400 };
401
402 static void test_MsiGetFileHash(void)
403 {
404     const char name[] = "msitest.bin";
405     UINT r;
406     MSIFILEHASHINFO hash;
407     DWORD i;
408
409     if (!pMsiGetFileHashA)
410     {
411         skip("MsiGetFileHash not implemented\n");
412         return;
413     }
414
415     hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
416
417     /* szFilePath is NULL */
418     r = pMsiGetFileHashA(NULL, 0, &hash);
419     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
420
421     /* szFilePath is empty */
422     r = pMsiGetFileHashA("", 0, &hash);
423     ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
424        "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
425
426     /* szFilePath is nonexistent */
427     r = pMsiGetFileHashA(name, 0, &hash);
428     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
429
430     /* dwOptions is non-zero */
431     r = pMsiGetFileHashA(name, 1, &hash);
432     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
433
434     /* pHash.dwFileHashInfoSize is not correct */
435     hash.dwFileHashInfoSize = 0;
436     r = pMsiGetFileHashA(name, 0, &hash);
437     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
438
439     /* pHash is NULL */
440     r = pMsiGetFileHashA(name, 0, NULL);
441     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
442
443     for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
444     {
445         int ret;
446
447         create_file(name, hash_data[i].data, hash_data[i].size);
448
449         memset(&hash, 0, sizeof(MSIFILEHASHINFO));
450         hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
451
452         r = pMsiGetFileHashA(name, 0, &hash);
453         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
454
455         ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
456         ok(ret == 0 ||
457            broken(ret != 0), /* win95 */
458            "Hash incorrect\n");
459
460         DeleteFile(name);
461     }
462 }
463
464 /* copied from dlls/msi/registry.c */
465 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
466 {
467     DWORD i,n=1;
468     GUID guid;
469
470     if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
471         return FALSE;
472
473     for(i=0; i<8; i++)
474         out[7-i] = in[n++];
475     n++;
476     for(i=0; i<4; i++)
477         out[11-i] = in[n++];
478     n++;
479     for(i=0; i<4; i++)
480         out[15-i] = in[n++];
481     n++;
482     for(i=0; i<2; i++)
483     {
484         out[17+i*2] = in[n++];
485         out[16+i*2] = in[n++];
486     }
487     n++;
488     for( ; i<8; i++)
489     {
490         out[17+i*2] = in[n++];
491         out[16+i*2] = in[n++];
492     }
493     out[32]=0;
494     return TRUE;
495 }
496
497 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
498 {
499     WCHAR guidW[MAX_PATH];
500     WCHAR squashedW[MAX_PATH];
501     GUID guid;
502     HRESULT hr;
503     int size;
504
505     hr = CoCreateGuid(&guid);
506     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
507
508     size = StringFromGUID2(&guid, guidW, MAX_PATH);
509     ok(size == 39, "Expected 39, got %d\n", hr);
510
511     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
512     squash_guid(guidW, squashedW);
513     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
514 }
515
516 static void get_user_sid(LPSTR *usersid)
517 {
518     HANDLE token;
519     BYTE buf[1024];
520     DWORD size;
521     PTOKEN_USER user;
522
523     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
524     size = sizeof(buf);
525     GetTokenInformation(token, TokenUser, buf, size, &size);
526     user = (PTOKEN_USER)buf;
527     pConvertSidToStringSidA(user->User.Sid, usersid);
528     CloseHandle(token);
529 }
530
531 static void test_MsiQueryProductState(void)
532 {
533     CHAR prodcode[MAX_PATH];
534     CHAR prod_squashed[MAX_PATH];
535     CHAR keypath[MAX_PATH*2];
536     LPSTR usersid;
537     INSTALLSTATE state;
538     LONG res;
539     HKEY userkey, localkey, props;
540     HKEY prodkey;
541     DWORD data;
542
543     create_test_guid(prodcode, prod_squashed);
544     get_user_sid(&usersid);
545
546     /* NULL prodcode */
547     state = MsiQueryProductStateA(NULL);
548     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
549
550     /* empty prodcode */
551     state = MsiQueryProductStateA("");
552     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
553
554     /* garbage prodcode */
555     state = MsiQueryProductStateA("garbage");
556     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
557
558     /* guid without brackets */
559     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
560     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
561
562     /* guid with brackets */
563     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
564     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
565
566     /* same length as guid, but random */
567     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
568     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
569
570     /* MSIINSTALLCONTEXT_USERUNMANAGED */
571
572     state = MsiQueryProductStateA(prodcode);
573     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
574
575     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
576     lstrcatA(keypath, prod_squashed);
577
578     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
580
581     /* user product key exists */
582     state = MsiQueryProductStateA(prodcode);
583     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
584
585     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
586     lstrcatA(keypath, prodcode);
587
588     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
590
591     /* local uninstall key exists */
592     state = MsiQueryProductStateA(prodcode);
593     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
594
595     data = 1;
596     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
597     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
598
599     /* WindowsInstaller value exists */
600     state = MsiQueryProductStateA(prodcode);
601     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
602
603     RegDeleteValueA(localkey, "WindowsInstaller");
604     RegDeleteKeyA(localkey, "");
605
606     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
607     lstrcatA(keypath, usersid);
608     lstrcatA(keypath, "\\Products\\");
609     lstrcatA(keypath, prod_squashed);
610
611     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
612     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
613
614     /* local product key exists */
615     state = MsiQueryProductStateA(prodcode);
616     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
617
618     res = RegCreateKeyA(localkey, "InstallProperties", &props);
619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
620
621     /* install properties key exists */
622     state = MsiQueryProductStateA(prodcode);
623     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
624
625     data = 1;
626     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
628
629     /* WindowsInstaller value exists */
630     state = MsiQueryProductStateA(prodcode);
631     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
632
633     data = 2;
634     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
635     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
636
637     /* WindowsInstaller value is not 1 */
638     state = MsiQueryProductStateA(prodcode);
639     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
640
641     RegDeleteKeyA(userkey, "");
642
643     /* user product key does not exist */
644     state = MsiQueryProductStateA(prodcode);
645     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
646
647     RegDeleteValueA(props, "WindowsInstaller");
648     RegDeleteKeyA(props, "");
649     RegCloseKey(props);
650     RegDeleteKeyA(localkey, "");
651     RegCloseKey(localkey);
652     RegDeleteKeyA(userkey, "");
653     RegCloseKey(userkey);
654
655     /* MSIINSTALLCONTEXT_USERMANAGED */
656
657     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
658     lstrcatA(keypath, usersid);
659     lstrcatA(keypath, "\\Installer\\Products\\");
660     lstrcatA(keypath, prod_squashed);
661
662     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
663     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
664
665     state = MsiQueryProductStateA(prodcode);
666     ok(state == INSTALLSTATE_ADVERTISED,
667        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
668
669     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
670     lstrcatA(keypath, usersid);
671     lstrcatA(keypath, "\\Products\\");
672     lstrcatA(keypath, prod_squashed);
673
674     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
675     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
676
677     state = MsiQueryProductStateA(prodcode);
678     ok(state == INSTALLSTATE_ADVERTISED,
679        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
680
681     res = RegCreateKeyA(localkey, "InstallProperties", &props);
682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
683
684     state = MsiQueryProductStateA(prodcode);
685     ok(state == INSTALLSTATE_ADVERTISED,
686        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
687
688     data = 1;
689     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
690     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
691
692     /* WindowsInstaller value exists */
693     state = MsiQueryProductStateA(prodcode);
694     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
695
696     RegDeleteValueA(props, "WindowsInstaller");
697     RegDeleteKeyA(props, "");
698     RegCloseKey(props);
699     RegDeleteKeyA(localkey, "");
700     RegCloseKey(localkey);
701     RegDeleteKeyA(prodkey, "");
702     RegCloseKey(prodkey);
703
704     /* MSIINSTALLCONTEXT_MACHINE */
705
706     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
707     lstrcatA(keypath, prod_squashed);
708
709     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
711
712     state = MsiQueryProductStateA(prodcode);
713     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
714
715     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
716     lstrcatA(keypath, "S-1-5-18\\Products\\");
717     lstrcatA(keypath, prod_squashed);
718
719     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
721
722     state = MsiQueryProductStateA(prodcode);
723     ok(state == INSTALLSTATE_ADVERTISED,
724        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
725
726     res = RegCreateKeyA(localkey, "InstallProperties", &props);
727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
728
729     state = MsiQueryProductStateA(prodcode);
730     ok(state == INSTALLSTATE_ADVERTISED,
731        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
732
733     data = 1;
734     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
735     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
736
737     /* WindowsInstaller value exists */
738     state = MsiQueryProductStateA(prodcode);
739     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
740
741     RegDeleteValueA(props, "WindowsInstaller");
742     RegDeleteKeyA(props, "");
743     RegCloseKey(props);
744     RegDeleteKeyA(localkey, "");
745     RegCloseKey(localkey);
746     RegDeleteKeyA(prodkey, "");
747     RegCloseKey(prodkey);
748
749     LocalFree(usersid);
750 }
751
752 static const char table_enc85[] =
753 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
754 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
755 "yz{}~";
756
757 /*
758  *  Encodes a base85 guid given a GUID pointer
759  *  Caller should provide a 21 character buffer for the encoded string.
760  *
761  *  returns TRUE if successful, FALSE if not
762  */
763 static BOOL encode_base85_guid( GUID *guid, LPWSTR str )
764 {
765     unsigned int x, *p, i;
766
767     p = (unsigned int*) guid;
768     for( i=0; i<4; i++ )
769     {
770         x = p[i];
771         *str++ = table_enc85[x%85];
772         x = x/85;
773         *str++ = table_enc85[x%85];
774         x = x/85;
775         *str++ = table_enc85[x%85];
776         x = x/85;
777         *str++ = table_enc85[x%85];
778         x = x/85;
779         *str++ = table_enc85[x%85];
780     }
781     *str = 0;
782
783     return TRUE;
784 }
785
786 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
787 {
788     WCHAR guidW[MAX_PATH];
789     WCHAR base85W[MAX_PATH];
790     WCHAR squashedW[MAX_PATH];
791     GUID guid;
792     HRESULT hr;
793     int size;
794
795     hr = CoCreateGuid(&guid);
796     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
797
798     size = StringFromGUID2(&guid, guidW, MAX_PATH);
799     ok(size == 39, "Expected 39, got %d\n", hr);
800
801     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
802     encode_base85_guid(&guid, base85W);
803     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
804     squash_guid(guidW, squashedW);
805     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
806 }
807
808 static void test_MsiQueryFeatureState(void)
809 {
810     HKEY userkey, localkey, compkey;
811     CHAR prodcode[MAX_PATH];
812     CHAR prod_squashed[MAX_PATH];
813     CHAR component[MAX_PATH];
814     CHAR comp_base85[MAX_PATH];
815     CHAR comp_squashed[MAX_PATH];
816     CHAR keypath[MAX_PATH*2];
817     INSTALLSTATE state;
818     LPSTR usersid;
819     LONG res;
820
821     create_test_guid(prodcode, prod_squashed);
822     compose_base85_guid(component, comp_base85, comp_squashed);
823     get_user_sid(&usersid);
824
825     /* NULL prodcode */
826     state = MsiQueryFeatureStateA(NULL, "feature");
827     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
828
829     /* empty prodcode */
830     state = MsiQueryFeatureStateA("", "feature");
831     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
832
833     /* garbage prodcode */
834     state = MsiQueryFeatureStateA("garbage", "feature");
835     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
836
837     /* guid without brackets */
838     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
839     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
840
841     /* guid with brackets */
842     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
843     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
844
845     /* same length as guid, but random */
846     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
847     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
848
849     /* NULL szFeature */
850     state = MsiQueryFeatureStateA(prodcode, NULL);
851     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
852
853     /* empty szFeature */
854     state = MsiQueryFeatureStateA(prodcode, "");
855     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
856
857     /* feature key does not exist yet */
858     state = MsiQueryFeatureStateA(prodcode, "feature");
859     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
860
861     /* MSIINSTALLCONTEXT_USERUNMANAGED */
862
863     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
864     lstrcatA(keypath, prod_squashed);
865
866     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
867     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
868
869     /* feature key exists */
870     state = MsiQueryFeatureStateA(prodcode, "feature");
871     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
872
873     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
874     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
875
876     /* feature value exists */
877     state = MsiQueryFeatureStateA(prodcode, "feature");
878     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
879
880     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
881     lstrcatA(keypath, usersid);
882     lstrcatA(keypath, "\\Products\\");
883     lstrcatA(keypath, prod_squashed);
884     lstrcatA(keypath, "\\Features");
885
886     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
888
889     /* userdata features key exists */
890     state = MsiQueryFeatureStateA(prodcode, "feature");
891     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
892
893     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
894     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
895
896     state = MsiQueryFeatureStateA(prodcode, "feature");
897     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
898
899     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
900     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
901
902     state = MsiQueryFeatureStateA(prodcode, "feature");
903     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
904
905     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
907
908     state = MsiQueryFeatureStateA(prodcode, "feature");
909     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
910
911     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
913
914     state = MsiQueryFeatureStateA(prodcode, "feature");
915     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
916
917     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
918     lstrcatA(keypath, usersid);
919     lstrcatA(keypath, "\\Components\\");
920     lstrcatA(keypath, comp_squashed);
921
922     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
924
925     state = MsiQueryFeatureStateA(prodcode, "feature");
926     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
927
928     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
930
931     state = MsiQueryFeatureStateA(prodcode, "feature");
932     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
933
934     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
936
937     /* INSTALLSTATE_LOCAL */
938     state = MsiQueryFeatureStateA(prodcode, "feature");
939     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
940
941     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
943
944     /* INSTALLSTATE_SOURCE */
945     state = MsiQueryFeatureStateA(prodcode, "feature");
946     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
947
948     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
949     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
950
951     /* bad INSTALLSTATE_SOURCE */
952     state = MsiQueryFeatureStateA(prodcode, "feature");
953     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
954
955     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
957
958     /* INSTALLSTATE_SOURCE */
959     state = MsiQueryFeatureStateA(prodcode, "feature");
960     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
961
962     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
964
965     /* bad INSTALLSTATE_SOURCE */
966     state = MsiQueryFeatureStateA(prodcode, "feature");
967     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
968
969     RegDeleteValueA(compkey, prod_squashed);
970     RegDeleteKeyA(compkey, "");
971     RegDeleteValueA(localkey, "feature");
972     RegDeleteValueA(userkey, "feature");
973     RegDeleteKeyA(userkey, "");
974     RegCloseKey(compkey);
975     RegCloseKey(localkey);
976     RegCloseKey(userkey);
977
978     /* MSIINSTALLCONTEXT_USERMANAGED */
979
980     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
981     lstrcatA(keypath, usersid);
982     lstrcatA(keypath, "\\Installer\\Features\\");
983     lstrcatA(keypath, prod_squashed);
984
985     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
987
988     /* feature key exists */
989     state = MsiQueryFeatureStateA(prodcode, "feature");
990     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
991
992     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
993     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
994
995     /* feature value exists */
996     state = MsiQueryFeatureStateA(prodcode, "feature");
997     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
998
999     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1000     lstrcatA(keypath, usersid);
1001     lstrcatA(keypath, "\\Products\\");
1002     lstrcatA(keypath, prod_squashed);
1003     lstrcatA(keypath, "\\Features");
1004
1005     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1006     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1007
1008     /* userdata features key exists */
1009     state = MsiQueryFeatureStateA(prodcode, "feature");
1010     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1011
1012     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1014
1015     state = MsiQueryFeatureStateA(prodcode, "feature");
1016     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1017
1018     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1020
1021     state = MsiQueryFeatureStateA(prodcode, "feature");
1022     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1023
1024     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1026
1027     state = MsiQueryFeatureStateA(prodcode, "feature");
1028     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1029
1030     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
1031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1032
1033     state = MsiQueryFeatureStateA(prodcode, "feature");
1034     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1035
1036     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1037     lstrcatA(keypath, usersid);
1038     lstrcatA(keypath, "\\Components\\");
1039     lstrcatA(keypath, comp_squashed);
1040
1041     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1042     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1043
1044     state = MsiQueryFeatureStateA(prodcode, "feature");
1045     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1046
1047     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1049
1050     state = MsiQueryFeatureStateA(prodcode, "feature");
1051     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1052
1053     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
1054     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1055
1056     state = MsiQueryFeatureStateA(prodcode, "feature");
1057     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1058
1059     RegDeleteValueA(compkey, prod_squashed);
1060     RegDeleteKeyA(compkey, "");
1061     RegDeleteValueA(localkey, "feature");
1062     RegDeleteValueA(userkey, "feature");
1063     RegDeleteKeyA(userkey, "");
1064     RegCloseKey(compkey);
1065     RegCloseKey(localkey);
1066     RegCloseKey(userkey);
1067
1068     /* MSIINSTALLCONTEXT_MACHINE */
1069
1070     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1071     lstrcatA(keypath, prod_squashed);
1072
1073     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
1074     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1075
1076     /* feature key exists */
1077     state = MsiQueryFeatureStateA(prodcode, "feature");
1078     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1079
1080     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1081     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1082
1083     /* feature value exists */
1084     state = MsiQueryFeatureStateA(prodcode, "feature");
1085     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1086
1087     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1088     lstrcatA(keypath, "S-1-5-18\\Products\\");
1089     lstrcatA(keypath, prod_squashed);
1090     lstrcatA(keypath, "\\Features");
1091
1092     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1094
1095     /* userdata features key exists */
1096     state = MsiQueryFeatureStateA(prodcode, "feature");
1097     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1098
1099     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1101
1102     state = MsiQueryFeatureStateA(prodcode, "feature");
1103     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1104
1105     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1107
1108     state = MsiQueryFeatureStateA(prodcode, "feature");
1109     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1110
1111     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1113
1114     state = MsiQueryFeatureStateA(prodcode, "feature");
1115     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1116
1117     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
1118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1119
1120     state = MsiQueryFeatureStateA(prodcode, "feature");
1121     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1122
1123     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1124     lstrcatA(keypath, "S-1-5-18\\Components\\");
1125     lstrcatA(keypath, comp_squashed);
1126
1127     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
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 *)"", 1);
1134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1135
1136     state = MsiQueryFeatureStateA(prodcode, "feature");
1137     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1138
1139     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
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     RegDeleteKeyA(compkey, "");
1147     RegDeleteValueA(localkey, "feature");
1148     RegDeleteValueA(userkey, "feature");
1149     RegDeleteKeyA(userkey, "");
1150     RegCloseKey(compkey);
1151     RegCloseKey(localkey);
1152     RegCloseKey(userkey);
1153 }
1154
1155 static void test_MsiQueryComponentState(void)
1156 {
1157     HKEY compkey, prodkey;
1158     CHAR prodcode[MAX_PATH];
1159     CHAR prod_squashed[MAX_PATH];
1160     CHAR component[MAX_PATH];
1161     CHAR comp_base85[MAX_PATH];
1162     CHAR comp_squashed[MAX_PATH];
1163     CHAR keypath[MAX_PATH];
1164     INSTALLSTATE state;
1165     LPSTR usersid;
1166     LONG res;
1167     UINT r;
1168
1169     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1170
1171     if (!pMsiQueryComponentStateA)
1172     {
1173         skip("MsiQueryComponentStateA not implemented\n");
1174         return;
1175     }
1176
1177     create_test_guid(prodcode, prod_squashed);
1178     compose_base85_guid(component, comp_base85, comp_squashed);
1179     get_user_sid(&usersid);
1180
1181     /* NULL szProductCode */
1182     state = MAGIC_ERROR;
1183     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1184     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1185     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1186
1187     /* empty szProductCode */
1188     state = MAGIC_ERROR;
1189     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1190     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1191     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1192
1193     /* random szProductCode */
1194     state = MAGIC_ERROR;
1195     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1196     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1197     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1198
1199     /* GUID-length szProductCode */
1200     state = MAGIC_ERROR;
1201     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1202     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1203     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1204
1205     /* GUID-length with brackets */
1206     state = MAGIC_ERROR;
1207     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1208     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1209     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1210
1211     /* actual GUID */
1212     state = MAGIC_ERROR;
1213     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1214     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1215     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1216
1217     state = MAGIC_ERROR;
1218     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1219     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1220     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1221
1222     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1223     lstrcatA(keypath, prod_squashed);
1224
1225     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1227
1228     state = MAGIC_ERROR;
1229     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1230     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1231     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1232
1233     RegDeleteKeyA(prodkey, "");
1234     RegCloseKey(prodkey);
1235
1236     /* create local system product key */
1237     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1238     lstrcatA(keypath, prod_squashed);
1239     lstrcatA(keypath, "\\InstallProperties");
1240
1241     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1242     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1243
1244     /* local system product key exists */
1245     state = MAGIC_ERROR;
1246     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1247     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1248     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1249
1250     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1251     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1252
1253     /* LocalPackage value exists */
1254     state = MAGIC_ERROR;
1255     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1256     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1257     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1258
1259     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1260     lstrcatA(keypath, comp_squashed);
1261
1262     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1263     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1264
1265     /* component key exists */
1266     state = MAGIC_ERROR;
1267     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1268     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1269     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1270
1271     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1273
1274     /* component\product exists */
1275     state = MAGIC_ERROR;
1276     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1278     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1279        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1280
1281     /* NULL component, product exists */
1282     state = MAGIC_ERROR;
1283     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1284     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1285     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1286
1287     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1289
1290     /* INSTALLSTATE_LOCAL */
1291     state = MAGIC_ERROR;
1292     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1293     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1294     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1295
1296     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1297     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1298
1299     /* INSTALLSTATE_SOURCE */
1300     state = MAGIC_ERROR;
1301     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1303     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1304
1305     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1306     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1307
1308     /* bad INSTALLSTATE_SOURCE */
1309     state = MAGIC_ERROR;
1310     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1311     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1312     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1313
1314     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1315     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1316
1317     /* INSTALLSTATE_SOURCE */
1318     state = MAGIC_ERROR;
1319     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1320     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1321     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1322
1323     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1325
1326     /* bad INSTALLSTATE_SOURCE */
1327     state = MAGIC_ERROR;
1328     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1329     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1330     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1331
1332     RegDeleteValueA(prodkey, "LocalPackage");
1333     RegDeleteKeyA(prodkey, "");
1334     RegDeleteValueA(compkey, prod_squashed);
1335     RegDeleteKeyA(prodkey, "");
1336     RegCloseKey(prodkey);
1337     RegCloseKey(compkey);
1338
1339     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1340
1341     state = MAGIC_ERROR;
1342     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1343     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1344     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1345
1346     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1347     lstrcatA(keypath, prod_squashed);
1348
1349     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1351
1352     state = MAGIC_ERROR;
1353     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1354     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1355     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1356
1357     RegDeleteKeyA(prodkey, "");
1358     RegCloseKey(prodkey);
1359
1360     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1361     lstrcatA(keypath, usersid);
1362     lstrcatA(keypath, "\\Products\\");
1363     lstrcatA(keypath, prod_squashed);
1364     lstrcatA(keypath, "\\InstallProperties");
1365
1366     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1368
1369     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1371
1372     RegCloseKey(prodkey);
1373
1374     state = MAGIC_ERROR;
1375     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1376     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1377     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1378
1379     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1380     lstrcatA(keypath, usersid);
1381     lstrcatA(keypath, "\\Components\\");
1382     lstrcatA(keypath, comp_squashed);
1383
1384     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1385     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1386
1387     /* component key exists */
1388     state = MAGIC_ERROR;
1389     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1390     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1391     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1392
1393     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1395
1396     /* component\product exists */
1397     state = MAGIC_ERROR;
1398     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1399     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1400     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1401        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, 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     state = MAGIC_ERROR;
1407     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1408     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1409     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1410
1411     /* MSIINSTALLCONTEXT_USERMANAGED */
1412
1413     state = MAGIC_ERROR;
1414     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1415     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1416     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1417
1418     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1419     lstrcatA(keypath, prod_squashed);
1420
1421     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1423
1424     state = MAGIC_ERROR;
1425     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1426     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1427     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1428
1429     RegDeleteKeyA(prodkey, "");
1430     RegCloseKey(prodkey);
1431
1432     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1433     lstrcatA(keypath, usersid);
1434     lstrcatA(keypath, "\\Installer\\Products\\");
1435     lstrcatA(keypath, prod_squashed);
1436
1437     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1439
1440     state = MAGIC_ERROR;
1441     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1442     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1443     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1444
1445     RegDeleteKeyA(prodkey, "");
1446     RegCloseKey(prodkey);
1447
1448     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1449     lstrcatA(keypath, usersid);
1450     lstrcatA(keypath, "\\Products\\");
1451     lstrcatA(keypath, prod_squashed);
1452     lstrcatA(keypath, "\\InstallProperties");
1453
1454     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1455     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1456
1457     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1459
1460     state = MAGIC_ERROR;
1461     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1463     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1464
1465     RegDeleteValueA(prodkey, "LocalPackage");
1466     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1467     RegDeleteKeyA(prodkey, "");
1468     RegDeleteValueA(compkey, prod_squashed);
1469     RegDeleteKeyA(compkey, "");
1470     RegCloseKey(prodkey);
1471     RegCloseKey(compkey);
1472 }
1473
1474 static void test_MsiGetComponentPath(void)
1475 {
1476     HKEY compkey, prodkey, installprop;
1477     CHAR prodcode[MAX_PATH];
1478     CHAR prod_squashed[MAX_PATH];
1479     CHAR component[MAX_PATH];
1480     CHAR comp_base85[MAX_PATH];
1481     CHAR comp_squashed[MAX_PATH];
1482     CHAR keypath[MAX_PATH];
1483     CHAR path[MAX_PATH];
1484     INSTALLSTATE state;
1485     LPSTR usersid;
1486     DWORD size, val;
1487     LONG res;
1488
1489     create_test_guid(prodcode, prod_squashed);
1490     compose_base85_guid(component, comp_base85, comp_squashed);
1491     get_user_sid(&usersid);
1492
1493     /* NULL szProduct */
1494     size = MAX_PATH;
1495     state = MsiGetComponentPathA(NULL, component, path, &size);
1496     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1497     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1498
1499     /* NULL szComponent */
1500     size = MAX_PATH;
1501     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1502     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1503     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1504
1505     /* NULL lpPathBuf */
1506     size = MAX_PATH;
1507     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1508     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1509     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1510
1511     /* NULL pcchBuf */
1512     size = MAX_PATH;
1513     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1514     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1515     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1516
1517     /* all params valid */
1518     size = MAX_PATH;
1519     state = MsiGetComponentPathA(prodcode, component, path, &size);
1520     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1521     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1522
1523     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1524     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1525     lstrcatA(keypath, comp_squashed);
1526
1527     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1528     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1529
1530     /* local system component key exists */
1531     size = MAX_PATH;
1532     state = MsiGetComponentPathA(prodcode, component, path, &size);
1533     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1534     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1535
1536     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1537     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1538
1539     /* product value exists */
1540     size = MAX_PATH;
1541     state = MsiGetComponentPathA(prodcode, component, path, &size);
1542     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1543     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1544     ok(size == 10, "Expected 10, got %d\n", size);
1545
1546     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1547     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1548     lstrcatA(keypath, prod_squashed);
1549     lstrcatA(keypath, "\\InstallProperties");
1550
1551     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1552     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1553
1554     val = 1;
1555     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1557
1558     /* install properties key exists */
1559     size = MAX_PATH;
1560     state = MsiGetComponentPathA(prodcode, component, path, &size);
1561     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1562     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1563     ok(size == 10, "Expected 10, got %d\n", size);
1564
1565     create_file("C:\\imapath", "C:\\imapath", 11);
1566
1567     /* file exists */
1568     size = MAX_PATH;
1569     state = MsiGetComponentPathA(prodcode, component, path, &size);
1570     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1571     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1572     ok(size == 10, "Expected 10, got %d\n", size);
1573
1574     RegDeleteValueA(compkey, prod_squashed);
1575     RegDeleteKeyA(compkey, "");
1576     RegDeleteValueA(installprop, "WindowsInstaller");
1577     RegDeleteKeyA(installprop, "");
1578     RegCloseKey(compkey);
1579     RegCloseKey(installprop);
1580     DeleteFileA("C:\\imapath");
1581
1582     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1583     lstrcatA(keypath, "Installer\\UserData\\");
1584     lstrcatA(keypath, usersid);
1585     lstrcatA(keypath, "\\Components\\");
1586     lstrcatA(keypath, comp_squashed);
1587
1588     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1590
1591     /* user managed component key exists */
1592     size = MAX_PATH;
1593     state = MsiGetComponentPathA(prodcode, component, path, &size);
1594     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1595     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1596
1597     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1598     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1599
1600     /* product value exists */
1601     size = MAX_PATH;
1602     state = MsiGetComponentPathA(prodcode, component, path, &size);
1603     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1604     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1605     ok(size == 10, "Expected 10, got %d\n", size);
1606
1607     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1608     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1609     lstrcatA(keypath, prod_squashed);
1610     lstrcatA(keypath, "\\InstallProperties");
1611
1612     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1614
1615     val = 1;
1616     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1617     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1618
1619     /* install properties key exists */
1620     size = MAX_PATH;
1621     state = MsiGetComponentPathA(prodcode, component, path, &size);
1622     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1623     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1624     ok(size == 10, "Expected 10, got %d\n", size);
1625
1626     create_file("C:\\imapath", "C:\\imapath", 11);
1627
1628     /* file exists */
1629     size = MAX_PATH;
1630     state = MsiGetComponentPathA(prodcode, component, path, &size);
1631     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1632     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1633     ok(size == 10, "Expected 10, got %d\n", size);
1634
1635     RegDeleteValueA(compkey, prod_squashed);
1636     RegDeleteKeyA(compkey, "");
1637     RegDeleteValueA(installprop, "WindowsInstaller");
1638     RegDeleteKeyA(installprop, "");
1639     RegCloseKey(compkey);
1640     RegCloseKey(installprop);
1641     DeleteFileA("C:\\imapath");
1642
1643     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1644     lstrcatA(keypath, "Installer\\Managed\\");
1645     lstrcatA(keypath, usersid);
1646     lstrcatA(keypath, "\\Installer\\Products\\");
1647     lstrcatA(keypath, prod_squashed);
1648
1649     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1651
1652     /* user managed product key exists */
1653     size = MAX_PATH;
1654     state = MsiGetComponentPathA(prodcode, component, path, &size);
1655     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1656     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1657
1658     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1659     lstrcatA(keypath, "Installer\\UserData\\");
1660     lstrcatA(keypath, usersid);
1661     lstrcatA(keypath, "\\Components\\");
1662     lstrcatA(keypath, comp_squashed);
1663
1664     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1665     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1666
1667     /* user managed component key exists */
1668     size = MAX_PATH;
1669     state = MsiGetComponentPathA(prodcode, component, path, &size);
1670     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1671     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1672
1673     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1675
1676     /* product value exists */
1677     size = MAX_PATH;
1678     state = MsiGetComponentPathA(prodcode, component, path, &size);
1679     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1680     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1681     ok(size == 10, "Expected 10, got %d\n", size);
1682
1683     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1684     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1685     lstrcatA(keypath, prod_squashed);
1686     lstrcatA(keypath, "\\InstallProperties");
1687
1688     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1690
1691     val = 1;
1692     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1694
1695     /* install properties key exists */
1696     size = MAX_PATH;
1697     state = MsiGetComponentPathA(prodcode, component, path, &size);
1698     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1699     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1700     ok(size == 10, "Expected 10, got %d\n", size);
1701
1702     create_file("C:\\imapath", "C:\\imapath", 11);
1703
1704     /* file exists */
1705     size = MAX_PATH;
1706     state = MsiGetComponentPathA(prodcode, component, path, &size);
1707     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1708     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1709     ok(size == 10, "Expected 10, got %d\n", size);
1710
1711     RegDeleteValueA(compkey, prod_squashed);
1712     RegDeleteKeyA(prodkey, "");
1713     RegDeleteKeyA(compkey, "");
1714     RegDeleteValueA(installprop, "WindowsInstaller");
1715     RegDeleteKeyA(installprop, "");
1716     RegCloseKey(prodkey);
1717     RegCloseKey(compkey);
1718     RegCloseKey(installprop);
1719     DeleteFileA("C:\\imapath");
1720
1721     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1722     lstrcatA(keypath, prod_squashed);
1723
1724     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1726
1727     /* user unmanaged product key exists */
1728     size = MAX_PATH;
1729     state = MsiGetComponentPathA(prodcode, component, path, &size);
1730     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1731     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1732
1733     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1734     lstrcatA(keypath, "Installer\\UserData\\");
1735     lstrcatA(keypath, usersid);
1736     lstrcatA(keypath, "\\Components\\");
1737     lstrcatA(keypath, comp_squashed);
1738
1739     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1741
1742     /* user unmanaged component key exists */
1743     size = MAX_PATH;
1744     state = MsiGetComponentPathA(prodcode, component, path, &size);
1745     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1746     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1747
1748     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1749     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1750
1751     /* product value exists */
1752     size = MAX_PATH;
1753     state = MsiGetComponentPathA(prodcode, component, path, &size);
1754     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1755     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1756     ok(size == 10, "Expected 10, got %d\n", size);
1757
1758     create_file("C:\\imapath", "C:\\imapath", 11);
1759
1760     /* file exists */
1761     size = MAX_PATH;
1762     state = MsiGetComponentPathA(prodcode, component, path, &size);
1763     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1764     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1765     ok(size == 10, "Expected 10, got %d\n", size);
1766
1767     RegDeleteValueA(compkey, prod_squashed);
1768     RegDeleteKeyA(prodkey, "");
1769     RegDeleteKeyA(compkey, "");
1770     RegCloseKey(prodkey);
1771     RegCloseKey(compkey);
1772     DeleteFileA("C:\\imapath");
1773
1774     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1775     lstrcatA(keypath, prod_squashed);
1776
1777     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1779
1780     /* local classes product key exists */
1781     size = MAX_PATH;
1782     state = MsiGetComponentPathA(prodcode, component, path, &size);
1783     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1784     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1785
1786     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1787     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1788     lstrcatA(keypath, comp_squashed);
1789
1790     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1792
1793     /* local user component key exists */
1794     size = MAX_PATH;
1795     state = MsiGetComponentPathA(prodcode, component, path, &size);
1796     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1797     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1798
1799     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1800     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1801
1802     /* product value exists */
1803     size = MAX_PATH;
1804     state = MsiGetComponentPathA(prodcode, component, path, &size);
1805     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1806     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1807     ok(size == 10, "Expected 10, got %d\n", size);
1808
1809     create_file("C:\\imapath", "C:\\imapath", 11);
1810
1811     /* file exists */
1812     size = MAX_PATH;
1813     state = MsiGetComponentPathA(prodcode, component, path, &size);
1814     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1815     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1816     ok(size == 10, "Expected 10, got %d\n", size);
1817
1818     RegDeleteValueA(compkey, prod_squashed);
1819     RegDeleteKeyA(prodkey, "");
1820     RegDeleteKeyA(compkey, "");
1821     RegCloseKey(prodkey);
1822     RegCloseKey(compkey);
1823     DeleteFileA("C:\\imapath");
1824 }
1825
1826 static void test_MsiGetProductCode(void)
1827 {
1828     HKEY compkey, prodkey;
1829     CHAR prodcode[MAX_PATH];
1830     CHAR prod_squashed[MAX_PATH];
1831     CHAR prodcode2[MAX_PATH];
1832     CHAR prod2_squashed[MAX_PATH];
1833     CHAR component[MAX_PATH];
1834     CHAR comp_base85[MAX_PATH];
1835     CHAR comp_squashed[MAX_PATH];
1836     CHAR keypath[MAX_PATH];
1837     CHAR product[MAX_PATH];
1838     LPSTR usersid;
1839     LONG res;
1840     UINT r;
1841
1842     create_test_guid(prodcode, prod_squashed);
1843     create_test_guid(prodcode2, prod2_squashed);
1844     compose_base85_guid(component, comp_base85, comp_squashed);
1845     get_user_sid(&usersid);
1846
1847     /* szComponent is NULL */
1848     lstrcpyA(product, "prod");
1849     r = MsiGetProductCodeA(NULL, product);
1850     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1851     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1852
1853     /* szComponent is empty */
1854     lstrcpyA(product, "prod");
1855     r = MsiGetProductCodeA("", product);
1856     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1857     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1858
1859     /* garbage szComponent */
1860     lstrcpyA(product, "prod");
1861     r = MsiGetProductCodeA("garbage", product);
1862     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1863     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1864
1865     /* guid without brackets */
1866     lstrcpyA(product, "prod");
1867     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
1868     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1869     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1870
1871     /* guid with brackets */
1872     lstrcpyA(product, "prod");
1873     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
1874     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1875     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1876
1877     /* same length as guid, but random */
1878     lstrcpyA(product, "prod");
1879     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
1880     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1881     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1882
1883     /* all params correct, szComponent not published */
1884     lstrcpyA(product, "prod");
1885     r = MsiGetProductCodeA(component, product);
1886     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1887     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1888
1889     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1890     lstrcatA(keypath, "Installer\\UserData\\");
1891     lstrcatA(keypath, usersid);
1892     lstrcatA(keypath, "\\Components\\");
1893     lstrcatA(keypath, comp_squashed);
1894
1895     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1896     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1897
1898     /* user unmanaged component key exists */
1899     lstrcpyA(product, "prod");
1900     r = MsiGetProductCodeA(component, product);
1901     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1902     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1903
1904     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1906
1907     /* product value exists */
1908     lstrcpyA(product, "prod");
1909     r = MsiGetProductCodeA(component, product);
1910     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1911     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1912
1913     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1915
1916     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1917     lstrcatA(keypath, "Installer\\Managed\\");
1918     lstrcatA(keypath, usersid);
1919     lstrcatA(keypath, "\\Installer\\Products\\");
1920     lstrcatA(keypath, prod_squashed);
1921
1922     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1924
1925     /* user managed product key of first product exists */
1926     lstrcpyA(product, "prod");
1927     r = MsiGetProductCodeA(component, product);
1928     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1929     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1930
1931     RegDeleteKeyA(prodkey, "");
1932     RegCloseKey(prodkey);
1933
1934     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1935     lstrcatA(keypath, prod_squashed);
1936
1937     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1938     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1939
1940     /* user unmanaged product key exists */
1941     lstrcpyA(product, "prod");
1942     r = MsiGetProductCodeA(component, product);
1943     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1944     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1945
1946     RegDeleteKeyA(prodkey, "");
1947     RegCloseKey(prodkey);
1948
1949     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1950     lstrcatA(keypath, prod_squashed);
1951
1952     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1953     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1954
1955     /* local classes product key exists */
1956     lstrcpyA(product, "prod");
1957     r = MsiGetProductCodeA(component, product);
1958     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1959     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1960
1961     RegDeleteKeyA(prodkey, "");
1962     RegCloseKey(prodkey);
1963
1964     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1965     lstrcatA(keypath, "Installer\\Managed\\");
1966     lstrcatA(keypath, usersid);
1967     lstrcatA(keypath, "\\Installer\\Products\\");
1968     lstrcatA(keypath, prod2_squashed);
1969
1970     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1972
1973     /* user managed product key of second product exists */
1974     lstrcpyA(product, "prod");
1975     r = MsiGetProductCodeA(component, product);
1976     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1977     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
1978
1979     RegDeleteKeyA(prodkey, "");
1980     RegCloseKey(prodkey);
1981     RegDeleteValueA(compkey, prod_squashed);
1982     RegDeleteValueA(compkey, prod2_squashed);
1983     RegDeleteKeyA(compkey, "");
1984     RegCloseKey(compkey);
1985
1986     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1987     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1988     lstrcatA(keypath, comp_squashed);
1989
1990     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1992
1993     /* local user component key exists */
1994     lstrcpyA(product, "prod");
1995     r = MsiGetProductCodeA(component, product);
1996     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1997     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1998
1999     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2001
2002     /* product value exists */
2003     lstrcpyA(product, "prod");
2004     r = MsiGetProductCodeA(component, product);
2005     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2006     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2007
2008     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2010
2011     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2012     lstrcatA(keypath, "Installer\\Managed\\");
2013     lstrcatA(keypath, usersid);
2014     lstrcatA(keypath, "\\Installer\\Products\\");
2015     lstrcatA(keypath, prod_squashed);
2016
2017     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2019
2020     /* user managed product key of first product exists */
2021     lstrcpyA(product, "prod");
2022     r = MsiGetProductCodeA(component, product);
2023     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2024     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2025
2026     RegDeleteKeyA(prodkey, "");
2027     RegCloseKey(prodkey);
2028
2029     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2030     lstrcatA(keypath, prod_squashed);
2031
2032     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2033     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2034
2035     /* user unmanaged product key exists */
2036     lstrcpyA(product, "prod");
2037     r = MsiGetProductCodeA(component, product);
2038     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2039     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2040
2041     RegDeleteKeyA(prodkey, "");
2042     RegCloseKey(prodkey);
2043
2044     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2045     lstrcatA(keypath, prod_squashed);
2046
2047     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2049
2050     /* local classes product key exists */
2051     lstrcpyA(product, "prod");
2052     r = MsiGetProductCodeA(component, product);
2053     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2054     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2055
2056     RegDeleteKeyA(prodkey, "");
2057     RegCloseKey(prodkey);
2058
2059     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2060     lstrcatA(keypath, "Installer\\Managed\\");
2061     lstrcatA(keypath, usersid);
2062     lstrcatA(keypath, "\\Installer\\Products\\");
2063     lstrcatA(keypath, prod2_squashed);
2064
2065     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2067
2068     /* user managed product key of second product exists */
2069     lstrcpyA(product, "prod");
2070     r = MsiGetProductCodeA(component, product);
2071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2072     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2073
2074     RegDeleteKeyA(prodkey, "");
2075     RegCloseKey(prodkey);
2076     RegDeleteValueA(compkey, prod_squashed);
2077     RegDeleteValueA(compkey, prod2_squashed);
2078     RegDeleteKeyA(compkey, "");
2079     RegCloseKey(compkey);
2080 }
2081
2082 static void test_MsiEnumClients(void)
2083 {
2084     HKEY compkey;
2085     CHAR prodcode[MAX_PATH];
2086     CHAR prod_squashed[MAX_PATH];
2087     CHAR prodcode2[MAX_PATH];
2088     CHAR prod2_squashed[MAX_PATH];
2089     CHAR component[MAX_PATH];
2090     CHAR comp_base85[MAX_PATH];
2091     CHAR comp_squashed[MAX_PATH];
2092     CHAR product[MAX_PATH];
2093     CHAR keypath[MAX_PATH];
2094     LPSTR usersid;
2095     LONG res;
2096     UINT r;
2097
2098     create_test_guid(prodcode, prod_squashed);
2099     create_test_guid(prodcode2, prod2_squashed);
2100     compose_base85_guid(component, comp_base85, comp_squashed);
2101     get_user_sid(&usersid);
2102
2103     /* NULL szComponent */
2104     product[0] = '\0';
2105     r = MsiEnumClientsA(NULL, 0, product);
2106     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2107     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2108
2109     /* empty szComponent */
2110     product[0] = '\0';
2111     r = MsiEnumClientsA("", 0, product);
2112     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2113     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2114
2115     /* NULL lpProductBuf */
2116     r = MsiEnumClientsA(component, 0, NULL);
2117     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2118
2119     /* all params correct, component missing */
2120     product[0] = '\0';
2121     r = MsiEnumClientsA(component, 0, product);
2122     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2123     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2124
2125     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2126     lstrcatA(keypath, "Installer\\UserData\\");
2127     lstrcatA(keypath, usersid);
2128     lstrcatA(keypath, "\\Components\\");
2129     lstrcatA(keypath, comp_squashed);
2130
2131     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2133
2134     /* user unmanaged component key exists */
2135     product[0] = '\0';
2136     r = MsiEnumClientsA(component, 0, product);
2137     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2138     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2139
2140     /* index > 0, no products exist */
2141     product[0] = '\0';
2142     r = MsiEnumClientsA(component, 1, product);
2143     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2144     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2145
2146     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2148
2149     /* product value exists */
2150     r = MsiEnumClientsA(component, 0, product);
2151     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2152     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2153
2154     /* try index 0 again */
2155     product[0] = '\0';
2156     r = MsiEnumClientsA(component, 0, product);
2157     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2158     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2159
2160     /* try index 1, second product value does not exist */
2161     product[0] = '\0';
2162     r = MsiEnumClientsA(component, 1, product);
2163     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2164     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2165
2166     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2167     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2168
2169     /* try index 1, second product value does exist */
2170     product[0] = '\0';
2171     r = MsiEnumClientsA(component, 1, product);
2172     todo_wine
2173     {
2174         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2175         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2176     }
2177
2178     /* start the enumeration over */
2179     product[0] = '\0';
2180     r = MsiEnumClientsA(component, 0, product);
2181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2182     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2183        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2184
2185     /* correctly query second product */
2186     product[0] = '\0';
2187     r = MsiEnumClientsA(component, 1, product);
2188     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2189     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2190        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2191
2192     RegDeleteValueA(compkey, prod_squashed);
2193     RegDeleteValueA(compkey, prod2_squashed);
2194     RegDeleteKeyA(compkey, "");
2195     RegCloseKey(compkey);
2196
2197     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2198     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2199     lstrcatA(keypath, comp_squashed);
2200
2201     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2203
2204     /* user local component key exists */
2205     product[0] = '\0';
2206     r = MsiEnumClientsA(component, 0, product);
2207     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2208     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2209
2210     /* index > 0, no products exist */
2211     product[0] = '\0';
2212     r = MsiEnumClientsA(component, 1, product);
2213     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2214     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2215
2216     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2218
2219     /* product value exists */
2220     product[0] = '\0';
2221     r = MsiEnumClientsA(component, 0, product);
2222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2223     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2224
2225     /* try index 0 again */
2226     product[0] = '\0';
2227     r = MsiEnumClientsA(component, 0, product);
2228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2229
2230     /* try index 1, second product value does not exist */
2231     product[0] = '\0';
2232     r = MsiEnumClientsA(component, 1, product);
2233     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2234     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2235
2236     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2238
2239     /* try index 1, second product value does exist */
2240     product[0] = '\0';
2241     r = MsiEnumClientsA(component, 1, product);
2242     todo_wine
2243     {
2244         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2245         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2246     }
2247
2248     /* start the enumeration over */
2249     product[0] = '\0';
2250     r = MsiEnumClientsA(component, 0, product);
2251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2252     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2253        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2254
2255     /* correctly query second product */
2256     product[0] = '\0';
2257     r = MsiEnumClientsA(component, 1, product);
2258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2259     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2260        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2261
2262     RegDeleteValueA(compkey, prod_squashed);
2263     RegDeleteValueA(compkey, prod2_squashed);
2264     RegDeleteKeyA(compkey, "");
2265     RegCloseKey(compkey);
2266 }
2267
2268 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2269                              LPSTR *langcheck, LPDWORD langchecksz)
2270 {
2271     LPSTR version;
2272     VS_FIXEDFILEINFO *ffi;
2273     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2274     USHORT *lang;
2275
2276     version = HeapAlloc(GetProcessHeap(), 0, size);
2277     GetFileVersionInfoA(path, 0, size, version);
2278
2279     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2280     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2281     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2282             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2283             LOWORD(ffi->dwFileVersionLS));
2284     *verchecksz = lstrlenA(*vercheck);
2285
2286     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2287     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2288     sprintf(*langcheck, "%d", *lang);
2289     *langchecksz = lstrlenA(*langcheck);
2290
2291     HeapFree(GetProcessHeap(), 0, version);
2292 }
2293
2294 static void test_MsiGetFileVersion(void)
2295 {
2296     UINT r;
2297     DWORD versz, langsz;
2298     char version[MAX_PATH];
2299     char lang[MAX_PATH];
2300     char path[MAX_PATH];
2301     LPSTR vercheck, langcheck;
2302     DWORD verchecksz, langchecksz;
2303
2304     /* NULL szFilePath */
2305     versz = MAX_PATH;
2306     langsz = MAX_PATH;
2307     lstrcpyA(version, "version");
2308     lstrcpyA(lang, "lang");
2309     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2310     ok(r == ERROR_INVALID_PARAMETER,
2311        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2312     ok(!lstrcmpA(version, "version"),
2313        "Expected version to be unchanged, got %s\n", version);
2314     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2315     ok(!lstrcmpA(lang, "lang"),
2316        "Expected lang to be unchanged, got %s\n", lang);
2317     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2318
2319     /* empty szFilePath */
2320     versz = MAX_PATH;
2321     langsz = MAX_PATH;
2322     lstrcpyA(version, "version");
2323     lstrcpyA(lang, "lang");
2324     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2325     ok(r == ERROR_FILE_NOT_FOUND,
2326        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2327     ok(!lstrcmpA(version, "version"),
2328        "Expected version to be unchanged, got %s\n", version);
2329     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2330     ok(!lstrcmpA(lang, "lang"),
2331        "Expected lang to be unchanged, got %s\n", lang);
2332     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2333
2334     /* nonexistent szFilePath */
2335     versz = MAX_PATH;
2336     langsz = MAX_PATH;
2337     lstrcpyA(version, "version");
2338     lstrcpyA(lang, "lang");
2339     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2340     ok(r == ERROR_FILE_NOT_FOUND,
2341        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2342     ok(!lstrcmpA(version, "version"),
2343        "Expected version to be unchanged, got %s\n", version);
2344     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2345     ok(!lstrcmpA(lang, "lang"),
2346        "Expected lang to be unchanged, got %s\n", lang);
2347     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2348
2349     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2350     versz = MAX_PATH;
2351     langsz = MAX_PATH;
2352     lstrcpyA(version, "version");
2353     lstrcpyA(lang, "lang");
2354     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2355     ok(r == ERROR_INVALID_PARAMETER,
2356        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2357     ok(!lstrcmpA(version, "version"),
2358        "Expected version to be unchanged, got %s\n", version);
2359     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2360     ok(!lstrcmpA(lang, "lang"),
2361        "Expected lang to be unchanged, got %s\n", lang);
2362     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2363
2364     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2365     versz = MAX_PATH;
2366     langsz = MAX_PATH;
2367     lstrcpyA(version, "version");
2368     lstrcpyA(lang, "lang");
2369     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2370     ok(r == ERROR_INVALID_PARAMETER,
2371        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2372     ok(!lstrcmpA(version, "version"),
2373        "Expected version to be unchanged, got %s\n", version);
2374     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2375     ok(!lstrcmpA(lang, "lang"),
2376        "Expected lang to be unchanged, got %s\n", lang);
2377     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2378
2379     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2380     versz = 0;
2381     langsz = MAX_PATH;
2382     lstrcpyA(version, "version");
2383     lstrcpyA(lang, "lang");
2384     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2385     ok(r == ERROR_FILE_NOT_FOUND,
2386        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2387     ok(!lstrcmpA(version, "version"),
2388        "Expected version to be unchanged, got %s\n", version);
2389     ok(versz == 0, "Expected 0, got %d\n", versz);
2390     ok(!lstrcmpA(lang, "lang"),
2391        "Expected lang to be unchanged, got %s\n", lang);
2392     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2393
2394     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2395     versz = MAX_PATH;
2396     langsz = 0;
2397     lstrcpyA(version, "version");
2398     lstrcpyA(lang, "lang");
2399     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2400     ok(r == ERROR_FILE_NOT_FOUND,
2401        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2402     ok(!lstrcmpA(version, "version"),
2403        "Expected version to be unchanged, got %s\n", version);
2404     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2405     ok(!lstrcmpA(lang, "lang"),
2406        "Expected lang to be unchanged, got %s\n", lang);
2407     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2408
2409     /* nonexistent szFilePath, rest NULL */
2410     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2411     ok(r == ERROR_FILE_NOT_FOUND,
2412        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2413
2414     create_file("ver.txt", "ver.txt", 20);
2415
2416     /* file exists, no version information */
2417     versz = MAX_PATH;
2418     langsz = MAX_PATH;
2419     lstrcpyA(version, "version");
2420     lstrcpyA(lang, "lang");
2421     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2422     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2423     ok(!lstrcmpA(version, "version"),
2424        "Expected version to be unchanged, got %s\n", version);
2425     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2426     ok(!lstrcmpA(lang, "lang"),
2427        "Expected lang to be unchanged, got %s\n", lang);
2428     ok(r == ERROR_FILE_INVALID,
2429        "Expected ERROR_FILE_INVALID, got %d\n", r);
2430
2431     DeleteFileA("ver.txt");
2432
2433     /* relative path, has version information */
2434     versz = MAX_PATH;
2435     langsz = MAX_PATH;
2436     lstrcpyA(version, "version");
2437     lstrcpyA(lang, "lang");
2438     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2439     todo_wine
2440     {
2441         ok(r == ERROR_FILE_NOT_FOUND,
2442            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2443         ok(!lstrcmpA(version, "version"),
2444            "Expected version to be unchanged, got %s\n", version);
2445         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2446         ok(!lstrcmpA(lang, "lang"),
2447            "Expected lang to be unchanged, got %s\n", lang);
2448         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2449     }
2450
2451     GetSystemDirectoryA(path, MAX_PATH);
2452     lstrcatA(path, "\\kernel32.dll");
2453
2454     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2455
2456     /* absolute path, has version information */
2457     versz = MAX_PATH;
2458     langsz = MAX_PATH;
2459     lstrcpyA(version, "version");
2460     lstrcpyA(lang, "lang");
2461     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2463     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2464     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2465     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2466     ok(!lstrcmpA(version, vercheck),
2467         "Expected %s, got %s\n", vercheck, version);
2468
2469     /* only check version */
2470     versz = MAX_PATH;
2471     lstrcpyA(version, "version");
2472     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2473     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2474     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2475     ok(!lstrcmpA(version, vercheck),
2476        "Expected %s, got %s\n", vercheck, version);
2477
2478     /* only check language */
2479     langsz = MAX_PATH;
2480     lstrcpyA(lang, "lang");
2481     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2483     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2484     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2485
2486     /* check neither version nor language */
2487     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2488     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2489
2490     /* get pcchVersionBuf */
2491     versz = MAX_PATH;
2492     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2494     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2495
2496     /* get pcchLangBuf */
2497     langsz = MAX_PATH;
2498     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2499     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2500     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2501
2502     /* pcchVersionBuf not big enough */
2503     versz = 5;
2504     lstrcpyA(version, "version");
2505     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2506     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2507     ok(!strncmp(version, vercheck, 4),
2508        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2509     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2510
2511     /* pcchLangBuf not big enough */
2512     langsz = 3;
2513     lstrcpyA(lang, "lang");
2514     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2515     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2516     ok(!strncmp(lang, langcheck, 2),
2517        "Expected first character of %s, got %s\n", langcheck, lang);
2518     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2519
2520     HeapFree(GetProcessHeap(), 0, vercheck);
2521     HeapFree(GetProcessHeap(), 0, langcheck);
2522 }
2523
2524 static void test_MsiGetProductInfo(void)
2525 {
2526     UINT r;
2527     LONG res;
2528     HKEY propkey, source;
2529     HKEY prodkey, localkey;
2530     CHAR prodcode[MAX_PATH];
2531     CHAR prod_squashed[MAX_PATH];
2532     CHAR packcode[MAX_PATH];
2533     CHAR pack_squashed[MAX_PATH];
2534     CHAR buf[MAX_PATH];
2535     CHAR keypath[MAX_PATH];
2536     LPSTR usersid;
2537     DWORD sz, val = 42;
2538
2539     create_test_guid(prodcode, prod_squashed);
2540     create_test_guid(packcode, pack_squashed);
2541     get_user_sid(&usersid);
2542
2543     /* NULL szProduct */
2544     sz = MAX_PATH;
2545     lstrcpyA(buf, "apple");
2546     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2547     ok(r == ERROR_INVALID_PARAMETER,
2548        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2549     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2550     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2551
2552     /* empty szProduct */
2553     sz = MAX_PATH;
2554     lstrcpyA(buf, "apple");
2555     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2556     ok(r == ERROR_INVALID_PARAMETER,
2557        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2558     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2559     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2560
2561     /* garbage szProduct */
2562     sz = MAX_PATH;
2563     lstrcpyA(buf, "apple");
2564     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2565     ok(r == ERROR_INVALID_PARAMETER,
2566        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2567     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2568     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2569
2570     /* guid without brackets */
2571     sz = MAX_PATH;
2572     lstrcpyA(buf, "apple");
2573     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2574                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2575     ok(r == ERROR_INVALID_PARAMETER,
2576        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2577     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2578     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2579
2580     /* guid with brackets */
2581     sz = MAX_PATH;
2582     lstrcpyA(buf, "apple");
2583     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2584                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2585     ok(r == ERROR_UNKNOWN_PRODUCT,
2586        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2587     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2588     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2589
2590     /* same length as guid, but random */
2591     sz = MAX_PATH;
2592     lstrcpyA(buf, "apple");
2593     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2594                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2595     ok(r == ERROR_INVALID_PARAMETER,
2596        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2597     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2598     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2599
2600     /* not installed, NULL szAttribute */
2601     sz = MAX_PATH;
2602     lstrcpyA(buf, "apple");
2603     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2604     ok(r == ERROR_INVALID_PARAMETER,
2605        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2606     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2607     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2608
2609     /* not installed, NULL lpValueBuf */
2610     sz = MAX_PATH;
2611     lstrcpyA(buf, "apple");
2612     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2613     ok(r == ERROR_UNKNOWN_PRODUCT,
2614        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2615     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2616     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2617
2618     /* not installed, NULL pcchValueBuf */
2619     sz = MAX_PATH;
2620     lstrcpyA(buf, "apple");
2621     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2622     ok(r == ERROR_INVALID_PARAMETER,
2623        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2624     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2625     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2626
2627     /* created guid cannot possibly be an installed product code */
2628     sz = MAX_PATH;
2629     lstrcpyA(buf, "apple");
2630     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2631     ok(r == ERROR_UNKNOWN_PRODUCT,
2632        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2633     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2634     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2635
2636     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2637     lstrcatA(keypath, usersid);
2638     lstrcatA(keypath, "\\Installer\\Products\\");
2639     lstrcatA(keypath, prod_squashed);
2640
2641     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2643
2644     /* managed product code exists */
2645     sz = MAX_PATH;
2646     lstrcpyA(buf, "apple");
2647     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2648     ok(r == ERROR_UNKNOWN_PROPERTY,
2649        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2650     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2651     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2652
2653     RegDeleteKeyA(prodkey, "");
2654     RegCloseKey(prodkey);
2655
2656     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2657     lstrcatA(keypath, usersid);
2658     lstrcatA(keypath, "\\Products\\");
2659     lstrcatA(keypath, prod_squashed);
2660
2661     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2662     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2663
2664     /* local user product code exists */
2665     sz = MAX_PATH;
2666     lstrcpyA(buf, "apple");
2667     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2668     ok(r == ERROR_UNKNOWN_PRODUCT,
2669        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2670     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2671     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2672
2673     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2674     lstrcatA(keypath, usersid);
2675     lstrcatA(keypath, "\\Installer\\Products\\");
2676     lstrcatA(keypath, prod_squashed);
2677
2678     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2680
2681     /* both local and managed product code exist */
2682     sz = MAX_PATH;
2683     lstrcpyA(buf, "apple");
2684     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2685     ok(r == ERROR_UNKNOWN_PROPERTY,
2686        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2687     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2688     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2689
2690     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2691     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2692
2693     /* InstallProperties key exists */
2694     sz = MAX_PATH;
2695     lstrcpyA(buf, "apple");
2696     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2697     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2698     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2699     ok(sz == 0, "Expected 0, got %d\n", sz);
2700
2701     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2703
2704     /* HelpLink value exists */
2705     sz = MAX_PATH;
2706     lstrcpyA(buf, "apple");
2707     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2708     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2709     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2710     ok(sz == 4, "Expected 4, got %d\n", sz);
2711
2712     /* pcchBuf is NULL */
2713     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
2714     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2715
2716     /* lpValueBuf is NULL */
2717     sz = MAX_PATH;
2718     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2719     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2720     ok(sz == 4, "Expected 4, got %d\n", sz);
2721
2722     /* lpValueBuf is NULL, pcchValueBuf is too small */
2723     sz = 2;
2724     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2726     ok(sz == 4, "Expected 4, got %d\n", sz);
2727
2728     /* lpValueBuf is NULL, pcchValueBuf is too small */
2729     sz = 2;
2730     lstrcpyA(buf, "apple");
2731     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2732     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
2733     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2734     ok(sz == 4, "Expected 4, got %d\n", sz);
2735
2736     /* lpValueBuf is NULL, pcchValueBuf is exactly 4 */
2737     sz = 4;
2738     lstrcpyA(buf, "apple");
2739     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2740     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2741     ok(!lstrcmpA(buf, "apple"),
2742        "Expected buf to remain unchanged, got \"%s\"\n", buf);
2743     ok(sz == 4, "Expected 4, got %d\n", sz);
2744
2745     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
2746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2747
2748     /* random property not supported by MSI, value exists */
2749     sz = MAX_PATH;
2750     lstrcpyA(buf, "apple");
2751     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
2752     ok(r == ERROR_UNKNOWN_PROPERTY,
2753        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2754     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2755     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2756
2757     RegDeleteValueA(propkey, "IMadeThis");
2758     RegDeleteValueA(propkey, "HelpLink");
2759     RegDeleteKeyA(propkey, "");
2760     RegDeleteKeyA(localkey, "");
2761     RegDeleteKeyA(prodkey, "");
2762     RegCloseKey(propkey);
2763     RegCloseKey(localkey);
2764     RegCloseKey(prodkey);
2765
2766     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2767     lstrcatA(keypath, prod_squashed);
2768
2769     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2770     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2771
2772     /* user product key exists */
2773     sz = MAX_PATH;
2774     lstrcpyA(buf, "apple");
2775     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2776     ok(r == ERROR_UNKNOWN_PROPERTY,
2777        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2778     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2779     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2780
2781     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2782     lstrcatA(keypath, usersid);
2783     lstrcatA(keypath, "\\Products\\");
2784     lstrcatA(keypath, prod_squashed);
2785
2786     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2788
2789     /* local user product key exists */
2790     sz = MAX_PATH;
2791     lstrcpyA(buf, "apple");
2792     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2793     ok(r == ERROR_UNKNOWN_PROPERTY,
2794        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2795     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2796     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2797
2798     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2799     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2800
2801     /* InstallProperties key exists */
2802     sz = MAX_PATH;
2803     lstrcpyA(buf, "apple");
2804     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2805     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2806     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2807     ok(sz == 0, "Expected 0, got %d\n", sz);
2808
2809     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2810     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2811
2812     /* HelpLink value exists */
2813     sz = MAX_PATH;
2814     lstrcpyA(buf, "apple");
2815     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2816     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2817     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2818     ok(sz == 4, "Expected 4, got %d\n", sz);
2819
2820     RegDeleteValueA(propkey, "HelpLink");
2821     RegDeleteKeyA(propkey, "");
2822     RegDeleteKeyA(localkey, "");
2823     RegDeleteKeyA(prodkey, "");
2824     RegCloseKey(propkey);
2825     RegCloseKey(localkey);
2826     RegCloseKey(prodkey);
2827
2828     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2829     lstrcatA(keypath, prod_squashed);
2830
2831     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2832     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2833
2834     /* classes product key exists */
2835     sz = MAX_PATH;
2836     lstrcpyA(buf, "apple");
2837     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2838     ok(r == ERROR_UNKNOWN_PROPERTY,
2839        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2840     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2841     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2842
2843     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2844     lstrcatA(keypath, usersid);
2845     lstrcatA(keypath, "\\Products\\");
2846     lstrcatA(keypath, prod_squashed);
2847
2848     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2849     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2850
2851     /* local user product key exists */
2852     sz = MAX_PATH;
2853     lstrcpyA(buf, "apple");
2854     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2855     ok(r == ERROR_UNKNOWN_PROPERTY,
2856        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2857     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2858     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2859
2860     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2861     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2862
2863     /* InstallProperties key exists */
2864     sz = MAX_PATH;
2865     lstrcpyA(buf, "apple");
2866     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2867     ok(r == ERROR_UNKNOWN_PROPERTY,
2868        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2869     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2870     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2871
2872     RegDeleteKeyA(propkey, "");
2873     RegDeleteKeyA(localkey, "");
2874     RegCloseKey(propkey);
2875     RegCloseKey(localkey);
2876
2877     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2878     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
2879     lstrcatA(keypath, prod_squashed);
2880
2881     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2882     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2883
2884     /* Local System product key exists */
2885     sz = MAX_PATH;
2886     lstrcpyA(buf, "apple");
2887     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2888     ok(r == ERROR_UNKNOWN_PROPERTY,
2889         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2890     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2891     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2892
2893     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2894     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2895
2896     /* InstallProperties key exists */
2897     sz = MAX_PATH;
2898     lstrcpyA(buf, "apple");
2899     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2900     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2901     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2902     ok(sz == 0, "Expected 0, got %d\n", sz);
2903
2904     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2906
2907     /* HelpLink value exists */
2908     sz = MAX_PATH;
2909     lstrcpyA(buf, "apple");
2910     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2911     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2912     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2913     ok(sz == 4, "Expected 4, got %d\n", sz);
2914
2915     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
2916                          (const BYTE *)&val, sizeof(DWORD));
2917     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2918
2919     /* HelpLink type is REG_DWORD */
2920     sz = MAX_PATH;
2921     lstrcpyA(buf, "apple");
2922     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2923     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2924     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2925     ok(sz == 2, "Expected 2, got %d\n", sz);
2926
2927     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
2928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2929
2930     /* DisplayName value exists */
2931     sz = MAX_PATH;
2932     lstrcpyA(buf, "apple");
2933     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2934     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2935     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
2936     ok(sz == 4, "Expected 4, got %d\n", sz);
2937
2938     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
2939                          (const BYTE *)&val, sizeof(DWORD));
2940     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2941
2942     /* DisplayName type is REG_DWORD */
2943     sz = MAX_PATH;
2944     lstrcpyA(buf, "apple");
2945     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2946     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2947     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2948     ok(sz == 2, "Expected 2, got %d\n", sz);
2949
2950     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
2951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2952
2953     /* DisplayVersion value exists */
2954     sz = MAX_PATH;
2955     lstrcpyA(buf, "apple");
2956     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2957     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2958     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
2959     ok(sz == 5, "Expected 5, got %d\n", sz);
2960
2961     res = RegSetValueExA(propkey, "DisplayVersion", 0,
2962                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2964
2965     /* DisplayVersion type is REG_DWORD */
2966     sz = MAX_PATH;
2967     lstrcpyA(buf, "apple");
2968     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2969     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2970     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2971     ok(sz == 2, "Expected 2, got %d\n", sz);
2972
2973     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
2974     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2975
2976     /* HelpTelephone value exists */
2977     sz = MAX_PATH;
2978     lstrcpyA(buf, "apple");
2979     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2980     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2981     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
2982     ok(sz == 4, "Expected 4, got %d\n", sz);
2983
2984     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
2985                          (const BYTE *)&val, sizeof(DWORD));
2986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2987
2988     /* HelpTelephone type is REG_DWORD */
2989     sz = MAX_PATH;
2990     lstrcpyA(buf, "apple");
2991     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2992     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2993     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2994     ok(sz == 2, "Expected 2, got %d\n", sz);
2995
2996     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
2997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2998
2999     /* InstallLocation value exists */
3000     sz = MAX_PATH;
3001     lstrcpyA(buf, "apple");
3002     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3004     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3005     ok(sz == 3, "Expected 3, got %d\n", sz);
3006
3007     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3008                          (const BYTE *)&val, sizeof(DWORD));
3009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3010
3011     /* InstallLocation type is REG_DWORD */
3012     sz = MAX_PATH;
3013     lstrcpyA(buf, "apple");
3014     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3016     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3017     ok(sz == 2, "Expected 2, got %d\n", sz);
3018
3019     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3020     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3021
3022     /* InstallSource value exists */
3023     sz = MAX_PATH;
3024     lstrcpyA(buf, "apple");
3025     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3027     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3028     ok(sz == 6, "Expected 6, got %d\n", sz);
3029
3030     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3031                          (const BYTE *)&val, sizeof(DWORD));
3032     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3033
3034     /* InstallSource type is REG_DWORD */
3035     sz = MAX_PATH;
3036     lstrcpyA(buf, "apple");
3037     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3038     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3039     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3040     ok(sz == 2, "Expected 2, got %d\n", sz);
3041
3042     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3044
3045     /* InstallDate value exists */
3046     sz = MAX_PATH;
3047     lstrcpyA(buf, "apple");
3048     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3049     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3050     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3051     ok(sz == 4, "Expected 4, got %d\n", sz);
3052
3053     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3054                          (const BYTE *)&val, sizeof(DWORD));
3055     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3056
3057     /* InstallDate type is REG_DWORD */
3058     sz = MAX_PATH;
3059     lstrcpyA(buf, "apple");
3060     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3062     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3063     ok(sz == 2, "Expected 2, got %d\n", sz);
3064
3065     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3067
3068     /* Publisher value exists */
3069     sz = MAX_PATH;
3070     lstrcpyA(buf, "apple");
3071     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3073     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3074     ok(sz == 3, "Expected 3, got %d\n", sz);
3075
3076     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3077                          (const BYTE *)&val, sizeof(DWORD));
3078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3079
3080     /* Publisher type is REG_DWORD */
3081     sz = MAX_PATH;
3082     lstrcpyA(buf, "apple");
3083     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3084     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3085     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3086     ok(sz == 2, "Expected 2, got %d\n", sz);
3087
3088     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3089     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3090
3091     /* LocalPackage value exists */
3092     sz = MAX_PATH;
3093     lstrcpyA(buf, "apple");
3094     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3095     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3096     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3097     ok(sz == 4, "Expected 4, got %d\n", sz);
3098
3099     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3100                          (const BYTE *)&val, sizeof(DWORD));
3101     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3102
3103     /* LocalPackage type is REG_DWORD */
3104     sz = MAX_PATH;
3105     lstrcpyA(buf, "apple");
3106     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3107     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3108     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3109     ok(sz == 2, "Expected 2, got %d\n", sz);
3110
3111     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3113
3114     /* UrlInfoAbout value exists */
3115     sz = MAX_PATH;
3116     lstrcpyA(buf, "apple");
3117     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3118     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3119     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3120     ok(sz == 5, "Expected 5, got %d\n", sz);
3121
3122     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3123                          (const BYTE *)&val, sizeof(DWORD));
3124     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3125
3126     /* UrlInfoAbout type is REG_DWORD */
3127     sz = MAX_PATH;
3128     lstrcpyA(buf, "apple");
3129     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3130     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3131     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3132     ok(sz == 2, "Expected 2, got %d\n", sz);
3133
3134     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3136
3137     /* UrlUpdateInfo value exists */
3138     sz = MAX_PATH;
3139     lstrcpyA(buf, "apple");
3140     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3142     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3143     ok(sz == 4, "Expected 4, got %d\n", sz);
3144
3145     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3146                          (const BYTE *)&val, sizeof(DWORD));
3147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3148
3149     /* UrlUpdateInfo type is REG_DWORD */
3150     sz = MAX_PATH;
3151     lstrcpyA(buf, "apple");
3152     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3153     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3154     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3155     ok(sz == 2, "Expected 2, got %d\n", sz);
3156
3157     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3159
3160     /* VersionMinor value exists */
3161     sz = MAX_PATH;
3162     lstrcpyA(buf, "apple");
3163     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3165     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3166     ok(sz == 1, "Expected 1, got %d\n", sz);
3167
3168     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3169                          (const BYTE *)&val, sizeof(DWORD));
3170     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3171
3172     /* VersionMinor type is REG_DWORD */
3173     sz = MAX_PATH;
3174     lstrcpyA(buf, "apple");
3175     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3177     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3178     ok(sz == 2, "Expected 2, got %d\n", sz);
3179
3180     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3181     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3182
3183     /* VersionMajor value exists */
3184     sz = MAX_PATH;
3185     lstrcpyA(buf, "apple");
3186     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3187     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3188     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3189     ok(sz == 1, "Expected 1, got %d\n", sz);
3190
3191     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3192                          (const BYTE *)&val, sizeof(DWORD));
3193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3194
3195     /* VersionMajor type is REG_DWORD */
3196     sz = MAX_PATH;
3197     lstrcpyA(buf, "apple");
3198     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3199     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3200     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3201     ok(sz == 2, "Expected 2, got %d\n", sz);
3202
3203     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3205
3206     /* ProductID value exists */
3207     sz = MAX_PATH;
3208     lstrcpyA(buf, "apple");
3209     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3211     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3212     ok(sz == 2, "Expected 2, got %d\n", sz);
3213
3214     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3215                          (const BYTE *)&val, sizeof(DWORD));
3216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3217
3218     /* ProductID type is REG_DWORD */
3219     sz = MAX_PATH;
3220     lstrcpyA(buf, "apple");
3221     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3223     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3224     ok(sz == 2, "Expected 2, got %d\n", sz);
3225
3226     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3228
3229     /* RegCompany value exists */
3230     sz = MAX_PATH;
3231     lstrcpyA(buf, "apple");
3232     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3234     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3235     ok(sz == 4, "Expected 4, got %d\n", sz);
3236
3237     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3238                          (const BYTE *)&val, sizeof(DWORD));
3239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3240
3241     /* RegCompany type is REG_DWORD */
3242     sz = MAX_PATH;
3243     lstrcpyA(buf, "apple");
3244     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, 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, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3251
3252     /* RegOwner value exists */
3253     sz = MAX_PATH;
3254     lstrcpyA(buf, "apple");
3255     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3257     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3258     ok(sz == 3, "Expected 3, got %d\n", sz);
3259
3260     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3261                          (const BYTE *)&val, sizeof(DWORD));
3262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3263
3264     /* RegOwner type is REG_DWORD */
3265     sz = MAX_PATH;
3266     lstrcpyA(buf, "apple");
3267     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, 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, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3274
3275     /* InstanceType value exists */
3276     sz = MAX_PATH;
3277     lstrcpyA(buf, "apple");
3278     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3280     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3281     ok(sz == 0, "Expected 0, got %d\n", sz);
3282
3283     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3284                          (const BYTE *)&val, sizeof(DWORD));
3285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3286
3287     /* InstanceType type is REG_DWORD */
3288     sz = MAX_PATH;
3289     lstrcpyA(buf, "apple");
3290     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3291     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3292     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3293     ok(sz == 0, "Expected 0, got %d\n", sz);
3294
3295     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3297
3298     /* InstanceType value exists */
3299     sz = MAX_PATH;
3300     lstrcpyA(buf, "apple");
3301     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3303     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3304     ok(sz == 4, "Expected 4, got %d\n", sz);
3305
3306     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3307                          (const BYTE *)&val, sizeof(DWORD));
3308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3309
3310     /* InstanceType type is REG_DWORD */
3311     sz = MAX_PATH;
3312     lstrcpyA(buf, "apple");
3313     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, 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, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3320
3321     /* Transforms value exists */
3322     sz = MAX_PATH;
3323     lstrcpyA(buf, "apple");
3324     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3326     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3327     ok(sz == 0, "Expected 0, got %d\n", sz);
3328
3329     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3330                          (const BYTE *)&val, sizeof(DWORD));
3331     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3332
3333     /* Transforms type is REG_DWORD */
3334     sz = MAX_PATH;
3335     lstrcpyA(buf, "apple");
3336     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3338     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3339     ok(sz == 0, "Expected 0, got %d\n", sz);
3340
3341     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3343
3344     /* Transforms value exists */
3345     sz = MAX_PATH;
3346     lstrcpyA(buf, "apple");
3347     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3349     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3350     ok(sz == 6, "Expected 6, got %d\n", sz);
3351
3352     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3353                          (const BYTE *)&val, sizeof(DWORD));
3354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3355
3356     /* Transforms type is REG_DWORD */
3357     sz = MAX_PATH;
3358     lstrcpyA(buf, "apple");
3359     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, 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, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3366
3367     /* Language value exists */
3368     sz = MAX_PATH;
3369     lstrcpyA(buf, "apple");
3370     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3372     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3373     ok(sz == 0, "Expected 0, got %d\n", sz);
3374
3375     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3376                          (const BYTE *)&val, sizeof(DWORD));
3377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3378
3379     /* Language type is REG_DWORD */
3380     sz = MAX_PATH;
3381     lstrcpyA(buf, "apple");
3382     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3384     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3385     ok(sz == 0, "Expected 0, got %d\n", sz);
3386
3387     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3389
3390     /* Language value exists */
3391     sz = MAX_PATH;
3392     lstrcpyA(buf, "apple");
3393     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3394     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3395     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3396     ok(sz == 4, "Expected 4, got %d\n", sz);
3397
3398     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3399                          (const BYTE *)&val, sizeof(DWORD));
3400     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3401
3402     /* Language type is REG_DWORD */
3403     sz = MAX_PATH;
3404     lstrcpyA(buf, "apple");
3405     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, 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, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3412
3413     /* ProductName value exists */
3414     sz = MAX_PATH;
3415     lstrcpyA(buf, "apple");
3416     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3417     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3418     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3419     ok(sz == 0, "Expected 0, got %d\n", sz);
3420
3421     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3422                          (const BYTE *)&val, sizeof(DWORD));
3423     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3424
3425     /* ProductName type is REG_DWORD */
3426     sz = MAX_PATH;
3427     lstrcpyA(buf, "apple");
3428     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3429     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3430     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3431     ok(sz == 0, "Expected 0, got %d\n", sz);
3432
3433     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3435
3436     /* ProductName value exists */
3437     sz = MAX_PATH;
3438     lstrcpyA(buf, "apple");
3439     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3441     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3442     ok(sz == 4, "Expected 4, got %d\n", sz);
3443
3444     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3445                          (const BYTE *)&val, sizeof(DWORD));
3446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3447
3448     /* ProductName type is REG_DWORD */
3449     sz = MAX_PATH;
3450     lstrcpyA(buf, "apple");
3451     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, 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, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3457     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3458
3459     /* Assignment value exists */
3460     sz = MAX_PATH;
3461     lstrcpyA(buf, "apple");
3462     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3464     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3465     ok(sz == 0, "Expected 0, got %d\n", sz);
3466
3467     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3468                          (const BYTE *)&val, sizeof(DWORD));
3469     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3470
3471     /* Assignment type is REG_DWORD */
3472     sz = MAX_PATH;
3473     lstrcpyA(buf, "apple");
3474     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3475     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3476     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3477     ok(sz == 0, "Expected 0, got %d\n", sz);
3478
3479     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3481
3482     /* Assignment value exists */
3483     sz = MAX_PATH;
3484     lstrcpyA(buf, "apple");
3485     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3486     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3487     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3488     ok(sz == 2, "Expected 2, got %d\n", sz);
3489
3490     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3491                          (const BYTE *)&val, sizeof(DWORD));
3492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3493
3494     /* Assignment type is REG_DWORD */
3495     sz = MAX_PATH;
3496     lstrcpyA(buf, "apple");
3497     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, 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, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3504
3505     /* PackageCode value exists */
3506     sz = MAX_PATH;
3507     lstrcpyA(buf, "apple");
3508     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3510     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3511     ok(sz == 0, "Expected 0, got %d\n", sz);
3512
3513     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3514                          (const BYTE *)&val, sizeof(DWORD));
3515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3516
3517     /* PackageCode type is REG_DWORD */
3518     sz = MAX_PATH;
3519     lstrcpyA(buf, "apple");
3520     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3522     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3523     ok(sz == 0, "Expected 0, got %d\n", sz);
3524
3525     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3527
3528     /* PackageCode value exists */
3529     sz = MAX_PATH;
3530     lstrcpyA(buf, "apple");
3531     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3532     ok(r == ERROR_BAD_CONFIGURATION,
3533        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3534     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3535     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3536
3537     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3538                          (const BYTE *)&val, sizeof(DWORD));
3539     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3540
3541     /* PackageCode type is REG_DWORD */
3542     sz = MAX_PATH;
3543     lstrcpyA(buf, "apple");
3544     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3545     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3546     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3547     ok(sz == 2, "Expected 2, got %d\n", sz);
3548
3549     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3551
3552     /* PackageCode value exists */
3553     sz = MAX_PATH;
3554     lstrcpyA(buf, "apple");
3555     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3556     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3557     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3558     ok(sz == 38, "Expected 38, got %d\n", sz);
3559
3560     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3562
3563     /* Version value exists */
3564     sz = MAX_PATH;
3565     lstrcpyA(buf, "apple");
3566     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3567     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3568     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3569     ok(sz == 0, "Expected 0, got %d\n", sz);
3570
3571     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3572                          (const BYTE *)&val, sizeof(DWORD));
3573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3574
3575     /* Version type is REG_DWORD */
3576     sz = MAX_PATH;
3577     lstrcpyA(buf, "apple");
3578     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3579     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3580     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3581     ok(sz == 0, "Expected 0, got %d\n", sz);
3582
3583     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3584     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3585
3586     /* Version value exists */
3587     sz = MAX_PATH;
3588     lstrcpyA(buf, "apple");
3589     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3590     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3591     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3592     ok(sz == 3, "Expected 3, got %d\n", sz);
3593
3594     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3595                          (const BYTE *)&val, sizeof(DWORD));
3596     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3597
3598     /* Version type is REG_DWORD */
3599     sz = MAX_PATH;
3600     lstrcpyA(buf, "apple");
3601     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3602     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3603     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3604     ok(sz == 2, "Expected 2, got %d\n", sz);
3605
3606     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3608
3609     /* ProductIcon value exists */
3610     sz = MAX_PATH;
3611     lstrcpyA(buf, "apple");
3612     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, 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(propkey, "ProductIcon", 0, REG_DWORD,
3618                          (const BYTE *)&val, sizeof(DWORD));
3619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3620
3621     /* ProductIcon type is REG_DWORD */
3622     sz = MAX_PATH;
3623     lstrcpyA(buf, "apple");
3624     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3625     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3626     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3627     ok(sz == 0, "Expected 0, got %d\n", sz);
3628
3629     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3631
3632     /* ProductIcon value exists */
3633     sz = MAX_PATH;
3634     lstrcpyA(buf, "apple");
3635     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3636     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3637     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3638     ok(sz == 3, "Expected 3, got %d\n", sz);
3639
3640     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3641                          (const BYTE *)&val, sizeof(DWORD));
3642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3643
3644     /* ProductIcon type is REG_DWORD */
3645     sz = MAX_PATH;
3646     lstrcpyA(buf, "apple");
3647     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3648     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3649     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3650     ok(sz == 2, "Expected 2, got %d\n", sz);
3651
3652     res = RegCreateKeyA(prodkey, "SourceList", &source);
3653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3654
3655     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3657
3658     sz = MAX_PATH;
3659     lstrcpyA(buf, "apple");
3660     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3661     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3662     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
3663     ok(sz == 8, "Expected 8, got %d\n", sz);
3664
3665     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
3666                          (const BYTE *)&val, sizeof(DWORD));
3667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3668
3669     /* PackageName type is REG_DWORD */
3670     sz = MAX_PATH;
3671     lstrcpyA(buf, "apple");
3672     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3673     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3674     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3675     ok(sz == 2, "Expected 2, got %d\n", sz);
3676
3677     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3678     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3679
3680     /* Authorized value exists */
3681     sz = MAX_PATH;
3682     lstrcpyA(buf, "apple");
3683     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3684     if (r != ERROR_UNKNOWN_PROPERTY)
3685     {
3686         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3687         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3688         ok(sz == 0, "Expected 0, got %d\n", sz);
3689     }
3690
3691     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
3692                          (const BYTE *)&val, sizeof(DWORD));
3693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3694
3695     /* AuthorizedLUAApp type is REG_DWORD */
3696     sz = MAX_PATH;
3697     lstrcpyA(buf, "apple");
3698     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3699     if (r != ERROR_UNKNOWN_PROPERTY)
3700     {
3701         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3702         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3703         ok(sz == 0, "Expected 0, got %d\n", sz);
3704     }
3705
3706     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3707     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3708
3709     /* Authorized value exists */
3710     sz = MAX_PATH;
3711     lstrcpyA(buf, "apple");
3712     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3713     if (r != ERROR_UNKNOWN_PROPERTY)
3714     {
3715         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3716         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
3717         ok(sz == 4, "Expected 4, got %d\n", sz);
3718     }
3719
3720     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
3721                          (const BYTE *)&val, sizeof(DWORD));
3722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3723
3724     /* AuthorizedLUAApp type is REG_DWORD */
3725     sz = MAX_PATH;
3726     lstrcpyA(buf, "apple");
3727     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3728     if (r != ERROR_UNKNOWN_PROPERTY)
3729     {
3730         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3731         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3732         ok(sz == 2, "Expected 2, got %d\n", sz);
3733     }
3734
3735     RegDeleteValueA(propkey, "HelpLink");
3736     RegDeleteValueA(propkey, "DisplayName");
3737     RegDeleteValueA(propkey, "DisplayVersion");
3738     RegDeleteValueA(propkey, "HelpTelephone");
3739     RegDeleteValueA(propkey, "InstallLocation");
3740     RegDeleteValueA(propkey, "InstallSource");
3741     RegDeleteValueA(propkey, "InstallDate");
3742     RegDeleteValueA(propkey, "Publisher");
3743     RegDeleteValueA(propkey, "LocalPackage");
3744     RegDeleteValueA(propkey, "UrlInfoAbout");
3745     RegDeleteValueA(propkey, "UrlUpdateInfo");
3746     RegDeleteValueA(propkey, "VersionMinor");
3747     RegDeleteValueA(propkey, "VersionMajor");
3748     RegDeleteValueA(propkey, "ProductID");
3749     RegDeleteValueA(propkey, "RegCompany");
3750     RegDeleteValueA(propkey, "RegOwner");
3751     RegDeleteValueA(propkey, "InstanceType");
3752     RegDeleteValueA(propkey, "Transforms");
3753     RegDeleteValueA(propkey, "Language");
3754     RegDeleteValueA(propkey, "ProductName");
3755     RegDeleteValueA(propkey, "Assignment");
3756     RegDeleteValueA(propkey, "PackageCode");
3757     RegDeleteValueA(propkey, "Version");
3758     RegDeleteValueA(propkey, "ProductIcon");
3759     RegDeleteValueA(propkey, "AuthorizedLUAApp");
3760     RegDeleteKeyA(propkey, "");
3761     RegDeleteKeyA(localkey, "");
3762     RegDeleteValueA(prodkey, "InstanceType");
3763     RegDeleteValueA(prodkey, "Transforms");
3764     RegDeleteValueA(prodkey, "Language");
3765     RegDeleteValueA(prodkey, "ProductName");
3766     RegDeleteValueA(prodkey, "Assignment");
3767     RegDeleteValueA(prodkey, "PackageCode");
3768     RegDeleteValueA(prodkey, "Version");
3769     RegDeleteValueA(prodkey, "ProductIcon");
3770     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
3771     RegDeleteValueA(source, "PackageName");
3772     RegDeleteKeyA(source, "");
3773     RegDeleteKeyA(prodkey, "");
3774     RegCloseKey(propkey);
3775     RegCloseKey(localkey);
3776     RegCloseKey(source);
3777     RegCloseKey(prodkey);
3778 }
3779
3780 static void test_MsiGetProductInfoEx(void)
3781 {
3782     UINT r;
3783     LONG res;
3784     HKEY propkey, userkey;
3785     HKEY prodkey, localkey;
3786     CHAR prodcode[MAX_PATH];
3787     CHAR prod_squashed[MAX_PATH];
3788     CHAR packcode[MAX_PATH];
3789     CHAR pack_squashed[MAX_PATH];
3790     CHAR buf[MAX_PATH];
3791     CHAR keypath[MAX_PATH];
3792     LPSTR usersid;
3793     DWORD sz;
3794
3795     if (!pMsiGetProductInfoExA)
3796     {
3797         skip("MsiGetProductInfoExA is not available\n");
3798         return;
3799     }
3800
3801     create_test_guid(prodcode, prod_squashed);
3802     create_test_guid(packcode, pack_squashed);
3803     get_user_sid(&usersid);
3804
3805     /* NULL szProductCode */
3806     sz = MAX_PATH;
3807     lstrcpyA(buf, "apple");
3808     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3809                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3810     ok(r == ERROR_INVALID_PARAMETER,
3811        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3812     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3813     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3814
3815     /* empty szProductCode */
3816     sz = MAX_PATH;
3817     lstrcpyA(buf, "apple");
3818     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3819                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3820     ok(r == ERROR_INVALID_PARAMETER,
3821        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3822     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3823     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3824
3825     /* garbage szProductCode */
3826     sz = MAX_PATH;
3827     lstrcpyA(buf, "apple");
3828     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3829                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3830     ok(r == ERROR_INVALID_PARAMETER,
3831        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3832     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3833     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3834
3835     /* guid without brackets */
3836     sz = MAX_PATH;
3837     lstrcpyA(buf, "apple");
3838     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
3839                               MSIINSTALLCONTEXT_USERUNMANAGED,
3840                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3841     ok(r == ERROR_INVALID_PARAMETER,
3842        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3843     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3844     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3845
3846     /* guid with brackets */
3847     sz = MAX_PATH;
3848     lstrcpyA(buf, "apple");
3849     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
3850                               MSIINSTALLCONTEXT_USERUNMANAGED,
3851                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3852     ok(r == ERROR_UNKNOWN_PRODUCT,
3853        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3854     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3855     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3856
3857     /* szValue is non-NULL while pcchValue is NULL */
3858     lstrcpyA(buf, "apple");
3859     r = pMsiGetProductInfoExA(prodcode, usersid,
3860                               MSIINSTALLCONTEXT_USERUNMANAGED,
3861                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
3862     ok(r == ERROR_INVALID_PARAMETER,
3863        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3864     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3865
3866     /* dwContext is out of range */
3867     sz = MAX_PATH;
3868     lstrcpyA(buf, "apple");
3869     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
3870                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3871     ok(r == ERROR_INVALID_PARAMETER,
3872        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3873     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3874     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3875
3876     /* szProperty is NULL */
3877     sz = MAX_PATH;
3878     lstrcpyA(buf, "apple");
3879     r = pMsiGetProductInfoExA(prodcode, usersid,
3880                               MSIINSTALLCONTEXT_USERUNMANAGED,
3881                               NULL, buf, &sz);
3882     ok(r == ERROR_INVALID_PARAMETER,
3883        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3884     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3885     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3886
3887     /* szProperty is empty */
3888     sz = MAX_PATH;
3889     lstrcpyA(buf, "apple");
3890     r = pMsiGetProductInfoExA(prodcode, usersid,
3891                               MSIINSTALLCONTEXT_USERUNMANAGED,
3892                               "", buf, &sz);
3893     ok(r == ERROR_INVALID_PARAMETER,
3894        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3895     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3896     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3897
3898     /* szProperty is not a valid property */
3899     sz = MAX_PATH;
3900     lstrcpyA(buf, "apple");
3901     r = pMsiGetProductInfoExA(prodcode, usersid,
3902                               MSIINSTALLCONTEXT_USERUNMANAGED,
3903                               "notvalid", buf, &sz);
3904     ok(r == ERROR_UNKNOWN_PRODUCT,
3905        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3906     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3907     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3908
3909     /* same length as guid, but random */
3910     sz = MAX_PATH;
3911     lstrcpyA(buf, "apple");
3912     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
3913                               MSIINSTALLCONTEXT_USERUNMANAGED,
3914                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3915     ok(r == ERROR_INVALID_PARAMETER,
3916        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3917     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3918     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3919
3920     /* MSIINSTALLCONTEXT_USERUNMANAGED */
3921
3922     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3923     lstrcatA(keypath, usersid);
3924     lstrcatA(keypath, "\\Products\\");
3925     lstrcatA(keypath, prod_squashed);
3926
3927     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
3928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3929
3930     /* local user product key exists */
3931     sz = MAX_PATH;
3932     lstrcpyA(buf, "apple");
3933     r = pMsiGetProductInfoExA(prodcode, usersid,
3934                               MSIINSTALLCONTEXT_USERUNMANAGED,
3935                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3936     ok(r == ERROR_UNKNOWN_PRODUCT,
3937        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3938     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3939     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3940
3941     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
3942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3943
3944     /* InstallProperties key exists */
3945     sz = MAX_PATH;
3946     lstrcpyA(buf, "apple");
3947     r = pMsiGetProductInfoExA(prodcode, usersid,
3948                               MSIINSTALLCONTEXT_USERUNMANAGED,
3949                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3950     ok(r == ERROR_UNKNOWN_PRODUCT,
3951        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3952     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3953     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3954
3955     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3957
3958     /* LocalPackage value exists */
3959     sz = MAX_PATH;
3960     lstrcpyA(buf, "apple");
3961     r = pMsiGetProductInfoExA(prodcode, usersid,
3962                               MSIINSTALLCONTEXT_USERUNMANAGED,
3963                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3965     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
3966     ok(sz == 1, "Expected 1, got %d\n", sz);
3967
3968     RegDeleteValueA(propkey, "LocalPackage");
3969
3970     /* LocalPackage value must exist */
3971     sz = MAX_PATH;
3972     lstrcpyA(buf, "apple");
3973     r = pMsiGetProductInfoExA(prodcode, usersid,
3974                               MSIINSTALLCONTEXT_USERUNMANAGED,
3975                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3976     ok(r == ERROR_UNKNOWN_PRODUCT,
3977        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3978     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3979     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3980
3981     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3982     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3983
3984     /* LocalPackage exists, but HelpLink does not exist */
3985     sz = MAX_PATH;
3986     lstrcpyA(buf, "apple");
3987     r = pMsiGetProductInfoExA(prodcode, usersid,
3988                               MSIINSTALLCONTEXT_USERUNMANAGED,
3989                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3990     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3991     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3992     ok(sz == 0, "Expected 0, got %d\n", sz);
3993
3994     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3996
3997     /* HelpLink value exists */
3998     sz = MAX_PATH;
3999     lstrcpyA(buf, "apple");
4000     r = pMsiGetProductInfoExA(prodcode, usersid,
4001                               MSIINSTALLCONTEXT_USERUNMANAGED,
4002                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4004     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4005     ok(sz == 4, "Expected 4, got %d\n", sz);
4006
4007     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4009
4010     /* HelpTelephone value exists */
4011     sz = MAX_PATH;
4012     lstrcpyA(buf, "apple");
4013     r = pMsiGetProductInfoExA(prodcode, usersid,
4014                               MSIINSTALLCONTEXT_USERUNMANAGED,
4015                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4016     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4017     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4018     ok(sz == 5, "Expected 5, got %d\n", sz);
4019
4020     /* szValue and pcchValue are NULL */
4021     r = pMsiGetProductInfoExA(prodcode, usersid,
4022                               MSIINSTALLCONTEXT_USERUNMANAGED,
4023                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4025
4026     /* pcchValue is exactly 5 */
4027     sz = 5;
4028     lstrcpyA(buf, "apple");
4029     r = pMsiGetProductInfoExA(prodcode, usersid,
4030                               MSIINSTALLCONTEXT_USERUNMANAGED,
4031                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4032     ok(r == ERROR_MORE_DATA,
4033        "Expected ERROR_MORE_DATA, got %d\n", r);
4034     ok(sz == 10, "Expected 10, got %d\n", sz);
4035
4036     /* szValue is NULL, pcchValue is exactly 5 */
4037     sz = 5;
4038     r = pMsiGetProductInfoExA(prodcode, usersid,
4039                               MSIINSTALLCONTEXT_USERUNMANAGED,
4040                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4042     ok(sz == 10, "Expected 10, got %d\n", sz);
4043
4044     /* szValue is NULL, pcchValue is MAX_PATH */
4045     sz = MAX_PATH;
4046     r = pMsiGetProductInfoExA(prodcode, usersid,
4047                               MSIINSTALLCONTEXT_USERUNMANAGED,
4048                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4049     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4050     ok(sz == 10, "Expected 10, got %d\n", sz);
4051
4052     /* pcchValue is exactly 0 */
4053     sz = 0;
4054     lstrcpyA(buf, "apple");
4055     r = pMsiGetProductInfoExA(prodcode, usersid,
4056                               MSIINSTALLCONTEXT_USERUNMANAGED,
4057                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4058     ok(r == ERROR_MORE_DATA,
4059        "Expected ERROR_MORE_DATA, got %d\n", r);
4060     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4061     ok(sz == 10, "Expected 10, got %d\n", sz);
4062
4063     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4064     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4065
4066     /* szProperty is not a valid property */
4067     sz = MAX_PATH;
4068     lstrcpyA(buf, "apple");
4069     r = pMsiGetProductInfoExA(prodcode, usersid,
4070                               MSIINSTALLCONTEXT_USERUNMANAGED,
4071                               "notvalid", buf, &sz);
4072     ok(r == ERROR_UNKNOWN_PROPERTY,
4073        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4074     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4075     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4076
4077     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4079
4080     /* InstallDate value exists */
4081     sz = MAX_PATH;
4082     lstrcpyA(buf, "apple");
4083     r = pMsiGetProductInfoExA(prodcode, usersid,
4084                               MSIINSTALLCONTEXT_USERUNMANAGED,
4085                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4086     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4087     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4088     ok(sz == 4, "Expected 4, got %d\n", sz);
4089
4090     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4091     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4092
4093     /* DisplayName value exists */
4094     sz = MAX_PATH;
4095     lstrcpyA(buf, "apple");
4096     r = pMsiGetProductInfoExA(prodcode, usersid,
4097                               MSIINSTALLCONTEXT_USERUNMANAGED,
4098                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4099     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4100     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4101     ok(sz == 4, "Expected 4, got %d\n", sz);
4102
4103     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4104     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4105
4106     /* InstallLocation value exists */
4107     sz = MAX_PATH;
4108     lstrcpyA(buf, "apple");
4109     r = pMsiGetProductInfoExA(prodcode, usersid,
4110                               MSIINSTALLCONTEXT_USERUNMANAGED,
4111                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4112     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4113     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4114     ok(sz == 3, "Expected 3, got %d\n", sz);
4115
4116     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4117     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4118
4119     /* InstallSource value exists */
4120     sz = MAX_PATH;
4121     lstrcpyA(buf, "apple");
4122     r = pMsiGetProductInfoExA(prodcode, usersid,
4123                               MSIINSTALLCONTEXT_USERUNMANAGED,
4124                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4126     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4127     ok(sz == 6, "Expected 6, got %d\n", sz);
4128
4129     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4130     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4131
4132     /* LocalPackage value exists */
4133     sz = MAX_PATH;
4134     lstrcpyA(buf, "apple");
4135     r = pMsiGetProductInfoExA(prodcode, usersid,
4136                               MSIINSTALLCONTEXT_USERUNMANAGED,
4137                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4138     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4139     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4140     ok(sz == 5, "Expected 5, got %d\n", sz);
4141
4142     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4143     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4144
4145     /* Publisher value exists */
4146     sz = MAX_PATH;
4147     lstrcpyA(buf, "apple");
4148     r = pMsiGetProductInfoExA(prodcode, usersid,
4149                               MSIINSTALLCONTEXT_USERUNMANAGED,
4150                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4151     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4152     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4153     ok(sz == 3, "Expected 3, got %d\n", sz);
4154
4155     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4156     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4157
4158     /* URLInfoAbout value exists */
4159     sz = MAX_PATH;
4160     lstrcpyA(buf, "apple");
4161     r = pMsiGetProductInfoExA(prodcode, usersid,
4162                               MSIINSTALLCONTEXT_USERUNMANAGED,
4163                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4165     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4166     ok(sz == 5, "Expected 5, got %d\n", sz);
4167
4168     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4170
4171     /* URLUpdateInfo value exists */
4172     sz = MAX_PATH;
4173     lstrcpyA(buf, "apple");
4174     r = pMsiGetProductInfoExA(prodcode, usersid,
4175                               MSIINSTALLCONTEXT_USERUNMANAGED,
4176                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4177     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4178     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4179     ok(sz == 6, "Expected 6, got %d\n", sz);
4180
4181     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4183
4184     /* VersionMinor value exists */
4185     sz = MAX_PATH;
4186     lstrcpyA(buf, "apple");
4187     r = pMsiGetProductInfoExA(prodcode, usersid,
4188                               MSIINSTALLCONTEXT_USERUNMANAGED,
4189                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4190     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4191     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4192     ok(sz == 1, "Expected 1, got %d\n", sz);
4193
4194     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4196
4197     /* VersionMajor value exists */
4198     sz = MAX_PATH;
4199     lstrcpyA(buf, "apple");
4200     r = pMsiGetProductInfoExA(prodcode, usersid,
4201                               MSIINSTALLCONTEXT_USERUNMANAGED,
4202                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4203     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4204     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4205     ok(sz == 1, "Expected 1, got %d\n", sz);
4206
4207     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4208     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4209
4210     /* DisplayVersion value exists */
4211     sz = MAX_PATH;
4212     lstrcpyA(buf, "apple");
4213     r = pMsiGetProductInfoExA(prodcode, usersid,
4214                               MSIINSTALLCONTEXT_USERUNMANAGED,
4215                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4217     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4218     ok(sz == 5, "Expected 5, got %d\n", sz);
4219
4220     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4221     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4222
4223     /* ProductID value exists */
4224     sz = MAX_PATH;
4225     lstrcpyA(buf, "apple");
4226     r = pMsiGetProductInfoExA(prodcode, usersid,
4227                               MSIINSTALLCONTEXT_USERUNMANAGED,
4228                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4229     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4230     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4231     ok(sz == 2, "Expected 2, got %d\n", sz);
4232
4233     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4234     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4235
4236     /* RegCompany value exists */
4237     sz = MAX_PATH;
4238     lstrcpyA(buf, "apple");
4239     r = pMsiGetProductInfoExA(prodcode, usersid,
4240                               MSIINSTALLCONTEXT_USERUNMANAGED,
4241                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4242     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4243     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4244     ok(sz == 4, "Expected 4, got %d\n", sz);
4245
4246     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4248
4249     /* RegOwner value exists */
4250     sz = MAX_PATH;
4251     lstrcpyA(buf, "apple");
4252     r = pMsiGetProductInfoExA(prodcode, usersid,
4253                               MSIINSTALLCONTEXT_USERUNMANAGED,
4254                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4255     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4256     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4257     ok(sz == 5, "Expected 5, got %d\n", sz);
4258
4259     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4260     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4261
4262     /* Transforms value exists */
4263     sz = MAX_PATH;
4264     lstrcpyA(buf, "apple");
4265     r = pMsiGetProductInfoExA(prodcode, usersid,
4266                               MSIINSTALLCONTEXT_USERUNMANAGED,
4267                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4268     ok(r == ERROR_UNKNOWN_PRODUCT,
4269        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4270     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4271     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4272
4273     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4274     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4275
4276     /* Language value exists */
4277     sz = MAX_PATH;
4278     lstrcpyA(buf, "apple");
4279     r = pMsiGetProductInfoExA(prodcode, usersid,
4280                               MSIINSTALLCONTEXT_USERUNMANAGED,
4281                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4282     ok(r == ERROR_UNKNOWN_PRODUCT,
4283        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4284     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4285     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4286
4287     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4289
4290     /* ProductName value exists */
4291     sz = MAX_PATH;
4292     lstrcpyA(buf, "apple");
4293     r = pMsiGetProductInfoExA(prodcode, usersid,
4294                               MSIINSTALLCONTEXT_USERUNMANAGED,
4295                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4296     ok(r == ERROR_UNKNOWN_PRODUCT,
4297        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4298     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4299     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4300
4301     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4303
4304     /* FIXME */
4305
4306     /* AssignmentType value exists */
4307     sz = MAX_PATH;
4308     lstrcpyA(buf, "apple");
4309     r = pMsiGetProductInfoExA(prodcode, usersid,
4310                               MSIINSTALLCONTEXT_USERUNMANAGED,
4311                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4312     ok(r == ERROR_UNKNOWN_PRODUCT,
4313        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4314     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4315     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4316
4317     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4319
4320     /* PackageCode value exists */
4321     sz = MAX_PATH;
4322     lstrcpyA(buf, "apple");
4323     r = pMsiGetProductInfoExA(prodcode, usersid,
4324                               MSIINSTALLCONTEXT_USERUNMANAGED,
4325                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4326     ok(r == ERROR_UNKNOWN_PRODUCT,
4327        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4328     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4329     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4330
4331     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4333
4334     /* Version value exists */
4335     sz = MAX_PATH;
4336     lstrcpyA(buf, "apple");
4337     r = pMsiGetProductInfoExA(prodcode, usersid,
4338                               MSIINSTALLCONTEXT_USERUNMANAGED,
4339                               INSTALLPROPERTY_VERSION, buf, &sz);
4340     ok(r == ERROR_UNKNOWN_PRODUCT,
4341        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4342     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4343     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4344
4345     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4347
4348     /* ProductIcon value exists */
4349     sz = MAX_PATH;
4350     lstrcpyA(buf, "apple");
4351     r = pMsiGetProductInfoExA(prodcode, usersid,
4352                               MSIINSTALLCONTEXT_USERUNMANAGED,
4353                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4354     ok(r == ERROR_UNKNOWN_PRODUCT,
4355        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4356     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4357     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4358
4359     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4361
4362     /* PackageName value exists */
4363     sz = MAX_PATH;
4364     lstrcpyA(buf, "apple");
4365     r = pMsiGetProductInfoExA(prodcode, usersid,
4366                               MSIINSTALLCONTEXT_USERUNMANAGED,
4367                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4368     ok(r == ERROR_UNKNOWN_PRODUCT,
4369        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4370     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4371     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4372
4373     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4374     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4375
4376     /* AuthorizedLUAApp value exists */
4377     sz = MAX_PATH;
4378     lstrcpyA(buf, "apple");
4379     r = pMsiGetProductInfoExA(prodcode, usersid,
4380                               MSIINSTALLCONTEXT_USERUNMANAGED,
4381                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4382     ok(r == ERROR_UNKNOWN_PRODUCT,
4383        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4384     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4385     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4386
4387     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4388     RegDeleteValueA(propkey, "PackageName");
4389     RegDeleteValueA(propkey, "ProductIcon");
4390     RegDeleteValueA(propkey, "Version");
4391     RegDeleteValueA(propkey, "PackageCode");
4392     RegDeleteValueA(propkey, "AssignmentType");
4393     RegDeleteValueA(propkey, "ProductName");
4394     RegDeleteValueA(propkey, "Language");
4395     RegDeleteValueA(propkey, "Transforms");
4396     RegDeleteValueA(propkey, "RegOwner");
4397     RegDeleteValueA(propkey, "RegCompany");
4398     RegDeleteValueA(propkey, "ProductID");
4399     RegDeleteValueA(propkey, "DisplayVersion");
4400     RegDeleteValueA(propkey, "VersionMajor");
4401     RegDeleteValueA(propkey, "VersionMinor");
4402     RegDeleteValueA(propkey, "URLUpdateInfo");
4403     RegDeleteValueA(propkey, "URLInfoAbout");
4404     RegDeleteValueA(propkey, "Publisher");
4405     RegDeleteValueA(propkey, "LocalPackage");
4406     RegDeleteValueA(propkey, "InstallSource");
4407     RegDeleteValueA(propkey, "InstallLocation");
4408     RegDeleteValueA(propkey, "DisplayName");
4409     RegDeleteValueA(propkey, "InstallDate");
4410     RegDeleteValueA(propkey, "HelpTelephone");
4411     RegDeleteValueA(propkey, "HelpLink");
4412     RegDeleteValueA(propkey, "LocalPackage");
4413     RegDeleteKeyA(propkey, "");
4414     RegCloseKey(propkey);
4415     RegDeleteKeyA(localkey, "");
4416     RegCloseKey(localkey);
4417
4418     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4419     lstrcatA(keypath, usersid);
4420     lstrcatA(keypath, "\\Installer\\Products\\");
4421     lstrcatA(keypath, prod_squashed);
4422
4423     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
4424     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4425
4426     /* user product key exists */
4427     sz = MAX_PATH;
4428     lstrcpyA(buf, "apple");
4429     r = pMsiGetProductInfoExA(prodcode, usersid,
4430                               MSIINSTALLCONTEXT_USERUNMANAGED,
4431                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4432     ok(r == ERROR_UNKNOWN_PRODUCT,
4433        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4434     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4435     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4436
4437     RegDeleteKeyA(userkey, "");
4438     RegCloseKey(userkey);
4439
4440     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4441     lstrcatA(keypath, prod_squashed);
4442
4443     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4445
4446     sz = MAX_PATH;
4447     lstrcpyA(buf, "apple");
4448     r = pMsiGetProductInfoExA(prodcode, usersid,
4449                               MSIINSTALLCONTEXT_USERUNMANAGED,
4450                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4452     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4453     ok(sz == 1, "Expected 1, got %d\n", sz);
4454
4455     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4457
4458     /* HelpLink value exists */
4459     sz = MAX_PATH;
4460     lstrcpyA(buf, "apple");
4461     r = pMsiGetProductInfoExA(prodcode, usersid,
4462                               MSIINSTALLCONTEXT_USERUNMANAGED,
4463                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4464     ok(r == ERROR_UNKNOWN_PROPERTY,
4465        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4466     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4467     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4468
4469     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4470     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4471
4472     /* HelpTelephone value exists */
4473     sz = MAX_PATH;
4474     lstrcpyA(buf, "apple");
4475     r = pMsiGetProductInfoExA(prodcode, usersid,
4476                               MSIINSTALLCONTEXT_USERUNMANAGED,
4477                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4478     ok(r == ERROR_UNKNOWN_PROPERTY,
4479        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4480     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4481     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4482
4483     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4484     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4485
4486     /* InstallDate value exists */
4487     sz = MAX_PATH;
4488     lstrcpyA(buf, "apple");
4489     r = pMsiGetProductInfoExA(prodcode, usersid,
4490                               MSIINSTALLCONTEXT_USERUNMANAGED,
4491                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4492     ok(r == ERROR_UNKNOWN_PROPERTY,
4493        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4494     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4495     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4496
4497     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4499
4500     /* DisplayName value exists */
4501     sz = MAX_PATH;
4502     lstrcpyA(buf, "apple");
4503     r = pMsiGetProductInfoExA(prodcode, usersid,
4504                               MSIINSTALLCONTEXT_USERUNMANAGED,
4505                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4506     ok(r == ERROR_UNKNOWN_PROPERTY,
4507        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4508     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4509     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4510
4511     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4513
4514     /* InstallLocation value exists */
4515     sz = MAX_PATH;
4516     lstrcpyA(buf, "apple");
4517     r = pMsiGetProductInfoExA(prodcode, usersid,
4518                               MSIINSTALLCONTEXT_USERUNMANAGED,
4519                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4520     ok(r == ERROR_UNKNOWN_PROPERTY,
4521        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4522     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4523     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4524
4525     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4527
4528     /* InstallSource value exists */
4529     sz = MAX_PATH;
4530     lstrcpyA(buf, "apple");
4531     r = pMsiGetProductInfoExA(prodcode, usersid,
4532                               MSIINSTALLCONTEXT_USERUNMANAGED,
4533                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4534     ok(r == ERROR_UNKNOWN_PROPERTY,
4535        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4536     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4537     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4538
4539     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4541
4542     /* LocalPackage value exists */
4543     sz = MAX_PATH;
4544     lstrcpyA(buf, "apple");
4545     r = pMsiGetProductInfoExA(prodcode, usersid,
4546                               MSIINSTALLCONTEXT_USERUNMANAGED,
4547                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4548     ok(r == ERROR_UNKNOWN_PROPERTY,
4549        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4550     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4551     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4552
4553     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4555
4556     /* Publisher value exists */
4557     sz = MAX_PATH;
4558     lstrcpyA(buf, "apple");
4559     r = pMsiGetProductInfoExA(prodcode, usersid,
4560                               MSIINSTALLCONTEXT_USERUNMANAGED,
4561                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4562     ok(r == ERROR_UNKNOWN_PROPERTY,
4563        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4564     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4565     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4566
4567     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4569
4570     /* URLInfoAbout value exists */
4571     sz = MAX_PATH;
4572     lstrcpyA(buf, "apple");
4573     r = pMsiGetProductInfoExA(prodcode, usersid,
4574                               MSIINSTALLCONTEXT_USERUNMANAGED,
4575                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4576     ok(r == ERROR_UNKNOWN_PROPERTY,
4577        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4578     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4579     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4580
4581     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4583
4584     /* URLUpdateInfo value exists */
4585     sz = MAX_PATH;
4586     lstrcpyA(buf, "apple");
4587     r = pMsiGetProductInfoExA(prodcode, usersid,
4588                               MSIINSTALLCONTEXT_USERUNMANAGED,
4589                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4590     ok(r == ERROR_UNKNOWN_PROPERTY,
4591        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4592     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4593     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4594
4595     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4596     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4597
4598     /* VersionMinor value exists */
4599     sz = MAX_PATH;
4600     lstrcpyA(buf, "apple");
4601     r = pMsiGetProductInfoExA(prodcode, usersid,
4602                               MSIINSTALLCONTEXT_USERUNMANAGED,
4603                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4604     ok(r == ERROR_UNKNOWN_PROPERTY,
4605        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4606     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4607     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4608
4609     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4611
4612     /* VersionMajor value exists */
4613     sz = MAX_PATH;
4614     lstrcpyA(buf, "apple");
4615     r = pMsiGetProductInfoExA(prodcode, usersid,
4616                               MSIINSTALLCONTEXT_USERUNMANAGED,
4617                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4618     ok(r == ERROR_UNKNOWN_PROPERTY,
4619        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4620     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4621     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4622
4623     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4625
4626     /* DisplayVersion value exists */
4627     sz = MAX_PATH;
4628     lstrcpyA(buf, "apple");
4629     r = pMsiGetProductInfoExA(prodcode, usersid,
4630                               MSIINSTALLCONTEXT_USERUNMANAGED,
4631                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4632     ok(r == ERROR_UNKNOWN_PROPERTY,
4633        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4634     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4635     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4636
4637     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4639
4640     /* ProductID value exists */
4641     sz = MAX_PATH;
4642     lstrcpyA(buf, "apple");
4643     r = pMsiGetProductInfoExA(prodcode, usersid,
4644                               MSIINSTALLCONTEXT_USERUNMANAGED,
4645                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4646     ok(r == ERROR_UNKNOWN_PROPERTY,
4647        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4648     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4649     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4650
4651     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4653
4654     /* RegCompany value exists */
4655     sz = MAX_PATH;
4656     lstrcpyA(buf, "apple");
4657     r = pMsiGetProductInfoExA(prodcode, usersid,
4658                               MSIINSTALLCONTEXT_USERUNMANAGED,
4659                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4660     ok(r == ERROR_UNKNOWN_PROPERTY,
4661        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4662     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4663     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4664
4665     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4667
4668     /* RegOwner value exists */
4669     sz = MAX_PATH;
4670     lstrcpyA(buf, "apple");
4671     r = pMsiGetProductInfoExA(prodcode, usersid,
4672                               MSIINSTALLCONTEXT_USERUNMANAGED,
4673                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4674     ok(r == ERROR_UNKNOWN_PROPERTY,
4675        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4676     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4677     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4678
4679     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4681
4682     /* Transforms value exists */
4683     sz = MAX_PATH;
4684     lstrcpyA(buf, "apple");
4685     r = pMsiGetProductInfoExA(prodcode, usersid,
4686                               MSIINSTALLCONTEXT_USERUNMANAGED,
4687                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4688     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4689     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
4690     ok(sz == 5, "Expected 5, got %d\n", sz);
4691
4692     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4694
4695     /* Language value exists */
4696     sz = MAX_PATH;
4697     lstrcpyA(buf, "apple");
4698     r = pMsiGetProductInfoExA(prodcode, usersid,
4699                               MSIINSTALLCONTEXT_USERUNMANAGED,
4700                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4702     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4703     ok(sz == 4, "Expected 4, got %d\n", sz);
4704
4705     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4706     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4707
4708     /* ProductName value exists */
4709     sz = MAX_PATH;
4710     lstrcpyA(buf, "apple");
4711     r = pMsiGetProductInfoExA(prodcode, usersid,
4712                               MSIINSTALLCONTEXT_USERUNMANAGED,
4713                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4714     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4715     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4716     ok(sz == 4, "Expected 4, got %d\n", sz);
4717
4718     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4720
4721     /* FIXME */
4722
4723     /* AssignmentType value exists */
4724     sz = MAX_PATH;
4725     lstrcpyA(buf, "apple");
4726     r = pMsiGetProductInfoExA(prodcode, usersid,
4727                               MSIINSTALLCONTEXT_USERUNMANAGED,
4728                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4729     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4730     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4731     ok(sz == 0, "Expected 0, got %d\n", sz);
4732
4733     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4735
4736     /* FIXME */
4737
4738     /* PackageCode value exists */
4739     sz = MAX_PATH;
4740     lstrcpyA(buf, "apple");
4741     r = pMsiGetProductInfoExA(prodcode, usersid,
4742                               MSIINSTALLCONTEXT_USERUNMANAGED,
4743                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4744     todo_wine
4745     {
4746         ok(r == ERROR_BAD_CONFIGURATION,
4747            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4748         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4749         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4750     }
4751
4752     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4754
4755     /* Version value exists */
4756     sz = MAX_PATH;
4757     lstrcpyA(buf, "apple");
4758     r = pMsiGetProductInfoExA(prodcode, usersid,
4759                               MSIINSTALLCONTEXT_USERUNMANAGED,
4760                               INSTALLPROPERTY_VERSION, buf, &sz);
4761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4762     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4763     ok(sz == 3, "Expected 3, got %d\n", sz);
4764
4765     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4767
4768     /* ProductIcon value exists */
4769     sz = MAX_PATH;
4770     lstrcpyA(buf, "apple");
4771     r = pMsiGetProductInfoExA(prodcode, usersid,
4772                               MSIINSTALLCONTEXT_USERUNMANAGED,
4773                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4774     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4775     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
4776     ok(sz == 4, "Expected 4, got %d\n", sz);
4777
4778     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4780
4781     /* PackageName value exists */
4782     sz = MAX_PATH;
4783     lstrcpyA(buf, "apple");
4784     r = pMsiGetProductInfoExA(prodcode, usersid,
4785                               MSIINSTALLCONTEXT_USERUNMANAGED,
4786                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4787     todo_wine
4788     {
4789         ok(r == ERROR_UNKNOWN_PRODUCT,
4790            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4791         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4792         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4793     }
4794
4795     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4796     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4797
4798     /* AuthorizedLUAApp value exists */
4799     sz = MAX_PATH;
4800     lstrcpyA(buf, "apple");
4801     r = pMsiGetProductInfoExA(prodcode, usersid,
4802                               MSIINSTALLCONTEXT_USERUNMANAGED,
4803                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4805     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4806     ok(sz == 4, "Expected 4, got %d\n", sz);
4807
4808     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4809     RegDeleteValueA(prodkey, "PackageName");
4810     RegDeleteValueA(prodkey, "ProductIcon");
4811     RegDeleteValueA(prodkey, "Version");
4812     RegDeleteValueA(prodkey, "PackageCode");
4813     RegDeleteValueA(prodkey, "AssignmentType");
4814     RegDeleteValueA(prodkey, "ProductName");
4815     RegDeleteValueA(prodkey, "Language");
4816     RegDeleteValueA(prodkey, "Transforms");
4817     RegDeleteValueA(prodkey, "RegOwner");
4818     RegDeleteValueA(prodkey, "RegCompany");
4819     RegDeleteValueA(prodkey, "ProductID");
4820     RegDeleteValueA(prodkey, "DisplayVersion");
4821     RegDeleteValueA(prodkey, "VersionMajor");
4822     RegDeleteValueA(prodkey, "VersionMinor");
4823     RegDeleteValueA(prodkey, "URLUpdateInfo");
4824     RegDeleteValueA(prodkey, "URLInfoAbout");
4825     RegDeleteValueA(prodkey, "Publisher");
4826     RegDeleteValueA(prodkey, "LocalPackage");
4827     RegDeleteValueA(prodkey, "InstallSource");
4828     RegDeleteValueA(prodkey, "InstallLocation");
4829     RegDeleteValueA(prodkey, "DisplayName");
4830     RegDeleteValueA(prodkey, "InstallDate");
4831     RegDeleteValueA(prodkey, "HelpTelephone");
4832     RegDeleteValueA(prodkey, "HelpLink");
4833     RegDeleteValueA(prodkey, "LocalPackage");
4834     RegDeleteKeyA(prodkey, "");
4835     RegCloseKey(prodkey);
4836
4837     /* MSIINSTALLCONTEXT_USERMANAGED */
4838
4839     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4840     lstrcatA(keypath, usersid);
4841     lstrcatA(keypath, "\\Products\\");
4842     lstrcatA(keypath, prod_squashed);
4843
4844     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4845     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4846
4847     /* local user product key exists */
4848     sz = MAX_PATH;
4849     lstrcpyA(buf, "apple");
4850     r = pMsiGetProductInfoExA(prodcode, usersid,
4851                               MSIINSTALLCONTEXT_USERMANAGED,
4852                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4853     ok(r == ERROR_UNKNOWN_PRODUCT,
4854        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4855     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4856     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4857
4858     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4859     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4860
4861     /* InstallProperties key exists */
4862     sz = MAX_PATH;
4863     lstrcpyA(buf, "apple");
4864     r = pMsiGetProductInfoExA(prodcode, usersid,
4865                               MSIINSTALLCONTEXT_USERMANAGED,
4866                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4867     ok(r == ERROR_UNKNOWN_PRODUCT,
4868        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4869     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4870     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4871
4872     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4873     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4874
4875     /* ManagedLocalPackage value exists */
4876     sz = MAX_PATH;
4877     lstrcpyA(buf, "apple");
4878     r = pMsiGetProductInfoExA(prodcode, usersid,
4879                               MSIINSTALLCONTEXT_USERMANAGED,
4880                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4881     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4882     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4883     ok(sz == 1, "Expected 1, got %d\n", sz);
4884
4885     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4887
4888     /* HelpLink value exists */
4889     sz = MAX_PATH;
4890     lstrcpyA(buf, "apple");
4891     r = pMsiGetProductInfoExA(prodcode, usersid,
4892                               MSIINSTALLCONTEXT_USERMANAGED,
4893                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4894     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4895     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4896     ok(sz == 4, "Expected 4, got %d\n", sz);
4897
4898     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4899     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4900
4901     /* HelpTelephone value exists */
4902     sz = MAX_PATH;
4903     lstrcpyA(buf, "apple");
4904     r = pMsiGetProductInfoExA(prodcode, usersid,
4905                               MSIINSTALLCONTEXT_USERMANAGED,
4906                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4907     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4908     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4909     ok(sz == 5, "Expected 5, got %d\n", sz);
4910
4911     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4913
4914     /* InstallDate value exists */
4915     sz = MAX_PATH;
4916     lstrcpyA(buf, "apple");
4917     r = pMsiGetProductInfoExA(prodcode, usersid,
4918                               MSIINSTALLCONTEXT_USERMANAGED,
4919                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4920     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4921     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4922     ok(sz == 4, "Expected 4, got %d\n", sz);
4923
4924     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4925     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4926
4927     /* DisplayName value exists */
4928     sz = MAX_PATH;
4929     lstrcpyA(buf, "apple");
4930     r = pMsiGetProductInfoExA(prodcode, usersid,
4931                               MSIINSTALLCONTEXT_USERMANAGED,
4932                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4933     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4934     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4935     ok(sz == 4, "Expected 4, got %d\n", sz);
4936
4937     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4938     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4939
4940     /* InstallLocation value exists */
4941     sz = MAX_PATH;
4942     lstrcpyA(buf, "apple");
4943     r = pMsiGetProductInfoExA(prodcode, usersid,
4944                               MSIINSTALLCONTEXT_USERMANAGED,
4945                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4946     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4947     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4948     ok(sz == 3, "Expected 3, got %d\n", sz);
4949
4950     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4952
4953     /* InstallSource value exists */
4954     sz = MAX_PATH;
4955     lstrcpyA(buf, "apple");
4956     r = pMsiGetProductInfoExA(prodcode, usersid,
4957                               MSIINSTALLCONTEXT_USERMANAGED,
4958                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4959     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4960     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4961     ok(sz == 6, "Expected 6, got %d\n", sz);
4962
4963     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4965
4966     /* LocalPackage value exists */
4967     sz = MAX_PATH;
4968     lstrcpyA(buf, "apple");
4969     r = pMsiGetProductInfoExA(prodcode, usersid,
4970                               MSIINSTALLCONTEXT_USERMANAGED,
4971                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4972     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4973     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4974     ok(sz == 5, "Expected 5, got %d\n", sz);
4975
4976     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4978
4979     /* Publisher value exists */
4980     sz = MAX_PATH;
4981     lstrcpyA(buf, "apple");
4982     r = pMsiGetProductInfoExA(prodcode, usersid,
4983                               MSIINSTALLCONTEXT_USERMANAGED,
4984                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4985     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4986     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4987     ok(sz == 3, "Expected 3, got %d\n", sz);
4988
4989     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4990     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4991
4992     /* URLInfoAbout value exists */
4993     sz = MAX_PATH;
4994     lstrcpyA(buf, "apple");
4995     r = pMsiGetProductInfoExA(prodcode, usersid,
4996                               MSIINSTALLCONTEXT_USERMANAGED,
4997                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4998     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4999     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5000     ok(sz == 5, "Expected 5, got %d\n", sz);
5001
5002     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5003     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5004
5005     /* URLUpdateInfo value exists */
5006     sz = MAX_PATH;
5007     lstrcpyA(buf, "apple");
5008     r = pMsiGetProductInfoExA(prodcode, usersid,
5009                               MSIINSTALLCONTEXT_USERMANAGED,
5010                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5012     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5013     ok(sz == 6, "Expected 6, got %d\n", sz);
5014
5015     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5016     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5017
5018     /* VersionMinor value exists */
5019     sz = MAX_PATH;
5020     lstrcpyA(buf, "apple");
5021     r = pMsiGetProductInfoExA(prodcode, usersid,
5022                               MSIINSTALLCONTEXT_USERMANAGED,
5023                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5025     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5026     ok(sz == 1, "Expected 1, got %d\n", sz);
5027
5028     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5029     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5030
5031     /* VersionMajor value exists */
5032     sz = MAX_PATH;
5033     lstrcpyA(buf, "apple");
5034     r = pMsiGetProductInfoExA(prodcode, usersid,
5035                               MSIINSTALLCONTEXT_USERMANAGED,
5036                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5037     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5038     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5039     ok(sz == 1, "Expected 1, got %d\n", sz);
5040
5041     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5042     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5043
5044     /* DisplayVersion value exists */
5045     sz = MAX_PATH;
5046     lstrcpyA(buf, "apple");
5047     r = pMsiGetProductInfoExA(prodcode, usersid,
5048                               MSIINSTALLCONTEXT_USERMANAGED,
5049                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5050     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5051     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5052     ok(sz == 5, "Expected 5, got %d\n", sz);
5053
5054     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5055     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5056
5057     /* ProductID value exists */
5058     sz = MAX_PATH;
5059     lstrcpyA(buf, "apple");
5060     r = pMsiGetProductInfoExA(prodcode, usersid,
5061                               MSIINSTALLCONTEXT_USERMANAGED,
5062                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5063     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5064     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5065     ok(sz == 2, "Expected 2, got %d\n", sz);
5066
5067     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5068     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5069
5070     /* RegCompany value exists */
5071     sz = MAX_PATH;
5072     lstrcpyA(buf, "apple");
5073     r = pMsiGetProductInfoExA(prodcode, usersid,
5074                               MSIINSTALLCONTEXT_USERMANAGED,
5075                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5076     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5077     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5078     ok(sz == 4, "Expected 4, got %d\n", sz);
5079
5080     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5081     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5082
5083     /* RegOwner value exists */
5084     sz = MAX_PATH;
5085     lstrcpyA(buf, "apple");
5086     r = pMsiGetProductInfoExA(prodcode, usersid,
5087                               MSIINSTALLCONTEXT_USERMANAGED,
5088                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5090     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5091     ok(sz == 5, "Expected 5, got %d\n", sz);
5092
5093     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5094     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5095
5096     /* Transforms value exists */
5097     sz = MAX_PATH;
5098     lstrcpyA(buf, "apple");
5099     r = pMsiGetProductInfoExA(prodcode, usersid,
5100                               MSIINSTALLCONTEXT_USERMANAGED,
5101                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5102     ok(r == ERROR_UNKNOWN_PRODUCT,
5103        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5104     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5105     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5106
5107     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5108     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5109
5110     /* Language value exists */
5111     sz = MAX_PATH;
5112     lstrcpyA(buf, "apple");
5113     r = pMsiGetProductInfoExA(prodcode, usersid,
5114                               MSIINSTALLCONTEXT_USERMANAGED,
5115                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5116     ok(r == ERROR_UNKNOWN_PRODUCT,
5117        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5118     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5119     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5120
5121     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5122     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5123
5124     /* ProductName value exists */
5125     sz = MAX_PATH;
5126     lstrcpyA(buf, "apple");
5127     r = pMsiGetProductInfoExA(prodcode, usersid,
5128                               MSIINSTALLCONTEXT_USERMANAGED,
5129                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5130     ok(r == ERROR_UNKNOWN_PRODUCT,
5131        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5132     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5133     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5134
5135     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5136     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5137
5138     /* FIXME */
5139
5140     /* AssignmentType value exists */
5141     sz = MAX_PATH;
5142     lstrcpyA(buf, "apple");
5143     r = pMsiGetProductInfoExA(prodcode, usersid,
5144                               MSIINSTALLCONTEXT_USERMANAGED,
5145                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5146     ok(r == ERROR_UNKNOWN_PRODUCT,
5147        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5148     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5149     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5150
5151     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5152     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5153
5154     /* PackageCode value exists */
5155     sz = MAX_PATH;
5156     lstrcpyA(buf, "apple");
5157     r = pMsiGetProductInfoExA(prodcode, usersid,
5158                               MSIINSTALLCONTEXT_USERMANAGED,
5159                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5160     ok(r == ERROR_UNKNOWN_PRODUCT,
5161        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5162     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5163     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5164
5165     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5166     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5167
5168     /* Version value exists */
5169     sz = MAX_PATH;
5170     lstrcpyA(buf, "apple");
5171     r = pMsiGetProductInfoExA(prodcode, usersid,
5172                               MSIINSTALLCONTEXT_USERMANAGED,
5173                               INSTALLPROPERTY_VERSION, buf, &sz);
5174     ok(r == ERROR_UNKNOWN_PRODUCT,
5175        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5176     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5177     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5178
5179     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5180     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5181
5182     /* ProductIcon value exists */
5183     sz = MAX_PATH;
5184     lstrcpyA(buf, "apple");
5185     r = pMsiGetProductInfoExA(prodcode, usersid,
5186                               MSIINSTALLCONTEXT_USERMANAGED,
5187                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5188     ok(r == ERROR_UNKNOWN_PRODUCT,
5189        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5190     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5191     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5192
5193     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5194     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5195
5196     /* PackageName value exists */
5197     sz = MAX_PATH;
5198     lstrcpyA(buf, "apple");
5199     r = pMsiGetProductInfoExA(prodcode, usersid,
5200                               MSIINSTALLCONTEXT_USERMANAGED,
5201                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5202     ok(r == ERROR_UNKNOWN_PRODUCT,
5203        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5204     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5205     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5206
5207     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5208     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5209
5210     /* AuthorizedLUAApp value exists */
5211     sz = MAX_PATH;
5212     lstrcpyA(buf, "apple");
5213     r = pMsiGetProductInfoExA(prodcode, usersid,
5214                               MSIINSTALLCONTEXT_USERMANAGED,
5215                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5216     ok(r == ERROR_UNKNOWN_PRODUCT,
5217        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5218     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5219     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5220
5221     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5222     RegDeleteValueA(propkey, "PackageName");
5223     RegDeleteValueA(propkey, "ProductIcon");
5224     RegDeleteValueA(propkey, "Version");
5225     RegDeleteValueA(propkey, "PackageCode");
5226     RegDeleteValueA(propkey, "AssignmentType");
5227     RegDeleteValueA(propkey, "ProductName");
5228     RegDeleteValueA(propkey, "Language");
5229     RegDeleteValueA(propkey, "Transforms");
5230     RegDeleteValueA(propkey, "RegOwner");
5231     RegDeleteValueA(propkey, "RegCompany");
5232     RegDeleteValueA(propkey, "ProductID");
5233     RegDeleteValueA(propkey, "DisplayVersion");
5234     RegDeleteValueA(propkey, "VersionMajor");
5235     RegDeleteValueA(propkey, "VersionMinor");
5236     RegDeleteValueA(propkey, "URLUpdateInfo");
5237     RegDeleteValueA(propkey, "URLInfoAbout");
5238     RegDeleteValueA(propkey, "Publisher");
5239     RegDeleteValueA(propkey, "LocalPackage");
5240     RegDeleteValueA(propkey, "InstallSource");
5241     RegDeleteValueA(propkey, "InstallLocation");
5242     RegDeleteValueA(propkey, "DisplayName");
5243     RegDeleteValueA(propkey, "InstallDate");
5244     RegDeleteValueA(propkey, "HelpTelephone");
5245     RegDeleteValueA(propkey, "HelpLink");
5246     RegDeleteValueA(propkey, "ManagedLocalPackage");
5247     RegDeleteKeyA(propkey, "");
5248     RegCloseKey(propkey);
5249     RegDeleteKeyA(localkey, "");
5250     RegCloseKey(localkey);
5251
5252     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5253     lstrcatA(keypath, usersid);
5254     lstrcatA(keypath, "\\Installer\\Products\\");
5255     lstrcatA(keypath, prod_squashed);
5256
5257     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5258     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5259
5260     /* user product key exists */
5261     sz = MAX_PATH;
5262     lstrcpyA(buf, "apple");
5263     r = pMsiGetProductInfoExA(prodcode, usersid,
5264                               MSIINSTALLCONTEXT_USERMANAGED,
5265                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5266     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5267     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5268     ok(sz == 1, "Expected 1, got %d\n", sz);
5269
5270     RegDeleteKeyA(userkey, "");
5271     RegCloseKey(userkey);
5272
5273     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5274     lstrcatA(keypath, prod_squashed);
5275
5276     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5277     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5278
5279     /* current user product key exists */
5280     sz = MAX_PATH;
5281     lstrcpyA(buf, "apple");
5282     r = pMsiGetProductInfoExA(prodcode, usersid,
5283                               MSIINSTALLCONTEXT_USERMANAGED,
5284                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5285     ok(r == ERROR_UNKNOWN_PRODUCT,
5286        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5287     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5288     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5289
5290     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5292
5293     /* HelpLink value exists, user product key does not exist */
5294     sz = MAX_PATH;
5295     lstrcpyA(buf, "apple");
5296     r = pMsiGetProductInfoExA(prodcode, usersid,
5297                               MSIINSTALLCONTEXT_USERMANAGED,
5298                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5299     ok(r == ERROR_UNKNOWN_PRODUCT,
5300        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5301     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5302     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5303
5304     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5305     lstrcatA(keypath, usersid);
5306     lstrcatA(keypath, "\\Installer\\Products\\");
5307     lstrcatA(keypath, prod_squashed);
5308
5309     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5311
5312     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5313     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5314
5315     /* HelpLink value exists, user product key does exist */
5316     sz = MAX_PATH;
5317     lstrcpyA(buf, "apple");
5318     r = pMsiGetProductInfoExA(prodcode, usersid,
5319                               MSIINSTALLCONTEXT_USERMANAGED,
5320                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5321     ok(r == ERROR_UNKNOWN_PROPERTY,
5322        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5323     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5324     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5325
5326     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5327     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5328
5329     /* HelpTelephone value exists */
5330     sz = MAX_PATH;
5331     lstrcpyA(buf, "apple");
5332     r = pMsiGetProductInfoExA(prodcode, usersid,
5333                               MSIINSTALLCONTEXT_USERMANAGED,
5334                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5335     ok(r == ERROR_UNKNOWN_PROPERTY,
5336        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5337     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5338     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5339
5340     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5341     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5342
5343     /* InstallDate value exists */
5344     sz = MAX_PATH;
5345     lstrcpyA(buf, "apple");
5346     r = pMsiGetProductInfoExA(prodcode, usersid,
5347                               MSIINSTALLCONTEXT_USERMANAGED,
5348                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5349     ok(r == ERROR_UNKNOWN_PROPERTY,
5350        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5351     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5352     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5353
5354     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5356
5357     /* DisplayName value exists */
5358     sz = MAX_PATH;
5359     lstrcpyA(buf, "apple");
5360     r = pMsiGetProductInfoExA(prodcode, usersid,
5361                               MSIINSTALLCONTEXT_USERMANAGED,
5362                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5363     ok(r == ERROR_UNKNOWN_PROPERTY,
5364        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5365     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5366     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5367
5368     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5369     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5370
5371     /* InstallLocation value exists */
5372     sz = MAX_PATH;
5373     lstrcpyA(buf, "apple");
5374     r = pMsiGetProductInfoExA(prodcode, usersid,
5375                               MSIINSTALLCONTEXT_USERMANAGED,
5376                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5377     ok(r == ERROR_UNKNOWN_PROPERTY,
5378        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5379     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5380     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5381
5382     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5383     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5384
5385     /* InstallSource value exists */
5386     sz = MAX_PATH;
5387     lstrcpyA(buf, "apple");
5388     r = pMsiGetProductInfoExA(prodcode, usersid,
5389                               MSIINSTALLCONTEXT_USERMANAGED,
5390                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5391     ok(r == ERROR_UNKNOWN_PROPERTY,
5392        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5393     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5394     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5395
5396     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5397     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5398
5399     /* LocalPackage value exists */
5400     sz = MAX_PATH;
5401     lstrcpyA(buf, "apple");
5402     r = pMsiGetProductInfoExA(prodcode, usersid,
5403                               MSIINSTALLCONTEXT_USERMANAGED,
5404                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5405     ok(r == ERROR_UNKNOWN_PROPERTY,
5406        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5407     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5408     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5409
5410     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5412
5413     /* Publisher value exists */
5414     sz = MAX_PATH;
5415     lstrcpyA(buf, "apple");
5416     r = pMsiGetProductInfoExA(prodcode, usersid,
5417                               MSIINSTALLCONTEXT_USERMANAGED,
5418                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5419     ok(r == ERROR_UNKNOWN_PROPERTY,
5420        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5421     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5422     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5423
5424     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5425     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5426
5427     /* URLInfoAbout value exists */
5428     sz = MAX_PATH;
5429     lstrcpyA(buf, "apple");
5430     r = pMsiGetProductInfoExA(prodcode, usersid,
5431                               MSIINSTALLCONTEXT_USERMANAGED,
5432                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5433     ok(r == ERROR_UNKNOWN_PROPERTY,
5434        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5435     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5436     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5437
5438     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5439     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5440
5441     /* URLUpdateInfo value exists */
5442     sz = MAX_PATH;
5443     lstrcpyA(buf, "apple");
5444     r = pMsiGetProductInfoExA(prodcode, usersid,
5445                               MSIINSTALLCONTEXT_USERMANAGED,
5446                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5447     ok(r == ERROR_UNKNOWN_PROPERTY,
5448        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5449     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5450     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5451
5452     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5453     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5454
5455     /* VersionMinor value exists */
5456     sz = MAX_PATH;
5457     lstrcpyA(buf, "apple");
5458     r = pMsiGetProductInfoExA(prodcode, usersid,
5459                               MSIINSTALLCONTEXT_USERMANAGED,
5460                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5461     ok(r == ERROR_UNKNOWN_PROPERTY,
5462        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5463     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5464     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5465
5466     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5467     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5468
5469     /* VersionMajor value exists */
5470     sz = MAX_PATH;
5471     lstrcpyA(buf, "apple");
5472     r = pMsiGetProductInfoExA(prodcode, usersid,
5473                               MSIINSTALLCONTEXT_USERMANAGED,
5474                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5475     ok(r == ERROR_UNKNOWN_PROPERTY,
5476        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5477     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5478     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5479
5480     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5481     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5482
5483     /* DisplayVersion value exists */
5484     sz = MAX_PATH;
5485     lstrcpyA(buf, "apple");
5486     r = pMsiGetProductInfoExA(prodcode, usersid,
5487                               MSIINSTALLCONTEXT_USERMANAGED,
5488                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5489     ok(r == ERROR_UNKNOWN_PROPERTY,
5490        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5491     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5492     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5493
5494     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5495     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5496
5497     /* ProductID value exists */
5498     sz = MAX_PATH;
5499     lstrcpyA(buf, "apple");
5500     r = pMsiGetProductInfoExA(prodcode, usersid,
5501                               MSIINSTALLCONTEXT_USERMANAGED,
5502                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5503     ok(r == ERROR_UNKNOWN_PROPERTY,
5504        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5505     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5506     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5507
5508     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5510
5511     /* RegCompany value exists */
5512     sz = MAX_PATH;
5513     lstrcpyA(buf, "apple");
5514     r = pMsiGetProductInfoExA(prodcode, usersid,
5515                               MSIINSTALLCONTEXT_USERMANAGED,
5516                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5517     ok(r == ERROR_UNKNOWN_PROPERTY,
5518        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5519     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5520     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5521
5522     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5524
5525     /* RegOwner value exists */
5526     sz = MAX_PATH;
5527     lstrcpyA(buf, "apple");
5528     r = pMsiGetProductInfoExA(prodcode, usersid,
5529                               MSIINSTALLCONTEXT_USERMANAGED,
5530                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5531     ok(r == ERROR_UNKNOWN_PROPERTY,
5532        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5533     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5534     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5535
5536     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5537     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5538
5539     /* Transforms value exists */
5540     sz = MAX_PATH;
5541     lstrcpyA(buf, "apple");
5542     r = pMsiGetProductInfoExA(prodcode, usersid,
5543                               MSIINSTALLCONTEXT_USERMANAGED,
5544                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5545     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5546     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5547     ok(sz == 5, "Expected 5, got %d\n", sz);
5548
5549     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5551
5552     /* Language value exists */
5553     sz = MAX_PATH;
5554     lstrcpyA(buf, "apple");
5555     r = pMsiGetProductInfoExA(prodcode, usersid,
5556                               MSIINSTALLCONTEXT_USERMANAGED,
5557                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5558     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5559     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5560     ok(sz == 4, "Expected 4, got %d\n", sz);
5561
5562     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5563     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5564
5565     /* ProductName value exists */
5566     sz = MAX_PATH;
5567     lstrcpyA(buf, "apple");
5568     r = pMsiGetProductInfoExA(prodcode, usersid,
5569                               MSIINSTALLCONTEXT_USERMANAGED,
5570                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5572     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5573     ok(sz == 4, "Expected 4, got %d\n", sz);
5574
5575     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5576     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5577
5578     /* FIXME */
5579
5580     /* AssignmentType value exists */
5581     sz = MAX_PATH;
5582     lstrcpyA(buf, "apple");
5583     r = pMsiGetProductInfoExA(prodcode, usersid,
5584                               MSIINSTALLCONTEXT_USERMANAGED,
5585                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5586     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5587     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5588     ok(sz == 0, "Expected 0, got %d\n", sz);
5589
5590     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5591     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5592
5593     /* FIXME */
5594
5595     /* PackageCode value exists */
5596     sz = MAX_PATH;
5597     lstrcpyA(buf, "apple");
5598     r = pMsiGetProductInfoExA(prodcode, usersid,
5599                               MSIINSTALLCONTEXT_USERMANAGED,
5600                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5601     todo_wine
5602     {
5603         ok(r == ERROR_BAD_CONFIGURATION,
5604            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5605         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5606         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5607     }
5608
5609     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5611
5612     /* Version value exists */
5613     sz = MAX_PATH;
5614     lstrcpyA(buf, "apple");
5615     r = pMsiGetProductInfoExA(prodcode, usersid,
5616                               MSIINSTALLCONTEXT_USERMANAGED,
5617                               INSTALLPROPERTY_VERSION, buf, &sz);
5618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5619     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5620     ok(sz == 3, "Expected 3, got %d\n", sz);
5621
5622     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5624
5625     /* ProductIcon value exists */
5626     sz = MAX_PATH;
5627     lstrcpyA(buf, "apple");
5628     r = pMsiGetProductInfoExA(prodcode, usersid,
5629                               MSIINSTALLCONTEXT_USERMANAGED,
5630                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5631     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5632     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5633     ok(sz == 4, "Expected 4, got %d\n", sz);
5634
5635     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5637
5638     /* PackageName value exists */
5639     sz = MAX_PATH;
5640     lstrcpyA(buf, "apple");
5641     r = pMsiGetProductInfoExA(prodcode, usersid,
5642                               MSIINSTALLCONTEXT_USERMANAGED,
5643                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5644     todo_wine
5645     {
5646         ok(r == ERROR_UNKNOWN_PRODUCT,
5647            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5648         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5649         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5650     }
5651
5652     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5654
5655     /* AuthorizedLUAApp value exists */
5656     sz = MAX_PATH;
5657     lstrcpyA(buf, "apple");
5658     r = pMsiGetProductInfoExA(prodcode, usersid,
5659                               MSIINSTALLCONTEXT_USERMANAGED,
5660                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5661     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5662     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5663     ok(sz == 4, "Expected 4, got %d\n", sz);
5664
5665     RegDeleteValueA(userkey, "AuthorizedLUAApp");
5666     RegDeleteValueA(userkey, "PackageName");
5667     RegDeleteValueA(userkey, "ProductIcon");
5668     RegDeleteValueA(userkey, "Version");
5669     RegDeleteValueA(userkey, "PackageCode");
5670     RegDeleteValueA(userkey, "AssignmentType");
5671     RegDeleteValueA(userkey, "ProductName");
5672     RegDeleteValueA(userkey, "Language");
5673     RegDeleteValueA(userkey, "Transforms");
5674     RegDeleteValueA(userkey, "RegOwner");
5675     RegDeleteValueA(userkey, "RegCompany");
5676     RegDeleteValueA(userkey, "ProductID");
5677     RegDeleteValueA(userkey, "DisplayVersion");
5678     RegDeleteValueA(userkey, "VersionMajor");
5679     RegDeleteValueA(userkey, "VersionMinor");
5680     RegDeleteValueA(userkey, "URLUpdateInfo");
5681     RegDeleteValueA(userkey, "URLInfoAbout");
5682     RegDeleteValueA(userkey, "Publisher");
5683     RegDeleteValueA(userkey, "LocalPackage");
5684     RegDeleteValueA(userkey, "InstallSource");
5685     RegDeleteValueA(userkey, "InstallLocation");
5686     RegDeleteValueA(userkey, "DisplayName");
5687     RegDeleteValueA(userkey, "InstallDate");
5688     RegDeleteValueA(userkey, "HelpTelephone");
5689     RegDeleteValueA(userkey, "HelpLink");
5690     RegDeleteKeyA(userkey, "");
5691     RegCloseKey(userkey);
5692     RegDeleteKeyA(prodkey, "");
5693     RegCloseKey(prodkey);
5694
5695     /* MSIINSTALLCONTEXT_MACHINE */
5696
5697     /* szUserSid is non-NULL */
5698     sz = MAX_PATH;
5699     lstrcpyA(buf, "apple");
5700     r = pMsiGetProductInfoExA(prodcode, usersid,
5701                               MSIINSTALLCONTEXT_MACHINE,
5702                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5703     ok(r == ERROR_INVALID_PARAMETER,
5704        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5705     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5706     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5707
5708     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
5709     lstrcatA(keypath, prod_squashed);
5710
5711     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5713
5714     /* local system product key exists */
5715     sz = MAX_PATH;
5716     lstrcpyA(buf, "apple");
5717     r = pMsiGetProductInfoExA(prodcode, NULL,
5718                               MSIINSTALLCONTEXT_MACHINE,
5719                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5720     ok(r == ERROR_UNKNOWN_PRODUCT,
5721        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5722     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5723     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5724
5725     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5727
5728     /* InstallProperties key exists */
5729     sz = MAX_PATH;
5730     lstrcpyA(buf, "apple");
5731     r = pMsiGetProductInfoExA(prodcode, NULL,
5732                               MSIINSTALLCONTEXT_MACHINE,
5733                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5734     ok(r == ERROR_UNKNOWN_PRODUCT,
5735        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5736     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5737     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5738
5739     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5741
5742     /* LocalPackage value exists */
5743     sz = MAX_PATH;
5744     lstrcpyA(buf, "apple");
5745     r = pMsiGetProductInfoExA(prodcode, NULL,
5746                               MSIINSTALLCONTEXT_MACHINE,
5747                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5748     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5749     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5750     ok(sz == 1, "Expected 1, got %d\n", sz);
5751
5752     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5754
5755     /* HelpLink value exists */
5756     sz = MAX_PATH;
5757     lstrcpyA(buf, "apple");
5758     r = pMsiGetProductInfoExA(prodcode, NULL,
5759                               MSIINSTALLCONTEXT_MACHINE,
5760                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5762     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5763     ok(sz == 4, "Expected 4, got %d\n", sz);
5764
5765     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5767
5768     /* HelpTelephone value exists */
5769     sz = MAX_PATH;
5770     lstrcpyA(buf, "apple");
5771     r = pMsiGetProductInfoExA(prodcode, NULL,
5772                               MSIINSTALLCONTEXT_MACHINE,
5773                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5774     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5775     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5776     ok(sz == 5, "Expected 5, got %d\n", sz);
5777
5778     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5780
5781     /* InstallDate value exists */
5782     sz = MAX_PATH;
5783     lstrcpyA(buf, "apple");
5784     r = pMsiGetProductInfoExA(prodcode, NULL,
5785                               MSIINSTALLCONTEXT_MACHINE,
5786                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5787     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5788     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5789     ok(sz == 4, "Expected 4, got %d\n", sz);
5790
5791     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5792     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5793
5794     /* DisplayName value exists */
5795     sz = MAX_PATH;
5796     lstrcpyA(buf, "apple");
5797     r = pMsiGetProductInfoExA(prodcode, NULL,
5798                               MSIINSTALLCONTEXT_MACHINE,
5799                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5801     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5802     ok(sz == 4, "Expected 4, got %d\n", sz);
5803
5804     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5805     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5806
5807     /* InstallLocation value exists */
5808     sz = MAX_PATH;
5809     lstrcpyA(buf, "apple");
5810     r = pMsiGetProductInfoExA(prodcode, NULL,
5811                               MSIINSTALLCONTEXT_MACHINE,
5812                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5813     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5814     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5815     ok(sz == 3, "Expected 3, got %d\n", sz);
5816
5817     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5818     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5819
5820     /* InstallSource value exists */
5821     sz = MAX_PATH;
5822     lstrcpyA(buf, "apple");
5823     r = pMsiGetProductInfoExA(prodcode, NULL,
5824                               MSIINSTALLCONTEXT_MACHINE,
5825                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5826     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5827     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5828     ok(sz == 6, "Expected 6, got %d\n", sz);
5829
5830     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5831     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5832
5833     /* LocalPackage value exists */
5834     sz = MAX_PATH;
5835     lstrcpyA(buf, "apple");
5836     r = pMsiGetProductInfoExA(prodcode, NULL,
5837                               MSIINSTALLCONTEXT_MACHINE,
5838                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5839     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5840     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5841     ok(sz == 5, "Expected 5, got %d\n", sz);
5842
5843     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5845
5846     /* Publisher value exists */
5847     sz = MAX_PATH;
5848     lstrcpyA(buf, "apple");
5849     r = pMsiGetProductInfoExA(prodcode, NULL,
5850                               MSIINSTALLCONTEXT_MACHINE,
5851                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5852     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5853     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5854     ok(sz == 3, "Expected 3, got %d\n", sz);
5855
5856     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5857     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5858
5859     /* URLInfoAbout value exists */
5860     sz = MAX_PATH;
5861     lstrcpyA(buf, "apple");
5862     r = pMsiGetProductInfoExA(prodcode, NULL,
5863                               MSIINSTALLCONTEXT_MACHINE,
5864                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5865     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5866     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5867     ok(sz == 5, "Expected 5, got %d\n", sz);
5868
5869     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5870     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5871
5872     /* URLUpdateInfo value exists */
5873     sz = MAX_PATH;
5874     lstrcpyA(buf, "apple");
5875     r = pMsiGetProductInfoExA(prodcode, NULL,
5876                               MSIINSTALLCONTEXT_MACHINE,
5877                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5878     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5879     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5880     ok(sz == 6, "Expected 6, got %d\n", sz);
5881
5882     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5883     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5884
5885     /* VersionMinor value exists */
5886     sz = MAX_PATH;
5887     lstrcpyA(buf, "apple");
5888     r = pMsiGetProductInfoExA(prodcode, NULL,
5889                               MSIINSTALLCONTEXT_MACHINE,
5890                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5891     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5892     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5893     ok(sz == 1, "Expected 1, got %d\n", sz);
5894
5895     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5896     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5897
5898     /* VersionMajor value exists */
5899     sz = MAX_PATH;
5900     lstrcpyA(buf, "apple");
5901     r = pMsiGetProductInfoExA(prodcode, NULL,
5902                               MSIINSTALLCONTEXT_MACHINE,
5903                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5904     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5905     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5906     ok(sz == 1, "Expected 1, got %d\n", sz);
5907
5908     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5909     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5910
5911     /* DisplayVersion value exists */
5912     sz = MAX_PATH;
5913     lstrcpyA(buf, "apple");
5914     r = pMsiGetProductInfoExA(prodcode, NULL,
5915                               MSIINSTALLCONTEXT_MACHINE,
5916                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5917     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5918     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5919     ok(sz == 5, "Expected 5, got %d\n", sz);
5920
5921     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5922     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5923
5924     /* ProductID value exists */
5925     sz = MAX_PATH;
5926     lstrcpyA(buf, "apple");
5927     r = pMsiGetProductInfoExA(prodcode, NULL,
5928                               MSIINSTALLCONTEXT_MACHINE,
5929                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5930     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5931     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5932     ok(sz == 2, "Expected 2, got %d\n", sz);
5933
5934     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5936
5937     /* RegCompany value exists */
5938     sz = MAX_PATH;
5939     lstrcpyA(buf, "apple");
5940     r = pMsiGetProductInfoExA(prodcode, NULL,
5941                               MSIINSTALLCONTEXT_MACHINE,
5942                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5943     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5944     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5945     ok(sz == 4, "Expected 4, got %d\n", sz);
5946
5947     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5948     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5949
5950     /* RegOwner value exists */
5951     sz = MAX_PATH;
5952     lstrcpyA(buf, "apple");
5953     r = pMsiGetProductInfoExA(prodcode, NULL,
5954                               MSIINSTALLCONTEXT_MACHINE,
5955                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5956     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5957     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5958     ok(sz == 5, "Expected 5, got %d\n", sz);
5959
5960     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5962
5963     /* Transforms value exists */
5964     sz = MAX_PATH;
5965     lstrcpyA(buf, "apple");
5966     r = pMsiGetProductInfoExA(prodcode, NULL,
5967                               MSIINSTALLCONTEXT_MACHINE,
5968                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5969     ok(r == ERROR_UNKNOWN_PRODUCT,
5970        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5971     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5972     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5973
5974     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5975     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5976
5977     /* Language value exists */
5978     sz = MAX_PATH;
5979     lstrcpyA(buf, "apple");
5980     r = pMsiGetProductInfoExA(prodcode, NULL,
5981                               MSIINSTALLCONTEXT_MACHINE,
5982                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5983     ok(r == ERROR_UNKNOWN_PRODUCT,
5984        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5985     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5986     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5987
5988     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5989     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5990
5991     /* ProductName value exists */
5992     sz = MAX_PATH;
5993     lstrcpyA(buf, "apple");
5994     r = pMsiGetProductInfoExA(prodcode, NULL,
5995                               MSIINSTALLCONTEXT_MACHINE,
5996                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5997     ok(r == ERROR_UNKNOWN_PRODUCT,
5998        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5999     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6000     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6001
6002     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6003     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6004
6005     /* FIXME */
6006
6007     /* AssignmentType value exists */
6008     sz = MAX_PATH;
6009     lstrcpyA(buf, "apple");
6010     r = pMsiGetProductInfoExA(prodcode, NULL,
6011                               MSIINSTALLCONTEXT_MACHINE,
6012                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6013     ok(r == ERROR_UNKNOWN_PRODUCT,
6014        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6015     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6016     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6017
6018     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6020
6021     /* PackageCode value exists */
6022     sz = MAX_PATH;
6023     lstrcpyA(buf, "apple");
6024     r = pMsiGetProductInfoExA(prodcode, NULL,
6025                               MSIINSTALLCONTEXT_MACHINE,
6026                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6027     ok(r == ERROR_UNKNOWN_PRODUCT,
6028        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6029     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6030     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6031
6032     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6033     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6034
6035     /* Version value exists */
6036     sz = MAX_PATH;
6037     lstrcpyA(buf, "apple");
6038     r = pMsiGetProductInfoExA(prodcode, NULL,
6039                               MSIINSTALLCONTEXT_MACHINE,
6040                               INSTALLPROPERTY_VERSION, buf, &sz);
6041     ok(r == ERROR_UNKNOWN_PRODUCT,
6042        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6043     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6044     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6045
6046     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6047     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6048
6049     /* ProductIcon value exists */
6050     sz = MAX_PATH;
6051     lstrcpyA(buf, "apple");
6052     r = pMsiGetProductInfoExA(prodcode, NULL,
6053                               MSIINSTALLCONTEXT_MACHINE,
6054                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6055     ok(r == ERROR_UNKNOWN_PRODUCT,
6056        "Expected ERROR_UNKNOWN_PRODUCT, 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     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6062
6063     /* PackageName value exists */
6064     sz = MAX_PATH;
6065     lstrcpyA(buf, "apple");
6066     r = pMsiGetProductInfoExA(prodcode, NULL,
6067                               MSIINSTALLCONTEXT_MACHINE,
6068                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6069     ok(r == ERROR_UNKNOWN_PRODUCT,
6070        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6071     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6072     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6073
6074     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6076
6077     /* AuthorizedLUAApp value exists */
6078     sz = MAX_PATH;
6079     lstrcpyA(buf, "apple");
6080     r = pMsiGetProductInfoExA(prodcode, NULL,
6081                               MSIINSTALLCONTEXT_MACHINE,
6082                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6083     ok(r == ERROR_UNKNOWN_PRODUCT,
6084        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6085     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6086     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6087
6088     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6089     RegDeleteValueA(propkey, "PackageName");
6090     RegDeleteValueA(propkey, "ProductIcon");
6091     RegDeleteValueA(propkey, "Version");
6092     RegDeleteValueA(propkey, "PackageCode");
6093     RegDeleteValueA(propkey, "AssignmentType");
6094     RegDeleteValueA(propkey, "ProductName");
6095     RegDeleteValueA(propkey, "Language");
6096     RegDeleteValueA(propkey, "Transforms");
6097     RegDeleteValueA(propkey, "RegOwner");
6098     RegDeleteValueA(propkey, "RegCompany");
6099     RegDeleteValueA(propkey, "ProductID");
6100     RegDeleteValueA(propkey, "DisplayVersion");
6101     RegDeleteValueA(propkey, "VersionMajor");
6102     RegDeleteValueA(propkey, "VersionMinor");
6103     RegDeleteValueA(propkey, "URLUpdateInfo");
6104     RegDeleteValueA(propkey, "URLInfoAbout");
6105     RegDeleteValueA(propkey, "Publisher");
6106     RegDeleteValueA(propkey, "LocalPackage");
6107     RegDeleteValueA(propkey, "InstallSource");
6108     RegDeleteValueA(propkey, "InstallLocation");
6109     RegDeleteValueA(propkey, "DisplayName");
6110     RegDeleteValueA(propkey, "InstallDate");
6111     RegDeleteValueA(propkey, "HelpTelephone");
6112     RegDeleteValueA(propkey, "HelpLink");
6113     RegDeleteValueA(propkey, "LocalPackage");
6114     RegDeleteKeyA(propkey, "");
6115     RegCloseKey(propkey);
6116     RegDeleteKeyA(localkey, "");
6117     RegCloseKey(localkey);
6118
6119     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6120     lstrcatA(keypath, prod_squashed);
6121
6122     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6124
6125     /* local classes product key exists */
6126     sz = MAX_PATH;
6127     lstrcpyA(buf, "apple");
6128     r = pMsiGetProductInfoExA(prodcode, NULL,
6129                               MSIINSTALLCONTEXT_MACHINE,
6130                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6131     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6132     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6133     ok(sz == 1, "Expected 1, got %d\n", sz);
6134
6135     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6136     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6137
6138     /* HelpLink value exists */
6139     sz = MAX_PATH;
6140     lstrcpyA(buf, "apple");
6141     r = pMsiGetProductInfoExA(prodcode, NULL,
6142                               MSIINSTALLCONTEXT_MACHINE,
6143                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6144     ok(r == ERROR_UNKNOWN_PROPERTY,
6145        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6146     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6147     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6148
6149     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6151
6152     /* HelpTelephone value exists */
6153     sz = MAX_PATH;
6154     lstrcpyA(buf, "apple");
6155     r = pMsiGetProductInfoExA(prodcode, NULL,
6156                               MSIINSTALLCONTEXT_MACHINE,
6157                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6158     ok(r == ERROR_UNKNOWN_PROPERTY,
6159        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6160     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6161     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6162
6163     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6165
6166     /* InstallDate value exists */
6167     sz = MAX_PATH;
6168     lstrcpyA(buf, "apple");
6169     r = pMsiGetProductInfoExA(prodcode, NULL,
6170                               MSIINSTALLCONTEXT_MACHINE,
6171                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6172     ok(r == ERROR_UNKNOWN_PROPERTY,
6173        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6174     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6175     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6176
6177     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6179
6180     /* DisplayName value exists */
6181     sz = MAX_PATH;
6182     lstrcpyA(buf, "apple");
6183     r = pMsiGetProductInfoExA(prodcode, NULL,
6184                               MSIINSTALLCONTEXT_MACHINE,
6185                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6186     ok(r == ERROR_UNKNOWN_PROPERTY,
6187        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6188     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6189     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6190
6191     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6192     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6193
6194     /* InstallLocation value exists */
6195     sz = MAX_PATH;
6196     lstrcpyA(buf, "apple");
6197     r = pMsiGetProductInfoExA(prodcode, NULL,
6198                               MSIINSTALLCONTEXT_MACHINE,
6199                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6200     ok(r == ERROR_UNKNOWN_PROPERTY,
6201        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6202     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6203     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6204
6205     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6206     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6207
6208     /* InstallSource value exists */
6209     sz = MAX_PATH;
6210     lstrcpyA(buf, "apple");
6211     r = pMsiGetProductInfoExA(prodcode, NULL,
6212                               MSIINSTALLCONTEXT_MACHINE,
6213                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6214     ok(r == ERROR_UNKNOWN_PROPERTY,
6215        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6216     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6217     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6218
6219     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6220     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6221
6222     /* LocalPackage value exists */
6223     sz = MAX_PATH;
6224     lstrcpyA(buf, "apple");
6225     r = pMsiGetProductInfoExA(prodcode, NULL,
6226                               MSIINSTALLCONTEXT_MACHINE,
6227                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6228     ok(r == ERROR_UNKNOWN_PROPERTY,
6229        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6230     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6231     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6232
6233     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6234     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6235
6236     /* Publisher value exists */
6237     sz = MAX_PATH;
6238     lstrcpyA(buf, "apple");
6239     r = pMsiGetProductInfoExA(prodcode, NULL,
6240                               MSIINSTALLCONTEXT_MACHINE,
6241                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6242     ok(r == ERROR_UNKNOWN_PROPERTY,
6243        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6244     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6245     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6246
6247     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6248     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6249
6250     /* URLInfoAbout value exists */
6251     sz = MAX_PATH;
6252     lstrcpyA(buf, "apple");
6253     r = pMsiGetProductInfoExA(prodcode, NULL,
6254                               MSIINSTALLCONTEXT_MACHINE,
6255                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6256     ok(r == ERROR_UNKNOWN_PROPERTY,
6257        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6258     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6259     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6260
6261     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6263
6264     /* URLUpdateInfo value exists */
6265     sz = MAX_PATH;
6266     lstrcpyA(buf, "apple");
6267     r = pMsiGetProductInfoExA(prodcode, NULL,
6268                               MSIINSTALLCONTEXT_MACHINE,
6269                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6270     ok(r == ERROR_UNKNOWN_PROPERTY,
6271        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6272     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6273     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6274
6275     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6276     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6277
6278     /* VersionMinor value exists */
6279     sz = MAX_PATH;
6280     lstrcpyA(buf, "apple");
6281     r = pMsiGetProductInfoExA(prodcode, NULL,
6282                               MSIINSTALLCONTEXT_MACHINE,
6283                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6284     ok(r == ERROR_UNKNOWN_PROPERTY,
6285        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6286     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6287     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6288
6289     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6290     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6291
6292     /* VersionMajor value exists */
6293     sz = MAX_PATH;
6294     lstrcpyA(buf, "apple");
6295     r = pMsiGetProductInfoExA(prodcode, NULL,
6296                               MSIINSTALLCONTEXT_MACHINE,
6297                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6298     ok(r == ERROR_UNKNOWN_PROPERTY,
6299        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6300     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6301     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6302
6303     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6305
6306     /* DisplayVersion value exists */
6307     sz = MAX_PATH;
6308     lstrcpyA(buf, "apple");
6309     r = pMsiGetProductInfoExA(prodcode, NULL,
6310                               MSIINSTALLCONTEXT_MACHINE,
6311                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6312     ok(r == ERROR_UNKNOWN_PROPERTY,
6313        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6314     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6315     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6316
6317     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6319
6320     /* ProductID value exists */
6321     sz = MAX_PATH;
6322     lstrcpyA(buf, "apple");
6323     r = pMsiGetProductInfoExA(prodcode, NULL,
6324                               MSIINSTALLCONTEXT_MACHINE,
6325                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6326     ok(r == ERROR_UNKNOWN_PROPERTY,
6327        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6328     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6329     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6330
6331     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6333
6334     /* RegCompany value exists */
6335     sz = MAX_PATH;
6336     lstrcpyA(buf, "apple");
6337     r = pMsiGetProductInfoExA(prodcode, NULL,
6338                               MSIINSTALLCONTEXT_MACHINE,
6339                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6340     ok(r == ERROR_UNKNOWN_PROPERTY,
6341        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6342     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6343     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6344
6345     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6347
6348     /* RegOwner value exists */
6349     sz = MAX_PATH;
6350     lstrcpyA(buf, "apple");
6351     r = pMsiGetProductInfoExA(prodcode, NULL,
6352                               MSIINSTALLCONTEXT_MACHINE,
6353                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6354     ok(r == ERROR_UNKNOWN_PROPERTY,
6355        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6356     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6357     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6358
6359     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6361
6362     /* Transforms value exists */
6363     sz = MAX_PATH;
6364     lstrcpyA(buf, "apple");
6365     r = pMsiGetProductInfoExA(prodcode, NULL,
6366                               MSIINSTALLCONTEXT_MACHINE,
6367                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6368     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6369     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6370     ok(sz == 5, "Expected 5, got %d\n", sz);
6371
6372     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6373     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6374
6375     /* Language value exists */
6376     sz = MAX_PATH;
6377     lstrcpyA(buf, "apple");
6378     r = pMsiGetProductInfoExA(prodcode, NULL,
6379                               MSIINSTALLCONTEXT_MACHINE,
6380                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6381     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6382     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6383     ok(sz == 4, "Expected 4, got %d\n", sz);
6384
6385     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6386     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6387
6388     /* ProductName value exists */
6389     sz = MAX_PATH;
6390     lstrcpyA(buf, "apple");
6391     r = pMsiGetProductInfoExA(prodcode, NULL,
6392                               MSIINSTALLCONTEXT_MACHINE,
6393                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6394     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6395     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6396     ok(sz == 4, "Expected 4, got %d\n", sz);
6397
6398     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6399     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6400
6401     /* FIXME */
6402
6403     /* AssignmentType value exists */
6404     sz = MAX_PATH;
6405     lstrcpyA(buf, "apple");
6406     r = pMsiGetProductInfoExA(prodcode, NULL,
6407                               MSIINSTALLCONTEXT_MACHINE,
6408                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6410     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6411     ok(sz == 0, "Expected 0, got %d\n", sz);
6412
6413     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6414     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6415
6416     /* FIXME */
6417
6418     /* PackageCode value exists */
6419     sz = MAX_PATH;
6420     lstrcpyA(buf, "apple");
6421     r = pMsiGetProductInfoExA(prodcode, NULL,
6422                               MSIINSTALLCONTEXT_MACHINE,
6423                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6424     todo_wine
6425     {
6426         ok(r == ERROR_BAD_CONFIGURATION,
6427            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6428         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6429         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6430     }
6431
6432     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6434
6435     /* Version value exists */
6436     sz = MAX_PATH;
6437     lstrcpyA(buf, "apple");
6438     r = pMsiGetProductInfoExA(prodcode, NULL,
6439                               MSIINSTALLCONTEXT_MACHINE,
6440                               INSTALLPROPERTY_VERSION, buf, &sz);
6441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6442     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6443     ok(sz == 3, "Expected 3, got %d\n", sz);
6444
6445     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6447
6448     /* ProductIcon value exists */
6449     sz = MAX_PATH;
6450     lstrcpyA(buf, "apple");
6451     r = pMsiGetProductInfoExA(prodcode, NULL,
6452                               MSIINSTALLCONTEXT_MACHINE,
6453                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6455     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6456     ok(sz == 4, "Expected 4, got %d\n", sz);
6457
6458     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6460
6461     /* PackageName value exists */
6462     sz = MAX_PATH;
6463     lstrcpyA(buf, "apple");
6464     r = pMsiGetProductInfoExA(prodcode, NULL,
6465                               MSIINSTALLCONTEXT_MACHINE,
6466                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6467     todo_wine
6468     {
6469         ok(r == ERROR_UNKNOWN_PRODUCT,
6470            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6471         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6472         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6473     }
6474
6475     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6476     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6477
6478     /* AuthorizedLUAApp value exists */
6479     sz = MAX_PATH;
6480     lstrcpyA(buf, "apple");
6481     r = pMsiGetProductInfoExA(prodcode, NULL,
6482                               MSIINSTALLCONTEXT_MACHINE,
6483                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6484     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6485     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6486     ok(sz == 4, "Expected 4, got %d\n", sz);
6487
6488     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6489     RegDeleteValueA(prodkey, "PackageName");
6490     RegDeleteValueA(prodkey, "ProductIcon");
6491     RegDeleteValueA(prodkey, "Version");
6492     RegDeleteValueA(prodkey, "PackageCode");
6493     RegDeleteValueA(prodkey, "AssignmentType");
6494     RegDeleteValueA(prodkey, "ProductName");
6495     RegDeleteValueA(prodkey, "Language");
6496     RegDeleteValueA(prodkey, "Transforms");
6497     RegDeleteValueA(prodkey, "RegOwner");
6498     RegDeleteValueA(prodkey, "RegCompany");
6499     RegDeleteValueA(prodkey, "ProductID");
6500     RegDeleteValueA(prodkey, "DisplayVersion");
6501     RegDeleteValueA(prodkey, "VersionMajor");
6502     RegDeleteValueA(prodkey, "VersionMinor");
6503     RegDeleteValueA(prodkey, "URLUpdateInfo");
6504     RegDeleteValueA(prodkey, "URLInfoAbout");
6505     RegDeleteValueA(prodkey, "Publisher");
6506     RegDeleteValueA(prodkey, "LocalPackage");
6507     RegDeleteValueA(prodkey, "InstallSource");
6508     RegDeleteValueA(prodkey, "InstallLocation");
6509     RegDeleteValueA(prodkey, "DisplayName");
6510     RegDeleteValueA(prodkey, "InstallDate");
6511     RegDeleteValueA(prodkey, "HelpTelephone");
6512     RegDeleteValueA(prodkey, "HelpLink");
6513     RegDeleteKeyA(prodkey, "");
6514     RegCloseKey(prodkey);
6515 }
6516
6517 #define INIT_USERINFO() \
6518     lstrcpyA(user, "apple"); \
6519     lstrcpyA(org, "orange"); \
6520     lstrcpyA(serial, "banana"); \
6521     usersz = orgsz = serialsz = MAX_PATH;
6522
6523 static void test_MsiGetUserInfo(void)
6524 {
6525     USERINFOSTATE state;
6526     CHAR user[MAX_PATH];
6527     CHAR org[MAX_PATH];
6528     CHAR serial[MAX_PATH];
6529     DWORD usersz, orgsz, serialsz;
6530     CHAR keypath[MAX_PATH * 2];
6531     CHAR prodcode[MAX_PATH];
6532     CHAR prod_squashed[MAX_PATH];
6533     HKEY prodkey, userprod, props;
6534     LPSTR usersid;
6535     LONG res;
6536
6537     create_test_guid(prodcode, prod_squashed);
6538     get_user_sid(&usersid);
6539
6540     /* NULL szProduct */
6541     INIT_USERINFO();
6542     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6543     ok(state == USERINFOSTATE_INVALIDARG,
6544        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6545     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6546     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6547     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6548     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6549     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6550     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6551
6552     /* empty szProductCode */
6553     INIT_USERINFO();
6554     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6555     ok(state == USERINFOSTATE_INVALIDARG,
6556        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6557     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6558     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6559     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6560     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6561     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6562     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6563
6564     /* garbage szProductCode */
6565     INIT_USERINFO();
6566     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6567     ok(state == USERINFOSTATE_INVALIDARG,
6568        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6569     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6570     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6571     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6572     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6573     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6574     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6575
6576     /* guid without brackets */
6577     INIT_USERINFO();
6578     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6579                             user, &usersz, org, &orgsz, serial, &serialsz);
6580     ok(state == USERINFOSTATE_INVALIDARG,
6581        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6582     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6583     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6584     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6585     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6586     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6587     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6588
6589     /* guid with brackets */
6590     INIT_USERINFO();
6591     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6592                             user, &usersz, org, &orgsz, serial, &serialsz);
6593     ok(state == USERINFOSTATE_UNKNOWN,
6594        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6595     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6596     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6597     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6598     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6599     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6600     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6601
6602     /* NULL lpUserNameBuf */
6603     INIT_USERINFO();
6604     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6605     ok(state == USERINFOSTATE_UNKNOWN,
6606        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6607     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6608     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6609     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6610     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6611     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6612
6613     /* NULL pcchUserNameBuf */
6614     INIT_USERINFO();
6615     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6616     ok(state == USERINFOSTATE_INVALIDARG,
6617        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6618     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6619     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6620     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6621     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6622     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6623
6624     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6625     INIT_USERINFO();
6626     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6627     ok(state == USERINFOSTATE_UNKNOWN,
6628        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6629     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6630     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6631     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6632     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6633
6634     /* NULL lpOrgNameBuf */
6635     INIT_USERINFO();
6636     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6637     ok(state == USERINFOSTATE_UNKNOWN,
6638        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6639     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6640     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6641     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6642     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6643     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6644
6645     /* NULL pcchOrgNameBuf */
6646     INIT_USERINFO();
6647     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
6648     ok(state == USERINFOSTATE_INVALIDARG,
6649        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6650     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6651     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6652     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6653     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6654     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6655
6656     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
6657     INIT_USERINFO();
6658     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
6659     ok(state == USERINFOSTATE_UNKNOWN,
6660        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6661     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6662     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6663     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6664     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6665
6666     /* NULL lpSerialBuf */
6667     INIT_USERINFO();
6668     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
6669     ok(state == USERINFOSTATE_UNKNOWN,
6670        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6671     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6672     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6673     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6674     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6675     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6676
6677     /* NULL pcchSerialBuf */
6678     INIT_USERINFO();
6679     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
6680     ok(state == USERINFOSTATE_INVALIDARG,
6681        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6682     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6683     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6684     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6685     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6686     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6687
6688     /* both lpSerialBuf and pcchSerialBuf NULL */
6689     INIT_USERINFO();
6690     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
6691     ok(state == USERINFOSTATE_UNKNOWN,
6692        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6693     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6694     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6695     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6696     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6697
6698     /* MSIINSTALLCONTEXT_USERMANAGED */
6699
6700     /* create local system product key */
6701     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6702     lstrcatA(keypath, usersid);
6703     lstrcatA(keypath, "\\Installer\\Products\\");
6704     lstrcatA(keypath, prod_squashed);
6705
6706     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6707     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6708
6709     /* managed product key exists */
6710     INIT_USERINFO();
6711     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6712     ok(state == USERINFOSTATE_ABSENT,
6713        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6714     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6715     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6716     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6717     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6718     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6719     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6720
6721     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6722     lstrcatA(keypath, "Installer\\UserData\\");
6723     lstrcatA(keypath, usersid);
6724     lstrcatA(keypath, "\\Products\\");
6725     lstrcatA(keypath, prod_squashed);
6726
6727     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6729
6730     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6731     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6732
6733     /* InstallProperties key exists */
6734     INIT_USERINFO();
6735     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6736     ok(state == USERINFOSTATE_ABSENT,
6737        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6738     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6739     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6740     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6741     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6742     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6743     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6744
6745     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6746     INIT_USERINFO();
6747     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6748     ok(state == USERINFOSTATE_ABSENT,
6749        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6750     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6751     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6752     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6753     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6754
6755     /* RegOwner, RegCompany don't exist, out params are NULL */
6756     INIT_USERINFO();
6757     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6758     ok(state == USERINFOSTATE_ABSENT,
6759        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6760     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6761     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6762
6763     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6764     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6765
6766     /* RegOwner value exists */
6767     INIT_USERINFO();
6768     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6769     ok(state == USERINFOSTATE_ABSENT,
6770        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6771     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6772     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6773     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6774     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6775     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6776     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6777
6778     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6780
6781     /* RegCompany value exists */
6782     INIT_USERINFO();
6783     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6784     ok(state == USERINFOSTATE_ABSENT,
6785        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6786     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6787     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6788     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6789     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6790     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6791     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6792
6793     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6794     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6795
6796     /* ProductID value exists */
6797     INIT_USERINFO();
6798     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6799     ok(state == USERINFOSTATE_PRESENT,
6800        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6801     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6802     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6803     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6804     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6805     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6806     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6807
6808     /* pcchUserNameBuf is too small */
6809     INIT_USERINFO();
6810     usersz = 0;
6811     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6812     ok(state == USERINFOSTATE_MOREDATA,
6813        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6814     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6815     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6816     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6817     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6818     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6819     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6820
6821     /* pcchUserNameBuf has no room for NULL terminator */
6822     INIT_USERINFO();
6823     usersz = 5;
6824     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6825     ok(state == USERINFOSTATE_MOREDATA,
6826        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6827     todo_wine
6828     {
6829         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6830     }
6831     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6832     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6833     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6834     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6835     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6836
6837     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
6838     INIT_USERINFO();
6839     usersz = 0;
6840     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6841     ok(state == USERINFOSTATE_PRESENT,
6842        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6843     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6844     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6845     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6846     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6847     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6848     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6849
6850     RegDeleteValueA(props, "ProductID");
6851     RegDeleteValueA(props, "RegCompany");
6852     RegDeleteValueA(props, "RegOwner");
6853     RegDeleteKeyA(props, "");
6854     RegCloseKey(props);
6855     RegDeleteKeyA(userprod, "");
6856     RegCloseKey(userprod);
6857     RegDeleteKeyA(prodkey, "");
6858     RegCloseKey(prodkey);
6859
6860     /* MSIINSTALLCONTEXT_USERUNMANAGED */
6861
6862     /* create local system product key */
6863     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6864     lstrcatA(keypath, prod_squashed);
6865
6866     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6867     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6868
6869     /* product key exists */
6870     INIT_USERINFO();
6871     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6872     ok(state == USERINFOSTATE_ABSENT,
6873        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6874     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6875     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6876     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6877     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6878     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6879     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6880
6881     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6882     lstrcatA(keypath, "Installer\\UserData\\");
6883     lstrcatA(keypath, usersid);
6884     lstrcatA(keypath, "\\Products\\");
6885     lstrcatA(keypath, prod_squashed);
6886
6887     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6889
6890     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6892
6893     /* InstallProperties key exists */
6894     INIT_USERINFO();
6895     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6896     ok(state == USERINFOSTATE_ABSENT,
6897        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6898     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6899     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6900     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6901     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6902     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6903     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6904
6905     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6906     INIT_USERINFO();
6907     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6908     ok(state == USERINFOSTATE_ABSENT,
6909        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6910     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6911     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6912     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6913     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6914
6915     /* RegOwner, RegCompany don't exist, out params are NULL */
6916     INIT_USERINFO();
6917     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6918     ok(state == USERINFOSTATE_ABSENT,
6919        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6920     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6921     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6922
6923     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6924     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6925
6926     /* RegOwner value exists */
6927     INIT_USERINFO();
6928     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6929     ok(state == USERINFOSTATE_ABSENT,
6930        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6931     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6932     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6933     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6934     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6935     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6936     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6937
6938     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6939     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6940
6941     /* RegCompany value exists */
6942     INIT_USERINFO();
6943     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6944     ok(state == USERINFOSTATE_ABSENT,
6945        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6946     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6947     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6948     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6949     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6950     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6951     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6952
6953     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6954     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6955
6956     /* ProductID value exists */
6957     INIT_USERINFO();
6958     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6959     ok(state == USERINFOSTATE_PRESENT,
6960        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6961     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6962     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6963     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6964     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6965     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6966     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6967
6968     RegDeleteValueA(props, "ProductID");
6969     RegDeleteValueA(props, "RegCompany");
6970     RegDeleteValueA(props, "RegOwner");
6971     RegDeleteKeyA(props, "");
6972     RegCloseKey(props);
6973     RegDeleteKeyA(userprod, "");
6974     RegCloseKey(userprod);
6975     RegDeleteKeyA(prodkey, "");
6976     RegCloseKey(prodkey);
6977
6978     /* MSIINSTALLCONTEXT_MACHINE */
6979
6980     /* create local system product key */
6981     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6982     lstrcatA(keypath, prod_squashed);
6983
6984     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6986
6987     /* product key exists */
6988     INIT_USERINFO();
6989     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6990     ok(state == USERINFOSTATE_ABSENT,
6991        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6992     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6993     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6994     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6995     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6996     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6997     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6998
6999     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7000     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7001     lstrcatA(keypath, "\\Products\\");
7002     lstrcatA(keypath, prod_squashed);
7003
7004     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
7005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7006
7007     res = RegCreateKeyA(userprod, "InstallProperties", &props);
7008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7009
7010     /* InstallProperties key exists */
7011     INIT_USERINFO();
7012     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7013     ok(state == USERINFOSTATE_ABSENT,
7014        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7015     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7016     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7017     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7018     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7019     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7020     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7021
7022     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7023     INIT_USERINFO();
7024     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7025     ok(state == USERINFOSTATE_ABSENT,
7026        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7027     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7028     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7029     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7030     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7031
7032     /* RegOwner, RegCompany don't exist, out params are NULL */
7033     INIT_USERINFO();
7034     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7035     ok(state == USERINFOSTATE_ABSENT,
7036        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7037     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7038     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7039
7040     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7041     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7042
7043     /* RegOwner value exists */
7044     INIT_USERINFO();
7045     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7046     ok(state == USERINFOSTATE_ABSENT,
7047        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7048     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7049     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7050     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7051     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7052     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7053     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7054
7055     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7056     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7057
7058     /* RegCompany value exists */
7059     INIT_USERINFO();
7060     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7061     ok(state == USERINFOSTATE_ABSENT,
7062        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7063     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7064     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7065     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7066     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7067     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7068     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7069
7070     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7071     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7072
7073     /* ProductID value exists */
7074     INIT_USERINFO();
7075     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7076     ok(state == USERINFOSTATE_PRESENT,
7077        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7078     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7079     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7080     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7081     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7082     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7083     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7084
7085     RegDeleteValueA(props, "ProductID");
7086     RegDeleteValueA(props, "RegCompany");
7087     RegDeleteValueA(props, "RegOwner");
7088     RegDeleteKeyA(props, "");
7089     RegCloseKey(props);
7090     RegDeleteKeyA(userprod, "");
7091     RegCloseKey(userprod);
7092     RegDeleteKeyA(prodkey, "");
7093     RegCloseKey(prodkey);
7094 }
7095
7096 static void test_MsiOpenProduct(void)
7097 {
7098     MSIHANDLE hprod, hdb;
7099     CHAR val[MAX_PATH];
7100     CHAR path[MAX_PATH];
7101     CHAR keypath[MAX_PATH*2];
7102     CHAR prodcode[MAX_PATH];
7103     CHAR prod_squashed[MAX_PATH];
7104     HKEY prodkey, userkey, props;
7105     LPSTR usersid;
7106     DWORD size;
7107     LONG res;
7108     UINT r;
7109
7110     GetCurrentDirectoryA(MAX_PATH, path);
7111     lstrcatA(path, "\\");
7112
7113     create_test_guid(prodcode, prod_squashed);
7114     get_user_sid(&usersid);
7115
7116     hdb = create_package_db(prodcode);
7117     MsiCloseHandle(hdb);
7118
7119     /* NULL szProduct */
7120     hprod = 0xdeadbeef;
7121     r = MsiOpenProductA(NULL, &hprod);
7122     ok(r == ERROR_INVALID_PARAMETER,
7123        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7124     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7125
7126     /* empty szProduct */
7127     hprod = 0xdeadbeef;
7128     r = MsiOpenProductA("", &hprod);
7129     ok(r == ERROR_INVALID_PARAMETER,
7130        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7131     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7132
7133     /* garbage szProduct */
7134     hprod = 0xdeadbeef;
7135     r = MsiOpenProductA("garbage", &hprod);
7136     ok(r == ERROR_INVALID_PARAMETER,
7137        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7138     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7139
7140     /* guid without brackets */
7141     hprod = 0xdeadbeef;
7142     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7143     ok(r == ERROR_INVALID_PARAMETER,
7144        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7145     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7146
7147     /* guid with brackets */
7148     hprod = 0xdeadbeef;
7149     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7150     ok(r == ERROR_UNKNOWN_PRODUCT,
7151        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7152     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7153
7154     /* same length as guid, but random */
7155     hprod = 0xdeadbeef;
7156     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7157     ok(r == ERROR_INVALID_PARAMETER,
7158        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7159     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7160
7161     /* hProduct is NULL */
7162     hprod = 0xdeadbeef;
7163     r = MsiOpenProductA(prodcode, NULL);
7164     ok(r == ERROR_INVALID_PARAMETER,
7165        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7166     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7167
7168     /* MSIINSTALLCONTEXT_USERMANAGED */
7169
7170     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7171     lstrcatA(keypath, "Installer\\Managed\\");
7172     lstrcatA(keypath, usersid);
7173     lstrcatA(keypath, "\\Installer\\Products\\");
7174     lstrcatA(keypath, prod_squashed);
7175
7176     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7177     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7178
7179     /* managed product key exists */
7180     hprod = 0xdeadbeef;
7181     r = MsiOpenProductA(prodcode, &hprod);
7182     ok(r == ERROR_UNKNOWN_PRODUCT,
7183        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7184     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7185
7186     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7187     lstrcatA(keypath, "Installer\\UserData\\");
7188     lstrcatA(keypath, usersid);
7189     lstrcatA(keypath, "\\Products\\");
7190     lstrcatA(keypath, prod_squashed);
7191
7192     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7194
7195     /* user product key exists */
7196     hprod = 0xdeadbeef;
7197     r = MsiOpenProductA(prodcode, &hprod);
7198     ok(r == ERROR_UNKNOWN_PRODUCT,
7199        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7200     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7201
7202     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7203     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7204
7205     /* InstallProperties key exists */
7206     hprod = 0xdeadbeef;
7207     r = MsiOpenProductA(prodcode, &hprod);
7208     ok(r == ERROR_UNKNOWN_PRODUCT,
7209        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7210     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7211
7212     lstrcpyA(val, path);
7213     lstrcatA(val, "\\winetest.msi");
7214     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7215                          (const BYTE *)val, lstrlenA(val) + 1);
7216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7217
7218     /* ManagedLocalPackage value exists */
7219     hprod = 0xdeadbeef;
7220     r = MsiOpenProductA(prodcode, &hprod);
7221     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7222     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7223
7224     size = MAX_PATH;
7225     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7226     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7227     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7228     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7229
7230     MsiCloseHandle(hprod);
7231
7232     RegDeleteValueA(props, "ManagedLocalPackage");
7233     RegDeleteKeyA(props, "");
7234     RegCloseKey(props);
7235     RegDeleteKeyA(userkey, "");
7236     RegCloseKey(userkey);
7237     RegDeleteKeyA(prodkey, "");
7238     RegCloseKey(prodkey);
7239
7240     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7241
7242     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7243     lstrcatA(keypath, prod_squashed);
7244
7245     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7246     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7247
7248     /* unmanaged product key exists */
7249     hprod = 0xdeadbeef;
7250     r = MsiOpenProductA(prodcode, &hprod);
7251     ok(r == ERROR_UNKNOWN_PRODUCT,
7252        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7253     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7254
7255     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7256     lstrcatA(keypath, "Installer\\UserData\\");
7257     lstrcatA(keypath, usersid);
7258     lstrcatA(keypath, "\\Products\\");
7259     lstrcatA(keypath, prod_squashed);
7260
7261     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7263
7264     /* user product key exists */
7265     hprod = 0xdeadbeef;
7266     r = MsiOpenProductA(prodcode, &hprod);
7267     ok(r == ERROR_UNKNOWN_PRODUCT,
7268        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7269     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7270
7271     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7273
7274     /* InstallProperties key exists */
7275     hprod = 0xdeadbeef;
7276     r = MsiOpenProductA(prodcode, &hprod);
7277     ok(r == ERROR_UNKNOWN_PRODUCT,
7278        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7279     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7280
7281     lstrcpyA(val, path);
7282     lstrcatA(val, "\\winetest.msi");
7283     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7284                          (const BYTE *)val, lstrlenA(val) + 1);
7285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7286
7287     /* LocalPackage value exists */
7288     hprod = 0xdeadbeef;
7289     r = MsiOpenProductA(prodcode, &hprod);
7290     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7291     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7292
7293     size = MAX_PATH;
7294     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7295     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7296     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7297     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7298
7299     MsiCloseHandle(hprod);
7300
7301     RegDeleteValueA(props, "LocalPackage");
7302     RegDeleteKeyA(props, "");
7303     RegCloseKey(props);
7304     RegDeleteKeyA(userkey, "");
7305     RegCloseKey(userkey);
7306     RegDeleteKeyA(prodkey, "");
7307     RegCloseKey(prodkey);
7308
7309     /* MSIINSTALLCONTEXT_MACHINE */
7310
7311     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7312     lstrcatA(keypath, prod_squashed);
7313
7314     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7315     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7316
7317     /* managed product key exists */
7318     hprod = 0xdeadbeef;
7319     r = MsiOpenProductA(prodcode, &hprod);
7320     ok(r == ERROR_UNKNOWN_PRODUCT,
7321        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7322     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7323
7324     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7325     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7326     lstrcatA(keypath, prod_squashed);
7327
7328     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7330
7331     /* user product key exists */
7332     hprod = 0xdeadbeef;
7333     r = MsiOpenProductA(prodcode, &hprod);
7334     ok(r == ERROR_UNKNOWN_PRODUCT,
7335        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7336     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7337
7338     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7339     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7340
7341     /* InstallProperties key exists */
7342     hprod = 0xdeadbeef;
7343     r = MsiOpenProductA(prodcode, &hprod);
7344     ok(r == ERROR_UNKNOWN_PRODUCT,
7345        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7346     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7347
7348     lstrcpyA(val, path);
7349     lstrcatA(val, "\\winetest.msi");
7350     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7351                          (const BYTE *)val, lstrlenA(val) + 1);
7352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7353
7354     /* LocalPackage value exists */
7355     hprod = 0xdeadbeef;
7356     r = MsiOpenProductA(prodcode, &hprod);
7357     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7358     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7359
7360     size = MAX_PATH;
7361     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7362     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7363     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7364     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7365
7366     MsiCloseHandle(hprod);
7367
7368     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7369                          (const BYTE *)"winetest.msi", 13);
7370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7371
7372     /* LocalPackage has just the package name */
7373     hprod = 0xdeadbeef;
7374     r = MsiOpenProductA(prodcode, &hprod);
7375     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7376        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7377     if (r == ERROR_SUCCESS)
7378         MsiCloseHandle(hprod);
7379     else
7380         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7381
7382     lstrcpyA(val, path);
7383     lstrcatA(val, "\\winetest.msi");
7384     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7385                          (const BYTE *)val, lstrlenA(val) + 1);
7386     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7387
7388     DeleteFileA(msifile);
7389
7390     /* local package does not exist */
7391     hprod = 0xdeadbeef;
7392     r = MsiOpenProductA(prodcode, &hprod);
7393     ok(r == ERROR_UNKNOWN_PRODUCT,
7394        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7395     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7396
7397     RegDeleteValueA(props, "LocalPackage");
7398     RegDeleteKeyA(props, "");
7399     RegCloseKey(props);
7400     RegDeleteKeyA(userkey, "");
7401     RegCloseKey(userkey);
7402     RegDeleteKeyA(prodkey, "");
7403     RegCloseKey(prodkey);
7404
7405     DeleteFileA(msifile);
7406 }
7407
7408 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7409 {
7410     MSIINSTALLCONTEXT context;
7411     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7412     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7413     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7414     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7415     HKEY prodkey, patches, udprod, udpatch, hpatch;
7416     DWORD size, data;
7417     LONG res;
7418     UINT r;
7419
7420     create_test_guid(prodcode, prod_squashed);
7421     create_test_guid(patch, patch_squashed);
7422
7423     /* MSIPATCHSTATE_APPLIED */
7424
7425     lstrcpyA(patchcode, "apple");
7426     lstrcpyA(targetprod, "banana");
7427     context = 0xdeadbeef;
7428     lstrcpyA(targetsid, "kiwi");
7429     size = MAX_PATH;
7430     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7431                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7432                            &context, targetsid, &size);
7433     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7434     ok(!lstrcmpA(patchcode, "apple"),
7435        "Expected patchcode to be unchanged, got %s\n", patchcode);
7436     ok(!lstrcmpA(targetprod, "banana"),
7437        "Expected targetprod to be unchanged, got %s\n", targetprod);
7438     ok(context == 0xdeadbeef,
7439        "Expected context to be unchanged, got %d\n", context);
7440     ok(!lstrcmpA(targetsid, "kiwi"),
7441        "Expected targetsid to be unchanged, got %s\n", targetsid);
7442     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7443
7444     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7445     lstrcatA(keypath, expectedsid);
7446     lstrcatA(keypath, "\\Installer\\Products\\");
7447     lstrcatA(keypath, prod_squashed);
7448
7449     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7450     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7451
7452     /* managed product key exists */
7453     lstrcpyA(patchcode, "apple");
7454     lstrcpyA(targetprod, "banana");
7455     context = 0xdeadbeef;
7456     lstrcpyA(targetsid, "kiwi");
7457     size = MAX_PATH;
7458     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7459                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7460                            &context, targetsid, &size);
7461     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7462     ok(!lstrcmpA(patchcode, "apple"),
7463        "Expected patchcode to be unchanged, got %s\n", patchcode);
7464     ok(!lstrcmpA(targetprod, "banana"),
7465        "Expected targetprod to be unchanged, got %s\n", targetprod);
7466     ok(context == 0xdeadbeef,
7467        "Expected context to be unchanged, got %d\n", context);
7468     ok(!lstrcmpA(targetsid, "kiwi"),
7469        "Expected targetsid to be unchanged, got %s\n", targetsid);
7470     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7471
7472     res = RegCreateKeyA(prodkey, "Patches", &patches);
7473     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7474
7475     /* patches key exists */
7476     lstrcpyA(patchcode, "apple");
7477     lstrcpyA(targetprod, "banana");
7478     context = 0xdeadbeef;
7479     lstrcpyA(targetsid, "kiwi");
7480     size = MAX_PATH;
7481     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7482                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7483                            &context, targetsid, &size);
7484     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7485     ok(!lstrcmpA(patchcode, "apple"),
7486        "Expected patchcode to be unchanged, got %s\n", patchcode);
7487     ok(!lstrcmpA(targetprod, "banana"),
7488        "Expected targetprod to be unchanged, got %s\n", targetprod);
7489     ok(context == 0xdeadbeef,
7490        "Expected context to be unchanged, got %d\n", context);
7491     ok(!lstrcmpA(targetsid, "kiwi"),
7492        "Expected targetsid to be unchanged, got %s\n", targetsid);
7493     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7494
7495     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7496                          (const BYTE *)patch_squashed,
7497                          lstrlenA(patch_squashed) + 1);
7498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7499
7500     /* Patches value exists, is not REG_MULTI_SZ */
7501     lstrcpyA(patchcode, "apple");
7502     lstrcpyA(targetprod, "banana");
7503     context = 0xdeadbeef;
7504     lstrcpyA(targetsid, "kiwi");
7505     size = MAX_PATH;
7506     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7507                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7508                            &context, targetsid, &size);
7509     ok(r == ERROR_BAD_CONFIGURATION,
7510        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7511     ok(!lstrcmpA(patchcode, "apple"),
7512        "Expected patchcode to be unchanged, got %s\n", patchcode);
7513     ok(!lstrcmpA(targetprod, "banana"),
7514        "Expected targetprod to be unchanged, got %s\n", targetprod);
7515     ok(context == 0xdeadbeef,
7516        "Expected context to be unchanged, got %d\n", context);
7517     ok(!lstrcmpA(targetsid, "kiwi"),
7518        "Expected targetsid to be unchanged, got %s\n", targetsid);
7519     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7520
7521     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7522                          (const BYTE *)"a\0b\0c\0\0", 7);
7523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7524
7525     /* Patches value exists, is not a squashed guid */
7526     lstrcpyA(patchcode, "apple");
7527     lstrcpyA(targetprod, "banana");
7528     context = 0xdeadbeef;
7529     lstrcpyA(targetsid, "kiwi");
7530     size = MAX_PATH;
7531     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7532                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7533                            &context, targetsid, &size);
7534     ok(r == ERROR_BAD_CONFIGURATION,
7535        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7536     ok(!lstrcmpA(patchcode, "apple"),
7537        "Expected patchcode to be unchanged, got %s\n", patchcode);
7538     ok(!lstrcmpA(targetprod, "banana"),
7539        "Expected targetprod to be unchanged, got %s\n", targetprod);
7540     ok(context == 0xdeadbeef,
7541        "Expected context to be unchanged, got %d\n", context);
7542     ok(!lstrcmpA(targetsid, "kiwi"),
7543        "Expected targetsid to be unchanged, got %s\n", targetsid);
7544     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7545
7546     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
7547     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7548                          (const BYTE *)patch_squashed,
7549                          lstrlenA(patch_squashed) + 2);
7550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7551
7552     /* Patches value exists */
7553     lstrcpyA(patchcode, "apple");
7554     lstrcpyA(targetprod, "banana");
7555     context = 0xdeadbeef;
7556     lstrcpyA(targetsid, "kiwi");
7557     size = MAX_PATH;
7558     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7559                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7560                            &context, targetsid, &size);
7561     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7562     ok(!lstrcmpA(patchcode, "apple"),
7563        "Expected patchcode to be unchanged, got %s\n", patchcode);
7564     ok(!lstrcmpA(targetprod, "banana"),
7565        "Expected targetprod to be unchanged, got %s\n", targetprod);
7566     ok(context == 0xdeadbeef,
7567        "Expected context to be unchanged, got %d\n", context);
7568     ok(!lstrcmpA(targetsid, "kiwi"),
7569        "Expected targetsid to be unchanged, got %s\n", targetsid);
7570     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7571
7572     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7573                          (const BYTE *)"whatever", 9);
7574     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7575
7576     /* patch squashed value exists */
7577     lstrcpyA(patchcode, "apple");
7578     lstrcpyA(targetprod, "banana");
7579     context = 0xdeadbeef;
7580     lstrcpyA(targetsid, "kiwi");
7581     size = MAX_PATH;
7582     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7583                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7584                            &context, targetsid, &size);
7585     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7586     ok(!lstrcmpA(patchcode, patch),
7587        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7588     ok(!lstrcmpA(targetprod, prodcode),
7589        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7590     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7591        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7592     ok(!lstrcmpA(targetsid, expectedsid),
7593        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7594     ok(size == lstrlenA(expectedsid),
7595        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7596
7597     /* increase the index */
7598     lstrcpyA(patchcode, "apple");
7599     lstrcpyA(targetprod, "banana");
7600     context = 0xdeadbeef;
7601     lstrcpyA(targetsid, "kiwi");
7602     size = MAX_PATH;
7603     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7604                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7605                            &context, targetsid, &size);
7606     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7607     ok(!lstrcmpA(patchcode, "apple"),
7608        "Expected patchcode to be unchanged, got %s\n", patchcode);
7609     ok(!lstrcmpA(targetprod, "banana"),
7610        "Expected targetprod to be unchanged, got %s\n", targetprod);
7611     ok(context == 0xdeadbeef,
7612        "Expected context to be unchanged, got %d\n", context);
7613     ok(!lstrcmpA(targetsid, "kiwi"),
7614        "Expected targetsid to be unchanged, got %s\n", targetsid);
7615     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7616
7617     /* increase again */
7618     lstrcpyA(patchcode, "apple");
7619     lstrcpyA(targetprod, "banana");
7620     context = 0xdeadbeef;
7621     lstrcpyA(targetsid, "kiwi");
7622     size = MAX_PATH;
7623     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7624                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
7625                            &context, targetsid, &size);
7626     ok(r == ERROR_INVALID_PARAMETER,
7627        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7628     ok(!lstrcmpA(patchcode, "apple"),
7629        "Expected patchcode to be unchanged, got %s\n", patchcode);
7630     ok(!lstrcmpA(targetprod, "banana"),
7631        "Expected targetprod to be unchanged, got %s\n", targetprod);
7632     ok(context == 0xdeadbeef,
7633        "Expected context to be unchanged, got %d\n", context);
7634     ok(!lstrcmpA(targetsid, "kiwi"),
7635        "Expected targetsid to be unchanged, got %s\n", targetsid);
7636     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7637
7638     /* szPatchCode is NULL */
7639     lstrcpyA(targetprod, "banana");
7640     context = 0xdeadbeef;
7641     lstrcpyA(targetsid, "kiwi");
7642     size = MAX_PATH;
7643     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7644                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
7645                            &context, targetsid, &size);
7646     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7647     ok(!lstrcmpA(targetprod, prodcode),
7648        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7649     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7650        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7651     ok(!lstrcmpA(targetsid, expectedsid),
7652        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7653     ok(size == lstrlenA(expectedsid),
7654        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7655
7656     /* szTargetProductCode is NULL */
7657     lstrcpyA(patchcode, "apple");
7658     context = 0xdeadbeef;
7659     lstrcpyA(targetsid, "kiwi");
7660     size = MAX_PATH;
7661     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7662                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
7663                            &context, targetsid, &size);
7664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7665     ok(!lstrcmpA(patchcode, patch),
7666        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7667     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7668        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7669     ok(!lstrcmpA(targetsid, expectedsid),
7670        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7671     ok(size == lstrlenA(expectedsid),
7672        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7673
7674     /* pdwTargetProductContext is NULL */
7675     lstrcpyA(patchcode, "apple");
7676     lstrcpyA(targetprod, "banana");
7677     lstrcpyA(targetsid, "kiwi");
7678     size = MAX_PATH;
7679     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7680                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7681                            NULL, targetsid, &size);
7682     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7683     ok(!lstrcmpA(patchcode, patch),
7684        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7685     ok(!lstrcmpA(targetprod, prodcode),
7686        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7687     ok(!lstrcmpA(targetsid, expectedsid),
7688        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7689     ok(size == lstrlenA(expectedsid),
7690        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7691
7692     /* szTargetUserSid is NULL */
7693     lstrcpyA(patchcode, "apple");
7694     lstrcpyA(targetprod, "banana");
7695     context = 0xdeadbeef;
7696     size = MAX_PATH;
7697     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7698                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7699                            &context, NULL, &size);
7700     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7701     ok(!lstrcmpA(patchcode, patch),
7702        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7703     ok(!lstrcmpA(targetprod, prodcode),
7704        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7705     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7706        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7707     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7708        "Expected %d, got %d\n", lstrlenA(expectedsid) * sizeof(WCHAR), size);
7709
7710     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
7711     lstrcpyA(patchcode, "apple");
7712     lstrcpyA(targetprod, "banana");
7713     context = 0xdeadbeef;
7714     lstrcpyA(targetsid, "kiwi");
7715     size = lstrlenA(expectedsid);
7716     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7717                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7718                            &context, targetsid, &size);
7719     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
7720     ok(!lstrcmpA(patchcode, patch),
7721        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7722     ok(!lstrcmpA(targetprod, prodcode),
7723        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7724     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7725        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7726     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
7727        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7728     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7729        "Expected %d, got %d\n", lstrlenA(expectedsid) * sizeof(WCHAR), size);
7730
7731     /* pcchTargetUserSid has enough room for NULL terminator */
7732     lstrcpyA(patchcode, "apple");
7733     lstrcpyA(targetprod, "banana");
7734     context = 0xdeadbeef;
7735     lstrcpyA(targetsid, "kiwi");
7736     size = lstrlenA(expectedsid) + 1;
7737     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7738                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7739                            &context, targetsid, &size);
7740     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7741     ok(!lstrcmpA(patchcode, patch),
7742        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7743     ok(!lstrcmpA(targetprod, prodcode),
7744        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7745     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7746        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7747     ok(!lstrcmpA(targetsid, expectedsid),
7748        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7749     ok(size == lstrlenA(expectedsid),
7750        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7751
7752     /* both szTargetuserSid and pcchTargetUserSid are NULL */
7753     lstrcpyA(patchcode, "apple");
7754     lstrcpyA(targetprod, "banana");
7755     context = 0xdeadbeef;
7756     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7757                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7758                            &context, NULL, NULL);
7759     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7760     ok(!lstrcmpA(patchcode, patch),
7761        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7762     ok(!lstrcmpA(targetprod, prodcode),
7763        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7764     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7765        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7766
7767     /* MSIPATCHSTATE_SUPERSEDED */
7768
7769     lstrcpyA(patchcode, "apple");
7770     lstrcpyA(targetprod, "banana");
7771     context = 0xdeadbeef;
7772     lstrcpyA(targetsid, "kiwi");
7773     size = MAX_PATH;
7774     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7775                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7776                            &context, targetsid, &size);
7777     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7778     ok(!lstrcmpA(patchcode, "apple"),
7779        "Expected patchcode to be unchanged, got %s\n", patchcode);
7780     ok(!lstrcmpA(targetprod, "banana"),
7781        "Expected targetprod to be unchanged, got %s\n", targetprod);
7782     ok(context == 0xdeadbeef,
7783        "Expected context to be unchanged, got %d\n", context);
7784     ok(!lstrcmpA(targetsid, "kiwi"),
7785        "Expected targetsid to be unchanged, got %s\n", targetsid);
7786     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7787
7788     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
7789     lstrcatA(keypath, expectedsid);
7790     lstrcatA(keypath, "\\Products\\");
7791     lstrcatA(keypath, prod_squashed);
7792
7793     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
7794     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7795
7796     /* UserData product key exists */
7797     lstrcpyA(patchcode, "apple");
7798     lstrcpyA(targetprod, "banana");
7799     context = 0xdeadbeef;
7800     lstrcpyA(targetsid, "kiwi");
7801     size = MAX_PATH;
7802     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7803                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7804                            &context, targetsid, &size);
7805     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7806     ok(!lstrcmpA(patchcode, "apple"),
7807        "Expected patchcode to be unchanged, got %s\n", patchcode);
7808     ok(!lstrcmpA(targetprod, "banana"),
7809        "Expected targetprod to be unchanged, got %s\n", targetprod);
7810     ok(context == 0xdeadbeef,
7811        "Expected context to be unchanged, got %d\n", context);
7812     ok(!lstrcmpA(targetsid, "kiwi"),
7813        "Expected targetsid to be unchanged, got %s\n", targetsid);
7814     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7815
7816     res = RegCreateKeyA(udprod, "Patches", &udpatch);
7817     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7818
7819     /* UserData patches key exists */
7820     lstrcpyA(patchcode, "apple");
7821     lstrcpyA(targetprod, "banana");
7822     context = 0xdeadbeef;
7823     lstrcpyA(targetsid, "kiwi");
7824     size = MAX_PATH;
7825     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7826                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7827                            &context, targetsid, &size);
7828     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7829     ok(!lstrcmpA(patchcode, "apple"),
7830        "Expected patchcode to be unchanged, got %s\n", patchcode);
7831     ok(!lstrcmpA(targetprod, "banana"),
7832        "Expected targetprod to be unchanged, got %s\n", targetprod);
7833     ok(context == 0xdeadbeef,
7834        "Expected context to be unchanged, got %d\n", context);
7835     ok(!lstrcmpA(targetsid, "kiwi"),
7836        "Expected targetsid to be unchanged, got %s\n", targetsid);
7837     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7838
7839     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
7840     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7841
7842     /* specific UserData patch key exists */
7843     lstrcpyA(patchcode, "apple");
7844     lstrcpyA(targetprod, "banana");
7845     context = 0xdeadbeef;
7846     lstrcpyA(targetsid, "kiwi");
7847     size = MAX_PATH;
7848     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7849                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7850                            &context, targetsid, &size);
7851     ok(r == ERROR_BAD_CONFIGURATION,
7852        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7853     ok(!lstrcmpA(patchcode, "apple"),
7854        "Expected patchcode to be unchanged, got %s\n", patchcode);
7855     ok(!lstrcmpA(targetprod, "banana"),
7856        "Expected targetprod to be unchanged, got %s\n", targetprod);
7857     ok(context == 0xdeadbeef,
7858        "Expected context to be unchanged, got %d\n", context);
7859     ok(!lstrcmpA(targetsid, "kiwi"),
7860        "Expected targetsid to be unchanged, got %s\n", targetsid);
7861     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7862
7863     data = MSIPATCHSTATE_SUPERSEDED;
7864     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
7865                          (const BYTE *)&data, sizeof(DWORD));
7866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7867
7868     /* State value exists */
7869     lstrcpyA(patchcode, "apple");
7870     lstrcpyA(targetprod, "banana");
7871     context = 0xdeadbeef;
7872     lstrcpyA(targetsid, "kiwi");
7873     size = MAX_PATH;
7874     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7875                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7876                            &context, targetsid, &size);
7877     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7878     ok(!lstrcmpA(patchcode, patch),
7879        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7880     ok(!lstrcmpA(targetprod, prodcode),
7881        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7882     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7883        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7884     ok(!lstrcmpA(targetsid, expectedsid),
7885        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7886     ok(size == lstrlenA(expectedsid),
7887        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7888
7889     /* MSIPATCHSTATE_OBSOLETED */
7890
7891     lstrcpyA(patchcode, "apple");
7892     lstrcpyA(targetprod, "banana");
7893     context = 0xdeadbeef;
7894     lstrcpyA(targetsid, "kiwi");
7895     size = MAX_PATH;
7896     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7897                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
7898                            &context, targetsid, &size);
7899     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, 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     data = MSIPATCHSTATE_OBSOLETED;
7911     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
7912                          (const BYTE *)&data, sizeof(DWORD));
7913     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7914
7915     /* State value is obsoleted */
7916     lstrcpyA(patchcode, "apple");
7917     lstrcpyA(targetprod, "banana");
7918     context = 0xdeadbeef;
7919     lstrcpyA(targetsid, "kiwi");
7920     size = MAX_PATH;
7921     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7922                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
7923                            &context, targetsid, &size);
7924     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7925     ok(!lstrcmpA(patchcode, patch),
7926        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7927     ok(!lstrcmpA(targetprod, prodcode),
7928        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7929     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7930        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7931     ok(!lstrcmpA(targetsid, expectedsid),
7932        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7933     ok(size == lstrlenA(expectedsid),
7934        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7935
7936     /* MSIPATCHSTATE_REGISTERED */
7937     /* FIXME */
7938
7939     /* MSIPATCHSTATE_ALL */
7940
7941     /* 1st */
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_ALL, 0, patchcode, targetprod,
7949                            &context, targetsid, &size);
7950     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7951     ok(!lstrcmpA(patchcode, patch),
7952        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7953     ok(!lstrcmpA(targetprod, prodcode),
7954        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7955     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7956        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7957     ok(!lstrcmpA(targetsid, expectedsid),
7958        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7959     ok(size == lstrlenA(expectedsid),
7960        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7961
7962     /* same patch in multiple places, only one is enumerated */
7963     lstrcpyA(patchcode, "apple");
7964     lstrcpyA(targetprod, "banana");
7965     context = 0xdeadbeef;
7966     lstrcpyA(targetsid, "kiwi");
7967     size = MAX_PATH;
7968     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7969                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
7970                            &context, targetsid, &size);
7971     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7972     ok(!lstrcmpA(patchcode, "apple"),
7973        "Expected patchcode to be unchanged, got %s\n", patchcode);
7974     ok(!lstrcmpA(targetprod, "banana"),
7975        "Expected targetprod to be unchanged, got %s\n", targetprod);
7976     ok(context == 0xdeadbeef,
7977        "Expected context to be unchanged, got %d\n", context);
7978     ok(!lstrcmpA(targetsid, "kiwi"),
7979        "Expected targetsid to be unchanged, got %s\n", targetsid);
7980     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7981
7982     RegDeleteValueA(hpatch, "State");
7983     RegDeleteKeyA(hpatch, "");
7984     RegCloseKey(hpatch);
7985     RegDeleteKeyA(udpatch, "");
7986     RegCloseKey(udpatch);
7987     RegDeleteKeyA(udprod, "");
7988     RegCloseKey(udprod);
7989     RegDeleteValueA(patches, "Patches");
7990     RegDeleteKeyA(patches, "");
7991     RegCloseKey(patches);
7992     RegDeleteKeyA(prodkey, "");
7993     RegCloseKey(prodkey);
7994 }
7995
7996 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
7997 {
7998     MSIINSTALLCONTEXT context;
7999     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8000     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8001     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8002     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8003     HKEY prodkey, patches, udprod, udpatch;
8004     HKEY userkey, hpatch;
8005     DWORD size, data;
8006     LONG res;
8007     UINT r;
8008
8009     create_test_guid(prodcode, prod_squashed);
8010     create_test_guid(patch, patch_squashed);
8011
8012     /* MSIPATCHSTATE_APPLIED */
8013
8014     lstrcpyA(patchcode, "apple");
8015     lstrcpyA(targetprod, "banana");
8016     context = 0xdeadbeef;
8017     lstrcpyA(targetsid, "kiwi");
8018     size = MAX_PATH;
8019     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8020                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8021                            &context, targetsid, &size);
8022     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8023     ok(!lstrcmpA(patchcode, "apple"),
8024        "Expected patchcode to be unchanged, got %s\n", patchcode);
8025     ok(!lstrcmpA(targetprod, "banana"),
8026        "Expected targetprod to be unchanged, got %s\n", targetprod);
8027     ok(context == 0xdeadbeef,
8028        "Expected context to be unchanged, got %d\n", context);
8029     ok(!lstrcmpA(targetsid, "kiwi"),
8030        "Expected targetsid to be unchanged, got %s\n", targetsid);
8031     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8032
8033     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8034     lstrcatA(keypath, prod_squashed);
8035
8036     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8037     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8038
8039     /* current user product key exists */
8040     lstrcpyA(patchcode, "apple");
8041     lstrcpyA(targetprod, "banana");
8042     context = 0xdeadbeef;
8043     lstrcpyA(targetsid, "kiwi");
8044     size = MAX_PATH;
8045     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8046                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8047                            &context, targetsid, &size);
8048     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8049     ok(!lstrcmpA(patchcode, "apple"),
8050        "Expected patchcode to be unchanged, got %s\n", patchcode);
8051     ok(!lstrcmpA(targetprod, "banana"),
8052        "Expected targetprod to be unchanged, got %s\n", targetprod);
8053     ok(context == 0xdeadbeef,
8054        "Expected context to be unchanged, got %d\n", context);
8055     ok(!lstrcmpA(targetsid, "kiwi"),
8056        "Expected targetsid to be unchanged, got %s\n", targetsid);
8057     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8058
8059     res = RegCreateKeyA(prodkey, "Patches", &patches);
8060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8061
8062     /* Patches key exists */
8063     lstrcpyA(patchcode, "apple");
8064     lstrcpyA(targetprod, "banana");
8065     context = 0xdeadbeef;
8066     lstrcpyA(targetsid, "kiwi");
8067     size = MAX_PATH;
8068     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8069                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8070                            &context, targetsid, &size);
8071     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8072     ok(!lstrcmpA(patchcode, "apple"),
8073        "Expected patchcode to be unchanged, got %s\n", patchcode);
8074     ok(!lstrcmpA(targetprod, "banana"),
8075        "Expected targetprod to be unchanged, got %s\n", targetprod);
8076     ok(context == 0xdeadbeef,
8077        "Expected context to be unchanged, got %d\n", context);
8078     ok(!lstrcmpA(targetsid, "kiwi"),
8079        "Expected targetsid to be unchanged, got %s\n", targetsid);
8080     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8081
8082     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8083                          (const BYTE *)patch_squashed,
8084                          lstrlenA(patch_squashed) + 1);
8085     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8086
8087     /* Patches value exists, is not REG_MULTI_SZ */
8088     lstrcpyA(patchcode, "apple");
8089     lstrcpyA(targetprod, "banana");
8090     context = 0xdeadbeef;
8091     lstrcpyA(targetsid, "kiwi");
8092     size = MAX_PATH;
8093     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8094                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8095                            &context, targetsid, &size);
8096     ok(r == ERROR_BAD_CONFIGURATION,
8097        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8098     ok(!lstrcmpA(patchcode, "apple"),
8099        "Expected patchcode to be unchanged, got %s\n", patchcode);
8100     ok(!lstrcmpA(targetprod, "banana"),
8101        "Expected targetprod to be unchanged, got %s\n", targetprod);
8102     ok(context == 0xdeadbeef,
8103        "Expected context to be unchanged, got %d\n", context);
8104     ok(!lstrcmpA(targetsid, "kiwi"),
8105        "Expected targetsid to be unchanged, got %s\n", targetsid);
8106     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8107
8108     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8109                          (const BYTE *)"a\0b\0c\0\0", 7);
8110     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8111
8112     /* Patches value exists, is not a squashed guid */
8113     lstrcpyA(patchcode, "apple");
8114     lstrcpyA(targetprod, "banana");
8115     context = 0xdeadbeef;
8116     lstrcpyA(targetsid, "kiwi");
8117     size = MAX_PATH;
8118     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8119                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8120                            &context, targetsid, &size);
8121     ok(r == ERROR_BAD_CONFIGURATION,
8122        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8123     ok(!lstrcmpA(patchcode, "apple"),
8124        "Expected patchcode to be unchanged, got %s\n", patchcode);
8125     ok(!lstrcmpA(targetprod, "banana"),
8126        "Expected targetprod to be unchanged, got %s\n", targetprod);
8127     ok(context == 0xdeadbeef,
8128        "Expected context to be unchanged, got %d\n", context);
8129     ok(!lstrcmpA(targetsid, "kiwi"),
8130        "Expected targetsid to be unchanged, got %s\n", targetsid);
8131     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8132
8133     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8134                          (const BYTE *)patch_squashed,
8135                          lstrlenA(patch_squashed) + 1);
8136     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8137
8138     /* Patches value exists */
8139     lstrcpyA(patchcode, "apple");
8140     lstrcpyA(targetprod, "banana");
8141     context = 0xdeadbeef;
8142     lstrcpyA(targetsid, "kiwi");
8143     size = MAX_PATH;
8144     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8145                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8146                            &context, targetsid, &size);
8147     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8148     ok(!lstrcmpA(patchcode, "apple"),
8149        "Expected patchcode to be unchanged, got %s\n", patchcode);
8150     ok(!lstrcmpA(targetprod, "banana"),
8151        "Expected targetprod to be unchanged, got %s\n", targetprod);
8152     ok(context == 0xdeadbeef,
8153        "Expected context to be unchanged, got %d\n", context);
8154     ok(!lstrcmpA(targetsid, "kiwi"),
8155        "Expected targetsid to be unchanged, got %s\n", targetsid);
8156     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8157
8158     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8159                          (const BYTE *)"whatever", 9);
8160     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8161
8162     /* patch code value exists */
8163     lstrcpyA(patchcode, "apple");
8164     lstrcpyA(targetprod, "banana");
8165     context = 0xdeadbeef;
8166     lstrcpyA(targetsid, "kiwi");
8167     size = MAX_PATH;
8168     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8169                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8170                            &context, targetsid, &size);
8171     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8172     ok(!lstrcmpA(patchcode, "apple"),
8173        "Expected patchcode to be unchanged, got %s\n", patchcode);
8174     ok(!lstrcmpA(targetprod, "banana"),
8175        "Expected targetprod to be unchanged, got %s\n", targetprod);
8176     ok(context == 0xdeadbeef,
8177        "Expected context to be unchanged, got %d\n", context);
8178     ok(!lstrcmpA(targetsid, "kiwi"),
8179        "Expected targetsid to be unchanged, got %s\n", targetsid);
8180     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8181
8182     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8183     lstrcatA(keypath, expectedsid);
8184     lstrcatA(keypath, "\\Patches\\");
8185     lstrcatA(keypath, patch_squashed);
8186
8187     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
8188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8189
8190     /* userdata patch key exists */
8191     lstrcpyA(patchcode, "apple");
8192     lstrcpyA(targetprod, "banana");
8193     context = 0xdeadbeef;
8194     lstrcpyA(targetsid, "kiwi");
8195     size = MAX_PATH;
8196     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8197                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8198                            &context, targetsid, &size);
8199     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8200     ok(!lstrcmpA(patchcode, patch),
8201        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8202     ok(!lstrcmpA(targetprod, prodcode),
8203        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8204     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8205        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8206     ok(!lstrcmpA(targetsid, expectedsid),
8207        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8208     ok(size == lstrlenA(expectedsid),
8209        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8210
8211     /* MSIPATCHSTATE_SUPERSEDED */
8212
8213     lstrcpyA(patchcode, "apple");
8214     lstrcpyA(targetprod, "banana");
8215     context = 0xdeadbeef;
8216     lstrcpyA(targetsid, "kiwi");
8217     size = MAX_PATH;
8218     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8219                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8220                            &context, targetsid, &size);
8221     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8222     ok(!lstrcmpA(patchcode, "apple"),
8223        "Expected patchcode to be unchanged, got %s\n", patchcode);
8224     ok(!lstrcmpA(targetprod, "banana"),
8225        "Expected targetprod to be unchanged, got %s\n", targetprod);
8226     ok(context == 0xdeadbeef,
8227        "Expected context to be unchanged, got %d\n", context);
8228     ok(!lstrcmpA(targetsid, "kiwi"),
8229        "Expected targetsid to be unchanged, got %s\n", targetsid);
8230     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8231
8232     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8233     lstrcatA(keypath, expectedsid);
8234     lstrcatA(keypath, "\\Products\\");
8235     lstrcatA(keypath, prod_squashed);
8236
8237     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8239
8240     /* UserData product key exists */
8241     lstrcpyA(patchcode, "apple");
8242     lstrcpyA(targetprod, "banana");
8243     context = 0xdeadbeef;
8244     lstrcpyA(targetsid, "kiwi");
8245     size = MAX_PATH;
8246     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8247                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8248                            &context, targetsid, &size);
8249     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8250     ok(!lstrcmpA(patchcode, "apple"),
8251        "Expected patchcode to be unchanged, got %s\n", patchcode);
8252     ok(!lstrcmpA(targetprod, "banana"),
8253        "Expected targetprod to be unchanged, got %s\n", targetprod);
8254     ok(context == 0xdeadbeef,
8255        "Expected context to be unchanged, got %d\n", context);
8256     ok(!lstrcmpA(targetsid, "kiwi"),
8257        "Expected targetsid to be unchanged, got %s\n", targetsid);
8258     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8259
8260     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8261     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8262
8263     /* UserData patches key exists */
8264     lstrcpyA(patchcode, "apple");
8265     lstrcpyA(targetprod, "banana");
8266     context = 0xdeadbeef;
8267     lstrcpyA(targetsid, "kiwi");
8268     size = MAX_PATH;
8269     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8270                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8271                            &context, targetsid, &size);
8272     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8273     ok(!lstrcmpA(patchcode, "apple"),
8274        "Expected patchcode to be unchanged, got %s\n", patchcode);
8275     ok(!lstrcmpA(targetprod, "banana"),
8276        "Expected targetprod to be unchanged, got %s\n", targetprod);
8277     ok(context == 0xdeadbeef,
8278        "Expected context to be unchanged, got %d\n", context);
8279     ok(!lstrcmpA(targetsid, "kiwi"),
8280        "Expected targetsid to be unchanged, got %s\n", targetsid);
8281     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8282
8283     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8285
8286     /* specific UserData patch key exists */
8287     lstrcpyA(patchcode, "apple");
8288     lstrcpyA(targetprod, "banana");
8289     context = 0xdeadbeef;
8290     lstrcpyA(targetsid, "kiwi");
8291     size = MAX_PATH;
8292     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8293                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8294                            &context, targetsid, &size);
8295     ok(r == ERROR_BAD_CONFIGURATION,
8296        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8297     ok(!lstrcmpA(patchcode, "apple"),
8298        "Expected patchcode to be unchanged, got %s\n", patchcode);
8299     ok(!lstrcmpA(targetprod, "banana"),
8300        "Expected targetprod to be unchanged, got %s\n", targetprod);
8301     ok(context == 0xdeadbeef,
8302        "Expected context to be unchanged, got %d\n", context);
8303     ok(!lstrcmpA(targetsid, "kiwi"),
8304        "Expected targetsid to be unchanged, got %s\n", targetsid);
8305     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8306
8307     data = MSIPATCHSTATE_SUPERSEDED;
8308     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8309                          (const BYTE *)&data, sizeof(DWORD));
8310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8311
8312     /* State value exists */
8313     lstrcpyA(patchcode, "apple");
8314     lstrcpyA(targetprod, "banana");
8315     context = 0xdeadbeef;
8316     lstrcpyA(targetsid, "kiwi");
8317     size = MAX_PATH;
8318     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8319                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8320                            &context, targetsid, &size);
8321     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8322     ok(!lstrcmpA(patchcode, patch),
8323        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8324     ok(!lstrcmpA(targetprod, prodcode),
8325        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8326     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8327        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8328     ok(!lstrcmpA(targetsid, expectedsid),
8329        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8330     ok(size == lstrlenA(expectedsid),
8331        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8332
8333     /* MSIPATCHSTATE_OBSOLETED */
8334
8335     lstrcpyA(patchcode, "apple");
8336     lstrcpyA(targetprod, "banana");
8337     context = 0xdeadbeef;
8338     lstrcpyA(targetsid, "kiwi");
8339     size = MAX_PATH;
8340     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8341                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8342                            &context, targetsid, &size);
8343     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8344     ok(!lstrcmpA(patchcode, "apple"),
8345        "Expected patchcode to be unchanged, got %s\n", patchcode);
8346     ok(!lstrcmpA(targetprod, "banana"),
8347        "Expected targetprod to be unchanged, got %s\n", targetprod);
8348     ok(context == 0xdeadbeef,
8349        "Expected context to be unchanged, got %d\n", context);
8350     ok(!lstrcmpA(targetsid, "kiwi"),
8351        "Expected targetsid to be unchanged, got %s\n", targetsid);
8352     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8353
8354     data = MSIPATCHSTATE_OBSOLETED;
8355     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8356                          (const BYTE *)&data, sizeof(DWORD));
8357     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8358
8359     /* State value is obsoleted */
8360     lstrcpyA(patchcode, "apple");
8361     lstrcpyA(targetprod, "banana");
8362     context = 0xdeadbeef;
8363     lstrcpyA(targetsid, "kiwi");
8364     size = MAX_PATH;
8365     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8366                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8367                            &context, targetsid, &size);
8368     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8369     ok(!lstrcmpA(patchcode, patch),
8370        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8371     ok(!lstrcmpA(targetprod, prodcode),
8372        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8373     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8374        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8375     ok(!lstrcmpA(targetsid, expectedsid),
8376        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8377     ok(size == lstrlenA(expectedsid),
8378        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8379
8380     /* MSIPATCHSTATE_REGISTERED */
8381     /* FIXME */
8382
8383     /* MSIPATCHSTATE_ALL */
8384
8385     /* 1st */
8386     lstrcpyA(patchcode, "apple");
8387     lstrcpyA(targetprod, "banana");
8388     context = 0xdeadbeef;
8389     lstrcpyA(targetsid, "kiwi");
8390     size = MAX_PATH;
8391     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8392                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8393                            &context, targetsid, &size);
8394     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8395     ok(!lstrcmpA(patchcode, patch),
8396        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8397     ok(!lstrcmpA(targetprod, prodcode),
8398        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8399     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8400        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8401     ok(!lstrcmpA(targetsid, expectedsid),
8402        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8403     ok(size == lstrlenA(expectedsid),
8404        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8405
8406     /* same patch in multiple places, only one is enumerated */
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_ALL, 1, 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     RegDeleteValueA(hpatch, "State");
8427     RegDeleteKeyA(hpatch, "");
8428     RegCloseKey(hpatch);
8429     RegDeleteKeyA(udpatch, "");
8430     RegCloseKey(udpatch);
8431     RegDeleteKeyA(udprod, "");
8432     RegCloseKey(udprod);
8433     RegDeleteKeyA(userkey, "");
8434     RegCloseKey(userkey);
8435     RegDeleteValueA(patches, patch_squashed);
8436     RegDeleteValueA(patches, "Patches");
8437     RegDeleteKeyA(patches, "");
8438     RegCloseKey(patches);
8439     RegDeleteKeyA(prodkey, "");
8440     RegCloseKey(prodkey);
8441 }
8442
8443 static void test_MsiEnumPatchesEx_machine()
8444 {
8445     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8446     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8447     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8448     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8449     HKEY prodkey, patches, udprod, udpatch;
8450     HKEY hpatch;
8451     MSIINSTALLCONTEXT context;
8452     DWORD size, data;
8453     LONG res;
8454     UINT r;
8455
8456     create_test_guid(prodcode, prod_squashed);
8457     create_test_guid(patch, patch_squashed);
8458
8459     /* MSIPATCHSTATE_APPLIED */
8460
8461     lstrcpyA(patchcode, "apple");
8462     lstrcpyA(targetprod, "banana");
8463     context = 0xdeadbeef;
8464     lstrcpyA(targetsid, "kiwi");
8465     size = MAX_PATH;
8466     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8467                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8468                            &context, targetsid, &size);
8469     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8470     ok(!lstrcmpA(patchcode, "apple"),
8471        "Expected patchcode to be unchanged, got %s\n", patchcode);
8472     ok(!lstrcmpA(targetprod, "banana"),
8473        "Expected targetprod to be unchanged, got %s\n", targetprod);
8474     ok(context == 0xdeadbeef,
8475        "Expected context to be unchanged, got %d\n", context);
8476     ok(!lstrcmpA(targetsid, "kiwi"),
8477        "Expected targetsid to be unchanged, got %s\n", targetsid);
8478     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8479
8480     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8481     lstrcatA(keypath, prod_squashed);
8482
8483     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
8484     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8485
8486     /* local product key exists */
8487     lstrcpyA(patchcode, "apple");
8488     lstrcpyA(targetprod, "banana");
8489     context = 0xdeadbeef;
8490     lstrcpyA(targetsid, "kiwi");
8491     size = MAX_PATH;
8492     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8493                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8494                            &context, targetsid, &size);
8495     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8496     ok(!lstrcmpA(patchcode, "apple"),
8497        "Expected patchcode to be unchanged, got %s\n", patchcode);
8498     ok(!lstrcmpA(targetprod, "banana"),
8499        "Expected targetprod to be unchanged, got %s\n", targetprod);
8500     ok(context == 0xdeadbeef,
8501        "Expected context to be unchanged, got %d\n", context);
8502     ok(!lstrcmpA(targetsid, "kiwi"),
8503        "Expected targetsid to be unchanged, got %s\n", targetsid);
8504     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8505
8506     res = RegCreateKeyA(prodkey, "Patches", &patches);
8507     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8508
8509     /* Patches key exists */
8510     lstrcpyA(patchcode, "apple");
8511     lstrcpyA(targetprod, "banana");
8512     context = 0xdeadbeef;
8513     lstrcpyA(targetsid, "kiwi");
8514     size = MAX_PATH;
8515     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8516                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8517                            &context, targetsid, &size);
8518     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8519     ok(!lstrcmpA(patchcode, "apple"),
8520        "Expected patchcode to be unchanged, got %s\n", patchcode);
8521     ok(!lstrcmpA(targetprod, "banana"),
8522        "Expected targetprod to be unchanged, got %s\n", targetprod);
8523     ok(context == 0xdeadbeef,
8524        "Expected context to be unchanged, got %d\n", context);
8525     ok(!lstrcmpA(targetsid, "kiwi"),
8526        "Expected targetsid to be unchanged, got %s\n", targetsid);
8527     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8528
8529     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8530                          (const BYTE *)patch_squashed,
8531                          lstrlenA(patch_squashed) + 1);
8532     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8533
8534     /* Patches value exists, is not REG_MULTI_SZ */
8535     lstrcpyA(patchcode, "apple");
8536     lstrcpyA(targetprod, "banana");
8537     context = 0xdeadbeef;
8538     lstrcpyA(targetsid, "kiwi");
8539     size = MAX_PATH;
8540     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8541                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8542                            &context, targetsid, &size);
8543     ok(r == ERROR_BAD_CONFIGURATION,
8544        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8545     ok(!lstrcmpA(patchcode, "apple"),
8546        "Expected patchcode to be unchanged, got %s\n", patchcode);
8547     ok(!lstrcmpA(targetprod, "banana"),
8548        "Expected targetprod to be unchanged, got %s\n", targetprod);
8549     ok(context == 0xdeadbeef,
8550        "Expected context to be unchanged, got %d\n", context);
8551     ok(!lstrcmpA(targetsid, "kiwi"),
8552        "Expected targetsid to be unchanged, got %s\n", targetsid);
8553     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8554
8555     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8556                          (const BYTE *)"a\0b\0c\0\0", 7);
8557     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8558
8559     /* Patches value exists, is not a squashed guid */
8560     lstrcpyA(patchcode, "apple");
8561     lstrcpyA(targetprod, "banana");
8562     context = 0xdeadbeef;
8563     lstrcpyA(targetsid, "kiwi");
8564     size = MAX_PATH;
8565     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8566                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8567                            &context, targetsid, &size);
8568     ok(r == ERROR_BAD_CONFIGURATION,
8569        "Expected ERROR_BAD_CONFIGURATION, 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     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8581     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8582                          (const BYTE *)patch_squashed,
8583                          lstrlenA(patch_squashed) + 2);
8584     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8585
8586     /* Patches value exists */
8587     lstrcpyA(patchcode, "apple");
8588     lstrcpyA(targetprod, "banana");
8589     context = 0xdeadbeef;
8590     lstrcpyA(targetsid, "kiwi");
8591     size = MAX_PATH;
8592     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8593                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8594                            &context, targetsid, &size);
8595     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8596     ok(!lstrcmpA(patchcode, "apple"),
8597        "Expected patchcode to be unchanged, got %s\n", patchcode);
8598     ok(!lstrcmpA(targetprod, "banana"),
8599        "Expected targetprod to be unchanged, got %s\n", targetprod);
8600     ok(context == 0xdeadbeef,
8601        "Expected context to be unchanged, got %d\n", context);
8602     ok(!lstrcmpA(targetsid, "kiwi"),
8603        "Expected targetsid to be unchanged, got %s\n", targetsid);
8604     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8605
8606     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8607                          (const BYTE *)"whatever", 9);
8608     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8609
8610     /* patch code value exists */
8611     lstrcpyA(patchcode, "apple");
8612     lstrcpyA(targetprod, "banana");
8613     context = 0xdeadbeef;
8614     lstrcpyA(targetsid, "kiwi");
8615     size = MAX_PATH;
8616     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8617                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8618                            &context, targetsid, &size);
8619     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8620     ok(!lstrcmpA(patchcode, patch),
8621        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8622     ok(!lstrcmpA(targetprod, prodcode),
8623        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8624     ok(context == MSIINSTALLCONTEXT_MACHINE,
8625        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8626     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8627     ok(size == 0, "Expected 0, got %d\n", size);
8628
8629     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8630     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8631     lstrcatA(keypath, prod_squashed);
8632
8633     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8635
8636     /* local UserData product key exists */
8637     lstrcpyA(patchcode, "apple");
8638     lstrcpyA(targetprod, "banana");
8639     context = 0xdeadbeef;
8640     lstrcpyA(targetsid, "kiwi");
8641     size = MAX_PATH;
8642     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8643                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8644                            &context, targetsid, &size);
8645     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8646     ok(!lstrcmpA(patchcode, patch),
8647        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8648     ok(!lstrcmpA(targetprod, prodcode),
8649        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8650     ok(context == MSIINSTALLCONTEXT_MACHINE,
8651        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8652     ok(!lstrcmpA(targetsid, ""),
8653        "Expected \"\", got \"%s\"\n", targetsid);
8654     ok(size == 0, "Expected 0, got %d\n", size);
8655
8656     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8657     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8658
8659     /* local UserData Patches key exists */
8660     lstrcpyA(patchcode, "apple");
8661     lstrcpyA(targetprod, "banana");
8662     context = 0xdeadbeef;
8663     lstrcpyA(targetsid, "kiwi");
8664     size = MAX_PATH;
8665     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8666                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8667                            &context, targetsid, &size);
8668     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8669     ok(!lstrcmpA(patchcode, patch),
8670        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8671     ok(!lstrcmpA(targetprod, prodcode),
8672        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8673     ok(context == MSIINSTALLCONTEXT_MACHINE,
8674        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8675     ok(!lstrcmpA(targetsid, ""),
8676        "Expected \"\", got \"%s\"\n", targetsid);
8677     ok(size == 0, "Expected 0, got %d\n", size);
8678
8679     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8681
8682     /* local UserData Product patch key exists */
8683     lstrcpyA(patchcode, "apple");
8684     lstrcpyA(targetprod, "banana");
8685     context = 0xdeadbeef;
8686     lstrcpyA(targetsid, "kiwi");
8687     size = MAX_PATH;
8688     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8689                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8690                            &context, targetsid, &size);
8691     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8692     ok(!lstrcmpA(patchcode, "apple"),
8693        "Expected patchcode to be unchanged, got %s\n", patchcode);
8694     ok(!lstrcmpA(targetprod, "banana"),
8695        "Expected targetprod to be unchanged, got %s\n", targetprod);
8696     ok(context == 0xdeadbeef,
8697        "Expected context to be unchanged, got %d\n", context);
8698     ok(!lstrcmpA(targetsid, "kiwi"),
8699        "Expected targetsid to be unchanged, got %s\n", targetsid);
8700     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8701
8702     data = MSIPATCHSTATE_APPLIED;
8703     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8704                          (const BYTE *)&data, sizeof(DWORD));
8705     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8706
8707     /* State value exists */
8708     lstrcpyA(patchcode, "apple");
8709     lstrcpyA(targetprod, "banana");
8710     context = 0xdeadbeef;
8711     lstrcpyA(targetsid, "kiwi");
8712     size = MAX_PATH;
8713     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8714                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8715                            &context, targetsid, &size);
8716     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8717     ok(!lstrcmpA(patchcode, patch),
8718        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8719     ok(!lstrcmpA(targetprod, prodcode),
8720        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8721     ok(context == MSIINSTALLCONTEXT_MACHINE,
8722        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8723     ok(!lstrcmpA(targetsid, ""),
8724        "Expected \"\", got \"%s\"\n", targetsid);
8725     ok(size == 0, "Expected 0, got %d\n", size);
8726
8727     /* MSIPATCHSTATE_SUPERSEDED */
8728
8729     lstrcpyA(patchcode, "apple");
8730     lstrcpyA(targetprod, "banana");
8731     context = 0xdeadbeef;
8732     lstrcpyA(targetsid, "kiwi");
8733     size = MAX_PATH;
8734     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8735                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8736                            &context, targetsid, &size);
8737     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8738     ok(!lstrcmpA(patchcode, "apple"),
8739        "Expected patchcode to be unchanged, got %s\n", patchcode);
8740     ok(!lstrcmpA(targetprod, "banana"),
8741        "Expected targetprod to be unchanged, got %s\n", targetprod);
8742     ok(context == 0xdeadbeef,
8743        "Expected context to be unchanged, got %d\n", context);
8744     ok(!lstrcmpA(targetsid, "kiwi"),
8745        "Expected targetsid to be unchanged, got %s\n", targetsid);
8746     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8747
8748     data = MSIPATCHSTATE_SUPERSEDED;
8749     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8750                          (const BYTE *)&data, sizeof(DWORD));
8751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8752
8753     /* State value is MSIPATCHSTATE_SUPERSEDED */
8754     lstrcpyA(patchcode, "apple");
8755     lstrcpyA(targetprod, "banana");
8756     context = 0xdeadbeef;
8757     lstrcpyA(targetsid, "kiwi");
8758     size = MAX_PATH;
8759     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8760                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8761                            &context, targetsid, &size);
8762     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8763     ok(!lstrcmpA(patchcode, patch),
8764        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8765     ok(!lstrcmpA(targetprod, prodcode),
8766        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8767     ok(context == MSIINSTALLCONTEXT_MACHINE,
8768        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8769     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8770     ok(size == 0, "Expected 0, got %d\n", size);
8771
8772     /* MSIPATCHSTATE_OBSOLETED */
8773
8774     lstrcpyA(patchcode, "apple");
8775     lstrcpyA(targetprod, "banana");
8776     context = 0xdeadbeef;
8777     lstrcpyA(targetsid, "kiwi");
8778     size = MAX_PATH;
8779     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8780                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8781                            &context, targetsid, &size);
8782     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8783     ok(!lstrcmpA(patchcode, "apple"),
8784        "Expected patchcode to be unchanged, got %s\n", patchcode);
8785     ok(!lstrcmpA(targetprod, "banana"),
8786        "Expected targetprod to be unchanged, got %s\n", targetprod);
8787     ok(context == 0xdeadbeef,
8788        "Expected context to be unchanged, got %d\n", context);
8789     ok(!lstrcmpA(targetsid, "kiwi"),
8790        "Expected targetsid to be unchanged, got %s\n", targetsid);
8791     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8792
8793     data = MSIPATCHSTATE_OBSOLETED;
8794     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8795                          (const BYTE *)&data, sizeof(DWORD));
8796     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8797
8798     /* State value is obsoleted */
8799     lstrcpyA(patchcode, "apple");
8800     lstrcpyA(targetprod, "banana");
8801     context = 0xdeadbeef;
8802     lstrcpyA(targetsid, "kiwi");
8803     size = MAX_PATH;
8804     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8805                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8806                            &context, targetsid, &size);
8807     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8808     ok(!lstrcmpA(patchcode, patch),
8809        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8810     ok(!lstrcmpA(targetprod, prodcode),
8811        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8812     ok(context == MSIINSTALLCONTEXT_MACHINE,
8813        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8814     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8815     ok(size == 0, "Expected 0, got %d\n", size);
8816
8817     /* MSIPATCHSTATE_REGISTERED */
8818     /* FIXME */
8819
8820     /* MSIPATCHSTATE_ALL */
8821
8822     /* 1st */
8823     lstrcpyA(patchcode, "apple");
8824     lstrcpyA(targetprod, "banana");
8825     context = 0xdeadbeef;
8826     lstrcpyA(targetsid, "kiwi");
8827     size = MAX_PATH;
8828     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8829                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8830                            &context, targetsid, &size);
8831     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8832     ok(!lstrcmpA(patchcode, patch),
8833        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8834     ok(!lstrcmpA(targetprod, prodcode),
8835        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8836     ok(context == MSIINSTALLCONTEXT_MACHINE,
8837        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8838     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8839     ok(size == 0, "Expected 0, got %d\n", size);
8840
8841     /* same patch in multiple places, only one is enumerated */
8842     lstrcpyA(patchcode, "apple");
8843     lstrcpyA(targetprod, "banana");
8844     context = 0xdeadbeef;
8845     lstrcpyA(targetsid, "kiwi");
8846     size = MAX_PATH;
8847     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8848                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8849                            &context, targetsid, &size);
8850     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8851     ok(!lstrcmpA(patchcode, "apple"),
8852        "Expected patchcode to be unchanged, got %s\n", patchcode);
8853     ok(!lstrcmpA(targetprod, "banana"),
8854        "Expected targetprod to be unchanged, got %s\n", targetprod);
8855     ok(context == 0xdeadbeef,
8856        "Expected context to be unchanged, got %d\n", context);
8857     ok(!lstrcmpA(targetsid, "kiwi"),
8858        "Expected targetsid to be unchanged, got %s\n", targetsid);
8859     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8860
8861     RegDeleteValueA(patches, patch_squashed);
8862     RegDeleteValueA(patches, "Patches");
8863     RegDeleteKeyA(patches, "");
8864     RegCloseKey(patches);
8865     RegDeleteValueA(hpatch, "State");
8866     RegDeleteKeyA(hpatch, "");
8867     RegCloseKey(hpatch);
8868     RegDeleteKeyA(udpatch, "");
8869     RegCloseKey(udpatch);
8870     RegDeleteKeyA(udprod, "");
8871     RegCloseKey(udprod);
8872     RegDeleteKeyA(prodkey, "");
8873     RegCloseKey(prodkey);
8874 }
8875
8876 static void test_MsiEnumPatchesEx(void)
8877 {
8878     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8879     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8880     CHAR patchcode[MAX_PATH];
8881     MSIINSTALLCONTEXT context;
8882     LPSTR usersid;
8883     DWORD size;
8884     UINT r;
8885
8886     if (!pMsiEnumPatchesExA)
8887     {
8888         win_skip("MsiEnumPatchesExA not implemented\n");
8889         return;
8890     }
8891
8892     create_test_guid(prodcode, prod_squashed);
8893     get_user_sid(&usersid);
8894
8895     /* empty szProductCode */
8896     lstrcpyA(patchcode, "apple");
8897     lstrcpyA(targetprod, "banana");
8898     context = 0xdeadbeef;
8899     lstrcpyA(targetsid, "kiwi");
8900     size = MAX_PATH;
8901     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8902                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
8903                            targetsid, &size);
8904     ok(r == ERROR_INVALID_PARAMETER,
8905        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8906     ok(!lstrcmpA(patchcode, "apple"),
8907        "Expected patchcode to be unchanged, got %s\n", patchcode);
8908     ok(!lstrcmpA(targetprod, "banana"),
8909        "Expected targetprod to be unchanged, got %s\n", targetprod);
8910     ok(context == 0xdeadbeef,
8911        "Expected context to be unchanged, got %d\n", context);
8912     ok(!lstrcmpA(targetsid, "kiwi"),
8913        "Expected targetsid to be unchanged, got %s\n", targetsid);
8914     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8915
8916     /* garbage szProductCode */
8917     lstrcpyA(patchcode, "apple");
8918     lstrcpyA(targetprod, "banana");
8919     context = 0xdeadbeef;
8920     lstrcpyA(targetsid, "kiwi");
8921     size = MAX_PATH;
8922     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8923                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
8924                            targetsid, &size);
8925     ok(r == ERROR_INVALID_PARAMETER,
8926        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8927     ok(!lstrcmpA(patchcode, "apple"),
8928        "Expected patchcode to be unchanged, got %s\n", patchcode);
8929     ok(!lstrcmpA(targetprod, "banana"),
8930        "Expected targetprod to be unchanged, got %s\n", targetprod);
8931     ok(context == 0xdeadbeef,
8932        "Expected context to be unchanged, got %d\n", context);
8933     ok(!lstrcmpA(targetsid, "kiwi"),
8934        "Expected targetsid to be unchanged, got %s\n", targetsid);
8935     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8936
8937     /* guid without brackets */
8938     lstrcpyA(patchcode, "apple");
8939     lstrcpyA(targetprod, "banana");
8940     context = 0xdeadbeef;
8941     lstrcpyA(targetsid, "kiwi");
8942     size = MAX_PATH;
8943     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
8944                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
8945                            0, patchcode, targetprod, &context,
8946                            targetsid, &size);
8947     ok(r == ERROR_INVALID_PARAMETER,
8948        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8949     ok(!lstrcmpA(patchcode, "apple"),
8950        "Expected patchcode to be unchanged, got %s\n", patchcode);
8951     ok(!lstrcmpA(targetprod, "banana"),
8952        "Expected targetprod to be unchanged, got %s\n", targetprod);
8953     ok(context == 0xdeadbeef,
8954        "Expected context to be unchanged, got %d\n", context);
8955     ok(!lstrcmpA(targetsid, "kiwi"),
8956        "Expected targetsid to be unchanged, got %s\n", targetsid);
8957     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8958
8959     /* guid with brackets */
8960     lstrcpyA(patchcode, "apple");
8961     lstrcpyA(targetprod, "banana");
8962     context = 0xdeadbeef;
8963     lstrcpyA(targetsid, "kiwi");
8964     size = MAX_PATH;
8965     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
8966                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
8967                            0, patchcode, targetprod, &context,
8968                            targetsid, &size);
8969     ok(r == ERROR_NO_MORE_ITEMS,
8970        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8971     ok(!lstrcmpA(patchcode, "apple"),
8972        "Expected patchcode to be unchanged, got %s\n", patchcode);
8973     ok(!lstrcmpA(targetprod, "banana"),
8974        "Expected targetprod to be unchanged, got %s\n", targetprod);
8975     ok(context == 0xdeadbeef,
8976        "Expected context to be unchanged, got %d\n", context);
8977     ok(!lstrcmpA(targetsid, "kiwi"),
8978        "Expected targetsid to be unchanged, got %s\n", targetsid);
8979     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8980
8981     /* szUserSid is S-1-5-18 */
8982     lstrcpyA(patchcode, "apple");
8983     lstrcpyA(targetprod, "banana");
8984     context = 0xdeadbeef;
8985     lstrcpyA(targetsid, "kiwi");
8986     size = MAX_PATH;
8987     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
8988                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
8989                            0, patchcode, targetprod, &context,
8990                            targetsid, &size);
8991     ok(r == ERROR_INVALID_PARAMETER,
8992        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8993     ok(!lstrcmpA(patchcode, "apple"),
8994        "Expected patchcode to be unchanged, got %s\n", patchcode);
8995     ok(!lstrcmpA(targetprod, "banana"),
8996        "Expected targetprod to be unchanged, got %s\n", targetprod);
8997     ok(context == 0xdeadbeef,
8998        "Expected context to be unchanged, got %d\n", context);
8999     ok(!lstrcmpA(targetsid, "kiwi"),
9000        "Expected targetsid to be unchanged, got %s\n", targetsid);
9001     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9002
9003     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9004     lstrcpyA(patchcode, "apple");
9005     lstrcpyA(targetprod, "banana");
9006     context = 0xdeadbeef;
9007     lstrcpyA(targetsid, "kiwi");
9008     size = MAX_PATH;
9009     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9010                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9011                            &context, targetsid, &size);
9012     ok(r == ERROR_INVALID_PARAMETER,
9013        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9014     ok(!lstrcmpA(patchcode, "apple"),
9015        "Expected patchcode to be unchanged, got %s\n", patchcode);
9016     ok(!lstrcmpA(targetprod, "banana"),
9017        "Expected targetprod to be unchanged, got %s\n", targetprod);
9018     ok(context == 0xdeadbeef,
9019        "Expected context to be unchanged, got %d\n", context);
9020     ok(!lstrcmpA(targetsid, "kiwi"),
9021        "Expected targetsid to be unchanged, got %s\n", targetsid);
9022     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9023
9024     /* dwContext is out of bounds */
9025     lstrcpyA(patchcode, "apple");
9026     lstrcpyA(targetprod, "banana");
9027     context = 0xdeadbeef;
9028     lstrcpyA(targetsid, "kiwi");
9029     size = MAX_PATH;
9030     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9031                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9032                            &context, targetsid, &size);
9033     ok(r == ERROR_INVALID_PARAMETER,
9034        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9035     ok(!lstrcmpA(patchcode, "apple"),
9036        "Expected patchcode to be unchanged, got %s\n", patchcode);
9037     ok(!lstrcmpA(targetprod, "banana"),
9038        "Expected targetprod to be unchanged, got %s\n", targetprod);
9039     ok(context == 0xdeadbeef,
9040        "Expected context to be unchanged, got %d\n", context);
9041     ok(!lstrcmpA(targetsid, "kiwi"),
9042        "Expected targetsid to be unchanged, got %s\n", targetsid);
9043     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9044
9045     /* dwContext is out of bounds */
9046     lstrcpyA(patchcode, "apple");
9047     lstrcpyA(targetprod, "banana");
9048     context = 0xdeadbeef;
9049     lstrcpyA(targetsid, "kiwi");
9050     size = MAX_PATH;
9051     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9052                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9053                            &context, targetsid, &size);
9054     ok(r == ERROR_INVALID_PARAMETER,
9055        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9056     ok(!lstrcmpA(patchcode, "apple"),
9057        "Expected patchcode to be unchanged, got %s\n", patchcode);
9058     ok(!lstrcmpA(targetprod, "banana"),
9059        "Expected targetprod to be unchanged, got %s\n", targetprod);
9060     ok(context == 0xdeadbeef,
9061        "Expected context to be unchanged, got %d\n", context);
9062     ok(!lstrcmpA(targetsid, "kiwi"),
9063        "Expected targetsid to be unchanged, got %s\n", targetsid);
9064     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9065
9066     /* dwFilter is out of bounds */
9067     lstrcpyA(patchcode, "apple");
9068     lstrcpyA(targetprod, "banana");
9069     context = 0xdeadbeef;
9070     lstrcpyA(targetsid, "kiwi");
9071     size = MAX_PATH;
9072     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9073                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9074                            &context, targetsid, &size);
9075     ok(r == ERROR_INVALID_PARAMETER,
9076        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9077     ok(!lstrcmpA(patchcode, "apple"),
9078        "Expected patchcode to be unchanged, got %s\n", patchcode);
9079     ok(!lstrcmpA(targetprod, "banana"),
9080        "Expected targetprod to be unchanged, got %s\n", targetprod);
9081     ok(context == 0xdeadbeef,
9082        "Expected context to be unchanged, got %d\n", context);
9083     ok(!lstrcmpA(targetsid, "kiwi"),
9084        "Expected targetsid to be unchanged, got %s\n", targetsid);
9085     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9086
9087     /* dwFilter is out of bounds */
9088     lstrcpyA(patchcode, "apple");
9089     lstrcpyA(targetprod, "banana");
9090     context = 0xdeadbeef;
9091     lstrcpyA(targetsid, "kiwi");
9092     size = MAX_PATH;
9093     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9094                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9095                            &context, targetsid, &size);
9096     ok(r == ERROR_INVALID_PARAMETER,
9097        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9098     ok(!lstrcmpA(patchcode, "apple"),
9099        "Expected patchcode to be unchanged, got %s\n", patchcode);
9100     ok(!lstrcmpA(targetprod, "banana"),
9101        "Expected targetprod to be unchanged, got %s\n", targetprod);
9102     ok(context == 0xdeadbeef,
9103        "Expected context to be unchanged, got %d\n", context);
9104     ok(!lstrcmpA(targetsid, "kiwi"),
9105        "Expected targetsid to be unchanged, got %s\n", targetsid);
9106     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9107
9108     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9109     lstrcpyA(patchcode, "apple");
9110     lstrcpyA(targetprod, "banana");
9111     context = 0xdeadbeef;
9112     lstrcpyA(targetsid, "kiwi");
9113     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9114                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9115                            &context, targetsid, NULL);
9116     ok(r == ERROR_INVALID_PARAMETER,
9117        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9118     ok(!lstrcmpA(patchcode, "apple"),
9119        "Expected patchcode to be unchanged, got %s\n", patchcode);
9120     ok(!lstrcmpA(targetprod, "banana"),
9121        "Expected targetprod to be unchanged, got %s\n", targetprod);
9122     ok(context == 0xdeadbeef,
9123        "Expected context to be unchanged, got %d\n", context);
9124     ok(!lstrcmpA(targetsid, "kiwi"),
9125        "Expected targetsid to be unchanged, got %s\n", targetsid);
9126
9127     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9128     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9129     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9130     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9131     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9132     /* FIXME: Successfully test userunmanaged with a different user */
9133     test_MsiEnumPatchesEx_machine();
9134 }
9135
9136 static void test_MsiEnumPatches(void)
9137 {
9138     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9139     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9140     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9141     CHAR transforms[MAX_PATH];
9142     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9143     HKEY prodkey, patches, udprod;
9144     HKEY userkey, hpatch, udpatch;
9145     DWORD size, data;
9146     LPSTR usersid;
9147     LONG res;
9148     UINT r;
9149
9150     create_test_guid(prodcode, prod_squashed);
9151     create_test_guid(patchcode, patch_squashed);
9152     get_user_sid(&usersid);
9153
9154     /* NULL szProduct */
9155     size = MAX_PATH;
9156     lstrcpyA(patch, "apple");
9157     lstrcpyA(transforms, "banana");
9158     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9159     ok(r == ERROR_INVALID_PARAMETER,
9160        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9161     ok(!lstrcmpA(patch, "apple"),
9162        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9163     ok(!lstrcmpA(transforms, "banana"),
9164        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9165     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9166
9167     /* empty szProduct */
9168     size = MAX_PATH;
9169     lstrcpyA(patch, "apple");
9170     lstrcpyA(transforms, "banana");
9171     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9172     ok(r == ERROR_INVALID_PARAMETER,
9173        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9174     ok(!lstrcmpA(patch, "apple"),
9175        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9176     ok(!lstrcmpA(transforms, "banana"),
9177        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9178     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9179
9180     /* garbage szProduct */
9181     size = MAX_PATH;
9182     lstrcpyA(patch, "apple");
9183     lstrcpyA(transforms, "banana");
9184     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9185     ok(r == ERROR_INVALID_PARAMETER,
9186        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9187     ok(!lstrcmpA(patch, "apple"),
9188        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9189     ok(!lstrcmpA(transforms, "banana"),
9190        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9191     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9192
9193     /* guid without brackets */
9194     size = MAX_PATH;
9195     lstrcpyA(patch, "apple");
9196     lstrcpyA(transforms, "banana");
9197     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9198                         transforms, &size);
9199     ok(r == ERROR_INVALID_PARAMETER,
9200        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9201     ok(!lstrcmpA(patch, "apple"),
9202        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9203     ok(!lstrcmpA(transforms, "banana"),
9204        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9205     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9206
9207     /* guid with brackets */
9208     size = MAX_PATH;
9209     lstrcpyA(patch, "apple");
9210     lstrcpyA(transforms, "banana");
9211     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9212                         transforms, &size);
9213     ok(r == ERROR_UNKNOWN_PRODUCT,
9214        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9215     ok(!lstrcmpA(patch, "apple"),
9216        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9217     ok(!lstrcmpA(transforms, "banana"),
9218        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9219     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9220
9221     /* same length as guid, but random */
9222     size = MAX_PATH;
9223     lstrcpyA(patch, "apple");
9224     lstrcpyA(transforms, "banana");
9225     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9226                         transforms, &size);
9227     ok(r == ERROR_INVALID_PARAMETER,
9228        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9229     ok(!lstrcmpA(patch, "apple"),
9230        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9231     ok(!lstrcmpA(transforms, "banana"),
9232        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9233     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9234
9235     /* MSIINSTALLCONTEXT_USERMANAGED */
9236
9237     size = MAX_PATH;
9238     lstrcpyA(patch, "apple");
9239     lstrcpyA(transforms, "banana");
9240     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9241     ok(r == ERROR_UNKNOWN_PRODUCT,
9242        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9243     ok(!lstrcmpA(patch, "apple"),
9244        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9245     ok(!lstrcmpA(transforms, "banana"),
9246        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9247     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9248
9249     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9250     lstrcatA(keypath, usersid);
9251     lstrcatA(keypath, "\\Installer\\Products\\");
9252     lstrcatA(keypath, prod_squashed);
9253
9254     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9255     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9256
9257     /* managed product key exists */
9258     size = MAX_PATH;
9259     lstrcpyA(patch, "apple");
9260     lstrcpyA(transforms, "banana");
9261     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9262     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9263     ok(!lstrcmpA(patch, "apple"),
9264        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9265     ok(!lstrcmpA(transforms, "banana"),
9266        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9267     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9268
9269     res = RegCreateKeyA(prodkey, "Patches", &patches);
9270     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9271
9272     /* patches key exists */
9273     size = MAX_PATH;
9274     lstrcpyA(patch, "apple");
9275     lstrcpyA(transforms, "banana");
9276     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9277     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9278     ok(!lstrcmpA(patch, "apple"),
9279        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9280     ok(!lstrcmpA(transforms, "banana"),
9281        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9282     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9283
9284     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9285                          (const BYTE *)patch_squashed,
9286                          lstrlenA(patch_squashed) + 1);
9287     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9288
9289     /* Patches value exists, is not REG_MULTI_SZ */
9290     size = MAX_PATH;
9291     lstrcpyA(patch, "apple");
9292     lstrcpyA(transforms, "banana");
9293     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9294     ok(r == ERROR_BAD_CONFIGURATION,
9295        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9296     ok(!lstrcmpA(patch, "apple"),
9297        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9298     ok(!lstrcmpA(transforms, "banana"),
9299        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9300     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9301
9302     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9303                          (const BYTE *)"a\0b\0c\0\0", 7);
9304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9305
9306     /* Patches value exists, is not a squashed guid */
9307     size = MAX_PATH;
9308     lstrcpyA(patch, "apple");
9309     lstrcpyA(transforms, "banana");
9310     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9311     ok(r == ERROR_BAD_CONFIGURATION,
9312        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9313     ok(!lstrcmpA(patch, "apple"),
9314        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9315     ok(!lstrcmpA(transforms, "banana"),
9316        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9317     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9318
9319     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9320     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9321                          (const BYTE *)patch_squashed,
9322                          lstrlenA(patch_squashed) + 2);
9323     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9324
9325     /* Patches value exists */
9326     size = MAX_PATH;
9327     lstrcpyA(patch, "apple");
9328     lstrcpyA(transforms, "banana");
9329     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9330     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9331     ok(!lstrcmpA(patch, "apple"),
9332        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9333     ok(!lstrcmpA(transforms, "banana"),
9334        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9335     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9336
9337     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9338                          (const BYTE *)"whatever", 9);
9339     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9340
9341     /* patch squashed value exists */
9342     size = MAX_PATH;
9343     lstrcpyA(patch, "apple");
9344     lstrcpyA(transforms, "banana");
9345     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9346     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9347     ok(!lstrcmpA(patch, patchcode),
9348        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9349     ok(!lstrcmpA(transforms, "whatever"),
9350        "Expected \"whatever\", got \"%s\"\n", transforms);
9351     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9352
9353     /* lpPatchBuf is NULL */
9354     size = MAX_PATH;
9355     lstrcpyA(transforms, "banana");
9356     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9357     ok(r == ERROR_INVALID_PARAMETER,
9358        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9359     ok(!lstrcmpA(transforms, "banana"),
9360        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9361     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9362
9363     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9364     size = MAX_PATH;
9365     lstrcpyA(patch, "apple");
9366     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9367     ok(r == ERROR_INVALID_PARAMETER,
9368        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9369     ok(!lstrcmpA(patch, "apple"),
9370        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9371     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9372
9373     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9374     lstrcpyA(patch, "apple");
9375     lstrcpyA(transforms, "banana");
9376     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9377     ok(r == ERROR_INVALID_PARAMETER,
9378        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9379     ok(!lstrcmpA(patch, "apple"),
9380        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9381     ok(!lstrcmpA(transforms, "banana"),
9382        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9383
9384     /* pcchTransformsBuf is too small */
9385     size = 6;
9386     lstrcpyA(patch, "apple");
9387     lstrcpyA(transforms, "banana");
9388     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9389     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9390     ok(!lstrcmpA(patch, patchcode),
9391        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9392     ok(!lstrcmpA(transforms, "whate"),
9393        "Expected \"whate\", got \"%s\"\n", transforms);
9394     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
9395
9396     /* increase the index */
9397     size = MAX_PATH;
9398     lstrcpyA(patch, "apple");
9399     lstrcpyA(transforms, "banana");
9400     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9401     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9402     ok(!lstrcmpA(patch, "apple"),
9403        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9404     ok(!lstrcmpA(transforms, "banana"),
9405        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9406     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9407
9408     /* increase again */
9409     size = MAX_PATH;
9410     lstrcpyA(patch, "apple");
9411     lstrcpyA(transforms, "banana");
9412     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9413     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9414     ok(!lstrcmpA(patch, "apple"),
9415        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9416     ok(!lstrcmpA(transforms, "banana"),
9417        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9418     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9419
9420     RegDeleteValueA(patches, "Patches");
9421     RegDeleteKeyA(patches, "");
9422     RegCloseKey(patches);
9423     RegDeleteKeyA(prodkey, "");
9424     RegCloseKey(prodkey);
9425
9426     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9427
9428     size = MAX_PATH;
9429     lstrcpyA(patch, "apple");
9430     lstrcpyA(transforms, "banana");
9431     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9432     ok(r == ERROR_UNKNOWN_PRODUCT,
9433        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9434     ok(!lstrcmpA(patch, "apple"),
9435        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9436     ok(!lstrcmpA(transforms, "banana"),
9437        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9438     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9439
9440     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9441     lstrcatA(keypath, prod_squashed);
9442
9443     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9445
9446     /* current user product key exists */
9447     size = MAX_PATH;
9448     lstrcpyA(patch, "apple");
9449     lstrcpyA(transforms, "banana");
9450     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9451     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9452     ok(!lstrcmpA(patch, "apple"),
9453        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9454     ok(!lstrcmpA(transforms, "banana"),
9455        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9456     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9457
9458     res = RegCreateKeyA(prodkey, "Patches", &patches);
9459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9460
9461     /* Patches key exists */
9462     size = MAX_PATH;
9463     lstrcpyA(patch, "apple");
9464     lstrcpyA(transforms, "banana");
9465     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9466     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9467     ok(!lstrcmpA(patch, "apple"),
9468        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9469     ok(!lstrcmpA(transforms, "banana"),
9470        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9471     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9472
9473     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9474                          (const BYTE *)patch_squashed,
9475                          lstrlenA(patch_squashed) + 1);
9476     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9477
9478     /* Patches value exists, is not REG_MULTI_SZ */
9479     size = MAX_PATH;
9480     lstrcpyA(patch, "apple");
9481     lstrcpyA(transforms, "banana");
9482     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9483     ok(r == ERROR_BAD_CONFIGURATION,
9484        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9485     ok(!lstrcmpA(patch, "apple"),
9486        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9487     ok(!lstrcmpA(transforms, "banana"),
9488        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9489     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9490
9491     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9492                          (const BYTE *)"a\0b\0c\0\0", 7);
9493     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9494
9495     /* Patches value exists, is not a squashed guid */
9496     size = MAX_PATH;
9497     lstrcpyA(patch, "apple");
9498     lstrcpyA(transforms, "banana");
9499     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9500     ok(r == ERROR_BAD_CONFIGURATION,
9501        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9502     ok(!lstrcmpA(patch, "apple"),
9503        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9504     ok(!lstrcmpA(transforms, "banana"),
9505        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9506     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9507
9508     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9509     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9510                          (const BYTE *)patch_squashed,
9511                          lstrlenA(patch_squashed) + 2);
9512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9513
9514     /* Patches value exists */
9515     size = MAX_PATH;
9516     lstrcpyA(patch, "apple");
9517     lstrcpyA(transforms, "banana");
9518     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9519     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9520     ok(!lstrcmpA(patch, "apple"),
9521        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9522     ok(!lstrcmpA(transforms, "banana"),
9523        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9524     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9525
9526     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9527                          (const BYTE *)"whatever", 9);
9528     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9529
9530     /* patch code value exists */
9531     size = MAX_PATH;
9532     lstrcpyA(patch, "apple");
9533     lstrcpyA(transforms, "banana");
9534     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9535     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9536     ok(!lstrcmpA(patch, "apple"),
9537        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9538     ok(!lstrcmpA(transforms, "banana"),
9539        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9540     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9541
9542     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9543     lstrcatA(keypath, usersid);
9544     lstrcatA(keypath, "\\Patches\\");
9545     lstrcatA(keypath, patch_squashed);
9546
9547     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
9548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9549
9550     /* userdata patch key exists */
9551     size = MAX_PATH;
9552     lstrcpyA(patch, "apple");
9553     lstrcpyA(transforms, "banana");
9554     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9556     ok(!lstrcmpA(patch, patchcode),
9557        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9558     ok(!lstrcmpA(transforms, "whatever"),
9559        "Expected \"whatever\", got \"%s\"\n", transforms);
9560     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9561
9562     RegDeleteKeyA(userkey, "");
9563     RegCloseKey(userkey);
9564     RegDeleteValueA(patches, patch_squashed);
9565     RegDeleteValueA(patches, "Patches");
9566     RegDeleteKeyA(patches, "");
9567     RegCloseKey(patches);
9568     RegDeleteKeyA(prodkey, "");
9569     RegCloseKey(prodkey);
9570
9571     /* MSIINSTALLCONTEXT_MACHINE */
9572
9573     size = MAX_PATH;
9574     lstrcpyA(patch, "apple");
9575     lstrcpyA(transforms, "banana");
9576     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9577     ok(r == ERROR_UNKNOWN_PRODUCT,
9578        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9579     ok(!lstrcmpA(patch, "apple"),
9580        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9581     ok(!lstrcmpA(transforms, "banana"),
9582        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9583     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9584
9585     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9586     lstrcatA(keypath, prod_squashed);
9587
9588     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9590
9591     /* local product key exists */
9592     size = MAX_PATH;
9593     lstrcpyA(patch, "apple");
9594     lstrcpyA(transforms, "banana");
9595     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9596     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9597     ok(!lstrcmpA(patch, "apple"),
9598        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9599     ok(!lstrcmpA(transforms, "banana"),
9600        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9601     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9602
9603     res = RegCreateKeyA(prodkey, "Patches", &patches);
9604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9605
9606     /* Patches key exists */
9607     size = MAX_PATH;
9608     lstrcpyA(patch, "apple");
9609     lstrcpyA(transforms, "banana");
9610     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9611     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9612     ok(!lstrcmpA(patch, "apple"),
9613        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9614     ok(!lstrcmpA(transforms, "banana"),
9615        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9616     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9617
9618     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9619                          (const BYTE *)patch_squashed,
9620                          lstrlenA(patch_squashed) + 1);
9621     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9622
9623     /* Patches value exists, is not REG_MULTI_SZ */
9624     size = MAX_PATH;
9625     lstrcpyA(patch, "apple");
9626     lstrcpyA(transforms, "banana");
9627     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9628     ok(r == ERROR_BAD_CONFIGURATION,
9629        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9630     ok(!lstrcmpA(patch, "apple"),
9631        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9632     ok(!lstrcmpA(transforms, "banana"),
9633        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9634     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9635
9636     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9637                          (const BYTE *)"a\0b\0c\0\0", 7);
9638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9639
9640     /* Patches value exists, is not a squashed guid */
9641     size = MAX_PATH;
9642     lstrcpyA(patch, "apple");
9643     lstrcpyA(transforms, "banana");
9644     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9645     ok(r == ERROR_BAD_CONFIGURATION,
9646        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9647     ok(!lstrcmpA(patch, "apple"),
9648        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9649     ok(!lstrcmpA(transforms, "banana"),
9650        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9651     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9652
9653     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9654     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9655                          (const BYTE *)patch_squashed,
9656                          lstrlenA(patch_squashed) + 2);
9657     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9658
9659     /* Patches value exists */
9660     size = MAX_PATH;
9661     lstrcpyA(patch, "apple");
9662     lstrcpyA(transforms, "banana");
9663     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9664     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9665     ok(!lstrcmpA(patch, "apple"),
9666        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9667     ok(!lstrcmpA(transforms, "banana"),
9668        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9669     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9670
9671     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9672                          (const BYTE *)"whatever", 9);
9673     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9674
9675     /* patch code value exists */
9676     size = MAX_PATH;
9677     lstrcpyA(patch, "apple");
9678     lstrcpyA(transforms, "banana");
9679     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9680     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9681     ok(!lstrcmpA(patch, patchcode),
9682        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9683     ok(!lstrcmpA(transforms, "whatever"),
9684        "Expected \"whatever\", got \"%s\"\n", transforms);
9685     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9686
9687     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9688     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9689     lstrcatA(keypath, prod_squashed);
9690
9691     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9692     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9693
9694     /* local UserData product key exists */
9695     size = MAX_PATH;
9696     lstrcpyA(patch, "apple");
9697     lstrcpyA(transforms, "banana");
9698     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9699     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9700     ok(!lstrcmpA(patch, patchcode),
9701        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9702     ok(!lstrcmpA(transforms, "whatever"),
9703        "Expected \"whatever\", got \"%s\"\n", transforms);
9704     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9705
9706     res = RegCreateKeyA(udprod, "Patches", &udpatch);
9707     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9708
9709     /* local UserData Patches key exists */
9710     size = MAX_PATH;
9711     lstrcpyA(patch, "apple");
9712     lstrcpyA(transforms, "banana");
9713     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9714     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9715     ok(!lstrcmpA(patch, patchcode),
9716        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9717     ok(!lstrcmpA(transforms, "whatever"),
9718        "Expected \"whatever\", got \"%s\"\n", transforms);
9719     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9720
9721     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
9722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9723
9724     /* local UserData Product patch key exists */
9725     size = MAX_PATH;
9726     lstrcpyA(patch, "apple");
9727     lstrcpyA(transforms, "banana");
9728     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9729     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9730     ok(!lstrcmpA(patch, "apple"),
9731        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9732     ok(!lstrcmpA(transforms, "banana"),
9733        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9734     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9735
9736     data = MSIPATCHSTATE_APPLIED;
9737     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9738                          (const BYTE *)&data, sizeof(DWORD));
9739     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9740
9741     /* State value exists */
9742     size = MAX_PATH;
9743     lstrcpyA(patch, "apple");
9744     lstrcpyA(transforms, "banana");
9745     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9746     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9747     ok(!lstrcmpA(patch, patchcode),
9748        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9749     ok(!lstrcmpA(transforms, "whatever"),
9750        "Expected \"whatever\", got \"%s\"\n", transforms);
9751     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9752
9753     /* now duplicate some of the tests for the W version */
9754
9755     /* pcchTransformsBuf is too small */
9756     size = 6;
9757     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
9758     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9759     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9760     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9761     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9762     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9763     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
9764     ok(!lstrcmpA(patch, patchcode),
9765        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9766     ok(!lstrcmpA(transforms, "whate"),
9767        "Expected \"whate\", got \"%s\"\n", transforms);
9768     ok(size == 8, "Expected 8, got %d\n", size);
9769
9770     /* patch code value exists */
9771     size = MAX_PATH;
9772     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9773     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9774     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9775     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9776     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9777     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
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     RegDeleteValueA(patches, patch_squashed);
9785     RegDeleteValueA(patches, "Patches");
9786     RegDeleteKeyA(patches, "");
9787     RegCloseKey(patches);
9788     RegDeleteValueA(hpatch, "State");
9789     RegDeleteKeyA(hpatch, "");
9790     RegCloseKey(hpatch);
9791     RegDeleteKeyA(udpatch, "");
9792     RegCloseKey(udpatch);
9793     RegDeleteKeyA(udprod, "");
9794     RegCloseKey(udprod);
9795     RegDeleteKeyA(prodkey, "");
9796     RegCloseKey(prodkey);
9797 }
9798
9799 static void test_MsiGetPatchInfoEx(void)
9800 {
9801     CHAR keypath[MAX_PATH], val[MAX_PATH];
9802     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9803     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9804     HKEY prodkey, patches, udprod, props;
9805     HKEY hpatch, udpatch, prodpatches;
9806     LPSTR usersid;
9807     DWORD size;
9808     LONG res;
9809     UINT r;
9810
9811     if (!pMsiGetPatchInfoExA)
9812     {
9813         win_skip("MsiGetPatchInfoEx not implemented\n");
9814         return;
9815     }
9816
9817     create_test_guid(prodcode, prod_squashed);
9818     create_test_guid(patchcode, patch_squashed);
9819     get_user_sid(&usersid);
9820
9821     /* NULL szPatchCode */
9822     lstrcpyA(val, "apple");
9823     size = MAX_PATH;
9824     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9825                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9826     ok(r == ERROR_INVALID_PARAMETER,
9827        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9828     ok(!lstrcmpA(val, "apple"),
9829        "Expected val to be unchanged, got \"%s\"\n", val);
9830     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9831
9832     /* empty szPatchCode */
9833     size = MAX_PATH;
9834     lstrcpyA(val, "apple");
9835     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9836                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9837     ok(r == ERROR_INVALID_PARAMETER,
9838        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9839     ok(!lstrcmpA(val, "apple"),
9840        "Expected val to be unchanged, got \"%s\"\n", val);
9841     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9842
9843     /* garbage szPatchCode */
9844     size = MAX_PATH;
9845     lstrcpyA(val, "apple");
9846     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
9847                             MSIINSTALLCONTEXT_USERMANAGED,
9848                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9849     ok(r == ERROR_INVALID_PARAMETER,
9850        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9851     ok(!lstrcmpA(val, "apple"),
9852        "Expected val to be unchanged, got \"%s\"\n", val);
9853     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9854
9855     /* guid without brackets */
9856     size = MAX_PATH;
9857     lstrcpyA(val, "apple");
9858     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
9859                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9860                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9861     ok(r == ERROR_INVALID_PARAMETER,
9862        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9863     ok(!lstrcmpA(val, "apple"),
9864        "Expected val to be unchanged, got \"%s\"\n", val);
9865     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9866
9867     /* guid with brackets */
9868     size = MAX_PATH;
9869     lstrcpyA(val, "apple");
9870     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
9871                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9872                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9873     ok(r == ERROR_UNKNOWN_PRODUCT,
9874        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9875     ok(!lstrcmpA(val, "apple"),
9876        "Expected val to be unchanged, got \"%s\"\n", val);
9877     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9878
9879     /* same length as guid, but random */
9880     size = MAX_PATH;
9881     lstrcpyA(val, "apple");
9882     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
9883                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9884                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9885     ok(r == ERROR_INVALID_PARAMETER,
9886        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9887     ok(!lstrcmpA(val, "apple"),
9888        "Expected val to be unchanged, got \"%s\"\n", val);
9889     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9890
9891     /* NULL szProductCode */
9892     lstrcpyA(val, "apple");
9893     size = MAX_PATH;
9894     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9895                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9896     ok(r == ERROR_INVALID_PARAMETER,
9897        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9898     ok(!lstrcmpA(val, "apple"),
9899        "Expected val to be unchanged, got \"%s\"\n", val);
9900     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9901
9902     /* empty szProductCode */
9903     size = MAX_PATH;
9904     lstrcpyA(val, "apple");
9905     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
9906                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9907     ok(r == ERROR_INVALID_PARAMETER,
9908        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9909     ok(!lstrcmpA(val, "apple"),
9910        "Expected val to be unchanged, got \"%s\"\n", val);
9911     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9912
9913     /* garbage szProductCode */
9914     size = MAX_PATH;
9915     lstrcpyA(val, "apple");
9916     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
9917                             MSIINSTALLCONTEXT_USERMANAGED,
9918                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9919     ok(r == ERROR_INVALID_PARAMETER,
9920        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9921     ok(!lstrcmpA(val, "apple"),
9922        "Expected val to be unchanged, got \"%s\"\n", val);
9923     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9924
9925     /* guid without brackets */
9926     size = MAX_PATH;
9927     lstrcpyA(val, "apple");
9928     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
9929                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9930                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9931     ok(r == ERROR_INVALID_PARAMETER,
9932        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9933     ok(!lstrcmpA(val, "apple"),
9934        "Expected val to be unchanged, got \"%s\"\n", val);
9935     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9936
9937     /* guid with brackets */
9938     size = MAX_PATH;
9939     lstrcpyA(val, "apple");
9940     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
9941                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9942                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9943     ok(r == ERROR_UNKNOWN_PRODUCT,
9944        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9945     ok(!lstrcmpA(val, "apple"),
9946        "Expected val to be unchanged, got \"%s\"\n", val);
9947     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9948
9949     /* same length as guid, but random */
9950     size = MAX_PATH;
9951     lstrcpyA(val, "apple");
9952     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
9953                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9954                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9955     ok(r == ERROR_INVALID_PARAMETER,
9956        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9957     ok(!lstrcmpA(val, "apple"),
9958        "Expected val to be unchanged, got \"%s\"\n", val);
9959     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9960
9961     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
9962     size = MAX_PATH;
9963     lstrcpyA(val, "apple");
9964     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9965                             MSIINSTALLCONTEXT_USERMANAGED,
9966                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9967     ok(r == ERROR_INVALID_PARAMETER,
9968        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9969     ok(!lstrcmpA(val, "apple"),
9970        "Expected val to be unchanged, got \"%s\"\n", val);
9971     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9972
9973     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
9974     size = MAX_PATH;
9975     lstrcpyA(val, "apple");
9976     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9977                             MSIINSTALLCONTEXT_USERUNMANAGED,
9978                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9979     ok(r == ERROR_INVALID_PARAMETER,
9980        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9981     ok(!lstrcmpA(val, "apple"),
9982        "Expected val to be unchanged, got \"%s\"\n", val);
9983     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9984
9985     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
9986     size = MAX_PATH;
9987     lstrcpyA(val, "apple");
9988     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9989                             MSIINSTALLCONTEXT_MACHINE,
9990                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9991     ok(r == ERROR_INVALID_PARAMETER,
9992        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9993     ok(!lstrcmpA(val, "apple"),
9994        "Expected val to be unchanged, got \"%s\"\n", val);
9995     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9996
9997     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
9998     size = MAX_PATH;
9999     lstrcpyA(val, "apple");
10000     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10001                             MSIINSTALLCONTEXT_MACHINE,
10002                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10003     ok(r == ERROR_INVALID_PARAMETER,
10004        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10005     ok(!lstrcmpA(val, "apple"),
10006        "Expected val to be unchanged, got \"%s\"\n", val);
10007     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10008
10009     /* dwContext is out of range */
10010     size = MAX_PATH;
10011     lstrcpyA(val, "apple");
10012     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10013                             MSIINSTALLCONTEXT_NONE,
10014                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10015     ok(r == ERROR_INVALID_PARAMETER,
10016        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10017     ok(!lstrcmpA(val, "apple"),
10018        "Expected val to be unchanged, got \"%s\"\n", val);
10019     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10020
10021     /* dwContext is out of range */
10022     size = MAX_PATH;
10023     lstrcpyA(val, "apple");
10024     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10025                             MSIINSTALLCONTEXT_ALL,
10026                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10027     ok(r == ERROR_INVALID_PARAMETER,
10028        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10029     ok(!lstrcmpA(val, "apple"),
10030        "Expected val to be unchanged, got \"%s\"\n", val);
10031     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10032
10033     /* dwContext is invalid */
10034     size = MAX_PATH;
10035     lstrcpyA(val, "apple");
10036     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10037                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10038     ok(r == ERROR_INVALID_PARAMETER,
10039        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10040     ok(!lstrcmpA(val, "apple"),
10041        "Expected val to be unchanged, got \"%s\"\n", val);
10042     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10043
10044     /* MSIINSTALLCONTEXT_USERMANAGED */
10045
10046     size = MAX_PATH;
10047     lstrcpyA(val, "apple");
10048     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10049                             MSIINSTALLCONTEXT_USERMANAGED,
10050                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10051     ok(r == ERROR_UNKNOWN_PRODUCT,
10052        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10053     ok(!lstrcmpA(val, "apple"),
10054        "Expected val to be unchanged, got \"%s\"\n", val);
10055     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10056
10057     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10058     lstrcatA(keypath, usersid);
10059     lstrcatA(keypath, "\\Products\\");
10060     lstrcatA(keypath, prod_squashed);
10061
10062     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10063     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10064
10065     /* local UserData product key exists */
10066     size = MAX_PATH;
10067     lstrcpyA(val, "apple");
10068     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10069                             MSIINSTALLCONTEXT_USERMANAGED,
10070                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10071     ok(r == ERROR_UNKNOWN_PRODUCT,
10072        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10073     ok(!lstrcmpA(val, "apple"),
10074        "Expected val to be unchanged, got \"%s\"\n", val);
10075     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10076
10077     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10079
10080     /* InstallProperties key exists */
10081     size = MAX_PATH;
10082     lstrcpyA(val, "apple");
10083     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10084                             MSIINSTALLCONTEXT_USERMANAGED,
10085                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10086     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10087     ok(!lstrcmpA(val, "apple"),
10088        "Expected val to be unchanged, got \"%s\"\n", val);
10089     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10090
10091     res = RegCreateKeyA(udprod, "Patches", &patches);
10092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10093
10094     /* Patches key exists */
10095     size = MAX_PATH;
10096     lstrcpyA(val, "apple");
10097     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10098                             MSIINSTALLCONTEXT_USERMANAGED,
10099                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10100     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10101     ok(!lstrcmpA(val, "apple"),
10102        "Expected val to be unchanged, got \"%s\"\n", val);
10103     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10104
10105     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10107
10108     /* Patches key exists */
10109     size = MAX_PATH;
10110     lstrcpyA(val, "apple");
10111     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10112                             MSIINSTALLCONTEXT_USERMANAGED,
10113                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10114     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10115     ok(!lstrcmpA(val, "apple"),
10116        "Expected val to be unchanged, got \"%s\"\n", val);
10117     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10118
10119     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10120     lstrcatA(keypath, usersid);
10121     lstrcatA(keypath, "\\Installer\\Products\\");
10122     lstrcatA(keypath, prod_squashed);
10123
10124     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10125     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10126
10127     /* managed product key exists */
10128     size = MAX_PATH;
10129     lstrcpyA(val, "apple");
10130     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10131                             MSIINSTALLCONTEXT_USERMANAGED,
10132                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10133     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10134     ok(!lstrcmpA(val, "apple"),
10135        "Expected val to be unchanged, got \"%s\"\n", val);
10136     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10137
10138     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10140
10141     /* Patches key exists */
10142     size = MAX_PATH;
10143     lstrcpyA(val, "apple");
10144     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10145                             MSIINSTALLCONTEXT_USERMANAGED,
10146                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10147     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10148     ok(!lstrcmpA(val, "apple"),
10149        "Expected val to be unchanged, got \"%s\"\n", val);
10150     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10151
10152     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10153                          (const BYTE *)"transforms", 11);
10154     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10155
10156     /* specific patch value exists */
10157     size = MAX_PATH;
10158     lstrcpyA(val, "apple");
10159     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10160                             MSIINSTALLCONTEXT_USERMANAGED,
10161                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10162     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10163     ok(!lstrcmpA(val, "apple"),
10164        "Expected val to be unchanged, got \"%s\"\n", val);
10165     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10166
10167     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10168     lstrcatA(keypath, usersid);
10169     lstrcatA(keypath, "\\Patches\\");
10170     lstrcatA(keypath, patch_squashed);
10171
10172     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10173     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10174
10175     /* UserData Patches key exists */
10176     size = MAX_PATH;
10177     lstrcpyA(val, "apple");
10178     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10179                             MSIINSTALLCONTEXT_USERMANAGED,
10180                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10182     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10183     ok(size == 0, "Expected 0, got %d\n", size);
10184
10185     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10186                          (const BYTE *)"pack", 5);
10187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10188
10189     /* ManagedLocalPatch value exists */
10190     size = MAX_PATH;
10191     lstrcpyA(val, "apple");
10192     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10193                             MSIINSTALLCONTEXT_USERMANAGED,
10194                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10195     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10196     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10197     ok(size == 4, "Expected 4, got %d\n", size);
10198
10199     size = MAX_PATH;
10200     lstrcpyA(val, "apple");
10201     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10202                             MSIINSTALLCONTEXT_USERMANAGED,
10203                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10204     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10205     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10206     ok(size == 10, "Expected 10, got %d\n", size);
10207
10208     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10209                          (const BYTE *)"mydate", 7);
10210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10211
10212     /* Installed value exists */
10213     size = MAX_PATH;
10214     lstrcpyA(val, "apple");
10215     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10216                             MSIINSTALLCONTEXT_USERMANAGED,
10217                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10218     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10219     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10220     ok(size == 6, "Expected 6, got %d\n", size);
10221
10222     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10223                          (const BYTE *)"yes", 4);
10224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10225
10226     /* Uninstallable value exists */
10227     size = MAX_PATH;
10228     lstrcpyA(val, "apple");
10229     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10230                             MSIINSTALLCONTEXT_USERMANAGED,
10231                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10232     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10233     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10234     ok(size == 3, "Expected 3, got %d\n", size);
10235
10236     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10237                          (const BYTE *)"good", 5);
10238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10239
10240     /* State value exists */
10241     size = MAX_PATH;
10242     lstrcpyA(val, "apple");
10243     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10244                             MSIINSTALLCONTEXT_USERMANAGED,
10245                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10246     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10247     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10248     ok(size == 4, "Expected 4, got %d\n", size);
10249
10250     size = 1;
10251     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10252                          (const BYTE *)&size, sizeof(DWORD));
10253     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10254
10255     /* State value exists */
10256     size = MAX_PATH;
10257     lstrcpyA(val, "apple");
10258     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10259                             MSIINSTALLCONTEXT_USERMANAGED,
10260                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10262     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10263     ok(size == 1, "Expected 1, got %d\n", size);
10264
10265     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10266                          (const BYTE *)"display", 8);
10267     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10268
10269     /* DisplayName value exists */
10270     size = MAX_PATH;
10271     lstrcpyA(val, "apple");
10272     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10273                             MSIINSTALLCONTEXT_USERMANAGED,
10274                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10275     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10276     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10277     ok(size == 7, "Expected 7, got %d\n", size);
10278
10279     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10280                          (const BYTE *)"moreinfo", 9);
10281     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10282
10283     /* MoreInfoURL value exists */
10284     size = MAX_PATH;
10285     lstrcpyA(val, "apple");
10286     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10287                             MSIINSTALLCONTEXT_USERMANAGED,
10288                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10289     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10290     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10291     ok(size == 8, "Expected 8, got %d\n", size);
10292
10293     /* szProperty is invalid */
10294     size = MAX_PATH;
10295     lstrcpyA(val, "apple");
10296     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10297                             MSIINSTALLCONTEXT_USERMANAGED,
10298                             "IDontExist", val, &size);
10299     ok(r == ERROR_UNKNOWN_PROPERTY,
10300        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10301     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10302     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10303
10304     /* lpValue is NULL, while pcchValue is non-NULL */
10305     size = MAX_PATH;
10306     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10307                             MSIINSTALLCONTEXT_USERMANAGED,
10308                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10309     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10310     ok(size == 16, "Expected 16, got %d\n", size);
10311
10312     /* pcchValue is NULL, while lpValue is non-NULL */
10313     lstrcpyA(val, "apple");
10314     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10315                             MSIINSTALLCONTEXT_USERMANAGED,
10316                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10317     ok(r == ERROR_INVALID_PARAMETER,
10318        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10319     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10320
10321     /* both lpValue and pcchValue are NULL */
10322     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10323                             MSIINSTALLCONTEXT_USERMANAGED,
10324                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10326
10327     /* pcchValue doesn't have enough room for NULL terminator */
10328     size = 8;
10329     lstrcpyA(val, "apple");
10330     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10331                             MSIINSTALLCONTEXT_USERMANAGED,
10332                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10333     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10334     ok(!lstrcmpA(val, "moreinf"),
10335        "Expected \"moreinf\", got \"%s\"\n", val);
10336     ok(size == 16, "Expected 16, got %d\n", size);
10337
10338     /* pcchValue has exactly enough room for NULL terminator */
10339     size = 9;
10340     lstrcpyA(val, "apple");
10341     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10342                             MSIINSTALLCONTEXT_USERMANAGED,
10343                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10344     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10345     ok(!lstrcmpA(val, "moreinfo"),
10346        "Expected \"moreinfo\", got \"%s\"\n", val);
10347     ok(size == 8, "Expected 8, got %d\n", size);
10348
10349     /* pcchValue is too small, lpValue is NULL */
10350     size = 0;
10351     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10352                             MSIINSTALLCONTEXT_USERMANAGED,
10353                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10355     ok(size == 16, "Expected 16, got %d\n", size);
10356
10357     RegDeleteValueA(prodpatches, patch_squashed);
10358     RegDeleteKeyA(prodpatches, "");
10359     RegCloseKey(prodpatches);
10360     RegDeleteKeyA(prodkey, "");
10361     RegCloseKey(prodkey);
10362
10363     /* UserData is sufficient for all properties
10364      * except INSTALLPROPERTY_TRANSFORMS
10365      */
10366     size = MAX_PATH;
10367     lstrcpyA(val, "apple");
10368     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10369                             MSIINSTALLCONTEXT_USERMANAGED,
10370                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10372     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10373     ok(size == 4, "Expected 4, got %d\n", size);
10374
10375     /* UserData is sufficient for all properties
10376      * except INSTALLPROPERTY_TRANSFORMS
10377      */
10378     size = MAX_PATH;
10379     lstrcpyA(val, "apple");
10380     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10381                             MSIINSTALLCONTEXT_USERMANAGED,
10382                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10383     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10384     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10385     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10386
10387     RegDeleteValueA(hpatch, "MoreInfoURL");
10388     RegDeleteValueA(hpatch, "Display");
10389     RegDeleteValueA(hpatch, "State");
10390     RegDeleteValueA(hpatch, "Uninstallable");
10391     RegDeleteValueA(hpatch, "Installed");
10392     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10393     RegDeleteKeyA(udpatch, "");
10394     RegCloseKey(udpatch);
10395     RegDeleteKeyA(hpatch, "");
10396     RegCloseKey(hpatch);
10397     RegDeleteKeyA(patches, "");
10398     RegCloseKey(patches);
10399     RegDeleteKeyA(props, "");
10400     RegCloseKey(props);
10401     RegDeleteKeyA(udprod, "");
10402     RegCloseKey(udprod);
10403
10404     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10405
10406     size = MAX_PATH;
10407     lstrcpyA(val, "apple");
10408     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10409                             MSIINSTALLCONTEXT_USERUNMANAGED,
10410                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10411     ok(r == ERROR_UNKNOWN_PRODUCT,
10412        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10413     ok(!lstrcmpA(val, "apple"),
10414        "Expected val to be unchanged, got \"%s\"\n", val);
10415     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10416
10417     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10418     lstrcatA(keypath, usersid);
10419     lstrcatA(keypath, "\\Products\\");
10420     lstrcatA(keypath, prod_squashed);
10421
10422     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10423     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10424
10425     /* local UserData product key exists */
10426     size = MAX_PATH;
10427     lstrcpyA(val, "apple");
10428     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10429                             MSIINSTALLCONTEXT_USERUNMANAGED,
10430                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10431     ok(r == ERROR_UNKNOWN_PRODUCT,
10432        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10433     ok(!lstrcmpA(val, "apple"),
10434        "Expected val to be unchanged, got \"%s\"\n", val);
10435     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10436
10437     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10439
10440     /* InstallProperties key exists */
10441     size = MAX_PATH;
10442     lstrcpyA(val, "apple");
10443     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10444                             MSIINSTALLCONTEXT_USERUNMANAGED,
10445                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10446     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10447     ok(!lstrcmpA(val, "apple"),
10448        "Expected val to be unchanged, got \"%s\"\n", val);
10449     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10450
10451     res = RegCreateKeyA(udprod, "Patches", &patches);
10452     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10453
10454     /* Patches key exists */
10455     size = MAX_PATH;
10456     lstrcpyA(val, "apple");
10457     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10458                             MSIINSTALLCONTEXT_USERUNMANAGED,
10459                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10460     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10461     ok(!lstrcmpA(val, "apple"),
10462        "Expected val to be unchanged, got \"%s\"\n", val);
10463     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10464
10465     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10466     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10467
10468     /* Patches key exists */
10469     size = MAX_PATH;
10470     lstrcpyA(val, "apple");
10471     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10472                             MSIINSTALLCONTEXT_USERUNMANAGED,
10473                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10474     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, 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     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10480     lstrcatA(keypath, prod_squashed);
10481
10482     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10483     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10484
10485     /* current user product key exists */
10486     size = MAX_PATH;
10487     lstrcpyA(val, "apple");
10488     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10489                             MSIINSTALLCONTEXT_USERUNMANAGED,
10490                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10491     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10492     ok(!lstrcmpA(val, "apple"),
10493        "Expected val to be unchanged, got \"%s\"\n", val);
10494     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10495
10496     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10497     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10498
10499     /* Patches key exists */
10500     size = MAX_PATH;
10501     lstrcpyA(val, "apple");
10502     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10503                             MSIINSTALLCONTEXT_USERUNMANAGED,
10504                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10505     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10506     ok(!lstrcmpA(val, "apple"),
10507        "Expected val to be unchanged, got \"%s\"\n", val);
10508     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10509
10510     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10511                          (const BYTE *)"transforms", 11);
10512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10513
10514     /* specific patch value exists */
10515     size = MAX_PATH;
10516     lstrcpyA(val, "apple");
10517     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10518                             MSIINSTALLCONTEXT_USERUNMANAGED,
10519                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10520     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10521     ok(!lstrcmpA(val, "apple"),
10522        "Expected val to be unchanged, got \"%s\"\n", val);
10523     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10524
10525     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10526     lstrcatA(keypath, usersid);
10527     lstrcatA(keypath, "\\Patches\\");
10528     lstrcatA(keypath, patch_squashed);
10529
10530     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10531     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10532
10533     /* UserData Patches key exists */
10534     size = MAX_PATH;
10535     lstrcpyA(val, "apple");
10536     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10537                             MSIINSTALLCONTEXT_USERUNMANAGED,
10538                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10539     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10540     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10541     ok(size == 0, "Expected 0, got %d\n", size);
10542
10543     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10544                          (const BYTE *)"pack", 5);
10545     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10546
10547     /* LocalPatch value exists */
10548     size = MAX_PATH;
10549     lstrcpyA(val, "apple");
10550     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10551                             MSIINSTALLCONTEXT_USERUNMANAGED,
10552                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10553     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10554     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10555     ok(size == 4, "Expected 4, got %d\n", size);
10556
10557     size = MAX_PATH;
10558     lstrcpyA(val, "apple");
10559     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10560                             MSIINSTALLCONTEXT_USERUNMANAGED,
10561                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10562     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10563     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10564     ok(size == 10, "Expected 10, got %d\n", size);
10565
10566     RegDeleteValueA(prodpatches, patch_squashed);
10567     RegDeleteKeyA(prodpatches, "");
10568     RegCloseKey(prodpatches);
10569     RegDeleteKeyA(prodkey, "");
10570     RegCloseKey(prodkey);
10571
10572     /* UserData is sufficient for all properties
10573      * except INSTALLPROPERTY_TRANSFORMS
10574      */
10575     size = MAX_PATH;
10576     lstrcpyA(val, "apple");
10577     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10578                             MSIINSTALLCONTEXT_USERUNMANAGED,
10579                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10580     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10581     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10582     ok(size == 4, "Expected 4, got %d\n", size);
10583
10584     /* UserData is sufficient for all properties
10585      * except INSTALLPROPERTY_TRANSFORMS
10586      */
10587     size = MAX_PATH;
10588     lstrcpyA(val, "apple");
10589     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10590                             MSIINSTALLCONTEXT_USERUNMANAGED,
10591                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10592     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10593     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10594     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10595
10596     RegDeleteValueA(udpatch, "LocalPackage");
10597     RegDeleteKeyA(udpatch, "");
10598     RegCloseKey(udpatch);
10599     RegDeleteKeyA(hpatch, "");
10600     RegCloseKey(hpatch);
10601     RegDeleteKeyA(patches, "");
10602     RegCloseKey(patches);
10603     RegDeleteKeyA(props, "");
10604     RegCloseKey(props);
10605     RegDeleteKeyA(udprod, "");
10606     RegCloseKey(udprod);
10607
10608     /* MSIINSTALLCONTEXT_MACHINE */
10609
10610     size = MAX_PATH;
10611     lstrcpyA(val, "apple");
10612     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10613                             MSIINSTALLCONTEXT_MACHINE,
10614                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10615     ok(r == ERROR_UNKNOWN_PRODUCT,
10616        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10617     ok(!lstrcmpA(val, "apple"),
10618        "Expected val to be unchanged, got \"%s\"\n", val);
10619     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10620
10621     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10622     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10623     lstrcatA(keypath, prod_squashed);
10624
10625     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10626     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10627
10628     /* local UserData product key exists */
10629     size = MAX_PATH;
10630     lstrcpyA(val, "apple");
10631     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10632                             MSIINSTALLCONTEXT_MACHINE,
10633                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10634     ok(r == ERROR_UNKNOWN_PRODUCT,
10635        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10636     ok(!lstrcmpA(val, "apple"),
10637        "Expected val to be unchanged, got \"%s\"\n", val);
10638     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10639
10640     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10642
10643     /* InstallProperties key exists */
10644     size = MAX_PATH;
10645     lstrcpyA(val, "apple");
10646     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10647                             MSIINSTALLCONTEXT_MACHINE,
10648                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10649     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10650     ok(!lstrcmpA(val, "apple"),
10651        "Expected val to be unchanged, got \"%s\"\n", val);
10652     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10653
10654     res = RegCreateKeyA(udprod, "Patches", &patches);
10655     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10656
10657     /* Patches key exists */
10658     size = MAX_PATH;
10659     lstrcpyA(val, "apple");
10660     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10661                             MSIINSTALLCONTEXT_MACHINE,
10662                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10663     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10664     ok(!lstrcmpA(val, "apple"),
10665        "Expected val to be unchanged, got \"%s\"\n", val);
10666     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10667
10668     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10669     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10670
10671     /* Patches key exists */
10672     size = MAX_PATH;
10673     lstrcpyA(val, "apple");
10674     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10675                             MSIINSTALLCONTEXT_MACHINE,
10676                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10677     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10678     ok(!lstrcmpA(val, "apple"),
10679        "Expected val to be unchanged, got \"%s\"\n", val);
10680     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10681
10682     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10683     lstrcatA(keypath, prod_squashed);
10684
10685     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10687
10688     /* local product key exists */
10689     size = MAX_PATH;
10690     lstrcpyA(val, "apple");
10691     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10692                             MSIINSTALLCONTEXT_MACHINE,
10693                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10694     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10695     ok(!lstrcmpA(val, "apple"),
10696        "Expected val to be unchanged, got \"%s\"\n", val);
10697     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10698
10699     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10700     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10701
10702     /* Patches key exists */
10703     size = MAX_PATH;
10704     lstrcpyA(val, "apple");
10705     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10706                             MSIINSTALLCONTEXT_MACHINE,
10707                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10708     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10709     ok(!lstrcmpA(val, "apple"),
10710        "Expected val to be unchanged, got \"%s\"\n", val);
10711     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10712
10713     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10714                          (const BYTE *)"transforms", 11);
10715     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10716
10717     /* specific patch value exists */
10718     size = MAX_PATH;
10719     lstrcpyA(val, "apple");
10720     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10721                             MSIINSTALLCONTEXT_MACHINE,
10722                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10723     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10724     ok(!lstrcmpA(val, "apple"),
10725        "Expected val to be unchanged, got \"%s\"\n", val);
10726     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10727
10728     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10729     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
10730     lstrcatA(keypath, patch_squashed);
10731
10732     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10733     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10734
10735     /* UserData Patches key exists */
10736     size = MAX_PATH;
10737     lstrcpyA(val, "apple");
10738     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10739                             MSIINSTALLCONTEXT_MACHINE,
10740                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10741     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10742     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10743     ok(size == 0, "Expected 0, got %d\n", size);
10744
10745     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10746                          (const BYTE *)"pack", 5);
10747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10748
10749     /* LocalPatch value exists */
10750     size = MAX_PATH;
10751     lstrcpyA(val, "apple");
10752     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10753                             MSIINSTALLCONTEXT_MACHINE,
10754                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10755     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10756     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10757     ok(size == 4, "Expected 4, got %d\n", size);
10758
10759     size = MAX_PATH;
10760     lstrcpyA(val, "apple");
10761     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10762                             MSIINSTALLCONTEXT_MACHINE,
10763                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10764     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10765     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10766     ok(size == 10, "Expected 10, got %d\n", size);
10767
10768     RegDeleteValueA(prodpatches, patch_squashed);
10769     RegDeleteKeyA(prodpatches, "");
10770     RegCloseKey(prodpatches);
10771     RegDeleteKeyA(prodkey, "");
10772     RegCloseKey(prodkey);
10773
10774     /* UserData is sufficient for all properties
10775      * except INSTALLPROPERTY_TRANSFORMS
10776      */
10777     size = MAX_PATH;
10778     lstrcpyA(val, "apple");
10779     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10780                             MSIINSTALLCONTEXT_MACHINE,
10781                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10782     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10783     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10784     ok(size == 4, "Expected 4, got %d\n", size);
10785
10786     /* UserData is sufficient for all properties
10787      * except INSTALLPROPERTY_TRANSFORMS
10788      */
10789     size = MAX_PATH;
10790     lstrcpyA(val, "apple");
10791     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10792                             MSIINSTALLCONTEXT_MACHINE,
10793                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10794     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10795     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10796     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10797
10798     RegDeleteValueA(udpatch, "LocalPackage");
10799     RegDeleteKeyA(udpatch, "");
10800     RegCloseKey(udpatch);
10801     RegDeleteKeyA(hpatch, "");
10802     RegCloseKey(hpatch);
10803     RegDeleteKeyA(patches, "");
10804     RegCloseKey(patches);
10805     RegDeleteKeyA(props, "");
10806     RegCloseKey(props);
10807     RegDeleteKeyA(udprod, "");
10808     RegCloseKey(udprod);
10809 }
10810
10811 START_TEST(msi)
10812 {
10813     init_functionpointers();
10814
10815     test_usefeature();
10816     test_null();
10817     test_getcomponentpath();
10818     test_MsiGetFileHash();
10819
10820     if (!pConvertSidToStringSidA)
10821         skip("ConvertSidToStringSidA not implemented\n");
10822     else
10823     {
10824         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
10825         test_MsiQueryProductState();
10826         test_MsiQueryFeatureState();
10827         test_MsiQueryComponentState();
10828         test_MsiGetComponentPath();
10829         test_MsiGetProductCode();
10830         test_MsiEnumClients();
10831         test_MsiGetProductInfo();
10832         test_MsiGetProductInfoEx();
10833         test_MsiGetUserInfo();
10834         test_MsiOpenProduct();
10835         test_MsiEnumPatchesEx();
10836         test_MsiEnumPatches();
10837         test_MsiGetPatchInfoEx();
10838     }
10839
10840     test_MsiGetFileVersion();
10841 }