msi: Add more tests for the Installer.OpenPackage method.
[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         win_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         win_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     DWORD size;
520     PTOKEN_USER user;
521
522     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
523
524     size = 0;
525     GetTokenInformation(token, TokenUser, NULL, size, &size);
526     user = HeapAlloc(GetProcessHeap(), 0, size);
527
528     GetTokenInformation(token, TokenUser, user, size, &size);
529     pConvertSidToStringSidA(user->User.Sid, usersid);
530
531     HeapFree(GetProcessHeap(), 0, user);
532     CloseHandle(token);
533 }
534
535 static void test_MsiQueryProductState(void)
536 {
537     CHAR prodcode[MAX_PATH];
538     CHAR prod_squashed[MAX_PATH];
539     CHAR keypath[MAX_PATH*2];
540     LPSTR usersid;
541     INSTALLSTATE state;
542     LONG res;
543     HKEY userkey, localkey, props;
544     HKEY prodkey;
545     DWORD data;
546
547     create_test_guid(prodcode, prod_squashed);
548     get_user_sid(&usersid);
549
550     /* NULL prodcode */
551     state = MsiQueryProductStateA(NULL);
552     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
553
554     /* empty prodcode */
555     state = MsiQueryProductStateA("");
556     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
557
558     /* garbage prodcode */
559     state = MsiQueryProductStateA("garbage");
560     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
561
562     /* guid without brackets */
563     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
564     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
565
566     /* guid with brackets */
567     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
568     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
569
570     /* same length as guid, but random */
571     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
572     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
573
574     /* MSIINSTALLCONTEXT_USERUNMANAGED */
575
576     state = MsiQueryProductStateA(prodcode);
577     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
578
579     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
580     lstrcatA(keypath, prod_squashed);
581
582     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
583     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
584
585     /* user product key exists */
586     state = MsiQueryProductStateA(prodcode);
587     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
588
589     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
590     lstrcatA(keypath, prodcode);
591
592     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
594
595     /* local uninstall key exists */
596     state = MsiQueryProductStateA(prodcode);
597     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
598
599     data = 1;
600     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
602
603     /* WindowsInstaller value exists */
604     state = MsiQueryProductStateA(prodcode);
605     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
606
607     RegDeleteValueA(localkey, "WindowsInstaller");
608     RegDeleteKeyA(localkey, "");
609
610     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
611     lstrcatA(keypath, usersid);
612     lstrcatA(keypath, "\\Products\\");
613     lstrcatA(keypath, prod_squashed);
614
615     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
616     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
617
618     /* local product key exists */
619     state = MsiQueryProductStateA(prodcode);
620     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
621
622     res = RegCreateKeyA(localkey, "InstallProperties", &props);
623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
624
625     /* install properties key exists */
626     state = MsiQueryProductStateA(prodcode);
627     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
628
629     data = 1;
630     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
631     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
632
633     /* WindowsInstaller value exists */
634     state = MsiQueryProductStateA(prodcode);
635     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
636
637     data = 2;
638     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
639     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
640
641     /* WindowsInstaller value is not 1 */
642     state = MsiQueryProductStateA(prodcode);
643     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
644
645     RegDeleteKeyA(userkey, "");
646
647     /* user product key does not exist */
648     state = MsiQueryProductStateA(prodcode);
649     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
650
651     RegDeleteValueA(props, "WindowsInstaller");
652     RegDeleteKeyA(props, "");
653     RegCloseKey(props);
654     RegDeleteKeyA(localkey, "");
655     RegCloseKey(localkey);
656     RegDeleteKeyA(userkey, "");
657     RegCloseKey(userkey);
658
659     /* MSIINSTALLCONTEXT_USERMANAGED */
660
661     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
662     lstrcatA(keypath, usersid);
663     lstrcatA(keypath, "\\Installer\\Products\\");
664     lstrcatA(keypath, prod_squashed);
665
666     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
668
669     state = MsiQueryProductStateA(prodcode);
670     ok(state == INSTALLSTATE_ADVERTISED,
671        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
672
673     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
674     lstrcatA(keypath, usersid);
675     lstrcatA(keypath, "\\Products\\");
676     lstrcatA(keypath, prod_squashed);
677
678     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
680
681     state = MsiQueryProductStateA(prodcode);
682     ok(state == INSTALLSTATE_ADVERTISED,
683        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
684
685     res = RegCreateKeyA(localkey, "InstallProperties", &props);
686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
687
688     state = MsiQueryProductStateA(prodcode);
689     ok(state == INSTALLSTATE_ADVERTISED,
690        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
691
692     data = 1;
693     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
694     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
695
696     /* WindowsInstaller value exists */
697     state = MsiQueryProductStateA(prodcode);
698     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
699
700     RegDeleteValueA(props, "WindowsInstaller");
701     RegDeleteKeyA(props, "");
702     RegCloseKey(props);
703     RegDeleteKeyA(localkey, "");
704     RegCloseKey(localkey);
705     RegDeleteKeyA(prodkey, "");
706     RegCloseKey(prodkey);
707
708     /* MSIINSTALLCONTEXT_MACHINE */
709
710     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
711     lstrcatA(keypath, prod_squashed);
712
713     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
714     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
715
716     state = MsiQueryProductStateA(prodcode);
717     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
718
719     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
720     lstrcatA(keypath, "S-1-5-18\\Products\\");
721     lstrcatA(keypath, prod_squashed);
722
723     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
724     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
725
726     state = MsiQueryProductStateA(prodcode);
727     ok(state == INSTALLSTATE_ADVERTISED,
728        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
729
730     res = RegCreateKeyA(localkey, "InstallProperties", &props);
731     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
732
733     state = MsiQueryProductStateA(prodcode);
734     ok(state == INSTALLSTATE_ADVERTISED,
735        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
736
737     data = 1;
738     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
739     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
740
741     /* WindowsInstaller value exists */
742     state = MsiQueryProductStateA(prodcode);
743     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
744
745     RegDeleteValueA(props, "WindowsInstaller");
746     RegDeleteKeyA(props, "");
747     RegCloseKey(props);
748     RegDeleteKeyA(localkey, "");
749     RegCloseKey(localkey);
750     RegDeleteKeyA(prodkey, "");
751     RegCloseKey(prodkey);
752
753     LocalFree(usersid);
754 }
755
756 static const char table_enc85[] =
757 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
758 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
759 "yz{}~";
760
761 /*
762  *  Encodes a base85 guid given a GUID pointer
763  *  Caller should provide a 21 character buffer for the encoded string.
764  */
765 static void encode_base85_guid( GUID *guid, LPWSTR str )
766 {
767     unsigned int x, *p, i;
768
769     p = (unsigned int*) guid;
770     for( i=0; i<4; i++ )
771     {
772         x = p[i];
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         x = x/85;
781         *str++ = table_enc85[x%85];
782     }
783     *str = 0;
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, compkey2;
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], comp_squashed2[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     compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
824     get_user_sid(&usersid);
825
826     /* NULL prodcode */
827     state = MsiQueryFeatureStateA(NULL, "feature");
828     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
829
830     /* empty prodcode */
831     state = MsiQueryFeatureStateA("", "feature");
832     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
833
834     /* garbage prodcode */
835     state = MsiQueryFeatureStateA("garbage", "feature");
836     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
837
838     /* guid without brackets */
839     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
840     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
841
842     /* guid with brackets */
843     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
844     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
845
846     /* same length as guid, but random */
847     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
848     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
849
850     /* NULL szFeature */
851     state = MsiQueryFeatureStateA(prodcode, NULL);
852     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
853
854     /* empty szFeature */
855     state = MsiQueryFeatureStateA(prodcode, "");
856     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
857
858     /* feature key does not exist yet */
859     state = MsiQueryFeatureStateA(prodcode, "feature");
860     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
861
862     /* MSIINSTALLCONTEXT_USERUNMANAGED */
863
864     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
865     lstrcatA(keypath, prod_squashed);
866
867     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
868     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
869
870     /* feature key exists */
871     state = MsiQueryFeatureStateA(prodcode, "feature");
872     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
873
874     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
875     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
876
877     /* feature value exists */
878     state = MsiQueryFeatureStateA(prodcode, "feature");
879     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
880
881     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
882     lstrcatA(keypath, usersid);
883     lstrcatA(keypath, "\\Products\\");
884     lstrcatA(keypath, prod_squashed);
885     lstrcatA(keypath, "\\Features");
886
887     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
889
890     /* userdata features key exists */
891     state = MsiQueryFeatureStateA(prodcode, "feature");
892     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
893
894     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
895     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
896
897     state = MsiQueryFeatureStateA(prodcode, "feature");
898     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
899
900     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
901     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
902
903     state = MsiQueryFeatureStateA(prodcode, "feature");
904     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
905
906     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
907     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
908
909     state = MsiQueryFeatureStateA(prodcode, "feature");
910     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
911
912     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
913     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
914
915     state = MsiQueryFeatureStateA(prodcode, "feature");
916     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
917
918     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
919     lstrcatA(keypath, usersid);
920     lstrcatA(keypath, "\\Components\\");
921     lstrcatA(keypath, comp_squashed);
922
923     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
924     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
925
926     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
927     lstrcatA(keypath, usersid);
928     lstrcatA(keypath, "\\Components\\");
929     lstrcatA(keypath, comp_squashed2);
930
931     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2);
932     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
933
934     state = MsiQueryFeatureStateA(prodcode, "feature");
935     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
936
937     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
938     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
939
940     state = MsiQueryFeatureStateA(prodcode, "feature");
941     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
942
943     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
945
946     state = MsiQueryFeatureStateA(prodcode, "feature");
947     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
948
949     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
951
952     /* INSTALLSTATE_LOCAL */
953     state = MsiQueryFeatureStateA(prodcode, "feature");
954     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
955
956     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
958
959     /* INSTALLSTATE_SOURCE */
960     state = MsiQueryFeatureStateA(prodcode, "feature");
961     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
962
963     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
965
966     /* bad INSTALLSTATE_SOURCE */
967     state = MsiQueryFeatureStateA(prodcode, "feature");
968     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
969
970     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
972
973     /* INSTALLSTATE_SOURCE */
974     state = MsiQueryFeatureStateA(prodcode, "feature");
975     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
976
977     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
978     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
979
980     /* bad INSTALLSTATE_SOURCE */
981     state = MsiQueryFeatureStateA(prodcode, "feature");
982     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
983
984     RegDeleteValueA(compkey, prod_squashed);
985     RegDeleteValueA(compkey2, prod_squashed);
986     RegDeleteKeyA(compkey, "");
987     RegDeleteKeyA(compkey2, "");
988     RegDeleteValueA(localkey, "feature");
989     RegDeleteValueA(userkey, "feature");
990     RegDeleteKeyA(userkey, "");
991     RegCloseKey(compkey);
992     RegCloseKey(compkey2);
993     RegCloseKey(localkey);
994     RegCloseKey(userkey);
995
996     /* MSIINSTALLCONTEXT_USERMANAGED */
997
998     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
999     lstrcatA(keypath, usersid);
1000     lstrcatA(keypath, "\\Installer\\Features\\");
1001     lstrcatA(keypath, prod_squashed);
1002
1003     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
1004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1005
1006     /* feature key exists */
1007     state = MsiQueryFeatureStateA(prodcode, "feature");
1008     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1009
1010     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1012
1013     /* feature value exists */
1014     state = MsiQueryFeatureStateA(prodcode, "feature");
1015     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1016
1017     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1018     lstrcatA(keypath, usersid);
1019     lstrcatA(keypath, "\\Products\\");
1020     lstrcatA(keypath, prod_squashed);
1021     lstrcatA(keypath, "\\Features");
1022
1023     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1025
1026     /* userdata features key exists */
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 *)"aaaaaaaaaaaaaaaaaaa", 20);
1031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1032
1033     state = MsiQueryFeatureStateA(prodcode, "feature");
1034     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1035
1036     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1037     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1038
1039     state = MsiQueryFeatureStateA(prodcode, "feature");
1040     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1041
1042     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1044
1045     state = MsiQueryFeatureStateA(prodcode, "feature");
1046     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1047
1048     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1049     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1050
1051     state = MsiQueryFeatureStateA(prodcode, "feature");
1052     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1053
1054     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1055     lstrcatA(keypath, usersid);
1056     lstrcatA(keypath, "\\Components\\");
1057     lstrcatA(keypath, comp_squashed);
1058
1059     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1061
1062     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1063     lstrcatA(keypath, usersid);
1064     lstrcatA(keypath, "\\Components\\");
1065     lstrcatA(keypath, comp_squashed2);
1066
1067     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2);
1068     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1069
1070     state = MsiQueryFeatureStateA(prodcode, "feature");
1071     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1072
1073     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1074     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1075
1076     state = MsiQueryFeatureStateA(prodcode, "feature");
1077     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1078
1079     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1081
1082     state = MsiQueryFeatureStateA(prodcode, "feature");
1083     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1084
1085     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1087
1088     state = MsiQueryFeatureStateA(prodcode, "feature");
1089     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1090
1091     RegDeleteValueA(compkey, prod_squashed);
1092     RegDeleteValueA(compkey2, prod_squashed);
1093     RegDeleteKeyA(compkey, "");
1094     RegDeleteKeyA(compkey2, "");
1095     RegDeleteValueA(localkey, "feature");
1096     RegDeleteValueA(userkey, "feature");
1097     RegDeleteKeyA(userkey, "");
1098     RegCloseKey(compkey);
1099     RegCloseKey(compkey2);
1100     RegCloseKey(localkey);
1101     RegCloseKey(userkey);
1102
1103     /* MSIINSTALLCONTEXT_MACHINE */
1104
1105     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1106     lstrcatA(keypath, prod_squashed);
1107
1108     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
1109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1110
1111     /* feature key exists */
1112     state = MsiQueryFeatureStateA(prodcode, "feature");
1113     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1114
1115     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1117
1118     /* feature value exists */
1119     state = MsiQueryFeatureStateA(prodcode, "feature");
1120     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1121
1122     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1123     lstrcatA(keypath, "S-1-5-18\\Products\\");
1124     lstrcatA(keypath, prod_squashed);
1125     lstrcatA(keypath, "\\Features");
1126
1127     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1129
1130     /* userdata features key exists */
1131     state = MsiQueryFeatureStateA(prodcode, "feature");
1132     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1133
1134     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1136
1137     state = MsiQueryFeatureStateA(prodcode, "feature");
1138     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1139
1140     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1142
1143     state = MsiQueryFeatureStateA(prodcode, "feature");
1144     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1145
1146     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1148
1149     state = MsiQueryFeatureStateA(prodcode, "feature");
1150     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1151
1152     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1153     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1154
1155     state = MsiQueryFeatureStateA(prodcode, "feature");
1156     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1157
1158     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1159     lstrcatA(keypath, "S-1-5-18\\Components\\");
1160     lstrcatA(keypath, comp_squashed);
1161
1162     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1163     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1164
1165     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1166     lstrcatA(keypath, "S-1-5-18\\Components\\");
1167     lstrcatA(keypath, comp_squashed2);
1168
1169     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2);
1170     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1171
1172     state = MsiQueryFeatureStateA(prodcode, "feature");
1173     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1174
1175     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1176     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1177
1178     state = MsiQueryFeatureStateA(prodcode, "feature");
1179     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1180
1181     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1183
1184     state = MsiQueryFeatureStateA(prodcode, "feature");
1185     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1186
1187     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1189
1190     state = MsiQueryFeatureStateA(prodcode, "feature");
1191     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1192
1193     RegDeleteValueA(compkey, prod_squashed);
1194     RegDeleteValueA(compkey2, prod_squashed);
1195     RegDeleteKeyA(compkey, "");
1196     RegDeleteKeyA(compkey2, "");
1197     RegDeleteValueA(localkey, "feature");
1198     RegDeleteValueA(userkey, "feature");
1199     RegDeleteKeyA(userkey, "");
1200     RegCloseKey(compkey);
1201     RegCloseKey(compkey2);
1202     RegCloseKey(localkey);
1203     RegCloseKey(userkey);
1204     LocalFree(usersid);
1205 }
1206
1207 static void test_MsiQueryComponentState(void)
1208 {
1209     HKEY compkey, prodkey;
1210     CHAR prodcode[MAX_PATH];
1211     CHAR prod_squashed[MAX_PATH];
1212     CHAR component[MAX_PATH];
1213     CHAR comp_base85[MAX_PATH];
1214     CHAR comp_squashed[MAX_PATH];
1215     CHAR keypath[MAX_PATH];
1216     INSTALLSTATE state;
1217     LPSTR usersid;
1218     LONG res;
1219     UINT r;
1220
1221     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1222
1223     if (!pMsiQueryComponentStateA)
1224     {
1225         win_skip("MsiQueryComponentStateA not implemented\n");
1226         return;
1227     }
1228
1229     create_test_guid(prodcode, prod_squashed);
1230     compose_base85_guid(component, comp_base85, comp_squashed);
1231     get_user_sid(&usersid);
1232
1233     /* NULL szProductCode */
1234     state = MAGIC_ERROR;
1235     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1236     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1237     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1238
1239     /* empty szProductCode */
1240     state = MAGIC_ERROR;
1241     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1242     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1243     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1244
1245     /* random szProductCode */
1246     state = MAGIC_ERROR;
1247     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1248     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1249     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1250
1251     /* GUID-length szProductCode */
1252     state = MAGIC_ERROR;
1253     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1254     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1255     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1256
1257     /* GUID-length with brackets */
1258     state = MAGIC_ERROR;
1259     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1260     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1261     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1262
1263     /* actual GUID */
1264     state = MAGIC_ERROR;
1265     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1266     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1267     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1268
1269     state = MAGIC_ERROR;
1270     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1271     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1272     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1273
1274     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1275     lstrcatA(keypath, prod_squashed);
1276
1277     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1279
1280     state = MAGIC_ERROR;
1281     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1282     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1283     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1284
1285     RegDeleteKeyA(prodkey, "");
1286     RegCloseKey(prodkey);
1287
1288     /* create local system product key */
1289     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1290     lstrcatA(keypath, prod_squashed);
1291     lstrcatA(keypath, "\\InstallProperties");
1292
1293     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1294     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1295
1296     /* local system product key exists */
1297     state = MAGIC_ERROR;
1298     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1299     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1300     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1301
1302     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1304
1305     /* LocalPackage value exists */
1306     state = MAGIC_ERROR;
1307     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1308     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1309     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1310
1311     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1312     lstrcatA(keypath, comp_squashed);
1313
1314     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1315     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1316
1317     /* component key exists */
1318     state = MAGIC_ERROR;
1319     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1320     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1321     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1322
1323     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1325
1326     /* component\product exists */
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_NOTUSED || state == INSTALLSTATE_LOCAL,
1331        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1332
1333     /* NULL component, product exists */
1334     state = MAGIC_ERROR;
1335     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1336     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1337     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1338
1339     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1340     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1341
1342     /* INSTALLSTATE_LOCAL */
1343     state = MAGIC_ERROR;
1344     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1345     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1346     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1347
1348     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1349     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1350
1351     /* INSTALLSTATE_SOURCE */
1352     state = MAGIC_ERROR;
1353     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1355     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1356
1357     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1358     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1359
1360     /* bad INSTALLSTATE_SOURCE */
1361     state = MAGIC_ERROR;
1362     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1364     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1365
1366     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1368
1369     /* INSTALLSTATE_SOURCE */
1370     state = MAGIC_ERROR;
1371     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1372     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1373     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1374
1375     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1377
1378     /* bad INSTALLSTATE_SOURCE */
1379     state = MAGIC_ERROR;
1380     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1381     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1382     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1383
1384     RegDeleteValueA(prodkey, "LocalPackage");
1385     RegDeleteKeyA(prodkey, "");
1386     RegDeleteValueA(compkey, prod_squashed);
1387     RegDeleteKeyA(prodkey, "");
1388     RegCloseKey(prodkey);
1389     RegCloseKey(compkey);
1390
1391     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1392
1393     state = MAGIC_ERROR;
1394     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1395     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1396     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1397
1398     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1399     lstrcatA(keypath, prod_squashed);
1400
1401     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1403
1404     state = MAGIC_ERROR;
1405     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1406     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1407     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1408
1409     RegDeleteKeyA(prodkey, "");
1410     RegCloseKey(prodkey);
1411
1412     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1413     lstrcatA(keypath, usersid);
1414     lstrcatA(keypath, "\\Products\\");
1415     lstrcatA(keypath, prod_squashed);
1416     lstrcatA(keypath, "\\InstallProperties");
1417
1418     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1419     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1420
1421     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1423
1424     RegCloseKey(prodkey);
1425
1426     state = MAGIC_ERROR;
1427     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1428     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1429     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1430
1431     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1432     lstrcatA(keypath, usersid);
1433     lstrcatA(keypath, "\\Components\\");
1434     lstrcatA(keypath, comp_squashed);
1435
1436     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1437     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1438
1439     /* component key exists */
1440     state = MAGIC_ERROR;
1441     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, 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     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1447
1448     /* component\product exists */
1449     state = MAGIC_ERROR;
1450     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1452     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1453        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1454
1455     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1457
1458     state = MAGIC_ERROR;
1459     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1460     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1461     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1462
1463     /* MSIINSTALLCONTEXT_USERMANAGED */
1464
1465     state = MAGIC_ERROR;
1466     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1467     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1468     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1469
1470     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1471     lstrcatA(keypath, prod_squashed);
1472
1473     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1474     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1475
1476     state = MAGIC_ERROR;
1477     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1478     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1479     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1480
1481     RegDeleteKeyA(prodkey, "");
1482     RegCloseKey(prodkey);
1483
1484     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1485     lstrcatA(keypath, usersid);
1486     lstrcatA(keypath, "\\Installer\\Products\\");
1487     lstrcatA(keypath, prod_squashed);
1488
1489     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1490     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1491
1492     state = MAGIC_ERROR;
1493     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1494     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1495     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1496
1497     RegDeleteKeyA(prodkey, "");
1498     RegCloseKey(prodkey);
1499
1500     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1501     lstrcatA(keypath, usersid);
1502     lstrcatA(keypath, "\\Products\\");
1503     lstrcatA(keypath, prod_squashed);
1504     lstrcatA(keypath, "\\InstallProperties");
1505
1506     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1507     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1508
1509     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1510     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1511
1512     state = MAGIC_ERROR;
1513     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1514     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1515     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1516
1517     RegDeleteValueA(prodkey, "LocalPackage");
1518     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1519     RegDeleteKeyA(prodkey, "");
1520     RegDeleteValueA(compkey, prod_squashed);
1521     RegDeleteKeyA(compkey, "");
1522     RegCloseKey(prodkey);
1523     RegCloseKey(compkey);
1524     LocalFree(usersid);
1525 }
1526
1527 static void test_MsiGetComponentPath(void)
1528 {
1529     HKEY compkey, prodkey, installprop;
1530     CHAR prodcode[MAX_PATH];
1531     CHAR prod_squashed[MAX_PATH];
1532     CHAR component[MAX_PATH];
1533     CHAR comp_base85[MAX_PATH];
1534     CHAR comp_squashed[MAX_PATH];
1535     CHAR keypath[MAX_PATH];
1536     CHAR path[MAX_PATH];
1537     INSTALLSTATE state;
1538     LPSTR usersid;
1539     DWORD size, val;
1540     LONG res;
1541
1542     create_test_guid(prodcode, prod_squashed);
1543     compose_base85_guid(component, comp_base85, comp_squashed);
1544     get_user_sid(&usersid);
1545
1546     /* NULL szProduct */
1547     size = MAX_PATH;
1548     state = MsiGetComponentPathA(NULL, component, path, &size);
1549     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1550     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1551
1552     /* NULL szComponent */
1553     size = MAX_PATH;
1554     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1555     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1556     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1557
1558     /* NULL lpPathBuf */
1559     size = MAX_PATH;
1560     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1561     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1562     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1563
1564     /* NULL pcchBuf */
1565     size = MAX_PATH;
1566     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1567     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1568     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1569
1570     /* all params valid */
1571     size = MAX_PATH;
1572     state = MsiGetComponentPathA(prodcode, component, path, &size);
1573     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1574     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1575
1576     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1577     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1578     lstrcatA(keypath, comp_squashed);
1579
1580     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1581     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1582
1583     /* local system component key exists */
1584     size = MAX_PATH;
1585     state = MsiGetComponentPathA(prodcode, component, path, &size);
1586     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1587     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1588
1589     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1590     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1591
1592     /* product value exists */
1593     size = MAX_PATH;
1594     state = MsiGetComponentPathA(prodcode, component, path, &size);
1595     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1596     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1597     ok(size == 10, "Expected 10, got %d\n", size);
1598
1599     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1600     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1601     lstrcatA(keypath, prod_squashed);
1602     lstrcatA(keypath, "\\InstallProperties");
1603
1604     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1605     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1606
1607     val = 1;
1608     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1609     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1610
1611     /* install properties key exists */
1612     size = MAX_PATH;
1613     state = MsiGetComponentPathA(prodcode, component, path, &size);
1614     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1615     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1616     ok(size == 10, "Expected 10, got %d\n", size);
1617
1618     create_file("C:\\imapath", "C:\\imapath", 11);
1619
1620     /* file exists */
1621     size = MAX_PATH;
1622     state = MsiGetComponentPathA(prodcode, component, path, &size);
1623     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1624     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1625     ok(size == 10, "Expected 10, got %d\n", size);
1626
1627     RegDeleteValueA(compkey, prod_squashed);
1628     RegDeleteKeyA(compkey, "");
1629     RegDeleteValueA(installprop, "WindowsInstaller");
1630     RegDeleteKeyA(installprop, "");
1631     RegCloseKey(compkey);
1632     RegCloseKey(installprop);
1633     DeleteFileA("C:\\imapath");
1634
1635     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1636     lstrcatA(keypath, "Installer\\UserData\\");
1637     lstrcatA(keypath, usersid);
1638     lstrcatA(keypath, "\\Components\\");
1639     lstrcatA(keypath, comp_squashed);
1640
1641     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1643
1644     /* user managed component key exists */
1645     size = MAX_PATH;
1646     state = MsiGetComponentPathA(prodcode, component, path, &size);
1647     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1648     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1649
1650     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1651     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1652
1653     /* product value exists */
1654     size = MAX_PATH;
1655     state = MsiGetComponentPathA(prodcode, component, path, &size);
1656     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1657     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1658     ok(size == 10, "Expected 10, got %d\n", size);
1659
1660     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1661     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1662     lstrcatA(keypath, prod_squashed);
1663     lstrcatA(keypath, "\\InstallProperties");
1664
1665     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1667
1668     val = 1;
1669     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1670     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1671
1672     /* install properties key exists */
1673     size = MAX_PATH;
1674     state = MsiGetComponentPathA(prodcode, component, path, &size);
1675     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1676     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1677     ok(size == 10, "Expected 10, got %d\n", size);
1678
1679     create_file("C:\\imapath", "C:\\imapath", 11);
1680
1681     /* file exists */
1682     size = MAX_PATH;
1683     state = MsiGetComponentPathA(prodcode, component, path, &size);
1684     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1685     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1686     ok(size == 10, "Expected 10, got %d\n", size);
1687
1688     RegDeleteValueA(compkey, prod_squashed);
1689     RegDeleteKeyA(compkey, "");
1690     RegDeleteValueA(installprop, "WindowsInstaller");
1691     RegDeleteKeyA(installprop, "");
1692     RegCloseKey(compkey);
1693     RegCloseKey(installprop);
1694     DeleteFileA("C:\\imapath");
1695
1696     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1697     lstrcatA(keypath, "Installer\\Managed\\");
1698     lstrcatA(keypath, usersid);
1699     lstrcatA(keypath, "\\Installer\\Products\\");
1700     lstrcatA(keypath, prod_squashed);
1701
1702     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1703     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1704
1705     /* user managed product key exists */
1706     size = MAX_PATH;
1707     state = MsiGetComponentPathA(prodcode, component, path, &size);
1708     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1709     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1710
1711     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1712     lstrcatA(keypath, "Installer\\UserData\\");
1713     lstrcatA(keypath, usersid);
1714     lstrcatA(keypath, "\\Components\\");
1715     lstrcatA(keypath, comp_squashed);
1716
1717     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1718     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1719
1720     /* user managed component key exists */
1721     size = MAX_PATH;
1722     state = MsiGetComponentPathA(prodcode, component, path, &size);
1723     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1724     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1725
1726     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1728
1729     /* product value exists */
1730     size = MAX_PATH;
1731     state = MsiGetComponentPathA(prodcode, component, path, &size);
1732     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1733     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1734     ok(size == 10, "Expected 10, got %d\n", size);
1735
1736     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1737     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1738     lstrcatA(keypath, prod_squashed);
1739     lstrcatA(keypath, "\\InstallProperties");
1740
1741     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1742     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1743
1744     val = 1;
1745     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1747
1748     /* install properties key exists */
1749     size = MAX_PATH;
1750     state = MsiGetComponentPathA(prodcode, component, path, &size);
1751     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1752     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1753     ok(size == 10, "Expected 10, got %d\n", size);
1754
1755     create_file("C:\\imapath", "C:\\imapath", 11);
1756
1757     /* file exists */
1758     size = MAX_PATH;
1759     state = MsiGetComponentPathA(prodcode, component, path, &size);
1760     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1761     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1762     ok(size == 10, "Expected 10, got %d\n", size);
1763
1764     RegDeleteValueA(compkey, prod_squashed);
1765     RegDeleteKeyA(prodkey, "");
1766     RegDeleteKeyA(compkey, "");
1767     RegDeleteValueA(installprop, "WindowsInstaller");
1768     RegDeleteKeyA(installprop, "");
1769     RegCloseKey(prodkey);
1770     RegCloseKey(compkey);
1771     RegCloseKey(installprop);
1772     DeleteFileA("C:\\imapath");
1773
1774     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1775     lstrcatA(keypath, prod_squashed);
1776
1777     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1779
1780     /* user unmanaged 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\\");
1788     lstrcatA(keypath, usersid);
1789     lstrcatA(keypath, "\\Components\\");
1790     lstrcatA(keypath, comp_squashed);
1791
1792     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1793     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1794
1795     /* user unmanaged component key exists */
1796     size = MAX_PATH;
1797     state = MsiGetComponentPathA(prodcode, component, path, &size);
1798     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1799     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1800
1801     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1803
1804     /* product value exists */
1805     size = MAX_PATH;
1806     state = MsiGetComponentPathA(prodcode, component, path, &size);
1807     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1808     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1809     ok(size == 10, "Expected 10, got %d\n", size);
1810
1811     create_file("C:\\imapath", "C:\\imapath", 11);
1812
1813     /* file exists */
1814     size = MAX_PATH;
1815     state = MsiGetComponentPathA(prodcode, component, path, &size);
1816     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1817     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1818     ok(size == 10, "Expected 10, got %d\n", size);
1819
1820     RegDeleteValueA(compkey, prod_squashed);
1821     RegDeleteKeyA(prodkey, "");
1822     RegDeleteKeyA(compkey, "");
1823     RegCloseKey(prodkey);
1824     RegCloseKey(compkey);
1825     DeleteFileA("C:\\imapath");
1826
1827     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1828     lstrcatA(keypath, prod_squashed);
1829
1830     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1831     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1832
1833     /* local classes product key exists */
1834     size = MAX_PATH;
1835     state = MsiGetComponentPathA(prodcode, component, path, &size);
1836     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1837     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1838
1839     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1840     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1841     lstrcatA(keypath, comp_squashed);
1842
1843     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1845
1846     /* local user component key exists */
1847     size = MAX_PATH;
1848     state = MsiGetComponentPathA(prodcode, component, path, &size);
1849     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1850     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1851
1852     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1854
1855     /* product value exists */
1856     size = MAX_PATH;
1857     state = MsiGetComponentPathA(prodcode, component, path, &size);
1858     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1859     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1860     ok(size == 10, "Expected 10, got %d\n", size);
1861
1862     create_file("C:\\imapath", "C:\\imapath", 11);
1863
1864     /* file exists */
1865     size = MAX_PATH;
1866     state = MsiGetComponentPathA(prodcode, component, path, &size);
1867     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1868     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1869     ok(size == 10, "Expected 10, got %d\n", size);
1870
1871     RegDeleteValueA(compkey, prod_squashed);
1872     RegDeleteKeyA(prodkey, "");
1873     RegDeleteKeyA(compkey, "");
1874     RegCloseKey(prodkey);
1875     RegCloseKey(compkey);
1876     DeleteFileA("C:\\imapath");
1877     LocalFree(usersid);
1878 }
1879
1880 static void test_MsiGetProductCode(void)
1881 {
1882     HKEY compkey, prodkey;
1883     CHAR prodcode[MAX_PATH];
1884     CHAR prod_squashed[MAX_PATH];
1885     CHAR prodcode2[MAX_PATH];
1886     CHAR prod2_squashed[MAX_PATH];
1887     CHAR component[MAX_PATH];
1888     CHAR comp_base85[MAX_PATH];
1889     CHAR comp_squashed[MAX_PATH];
1890     CHAR keypath[MAX_PATH];
1891     CHAR product[MAX_PATH];
1892     LPSTR usersid;
1893     LONG res;
1894     UINT r;
1895
1896     create_test_guid(prodcode, prod_squashed);
1897     create_test_guid(prodcode2, prod2_squashed);
1898     compose_base85_guid(component, comp_base85, comp_squashed);
1899     get_user_sid(&usersid);
1900
1901     /* szComponent is NULL */
1902     lstrcpyA(product, "prod");
1903     r = MsiGetProductCodeA(NULL, product);
1904     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1905     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1906
1907     /* szComponent is empty */
1908     lstrcpyA(product, "prod");
1909     r = MsiGetProductCodeA("", product);
1910     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1911     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1912
1913     /* garbage szComponent */
1914     lstrcpyA(product, "prod");
1915     r = MsiGetProductCodeA("garbage", product);
1916     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1917     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1918
1919     /* guid without brackets */
1920     lstrcpyA(product, "prod");
1921     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
1922     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1923     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1924
1925     /* guid with brackets */
1926     lstrcpyA(product, "prod");
1927     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
1928     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1929     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1930
1931     /* same length as guid, but random */
1932     lstrcpyA(product, "prod");
1933     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
1934     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1935     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1936
1937     /* all params correct, szComponent not published */
1938     lstrcpyA(product, "prod");
1939     r = MsiGetProductCodeA(component, product);
1940     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1941     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1942
1943     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1944     lstrcatA(keypath, "Installer\\UserData\\");
1945     lstrcatA(keypath, usersid);
1946     lstrcatA(keypath, "\\Components\\");
1947     lstrcatA(keypath, comp_squashed);
1948
1949     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1951
1952     /* user unmanaged component key exists */
1953     lstrcpyA(product, "prod");
1954     r = MsiGetProductCodeA(component, product);
1955     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1956     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1957
1958     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1959     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1960
1961     /* product value exists */
1962     lstrcpyA(product, "prod");
1963     r = MsiGetProductCodeA(component, product);
1964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1965     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1966
1967     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1968     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1969
1970     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1971     lstrcatA(keypath, "Installer\\Managed\\");
1972     lstrcatA(keypath, usersid);
1973     lstrcatA(keypath, "\\Installer\\Products\\");
1974     lstrcatA(keypath, prod_squashed);
1975
1976     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1978
1979     /* user managed product key of first product exists */
1980     lstrcpyA(product, "prod");
1981     r = MsiGetProductCodeA(component, product);
1982     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1983     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1984
1985     RegDeleteKeyA(prodkey, "");
1986     RegCloseKey(prodkey);
1987
1988     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1989     lstrcatA(keypath, prod_squashed);
1990
1991     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1993
1994     /* user unmanaged product key exists */
1995     lstrcpyA(product, "prod");
1996     r = MsiGetProductCodeA(component, product);
1997     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1998     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1999
2000     RegDeleteKeyA(prodkey, "");
2001     RegCloseKey(prodkey);
2002
2003     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2004     lstrcatA(keypath, prod_squashed);
2005
2006     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2007     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2008
2009     /* local classes product key exists */
2010     lstrcpyA(product, "prod");
2011     r = MsiGetProductCodeA(component, product);
2012     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2013     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2014
2015     RegDeleteKeyA(prodkey, "");
2016     RegCloseKey(prodkey);
2017
2018     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2019     lstrcatA(keypath, "Installer\\Managed\\");
2020     lstrcatA(keypath, usersid);
2021     lstrcatA(keypath, "\\Installer\\Products\\");
2022     lstrcatA(keypath, prod2_squashed);
2023
2024     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2026
2027     /* user managed product key of second product exists */
2028     lstrcpyA(product, "prod");
2029     r = MsiGetProductCodeA(component, product);
2030     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2031     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2032
2033     RegDeleteKeyA(prodkey, "");
2034     RegCloseKey(prodkey);
2035     RegDeleteValueA(compkey, prod_squashed);
2036     RegDeleteValueA(compkey, prod2_squashed);
2037     RegDeleteKeyA(compkey, "");
2038     RegCloseKey(compkey);
2039
2040     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2041     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2042     lstrcatA(keypath, comp_squashed);
2043
2044     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2045     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2046
2047     /* local user component key exists */
2048     lstrcpyA(product, "prod");
2049     r = MsiGetProductCodeA(component, product);
2050     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2051     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2052
2053     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2054     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2055
2056     /* product value exists */
2057     lstrcpyA(product, "prod");
2058     r = MsiGetProductCodeA(component, product);
2059     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2060     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2061
2062     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2063     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2064
2065     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2066     lstrcatA(keypath, "Installer\\Managed\\");
2067     lstrcatA(keypath, usersid);
2068     lstrcatA(keypath, "\\Installer\\Products\\");
2069     lstrcatA(keypath, prod_squashed);
2070
2071     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2073
2074     /* user managed product key of first product exists */
2075     lstrcpyA(product, "prod");
2076     r = MsiGetProductCodeA(component, product);
2077     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2078     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2079
2080     RegDeleteKeyA(prodkey, "");
2081     RegCloseKey(prodkey);
2082
2083     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2084     lstrcatA(keypath, prod_squashed);
2085
2086     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2088
2089     /* user unmanaged product key exists */
2090     lstrcpyA(product, "prod");
2091     r = MsiGetProductCodeA(component, product);
2092     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2093     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2094
2095     RegDeleteKeyA(prodkey, "");
2096     RegCloseKey(prodkey);
2097
2098     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2099     lstrcatA(keypath, prod_squashed);
2100
2101     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2102     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2103
2104     /* local classes product key exists */
2105     lstrcpyA(product, "prod");
2106     r = MsiGetProductCodeA(component, product);
2107     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2108     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2109
2110     RegDeleteKeyA(prodkey, "");
2111     RegCloseKey(prodkey);
2112
2113     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2114     lstrcatA(keypath, "Installer\\Managed\\");
2115     lstrcatA(keypath, usersid);
2116     lstrcatA(keypath, "\\Installer\\Products\\");
2117     lstrcatA(keypath, prod2_squashed);
2118
2119     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2120     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2121
2122     /* user managed product key of second product exists */
2123     lstrcpyA(product, "prod");
2124     r = MsiGetProductCodeA(component, product);
2125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2126     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2127
2128     RegDeleteKeyA(prodkey, "");
2129     RegCloseKey(prodkey);
2130     RegDeleteValueA(compkey, prod_squashed);
2131     RegDeleteValueA(compkey, prod2_squashed);
2132     RegDeleteKeyA(compkey, "");
2133     RegCloseKey(compkey);
2134     LocalFree(usersid);
2135 }
2136
2137 static void test_MsiEnumClients(void)
2138 {
2139     HKEY compkey;
2140     CHAR prodcode[MAX_PATH];
2141     CHAR prod_squashed[MAX_PATH];
2142     CHAR prodcode2[MAX_PATH];
2143     CHAR prod2_squashed[MAX_PATH];
2144     CHAR component[MAX_PATH];
2145     CHAR comp_base85[MAX_PATH];
2146     CHAR comp_squashed[MAX_PATH];
2147     CHAR product[MAX_PATH];
2148     CHAR keypath[MAX_PATH];
2149     LPSTR usersid;
2150     LONG res;
2151     UINT r;
2152
2153     create_test_guid(prodcode, prod_squashed);
2154     create_test_guid(prodcode2, prod2_squashed);
2155     compose_base85_guid(component, comp_base85, comp_squashed);
2156     get_user_sid(&usersid);
2157
2158     /* NULL szComponent */
2159     product[0] = '\0';
2160     r = MsiEnumClientsA(NULL, 0, product);
2161     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2162     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2163
2164     /* empty szComponent */
2165     product[0] = '\0';
2166     r = MsiEnumClientsA("", 0, product);
2167     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2168     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2169
2170     /* NULL lpProductBuf */
2171     r = MsiEnumClientsA(component, 0, NULL);
2172     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2173
2174     /* all params correct, component missing */
2175     product[0] = '\0';
2176     r = MsiEnumClientsA(component, 0, product);
2177     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2178     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2179
2180     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2181     lstrcatA(keypath, "Installer\\UserData\\");
2182     lstrcatA(keypath, usersid);
2183     lstrcatA(keypath, "\\Components\\");
2184     lstrcatA(keypath, comp_squashed);
2185
2186     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2188
2189     /* user unmanaged component key exists */
2190     product[0] = '\0';
2191     r = MsiEnumClientsA(component, 0, product);
2192     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2193     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2194
2195     /* index > 0, no products exist */
2196     product[0] = '\0';
2197     r = MsiEnumClientsA(component, 1, product);
2198     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2199     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2200
2201     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2203
2204     /* product value exists */
2205     r = MsiEnumClientsA(component, 0, product);
2206     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2207     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2208
2209     /* try index 0 again */
2210     product[0] = '\0';
2211     r = MsiEnumClientsA(component, 0, product);
2212     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2213     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2214
2215     /* try index 1, second product value does not exist */
2216     product[0] = '\0';
2217     r = MsiEnumClientsA(component, 1, product);
2218     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2219     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2220
2221     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2222     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2223
2224     /* try index 1, second product value does exist */
2225     product[0] = '\0';
2226     r = MsiEnumClientsA(component, 1, product);
2227     todo_wine
2228     {
2229         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2230         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2231     }
2232
2233     /* start the enumeration over */
2234     product[0] = '\0';
2235     r = MsiEnumClientsA(component, 0, product);
2236     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2237     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2238        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2239
2240     /* correctly query second product */
2241     product[0] = '\0';
2242     r = MsiEnumClientsA(component, 1, product);
2243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2244     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2245        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2246
2247     RegDeleteValueA(compkey, prod_squashed);
2248     RegDeleteValueA(compkey, prod2_squashed);
2249     RegDeleteKeyA(compkey, "");
2250     RegCloseKey(compkey);
2251
2252     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2253     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2254     lstrcatA(keypath, comp_squashed);
2255
2256     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2258
2259     /* user local component key exists */
2260     product[0] = '\0';
2261     r = MsiEnumClientsA(component, 0, product);
2262     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2263     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2264
2265     /* index > 0, no products exist */
2266     product[0] = '\0';
2267     r = MsiEnumClientsA(component, 1, product);
2268     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2269     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2270
2271     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2273
2274     /* product value exists */
2275     product[0] = '\0';
2276     r = MsiEnumClientsA(component, 0, product);
2277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2278     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2279
2280     /* try index 0 again */
2281     product[0] = '\0';
2282     r = MsiEnumClientsA(component, 0, product);
2283     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2284
2285     /* try index 1, second product value does not exist */
2286     product[0] = '\0';
2287     r = MsiEnumClientsA(component, 1, product);
2288     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2289     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2290
2291     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2292     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2293
2294     /* try index 1, second product value does exist */
2295     product[0] = '\0';
2296     r = MsiEnumClientsA(component, 1, product);
2297     todo_wine
2298     {
2299         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2300         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2301     }
2302
2303     /* start the enumeration over */
2304     product[0] = '\0';
2305     r = MsiEnumClientsA(component, 0, product);
2306     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2307     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2308        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2309
2310     /* correctly query second product */
2311     product[0] = '\0';
2312     r = MsiEnumClientsA(component, 1, product);
2313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2314     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2315        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2316
2317     RegDeleteValueA(compkey, prod_squashed);
2318     RegDeleteValueA(compkey, prod2_squashed);
2319     RegDeleteKeyA(compkey, "");
2320     RegCloseKey(compkey);
2321     LocalFree(usersid);
2322 }
2323
2324 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2325                              LPSTR *langcheck, LPDWORD langchecksz)
2326 {
2327     LPSTR version;
2328     VS_FIXEDFILEINFO *ffi;
2329     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2330     USHORT *lang;
2331
2332     version = HeapAlloc(GetProcessHeap(), 0, size);
2333     GetFileVersionInfoA(path, 0, size, version);
2334
2335     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2336     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2337     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2338             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2339             LOWORD(ffi->dwFileVersionLS));
2340     *verchecksz = lstrlenA(*vercheck);
2341
2342     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2343     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2344     sprintf(*langcheck, "%d", *lang);
2345     *langchecksz = lstrlenA(*langcheck);
2346
2347     HeapFree(GetProcessHeap(), 0, version);
2348 }
2349
2350 static void test_MsiGetFileVersion(void)
2351 {
2352     UINT r;
2353     DWORD versz, langsz;
2354     char version[MAX_PATH];
2355     char lang[MAX_PATH];
2356     char path[MAX_PATH];
2357     LPSTR vercheck, langcheck;
2358     DWORD verchecksz, langchecksz;
2359
2360     /* NULL szFilePath */
2361     versz = MAX_PATH;
2362     langsz = MAX_PATH;
2363     lstrcpyA(version, "version");
2364     lstrcpyA(lang, "lang");
2365     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2366     ok(r == ERROR_INVALID_PARAMETER,
2367        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2368     ok(!lstrcmpA(version, "version"),
2369        "Expected version to be unchanged, got %s\n", version);
2370     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2371     ok(!lstrcmpA(lang, "lang"),
2372        "Expected lang to be unchanged, got %s\n", lang);
2373     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2374
2375     /* empty szFilePath */
2376     versz = MAX_PATH;
2377     langsz = MAX_PATH;
2378     lstrcpyA(version, "version");
2379     lstrcpyA(lang, "lang");
2380     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2381     ok(r == ERROR_FILE_NOT_FOUND,
2382        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2383     ok(!lstrcmpA(version, "version"),
2384        "Expected version to be unchanged, got %s\n", version);
2385     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2386     ok(!lstrcmpA(lang, "lang"),
2387        "Expected lang to be unchanged, got %s\n", lang);
2388     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2389
2390     /* nonexistent szFilePath */
2391     versz = MAX_PATH;
2392     langsz = MAX_PATH;
2393     lstrcpyA(version, "version");
2394     lstrcpyA(lang, "lang");
2395     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2396     ok(r == ERROR_FILE_NOT_FOUND,
2397        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2398     ok(!lstrcmpA(version, "version"),
2399        "Expected version to be unchanged, got %s\n", version);
2400     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2401     ok(!lstrcmpA(lang, "lang"),
2402        "Expected lang to be unchanged, got %s\n", lang);
2403     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2404
2405     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2406     versz = MAX_PATH;
2407     langsz = MAX_PATH;
2408     lstrcpyA(version, "version");
2409     lstrcpyA(lang, "lang");
2410     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2411     ok(r == ERROR_INVALID_PARAMETER,
2412        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2413     ok(!lstrcmpA(version, "version"),
2414        "Expected version to be unchanged, got %s\n", version);
2415     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2416     ok(!lstrcmpA(lang, "lang"),
2417        "Expected lang to be unchanged, got %s\n", lang);
2418     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2419
2420     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2421     versz = MAX_PATH;
2422     langsz = MAX_PATH;
2423     lstrcpyA(version, "version");
2424     lstrcpyA(lang, "lang");
2425     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2426     ok(r == ERROR_INVALID_PARAMETER,
2427        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2428     ok(!lstrcmpA(version, "version"),
2429        "Expected version to be unchanged, got %s\n", version);
2430     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2431     ok(!lstrcmpA(lang, "lang"),
2432        "Expected lang to be unchanged, got %s\n", lang);
2433     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2434
2435     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2436     versz = 0;
2437     langsz = MAX_PATH;
2438     lstrcpyA(version, "version");
2439     lstrcpyA(lang, "lang");
2440     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
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 == 0, "Expected 0, got %d\n", 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     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2451     versz = MAX_PATH;
2452     langsz = 0;
2453     lstrcpyA(version, "version");
2454     lstrcpyA(lang, "lang");
2455     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2456     ok(r == ERROR_FILE_NOT_FOUND,
2457        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2458     ok(!lstrcmpA(version, "version"),
2459        "Expected version to be unchanged, got %s\n", version);
2460     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2461     ok(!lstrcmpA(lang, "lang"),
2462        "Expected lang to be unchanged, got %s\n", lang);
2463     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2464
2465     /* nonexistent szFilePath, rest NULL */
2466     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2467     ok(r == ERROR_FILE_NOT_FOUND,
2468        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2469
2470     create_file("ver.txt", "ver.txt", 20);
2471
2472     /* file exists, no version information */
2473     versz = MAX_PATH;
2474     langsz = MAX_PATH;
2475     lstrcpyA(version, "version");
2476     lstrcpyA(lang, "lang");
2477     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2478     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2479     ok(!lstrcmpA(version, "version"),
2480        "Expected version to be unchanged, got %s\n", version);
2481     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2482     ok(!lstrcmpA(lang, "lang"),
2483        "Expected lang to be unchanged, got %s\n", lang);
2484     ok(r == ERROR_FILE_INVALID,
2485        "Expected ERROR_FILE_INVALID, got %d\n", r);
2486
2487     DeleteFileA("ver.txt");
2488
2489     /* relative path, has version information */
2490     versz = MAX_PATH;
2491     langsz = MAX_PATH;
2492     lstrcpyA(version, "version");
2493     lstrcpyA(lang, "lang");
2494     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2495     todo_wine
2496     {
2497         ok(r == ERROR_FILE_NOT_FOUND,
2498            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2499         ok(!lstrcmpA(version, "version"),
2500            "Expected version to be unchanged, got %s\n", version);
2501         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2502         ok(!lstrcmpA(lang, "lang"),
2503            "Expected lang to be unchanged, got %s\n", lang);
2504         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2505     }
2506
2507     GetSystemDirectoryA(path, MAX_PATH);
2508     lstrcatA(path, "\\kernel32.dll");
2509
2510     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2511
2512     /* absolute path, has version information */
2513     versz = MAX_PATH;
2514     langsz = MAX_PATH;
2515     lstrcpyA(version, "version");
2516     lstrcpyA(lang, "lang");
2517     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2518     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2519     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2520     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2521     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2522     ok(!lstrcmpA(version, vercheck),
2523         "Expected %s, got %s\n", vercheck, version);
2524
2525     /* only check version */
2526     versz = MAX_PATH;
2527     lstrcpyA(version, "version");
2528     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2529     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2530     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2531     ok(!lstrcmpA(version, vercheck),
2532        "Expected %s, got %s\n", vercheck, version);
2533
2534     /* only check language */
2535     langsz = MAX_PATH;
2536     lstrcpyA(lang, "lang");
2537     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2538     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2539     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2540     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2541
2542     /* check neither version nor language */
2543     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2545
2546     /* get pcchVersionBuf */
2547     versz = MAX_PATH;
2548     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2549     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2550     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2551
2552     /* get pcchLangBuf */
2553     langsz = MAX_PATH;
2554     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2556     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2557
2558     /* pcchVersionBuf not big enough */
2559     versz = 5;
2560     lstrcpyA(version, "version");
2561     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2562     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2563     ok(!strncmp(version, vercheck, 4),
2564        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2565     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2566
2567     /* pcchLangBuf not big enough */
2568     langsz = 3;
2569     lstrcpyA(lang, "lang");
2570     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2571     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2572     ok(!strncmp(lang, langcheck, 2),
2573        "Expected first character of %s, got %s\n", langcheck, lang);
2574     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2575
2576     HeapFree(GetProcessHeap(), 0, vercheck);
2577     HeapFree(GetProcessHeap(), 0, langcheck);
2578 }
2579
2580 static void test_MsiGetProductInfo(void)
2581 {
2582     UINT r;
2583     LONG res;
2584     HKEY propkey, source;
2585     HKEY prodkey, localkey;
2586     CHAR prodcode[MAX_PATH];
2587     CHAR prod_squashed[MAX_PATH];
2588     CHAR packcode[MAX_PATH];
2589     CHAR pack_squashed[MAX_PATH];
2590     CHAR buf[MAX_PATH];
2591     CHAR keypath[MAX_PATH];
2592     LPSTR usersid;
2593     DWORD sz, val = 42;
2594
2595     create_test_guid(prodcode, prod_squashed);
2596     create_test_guid(packcode, pack_squashed);
2597     get_user_sid(&usersid);
2598
2599     /* NULL szProduct */
2600     sz = MAX_PATH;
2601     lstrcpyA(buf, "apple");
2602     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2603     ok(r == ERROR_INVALID_PARAMETER,
2604        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2605     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2606     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2607
2608     /* empty szProduct */
2609     sz = MAX_PATH;
2610     lstrcpyA(buf, "apple");
2611     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2612     ok(r == ERROR_INVALID_PARAMETER,
2613        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2614     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2615     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2616
2617     /* garbage szProduct */
2618     sz = MAX_PATH;
2619     lstrcpyA(buf, "apple");
2620     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2621     ok(r == ERROR_INVALID_PARAMETER,
2622        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2623     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2624     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2625
2626     /* guid without brackets */
2627     sz = MAX_PATH;
2628     lstrcpyA(buf, "apple");
2629     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2630                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2631     ok(r == ERROR_INVALID_PARAMETER,
2632        "Expected ERROR_INVALID_PARAMETER, 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     /* guid with brackets */
2637     sz = MAX_PATH;
2638     lstrcpyA(buf, "apple");
2639     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2640                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2641     ok(r == ERROR_UNKNOWN_PRODUCT,
2642        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2643     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2644     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2645
2646     /* same length as guid, but random */
2647     sz = MAX_PATH;
2648     lstrcpyA(buf, "apple");
2649     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2650                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2651     ok(r == ERROR_INVALID_PARAMETER,
2652        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2653     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2654     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2655
2656     /* not installed, NULL szAttribute */
2657     sz = MAX_PATH;
2658     lstrcpyA(buf, "apple");
2659     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2660     ok(r == ERROR_INVALID_PARAMETER,
2661        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2662     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2663     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2664
2665     /* not installed, NULL lpValueBuf */
2666     sz = MAX_PATH;
2667     lstrcpyA(buf, "apple");
2668     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2669     ok(r == ERROR_UNKNOWN_PRODUCT,
2670        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2671     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2672     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2673
2674     /* not installed, NULL pcchValueBuf */
2675     sz = MAX_PATH;
2676     lstrcpyA(buf, "apple");
2677     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2678     ok(r == ERROR_INVALID_PARAMETER,
2679        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2680     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2681     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2682
2683     /* created guid cannot possibly be an installed product code */
2684     sz = MAX_PATH;
2685     lstrcpyA(buf, "apple");
2686     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2687     ok(r == ERROR_UNKNOWN_PRODUCT,
2688        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2689     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2690     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2691
2692     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2693     lstrcatA(keypath, usersid);
2694     lstrcatA(keypath, "\\Installer\\Products\\");
2695     lstrcatA(keypath, prod_squashed);
2696
2697     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2698     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2699
2700     /* managed product code exists */
2701     sz = MAX_PATH;
2702     lstrcpyA(buf, "apple");
2703     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2704     ok(r == ERROR_UNKNOWN_PROPERTY,
2705        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2706     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2707     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2708
2709     RegDeleteKeyA(prodkey, "");
2710     RegCloseKey(prodkey);
2711
2712     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2713     lstrcatA(keypath, usersid);
2714     lstrcatA(keypath, "\\Products\\");
2715     lstrcatA(keypath, prod_squashed);
2716
2717     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2718     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2719
2720     /* local user product code exists */
2721     sz = MAX_PATH;
2722     lstrcpyA(buf, "apple");
2723     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2724     ok(r == ERROR_UNKNOWN_PRODUCT,
2725        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2726     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2727     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2728
2729     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2730     lstrcatA(keypath, usersid);
2731     lstrcatA(keypath, "\\Installer\\Products\\");
2732     lstrcatA(keypath, prod_squashed);
2733
2734     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2735     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2736
2737     /* both local and managed product code exist */
2738     sz = MAX_PATH;
2739     lstrcpyA(buf, "apple");
2740     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2741     ok(r == ERROR_UNKNOWN_PROPERTY,
2742        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2743     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2744     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2745
2746     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2748
2749     /* InstallProperties key exists */
2750     sz = MAX_PATH;
2751     lstrcpyA(buf, "apple");
2752     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2753     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2754     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2755     ok(sz == 0, "Expected 0, got %d\n", sz);
2756
2757     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2759
2760     /* HelpLink value exists */
2761     sz = MAX_PATH;
2762     lstrcpyA(buf, "apple");
2763     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2764     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2765     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2766     ok(sz == 4, "Expected 4, got %d\n", sz);
2767
2768     /* pcchBuf is NULL */
2769     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
2770     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2771
2772     /* lpValueBuf is NULL */
2773     sz = MAX_PATH;
2774     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2775     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2776     ok(sz == 4, "Expected 4, got %d\n", sz);
2777
2778     /* lpValueBuf is NULL, pcchValueBuf is too small */
2779     sz = 2;
2780     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2781     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2782     ok(sz == 4, "Expected 4, got %d\n", sz);
2783
2784     /* lpValueBuf is NULL, pcchValueBuf is too small */
2785     sz = 2;
2786     lstrcpyA(buf, "apple");
2787     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2788     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
2789     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2790     ok(sz == 4, "Expected 4, got %d\n", sz);
2791
2792     /* lpValueBuf is NULL, pcchValueBuf is exactly 4 */
2793     sz = 4;
2794     lstrcpyA(buf, "apple");
2795     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2796     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2797     ok(!lstrcmpA(buf, "apple"),
2798        "Expected buf to remain unchanged, got \"%s\"\n", buf);
2799     ok(sz == 4, "Expected 4, got %d\n", sz);
2800
2801     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
2802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2803
2804     /* random property not supported by MSI, value exists */
2805     sz = MAX_PATH;
2806     lstrcpyA(buf, "apple");
2807     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
2808     ok(r == ERROR_UNKNOWN_PROPERTY,
2809        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2810     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2811     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2812
2813     RegDeleteValueA(propkey, "IMadeThis");
2814     RegDeleteValueA(propkey, "HelpLink");
2815     RegDeleteKeyA(propkey, "");
2816     RegDeleteKeyA(localkey, "");
2817     RegDeleteKeyA(prodkey, "");
2818     RegCloseKey(propkey);
2819     RegCloseKey(localkey);
2820     RegCloseKey(prodkey);
2821
2822     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2823     lstrcatA(keypath, prod_squashed);
2824
2825     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2826     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2827
2828     /* user product key exists */
2829     sz = MAX_PATH;
2830     lstrcpyA(buf, "apple");
2831     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2832     ok(r == ERROR_UNKNOWN_PROPERTY,
2833        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2834     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2835     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2836
2837     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2838     lstrcatA(keypath, usersid);
2839     lstrcatA(keypath, "\\Products\\");
2840     lstrcatA(keypath, prod_squashed);
2841
2842     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2843     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2844
2845     /* local user product key exists */
2846     sz = MAX_PATH;
2847     lstrcpyA(buf, "apple");
2848     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2849     ok(r == ERROR_UNKNOWN_PROPERTY,
2850        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2851     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2852     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2853
2854     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2855     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2856
2857     /* InstallProperties key exists */
2858     sz = MAX_PATH;
2859     lstrcpyA(buf, "apple");
2860     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2861     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2862     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2863     ok(sz == 0, "Expected 0, got %d\n", sz);
2864
2865     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2867
2868     /* HelpLink value exists */
2869     sz = MAX_PATH;
2870     lstrcpyA(buf, "apple");
2871     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2872     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2873     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2874     ok(sz == 4, "Expected 4, got %d\n", sz);
2875
2876     RegDeleteValueA(propkey, "HelpLink");
2877     RegDeleteKeyA(propkey, "");
2878     RegDeleteKeyA(localkey, "");
2879     RegDeleteKeyA(prodkey, "");
2880     RegCloseKey(propkey);
2881     RegCloseKey(localkey);
2882     RegCloseKey(prodkey);
2883
2884     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2885     lstrcatA(keypath, prod_squashed);
2886
2887     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2889
2890     /* classes product key exists */
2891     sz = MAX_PATH;
2892     lstrcpyA(buf, "apple");
2893     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2894     ok(r == ERROR_UNKNOWN_PROPERTY,
2895        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2896     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2897     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2898
2899     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2900     lstrcatA(keypath, usersid);
2901     lstrcatA(keypath, "\\Products\\");
2902     lstrcatA(keypath, prod_squashed);
2903
2904     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2906
2907     /* local user product key exists */
2908     sz = MAX_PATH;
2909     lstrcpyA(buf, "apple");
2910     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2911     ok(r == ERROR_UNKNOWN_PROPERTY,
2912        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2913     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2914     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2915
2916     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2917     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2918
2919     /* InstallProperties key exists */
2920     sz = MAX_PATH;
2921     lstrcpyA(buf, "apple");
2922     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2923     ok(r == ERROR_UNKNOWN_PROPERTY,
2924        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2925     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2926     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2927
2928     RegDeleteKeyA(propkey, "");
2929     RegDeleteKeyA(localkey, "");
2930     RegCloseKey(propkey);
2931     RegCloseKey(localkey);
2932
2933     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2934     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
2935     lstrcatA(keypath, prod_squashed);
2936
2937     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2938     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2939
2940     /* Local System product key exists */
2941     sz = MAX_PATH;
2942     lstrcpyA(buf, "apple");
2943     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2944     ok(r == ERROR_UNKNOWN_PROPERTY,
2945         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2946     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2947     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2948
2949     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2951
2952     /* InstallProperties key exists */
2953     sz = MAX_PATH;
2954     lstrcpyA(buf, "apple");
2955     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2956     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2957     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2958     ok(sz == 0, "Expected 0, got %d\n", sz);
2959
2960     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2962
2963     /* HelpLink value exists */
2964     sz = MAX_PATH;
2965     lstrcpyA(buf, "apple");
2966     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2967     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2968     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2969     ok(sz == 4, "Expected 4, got %d\n", sz);
2970
2971     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
2972                          (const BYTE *)&val, sizeof(DWORD));
2973     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2974
2975     /* HelpLink type is REG_DWORD */
2976     sz = MAX_PATH;
2977     lstrcpyA(buf, "apple");
2978     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2979     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2980     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2981     ok(sz == 2, "Expected 2, got %d\n", sz);
2982
2983     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
2984     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2985
2986     /* DisplayName value exists */
2987     sz = MAX_PATH;
2988     lstrcpyA(buf, "apple");
2989     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2990     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2991     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
2992     ok(sz == 4, "Expected 4, got %d\n", sz);
2993
2994     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
2995                          (const BYTE *)&val, sizeof(DWORD));
2996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2997
2998     /* DisplayName type is REG_DWORD */
2999     sz = MAX_PATH;
3000     lstrcpyA(buf, "apple");
3001     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3002     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3003     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3004     ok(sz == 2, "Expected 2, got %d\n", sz);
3005
3006     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3007     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3008
3009     /* DisplayVersion value exists */
3010     sz = MAX_PATH;
3011     lstrcpyA(buf, "apple");
3012     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3013     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3014     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3015     ok(sz == 5, "Expected 5, got %d\n", sz);
3016
3017     res = RegSetValueExA(propkey, "DisplayVersion", 0,
3018                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3020
3021     /* DisplayVersion type is REG_DWORD */
3022     sz = MAX_PATH;
3023     lstrcpyA(buf, "apple");
3024     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3025     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3026     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3027     ok(sz == 2, "Expected 2, got %d\n", sz);
3028
3029     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3030     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3031
3032     /* HelpTelephone value exists */
3033     sz = MAX_PATH;
3034     lstrcpyA(buf, "apple");
3035     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3036     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3037     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3038     ok(sz == 4, "Expected 4, got %d\n", sz);
3039
3040     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3041                          (const BYTE *)&val, sizeof(DWORD));
3042     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3043
3044     /* HelpTelephone type is REG_DWORD */
3045     sz = MAX_PATH;
3046     lstrcpyA(buf, "apple");
3047     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3048     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3049     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3050     ok(sz == 2, "Expected 2, got %d\n", sz);
3051
3052     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3054
3055     /* InstallLocation value exists */
3056     sz = MAX_PATH;
3057     lstrcpyA(buf, "apple");
3058     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3059     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3060     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3061     ok(sz == 3, "Expected 3, got %d\n", sz);
3062
3063     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3064                          (const BYTE *)&val, sizeof(DWORD));
3065     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3066
3067     /* InstallLocation type is REG_DWORD */
3068     sz = MAX_PATH;
3069     lstrcpyA(buf, "apple");
3070     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3072     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3073     ok(sz == 2, "Expected 2, got %d\n", sz);
3074
3075     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3076     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3077
3078     /* InstallSource value exists */
3079     sz = MAX_PATH;
3080     lstrcpyA(buf, "apple");
3081     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3082     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3083     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3084     ok(sz == 6, "Expected 6, got %d\n", sz);
3085
3086     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3087                          (const BYTE *)&val, sizeof(DWORD));
3088     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3089
3090     /* InstallSource type is REG_DWORD */
3091     sz = MAX_PATH;
3092     lstrcpyA(buf, "apple");
3093     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3094     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3095     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3096     ok(sz == 2, "Expected 2, got %d\n", sz);
3097
3098     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3099     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3100
3101     /* InstallDate value exists */
3102     sz = MAX_PATH;
3103     lstrcpyA(buf, "apple");
3104     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3105     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3106     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3107     ok(sz == 4, "Expected 4, got %d\n", sz);
3108
3109     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3110                          (const BYTE *)&val, sizeof(DWORD));
3111     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3112
3113     /* InstallDate type is REG_DWORD */
3114     sz = MAX_PATH;
3115     lstrcpyA(buf, "apple");
3116     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3117     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3118     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3119     ok(sz == 2, "Expected 2, got %d\n", sz);
3120
3121     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3122     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3123
3124     /* Publisher value exists */
3125     sz = MAX_PATH;
3126     lstrcpyA(buf, "apple");
3127     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3128     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3129     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3130     ok(sz == 3, "Expected 3, got %d\n", sz);
3131
3132     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3133                          (const BYTE *)&val, sizeof(DWORD));
3134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3135
3136     /* Publisher type is REG_DWORD */
3137     sz = MAX_PATH;
3138     lstrcpyA(buf, "apple");
3139     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3140     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3141     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3142     ok(sz == 2, "Expected 2, got %d\n", sz);
3143
3144     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3145     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3146
3147     /* LocalPackage value exists */
3148     sz = MAX_PATH;
3149     lstrcpyA(buf, "apple");
3150     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3151     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3152     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3153     ok(sz == 4, "Expected 4, got %d\n", sz);
3154
3155     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3156                          (const BYTE *)&val, sizeof(DWORD));
3157     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3158
3159     /* LocalPackage type is REG_DWORD */
3160     sz = MAX_PATH;
3161     lstrcpyA(buf, "apple");
3162     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3163     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3164     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3165     ok(sz == 2, "Expected 2, got %d\n", sz);
3166
3167     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3168     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3169
3170     /* UrlInfoAbout value exists */
3171     sz = MAX_PATH;
3172     lstrcpyA(buf, "apple");
3173     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3174     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3175     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3176     ok(sz == 5, "Expected 5, got %d\n", sz);
3177
3178     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3179                          (const BYTE *)&val, sizeof(DWORD));
3180     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3181
3182     /* UrlInfoAbout type is REG_DWORD */
3183     sz = MAX_PATH;
3184     lstrcpyA(buf, "apple");
3185     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3186     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3187     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3188     ok(sz == 2, "Expected 2, got %d\n", sz);
3189
3190     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3191     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3192
3193     /* UrlUpdateInfo value exists */
3194     sz = MAX_PATH;
3195     lstrcpyA(buf, "apple");
3196     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3197     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3198     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3199     ok(sz == 4, "Expected 4, got %d\n", sz);
3200
3201     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3202                          (const BYTE *)&val, sizeof(DWORD));
3203     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3204
3205     /* UrlUpdateInfo type is REG_DWORD */
3206     sz = MAX_PATH;
3207     lstrcpyA(buf, "apple");
3208     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3209     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3210     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3211     ok(sz == 2, "Expected 2, got %d\n", sz);
3212
3213     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3214     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3215
3216     /* VersionMinor value exists */
3217     sz = MAX_PATH;
3218     lstrcpyA(buf, "apple");
3219     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3220     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3221     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3222     ok(sz == 1, "Expected 1, got %d\n", sz);
3223
3224     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3225                          (const BYTE *)&val, sizeof(DWORD));
3226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3227
3228     /* VersionMinor type is REG_DWORD */
3229     sz = MAX_PATH;
3230     lstrcpyA(buf, "apple");
3231     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3232     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3233     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3234     ok(sz == 2, "Expected 2, got %d\n", sz);
3235
3236     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3238
3239     /* VersionMajor value exists */
3240     sz = MAX_PATH;
3241     lstrcpyA(buf, "apple");
3242     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3244     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3245     ok(sz == 1, "Expected 1, got %d\n", sz);
3246
3247     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3248                          (const BYTE *)&val, sizeof(DWORD));
3249     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3250
3251     /* VersionMajor type is REG_DWORD */
3252     sz = MAX_PATH;
3253     lstrcpyA(buf, "apple");
3254     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3255     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3256     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3257     ok(sz == 2, "Expected 2, got %d\n", sz);
3258
3259     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3260     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3261
3262     /* ProductID value exists */
3263     sz = MAX_PATH;
3264     lstrcpyA(buf, "apple");
3265     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3266     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3267     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3268     ok(sz == 2, "Expected 2, got %d\n", sz);
3269
3270     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3271                          (const BYTE *)&val, sizeof(DWORD));
3272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3273
3274     /* ProductID type is REG_DWORD */
3275     sz = MAX_PATH;
3276     lstrcpyA(buf, "apple");
3277     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3278     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3279     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3280     ok(sz == 2, "Expected 2, got %d\n", sz);
3281
3282     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3283     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3284
3285     /* RegCompany value exists */
3286     sz = MAX_PATH;
3287     lstrcpyA(buf, "apple");
3288     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3289     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3290     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3291     ok(sz == 4, "Expected 4, got %d\n", sz);
3292
3293     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3294                          (const BYTE *)&val, sizeof(DWORD));
3295     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3296
3297     /* RegCompany type is REG_DWORD */
3298     sz = MAX_PATH;
3299     lstrcpyA(buf, "apple");
3300     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3301     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3302     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3303     ok(sz == 2, "Expected 2, got %d\n", sz);
3304
3305     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3306     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3307
3308     /* RegOwner value exists */
3309     sz = MAX_PATH;
3310     lstrcpyA(buf, "apple");
3311     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3312     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3313     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3314     ok(sz == 3, "Expected 3, got %d\n", sz);
3315
3316     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3317                          (const BYTE *)&val, sizeof(DWORD));
3318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3319
3320     /* RegOwner type is REG_DWORD */
3321     sz = MAX_PATH;
3322     lstrcpyA(buf, "apple");
3323     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3324     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3325     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3326     ok(sz == 2, "Expected 2, got %d\n", sz);
3327
3328     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3330
3331     /* InstanceType value exists */
3332     sz = MAX_PATH;
3333     lstrcpyA(buf, "apple");
3334     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3335     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3336     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3337     ok(sz == 0, "Expected 0, got %d\n", sz);
3338
3339     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3340                          (const BYTE *)&val, sizeof(DWORD));
3341     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3342
3343     /* InstanceType type is REG_DWORD */
3344     sz = MAX_PATH;
3345     lstrcpyA(buf, "apple");
3346     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3347     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3348     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3349     ok(sz == 0, "Expected 0, got %d\n", sz);
3350
3351     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3353
3354     /* InstanceType value exists */
3355     sz = MAX_PATH;
3356     lstrcpyA(buf, "apple");
3357     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3358     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3359     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3360     ok(sz == 4, "Expected 4, got %d\n", sz);
3361
3362     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3363                          (const BYTE *)&val, sizeof(DWORD));
3364     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3365
3366     /* InstanceType type is REG_DWORD */
3367     sz = MAX_PATH;
3368     lstrcpyA(buf, "apple");
3369     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3370     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3371     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3372     ok(sz == 2, "Expected 2, got %d\n", sz);
3373
3374     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3375     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3376
3377     /* Transforms value exists */
3378     sz = MAX_PATH;
3379     lstrcpyA(buf, "apple");
3380     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3381     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3382     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3383     ok(sz == 0, "Expected 0, got %d\n", sz);
3384
3385     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3386                          (const BYTE *)&val, sizeof(DWORD));
3387     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3388
3389     /* Transforms type is REG_DWORD */
3390     sz = MAX_PATH;
3391     lstrcpyA(buf, "apple");
3392     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3393     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3394     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3395     ok(sz == 0, "Expected 0, got %d\n", sz);
3396
3397     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3398     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3399
3400     /* Transforms value exists */
3401     sz = MAX_PATH;
3402     lstrcpyA(buf, "apple");
3403     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3404     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3405     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3406     ok(sz == 6, "Expected 6, got %d\n", sz);
3407
3408     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3409                          (const BYTE *)&val, sizeof(DWORD));
3410     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3411
3412     /* Transforms type is REG_DWORD */
3413     sz = MAX_PATH;
3414     lstrcpyA(buf, "apple");
3415     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3416     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3417     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3418     ok(sz == 2, "Expected 2, got %d\n", sz);
3419
3420     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3421     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3422
3423     /* Language value exists */
3424     sz = MAX_PATH;
3425     lstrcpyA(buf, "apple");
3426     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3427     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3428     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3429     ok(sz == 0, "Expected 0, got %d\n", sz);
3430
3431     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3432                          (const BYTE *)&val, sizeof(DWORD));
3433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3434
3435     /* Language type is REG_DWORD */
3436     sz = MAX_PATH;
3437     lstrcpyA(buf, "apple");
3438     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3439     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3440     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3441     ok(sz == 0, "Expected 0, got %d\n", sz);
3442
3443     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3445
3446     /* Language value exists */
3447     sz = MAX_PATH;
3448     lstrcpyA(buf, "apple");
3449     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3450     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3451     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3452     ok(sz == 4, "Expected 4, got %d\n", sz);
3453
3454     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3455                          (const BYTE *)&val, sizeof(DWORD));
3456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3457
3458     /* Language type is REG_DWORD */
3459     sz = MAX_PATH;
3460     lstrcpyA(buf, "apple");
3461     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3463     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3464     ok(sz == 2, "Expected 2, got %d\n", sz);
3465
3466     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3467     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3468
3469     /* ProductName value exists */
3470     sz = MAX_PATH;
3471     lstrcpyA(buf, "apple");
3472     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3473     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3474     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3475     ok(sz == 0, "Expected 0, got %d\n", sz);
3476
3477     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3478                          (const BYTE *)&val, sizeof(DWORD));
3479     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3480
3481     /* ProductName type is REG_DWORD */
3482     sz = MAX_PATH;
3483     lstrcpyA(buf, "apple");
3484     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3485     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3486     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3487     ok(sz == 0, "Expected 0, got %d\n", sz);
3488
3489     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3490     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3491
3492     /* ProductName value exists */
3493     sz = MAX_PATH;
3494     lstrcpyA(buf, "apple");
3495     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3496     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3497     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3498     ok(sz == 4, "Expected 4, got %d\n", sz);
3499
3500     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3501                          (const BYTE *)&val, sizeof(DWORD));
3502     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3503
3504     /* ProductName type is REG_DWORD */
3505     sz = MAX_PATH;
3506     lstrcpyA(buf, "apple");
3507     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3508     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3509     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3510     ok(sz == 2, "Expected 2, got %d\n", sz);
3511
3512     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3513     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3514
3515     /* Assignment value exists */
3516     sz = MAX_PATH;
3517     lstrcpyA(buf, "apple");
3518     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3519     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3520     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3521     ok(sz == 0, "Expected 0, got %d\n", sz);
3522
3523     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3524                          (const BYTE *)&val, sizeof(DWORD));
3525     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3526
3527     /* Assignment type is REG_DWORD */
3528     sz = MAX_PATH;
3529     lstrcpyA(buf, "apple");
3530     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3531     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3532     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3533     ok(sz == 0, "Expected 0, got %d\n", sz);
3534
3535     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3536     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3537
3538     /* Assignment value exists */
3539     sz = MAX_PATH;
3540     lstrcpyA(buf, "apple");
3541     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3542     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3543     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3544     ok(sz == 2, "Expected 2, got %d\n", sz);
3545
3546     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3547                          (const BYTE *)&val, sizeof(DWORD));
3548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3549
3550     /* Assignment type is REG_DWORD */
3551     sz = MAX_PATH;
3552     lstrcpyA(buf, "apple");
3553     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3554     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3555     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3556     ok(sz == 2, "Expected 2, got %d\n", sz);
3557
3558     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3559     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3560
3561     /* PackageCode value exists */
3562     sz = MAX_PATH;
3563     lstrcpyA(buf, "apple");
3564     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3565     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3566     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3567     ok(sz == 0, "Expected 0, got %d\n", sz);
3568
3569     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3570                          (const BYTE *)&val, sizeof(DWORD));
3571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3572
3573     /* PackageCode type is REG_DWORD */
3574     sz = MAX_PATH;
3575     lstrcpyA(buf, "apple");
3576     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3577     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3578     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3579     ok(sz == 0, "Expected 0, got %d\n", sz);
3580
3581     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3583
3584     /* PackageCode value exists */
3585     sz = MAX_PATH;
3586     lstrcpyA(buf, "apple");
3587     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3588     ok(r == ERROR_BAD_CONFIGURATION,
3589        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3590     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3591     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3592
3593     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3594                          (const BYTE *)&val, sizeof(DWORD));
3595     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3596
3597     /* PackageCode type is REG_DWORD */
3598     sz = MAX_PATH;
3599     lstrcpyA(buf, "apple");
3600     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3601     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3602     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3603     ok(sz == 2, "Expected 2, got %d\n", sz);
3604
3605     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3606     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3607
3608     /* PackageCode value exists */
3609     sz = MAX_PATH;
3610     lstrcpyA(buf, "apple");
3611     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3612     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3613     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3614     ok(sz == 38, "Expected 38, got %d\n", sz);
3615
3616     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3617     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3618
3619     /* Version value exists */
3620     sz = MAX_PATH;
3621     lstrcpyA(buf, "apple");
3622     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3623     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3624     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3625     ok(sz == 0, "Expected 0, got %d\n", sz);
3626
3627     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3628                          (const BYTE *)&val, sizeof(DWORD));
3629     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3630
3631     /* Version type is REG_DWORD */
3632     sz = MAX_PATH;
3633     lstrcpyA(buf, "apple");
3634     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3635     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3636     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3637     ok(sz == 0, "Expected 0, got %d\n", sz);
3638
3639     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3640     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3641
3642     /* Version value exists */
3643     sz = MAX_PATH;
3644     lstrcpyA(buf, "apple");
3645     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3646     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3647     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3648     ok(sz == 3, "Expected 3, got %d\n", sz);
3649
3650     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3651                          (const BYTE *)&val, sizeof(DWORD));
3652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3653
3654     /* Version type is REG_DWORD */
3655     sz = MAX_PATH;
3656     lstrcpyA(buf, "apple");
3657     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3658     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3659     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3660     ok(sz == 2, "Expected 2, got %d\n", sz);
3661
3662     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3663     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3664
3665     /* ProductIcon value exists */
3666     sz = MAX_PATH;
3667     lstrcpyA(buf, "apple");
3668     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3669     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3670     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3671     ok(sz == 0, "Expected 0, got %d\n", sz);
3672
3673     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3674                          (const BYTE *)&val, sizeof(DWORD));
3675     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3676
3677     /* ProductIcon type is REG_DWORD */
3678     sz = MAX_PATH;
3679     lstrcpyA(buf, "apple");
3680     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3681     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3682     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3683     ok(sz == 0, "Expected 0, got %d\n", sz);
3684
3685     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3687
3688     /* ProductIcon value exists */
3689     sz = MAX_PATH;
3690     lstrcpyA(buf, "apple");
3691     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3692     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3693     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3694     ok(sz == 3, "Expected 3, got %d\n", sz);
3695
3696     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3697                          (const BYTE *)&val, sizeof(DWORD));
3698     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3699
3700     /* ProductIcon type is REG_DWORD */
3701     sz = MAX_PATH;
3702     lstrcpyA(buf, "apple");
3703     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3704     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3705     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3706     ok(sz == 2, "Expected 2, got %d\n", sz);
3707
3708     /* SourceList key does not exist */
3709     sz = MAX_PATH;
3710     lstrcpyA(buf, "apple");
3711     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3712     ok(r == ERROR_UNKNOWN_PRODUCT,
3713        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3714     ok(!lstrcmpA(buf, "apple"),
3715        "Expected buf to be unchanged, got \"%s\"\n", buf);
3716     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
3717
3718     res = RegCreateKeyA(prodkey, "SourceList", &source);
3719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3720
3721     /* SourceList key exists, but PackageName val does not exist */
3722     sz = MAX_PATH;
3723     lstrcpyA(buf, "apple");
3724     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3726     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3727     ok(sz == 0, "Expected 0, got %d\n", sz);
3728
3729     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3730     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3731
3732     /* PackageName val exists */
3733     sz = MAX_PATH;
3734     lstrcpyA(buf, "apple");
3735     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3736     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3737     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
3738     ok(sz == 8, "Expected 8, got %d\n", sz);
3739
3740     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
3741                          (const BYTE *)&val, sizeof(DWORD));
3742     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3743
3744     /* PackageName type is REG_DWORD */
3745     sz = MAX_PATH;
3746     lstrcpyA(buf, "apple");
3747     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3748     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3749     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3750     ok(sz == 2, "Expected 2, got %d\n", sz);
3751
3752     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3754
3755     /* Authorized value exists */
3756     sz = MAX_PATH;
3757     lstrcpyA(buf, "apple");
3758     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3759     if (r != ERROR_UNKNOWN_PROPERTY)
3760     {
3761         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3762         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3763         ok(sz == 0, "Expected 0, got %d\n", sz);
3764     }
3765
3766     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
3767                          (const BYTE *)&val, sizeof(DWORD));
3768     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3769
3770     /* AuthorizedLUAApp type is REG_DWORD */
3771     sz = MAX_PATH;
3772     lstrcpyA(buf, "apple");
3773     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3774     if (r != ERROR_UNKNOWN_PROPERTY)
3775     {
3776         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3777         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3778         ok(sz == 0, "Expected 0, got %d\n", sz);
3779     }
3780
3781     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3783
3784     /* Authorized value exists */
3785     sz = MAX_PATH;
3786     lstrcpyA(buf, "apple");
3787     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3788     if (r != ERROR_UNKNOWN_PROPERTY)
3789     {
3790         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3791         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
3792         ok(sz == 4, "Expected 4, got %d\n", sz);
3793     }
3794
3795     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
3796                          (const BYTE *)&val, sizeof(DWORD));
3797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3798
3799     /* AuthorizedLUAApp type is REG_DWORD */
3800     sz = MAX_PATH;
3801     lstrcpyA(buf, "apple");
3802     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3803     if (r != ERROR_UNKNOWN_PROPERTY)
3804     {
3805         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3806         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3807         ok(sz == 2, "Expected 2, got %d\n", sz);
3808     }
3809
3810     RegDeleteValueA(propkey, "HelpLink");
3811     RegDeleteValueA(propkey, "DisplayName");
3812     RegDeleteValueA(propkey, "DisplayVersion");
3813     RegDeleteValueA(propkey, "HelpTelephone");
3814     RegDeleteValueA(propkey, "InstallLocation");
3815     RegDeleteValueA(propkey, "InstallSource");
3816     RegDeleteValueA(propkey, "InstallDate");
3817     RegDeleteValueA(propkey, "Publisher");
3818     RegDeleteValueA(propkey, "LocalPackage");
3819     RegDeleteValueA(propkey, "UrlInfoAbout");
3820     RegDeleteValueA(propkey, "UrlUpdateInfo");
3821     RegDeleteValueA(propkey, "VersionMinor");
3822     RegDeleteValueA(propkey, "VersionMajor");
3823     RegDeleteValueA(propkey, "ProductID");
3824     RegDeleteValueA(propkey, "RegCompany");
3825     RegDeleteValueA(propkey, "RegOwner");
3826     RegDeleteValueA(propkey, "InstanceType");
3827     RegDeleteValueA(propkey, "Transforms");
3828     RegDeleteValueA(propkey, "Language");
3829     RegDeleteValueA(propkey, "ProductName");
3830     RegDeleteValueA(propkey, "Assignment");
3831     RegDeleteValueA(propkey, "PackageCode");
3832     RegDeleteValueA(propkey, "Version");
3833     RegDeleteValueA(propkey, "ProductIcon");
3834     RegDeleteValueA(propkey, "AuthorizedLUAApp");
3835     RegDeleteKeyA(propkey, "");
3836     RegDeleteKeyA(localkey, "");
3837     RegDeleteValueA(prodkey, "InstanceType");
3838     RegDeleteValueA(prodkey, "Transforms");
3839     RegDeleteValueA(prodkey, "Language");
3840     RegDeleteValueA(prodkey, "ProductName");
3841     RegDeleteValueA(prodkey, "Assignment");
3842     RegDeleteValueA(prodkey, "PackageCode");
3843     RegDeleteValueA(prodkey, "Version");
3844     RegDeleteValueA(prodkey, "ProductIcon");
3845     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
3846     RegDeleteValueA(source, "PackageName");
3847     RegDeleteKeyA(source, "");
3848     RegDeleteKeyA(prodkey, "");
3849     RegCloseKey(propkey);
3850     RegCloseKey(localkey);
3851     RegCloseKey(source);
3852     RegCloseKey(prodkey);
3853     LocalFree(usersid);
3854 }
3855
3856 static void test_MsiGetProductInfoEx(void)
3857 {
3858     UINT r;
3859     LONG res;
3860     HKEY propkey, userkey;
3861     HKEY prodkey, localkey;
3862     CHAR prodcode[MAX_PATH];
3863     CHAR prod_squashed[MAX_PATH];
3864     CHAR packcode[MAX_PATH];
3865     CHAR pack_squashed[MAX_PATH];
3866     CHAR buf[MAX_PATH];
3867     CHAR keypath[MAX_PATH];
3868     LPSTR usersid;
3869     DWORD sz;
3870
3871     if (!pMsiGetProductInfoExA)
3872     {
3873         win_skip("MsiGetProductInfoExA is not available\n");
3874         return;
3875     }
3876
3877     create_test_guid(prodcode, prod_squashed);
3878     create_test_guid(packcode, pack_squashed);
3879     get_user_sid(&usersid);
3880
3881     /* NULL szProductCode */
3882     sz = MAX_PATH;
3883     lstrcpyA(buf, "apple");
3884     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3885                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3886     ok(r == ERROR_INVALID_PARAMETER,
3887        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3888     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3889     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3890
3891     /* empty szProductCode */
3892     sz = MAX_PATH;
3893     lstrcpyA(buf, "apple");
3894     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3895                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3896     ok(r == ERROR_INVALID_PARAMETER,
3897        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3898     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3899     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3900
3901     /* garbage szProductCode */
3902     sz = MAX_PATH;
3903     lstrcpyA(buf, "apple");
3904     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3905                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3906     ok(r == ERROR_INVALID_PARAMETER,
3907        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3908     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3909     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3910
3911     /* guid without brackets */
3912     sz = MAX_PATH;
3913     lstrcpyA(buf, "apple");
3914     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
3915                               MSIINSTALLCONTEXT_USERUNMANAGED,
3916                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3917     ok(r == ERROR_INVALID_PARAMETER,
3918        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3919     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3920     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3921
3922     /* guid with brackets */
3923     sz = MAX_PATH;
3924     lstrcpyA(buf, "apple");
3925     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
3926                               MSIINSTALLCONTEXT_USERUNMANAGED,
3927                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3928     ok(r == ERROR_UNKNOWN_PRODUCT,
3929        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3930     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3931     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3932
3933     /* szValue is non-NULL while pcchValue is NULL */
3934     lstrcpyA(buf, "apple");
3935     r = pMsiGetProductInfoExA(prodcode, usersid,
3936                               MSIINSTALLCONTEXT_USERUNMANAGED,
3937                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
3938     ok(r == ERROR_INVALID_PARAMETER,
3939        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3940     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3941
3942     /* dwContext is out of range */
3943     sz = MAX_PATH;
3944     lstrcpyA(buf, "apple");
3945     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
3946                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3947     ok(r == ERROR_INVALID_PARAMETER,
3948        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3949     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3950     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3951
3952     /* szProperty is NULL */
3953     sz = MAX_PATH;
3954     lstrcpyA(buf, "apple");
3955     r = pMsiGetProductInfoExA(prodcode, usersid,
3956                               MSIINSTALLCONTEXT_USERUNMANAGED,
3957                               NULL, buf, &sz);
3958     ok(r == ERROR_INVALID_PARAMETER,
3959        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3960     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3961     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3962
3963     /* szProperty is empty */
3964     sz = MAX_PATH;
3965     lstrcpyA(buf, "apple");
3966     r = pMsiGetProductInfoExA(prodcode, usersid,
3967                               MSIINSTALLCONTEXT_USERUNMANAGED,
3968                               "", buf, &sz);
3969     ok(r == ERROR_INVALID_PARAMETER,
3970        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3971     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3972     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3973
3974     /* szProperty is not a valid property */
3975     sz = MAX_PATH;
3976     lstrcpyA(buf, "apple");
3977     r = pMsiGetProductInfoExA(prodcode, usersid,
3978                               MSIINSTALLCONTEXT_USERUNMANAGED,
3979                               "notvalid", buf, &sz);
3980     ok(r == ERROR_UNKNOWN_PRODUCT,
3981        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3982     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3983     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3984
3985     /* same length as guid, but random */
3986     sz = MAX_PATH;
3987     lstrcpyA(buf, "apple");
3988     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
3989                               MSIINSTALLCONTEXT_USERUNMANAGED,
3990                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3991     ok(r == ERROR_INVALID_PARAMETER,
3992        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3993     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3994     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3995
3996     /* MSIINSTALLCONTEXT_USERUNMANAGED */
3997
3998     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3999     lstrcatA(keypath, usersid);
4000     lstrcatA(keypath, "\\Products\\");
4001     lstrcatA(keypath, prod_squashed);
4002
4003     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4005
4006     /* local user product key exists */
4007     sz = MAX_PATH;
4008     lstrcpyA(buf, "apple");
4009     r = pMsiGetProductInfoExA(prodcode, usersid,
4010                               MSIINSTALLCONTEXT_USERUNMANAGED,
4011                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4012     ok(r == ERROR_UNKNOWN_PRODUCT,
4013        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4014     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4015     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4016
4017     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4019
4020     /* InstallProperties key exists */
4021     sz = MAX_PATH;
4022     lstrcpyA(buf, "apple");
4023     r = pMsiGetProductInfoExA(prodcode, usersid,
4024                               MSIINSTALLCONTEXT_USERUNMANAGED,
4025                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4026     ok(r == ERROR_UNKNOWN_PRODUCT,
4027        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4028     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4029     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4030
4031     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4032     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4033
4034     /* LocalPackage value exists */
4035     sz = MAX_PATH;
4036     lstrcpyA(buf, "apple");
4037     r = pMsiGetProductInfoExA(prodcode, usersid,
4038                               MSIINSTALLCONTEXT_USERUNMANAGED,
4039                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4040     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4041     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4042     ok(sz == 1, "Expected 1, got %d\n", sz);
4043
4044     RegDeleteValueA(propkey, "LocalPackage");
4045
4046     /* LocalPackage value must exist */
4047     sz = MAX_PATH;
4048     lstrcpyA(buf, "apple");
4049     r = pMsiGetProductInfoExA(prodcode, usersid,
4050                               MSIINSTALLCONTEXT_USERUNMANAGED,
4051                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4052     ok(r == ERROR_UNKNOWN_PRODUCT,
4053        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4054     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4055     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4056
4057     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4058     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4059
4060     /* LocalPackage exists, but HelpLink does not exist */
4061     sz = MAX_PATH;
4062     lstrcpyA(buf, "apple");
4063     r = pMsiGetProductInfoExA(prodcode, usersid,
4064                               MSIINSTALLCONTEXT_USERUNMANAGED,
4065                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4066     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4067     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4068     ok(sz == 0, "Expected 0, got %d\n", sz);
4069
4070     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4071     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4072
4073     /* HelpLink value exists */
4074     sz = MAX_PATH;
4075     lstrcpyA(buf, "apple");
4076     r = pMsiGetProductInfoExA(prodcode, usersid,
4077                               MSIINSTALLCONTEXT_USERUNMANAGED,
4078                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4079     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4080     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4081     ok(sz == 4, "Expected 4, got %d\n", sz);
4082
4083     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4084     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4085
4086     /* HelpTelephone value exists */
4087     sz = MAX_PATH;
4088     lstrcpyA(buf, "apple");
4089     r = pMsiGetProductInfoExA(prodcode, usersid,
4090                               MSIINSTALLCONTEXT_USERUNMANAGED,
4091                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4092     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4093     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4094     ok(sz == 5, "Expected 5, got %d\n", sz);
4095
4096     /* szValue and pcchValue are NULL */
4097     r = pMsiGetProductInfoExA(prodcode, usersid,
4098                               MSIINSTALLCONTEXT_USERUNMANAGED,
4099                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4100     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4101
4102     /* pcchValue is exactly 5 */
4103     sz = 5;
4104     lstrcpyA(buf, "apple");
4105     r = pMsiGetProductInfoExA(prodcode, usersid,
4106                               MSIINSTALLCONTEXT_USERUNMANAGED,
4107                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4108     ok(r == ERROR_MORE_DATA,
4109        "Expected ERROR_MORE_DATA, got %d\n", r);
4110     ok(sz == 10, "Expected 10, got %d\n", sz);
4111
4112     /* szValue is NULL, pcchValue is exactly 5 */
4113     sz = 5;
4114     r = pMsiGetProductInfoExA(prodcode, usersid,
4115                               MSIINSTALLCONTEXT_USERUNMANAGED,
4116                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4117     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4118     ok(sz == 10, "Expected 10, got %d\n", sz);
4119
4120     /* szValue is NULL, pcchValue is MAX_PATH */
4121     sz = MAX_PATH;
4122     r = pMsiGetProductInfoExA(prodcode, usersid,
4123                               MSIINSTALLCONTEXT_USERUNMANAGED,
4124                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4126     ok(sz == 10, "Expected 10, got %d\n", sz);
4127
4128     /* pcchValue is exactly 0 */
4129     sz = 0;
4130     lstrcpyA(buf, "apple");
4131     r = pMsiGetProductInfoExA(prodcode, usersid,
4132                               MSIINSTALLCONTEXT_USERUNMANAGED,
4133                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4134     ok(r == ERROR_MORE_DATA,
4135        "Expected ERROR_MORE_DATA, got %d\n", r);
4136     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4137     ok(sz == 10, "Expected 10, got %d\n", sz);
4138
4139     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4140     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4141
4142     /* szProperty is not a valid property */
4143     sz = MAX_PATH;
4144     lstrcpyA(buf, "apple");
4145     r = pMsiGetProductInfoExA(prodcode, usersid,
4146                               MSIINSTALLCONTEXT_USERUNMANAGED,
4147                               "notvalid", buf, &sz);
4148     ok(r == ERROR_UNKNOWN_PROPERTY,
4149        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4150     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4151     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4152
4153     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4154     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4155
4156     /* InstallDate value exists */
4157     sz = MAX_PATH;
4158     lstrcpyA(buf, "apple");
4159     r = pMsiGetProductInfoExA(prodcode, usersid,
4160                               MSIINSTALLCONTEXT_USERUNMANAGED,
4161                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4162     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4163     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4164     ok(sz == 4, "Expected 4, got %d\n", sz);
4165
4166     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4167     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4168
4169     /* DisplayName value exists */
4170     sz = MAX_PATH;
4171     lstrcpyA(buf, "apple");
4172     r = pMsiGetProductInfoExA(prodcode, usersid,
4173                               MSIINSTALLCONTEXT_USERUNMANAGED,
4174                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4175     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4176     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4177     ok(sz == 4, "Expected 4, got %d\n", sz);
4178
4179     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4180     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4181
4182     /* InstallLocation value exists */
4183     sz = MAX_PATH;
4184     lstrcpyA(buf, "apple");
4185     r = pMsiGetProductInfoExA(prodcode, usersid,
4186                               MSIINSTALLCONTEXT_USERUNMANAGED,
4187                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4188     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4189     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4190     ok(sz == 3, "Expected 3, got %d\n", sz);
4191
4192     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4194
4195     /* InstallSource value exists */
4196     sz = MAX_PATH;
4197     lstrcpyA(buf, "apple");
4198     r = pMsiGetProductInfoExA(prodcode, usersid,
4199                               MSIINSTALLCONTEXT_USERUNMANAGED,
4200                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4201     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4202     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4203     ok(sz == 6, "Expected 6, got %d\n", sz);
4204
4205     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4206     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4207
4208     /* LocalPackage value exists */
4209     sz = MAX_PATH;
4210     lstrcpyA(buf, "apple");
4211     r = pMsiGetProductInfoExA(prodcode, usersid,
4212                               MSIINSTALLCONTEXT_USERUNMANAGED,
4213                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4214     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4215     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4216     ok(sz == 5, "Expected 5, got %d\n", sz);
4217
4218     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4219     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4220
4221     /* Publisher value exists */
4222     sz = MAX_PATH;
4223     lstrcpyA(buf, "apple");
4224     r = pMsiGetProductInfoExA(prodcode, usersid,
4225                               MSIINSTALLCONTEXT_USERUNMANAGED,
4226                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4227     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4228     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4229     ok(sz == 3, "Expected 3, got %d\n", sz);
4230
4231     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4232     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4233
4234     /* URLInfoAbout value exists */
4235     sz = MAX_PATH;
4236     lstrcpyA(buf, "apple");
4237     r = pMsiGetProductInfoExA(prodcode, usersid,
4238                               MSIINSTALLCONTEXT_USERUNMANAGED,
4239                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4240     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4241     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4242     ok(sz == 5, "Expected 5, got %d\n", sz);
4243
4244     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4245     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4246
4247     /* URLUpdateInfo value exists */
4248     sz = MAX_PATH;
4249     lstrcpyA(buf, "apple");
4250     r = pMsiGetProductInfoExA(prodcode, usersid,
4251                               MSIINSTALLCONTEXT_USERUNMANAGED,
4252                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4253     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4254     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4255     ok(sz == 6, "Expected 6, got %d\n", sz);
4256
4257     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4258     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4259
4260     /* VersionMinor value exists */
4261     sz = MAX_PATH;
4262     lstrcpyA(buf, "apple");
4263     r = pMsiGetProductInfoExA(prodcode, usersid,
4264                               MSIINSTALLCONTEXT_USERUNMANAGED,
4265                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4266     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4267     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4268     ok(sz == 1, "Expected 1, got %d\n", sz);
4269
4270     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4271     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4272
4273     /* VersionMajor value exists */
4274     sz = MAX_PATH;
4275     lstrcpyA(buf, "apple");
4276     r = pMsiGetProductInfoExA(prodcode, usersid,
4277                               MSIINSTALLCONTEXT_USERUNMANAGED,
4278                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4280     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4281     ok(sz == 1, "Expected 1, got %d\n", sz);
4282
4283     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4285
4286     /* DisplayVersion value exists */
4287     sz = MAX_PATH;
4288     lstrcpyA(buf, "apple");
4289     r = pMsiGetProductInfoExA(prodcode, usersid,
4290                               MSIINSTALLCONTEXT_USERUNMANAGED,
4291                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4292     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4293     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4294     ok(sz == 5, "Expected 5, got %d\n", sz);
4295
4296     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4297     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4298
4299     /* ProductID value exists */
4300     sz = MAX_PATH;
4301     lstrcpyA(buf, "apple");
4302     r = pMsiGetProductInfoExA(prodcode, usersid,
4303                               MSIINSTALLCONTEXT_USERUNMANAGED,
4304                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4305     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4306     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4307     ok(sz == 2, "Expected 2, got %d\n", sz);
4308
4309     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4311
4312     /* RegCompany value exists */
4313     sz = MAX_PATH;
4314     lstrcpyA(buf, "apple");
4315     r = pMsiGetProductInfoExA(prodcode, usersid,
4316                               MSIINSTALLCONTEXT_USERUNMANAGED,
4317                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4318     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4319     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4320     ok(sz == 4, "Expected 4, got %d\n", sz);
4321
4322     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4323     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4324
4325     /* RegOwner value exists */
4326     sz = MAX_PATH;
4327     lstrcpyA(buf, "apple");
4328     r = pMsiGetProductInfoExA(prodcode, usersid,
4329                               MSIINSTALLCONTEXT_USERUNMANAGED,
4330                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4331     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4332     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4333     ok(sz == 5, "Expected 5, got %d\n", sz);
4334
4335     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4337
4338     /* Transforms value exists */
4339     sz = MAX_PATH;
4340     lstrcpyA(buf, "apple");
4341     r = pMsiGetProductInfoExA(prodcode, usersid,
4342                               MSIINSTALLCONTEXT_USERUNMANAGED,
4343                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4344     ok(r == ERROR_UNKNOWN_PRODUCT,
4345        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4346     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4347     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4348
4349     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4351
4352     /* Language value exists */
4353     sz = MAX_PATH;
4354     lstrcpyA(buf, "apple");
4355     r = pMsiGetProductInfoExA(prodcode, usersid,
4356                               MSIINSTALLCONTEXT_USERUNMANAGED,
4357                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4358     ok(r == ERROR_UNKNOWN_PRODUCT,
4359        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4360     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4361     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4362
4363     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4364     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4365
4366     /* ProductName value exists */
4367     sz = MAX_PATH;
4368     lstrcpyA(buf, "apple");
4369     r = pMsiGetProductInfoExA(prodcode, usersid,
4370                               MSIINSTALLCONTEXT_USERUNMANAGED,
4371                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4372     ok(r == ERROR_UNKNOWN_PRODUCT,
4373        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4374     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4375     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4376
4377     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4378     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4379
4380     /* FIXME */
4381
4382     /* AssignmentType value exists */
4383     sz = MAX_PATH;
4384     lstrcpyA(buf, "apple");
4385     r = pMsiGetProductInfoExA(prodcode, usersid,
4386                               MSIINSTALLCONTEXT_USERUNMANAGED,
4387                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4388     ok(r == ERROR_UNKNOWN_PRODUCT,
4389        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4390     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4391     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4392
4393     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4395
4396     /* PackageCode value exists */
4397     sz = MAX_PATH;
4398     lstrcpyA(buf, "apple");
4399     r = pMsiGetProductInfoExA(prodcode, usersid,
4400                               MSIINSTALLCONTEXT_USERUNMANAGED,
4401                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4402     ok(r == ERROR_UNKNOWN_PRODUCT,
4403        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4404     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4405     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4406
4407     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4409
4410     /* Version value exists */
4411     sz = MAX_PATH;
4412     lstrcpyA(buf, "apple");
4413     r = pMsiGetProductInfoExA(prodcode, usersid,
4414                               MSIINSTALLCONTEXT_USERUNMANAGED,
4415                               INSTALLPROPERTY_VERSION, buf, &sz);
4416     ok(r == ERROR_UNKNOWN_PRODUCT,
4417        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4418     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4419     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4420
4421     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4423
4424     /* ProductIcon value exists */
4425     sz = MAX_PATH;
4426     lstrcpyA(buf, "apple");
4427     r = pMsiGetProductInfoExA(prodcode, usersid,
4428                               MSIINSTALLCONTEXT_USERUNMANAGED,
4429                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4430     ok(r == ERROR_UNKNOWN_PRODUCT,
4431        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4432     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4433     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4434
4435     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4436     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4437
4438     /* PackageName value exists */
4439     sz = MAX_PATH;
4440     lstrcpyA(buf, "apple");
4441     r = pMsiGetProductInfoExA(prodcode, usersid,
4442                               MSIINSTALLCONTEXT_USERUNMANAGED,
4443                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4444     ok(r == ERROR_UNKNOWN_PRODUCT,
4445        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4446     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4447     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4448
4449     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4450     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4451
4452     /* AuthorizedLUAApp value exists */
4453     sz = MAX_PATH;
4454     lstrcpyA(buf, "apple");
4455     r = pMsiGetProductInfoExA(prodcode, usersid,
4456                               MSIINSTALLCONTEXT_USERUNMANAGED,
4457                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4458     ok(r == ERROR_UNKNOWN_PRODUCT,
4459        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4460     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4461     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4462
4463     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4464     RegDeleteValueA(propkey, "PackageName");
4465     RegDeleteValueA(propkey, "ProductIcon");
4466     RegDeleteValueA(propkey, "Version");
4467     RegDeleteValueA(propkey, "PackageCode");
4468     RegDeleteValueA(propkey, "AssignmentType");
4469     RegDeleteValueA(propkey, "ProductName");
4470     RegDeleteValueA(propkey, "Language");
4471     RegDeleteValueA(propkey, "Transforms");
4472     RegDeleteValueA(propkey, "RegOwner");
4473     RegDeleteValueA(propkey, "RegCompany");
4474     RegDeleteValueA(propkey, "ProductID");
4475     RegDeleteValueA(propkey, "DisplayVersion");
4476     RegDeleteValueA(propkey, "VersionMajor");
4477     RegDeleteValueA(propkey, "VersionMinor");
4478     RegDeleteValueA(propkey, "URLUpdateInfo");
4479     RegDeleteValueA(propkey, "URLInfoAbout");
4480     RegDeleteValueA(propkey, "Publisher");
4481     RegDeleteValueA(propkey, "LocalPackage");
4482     RegDeleteValueA(propkey, "InstallSource");
4483     RegDeleteValueA(propkey, "InstallLocation");
4484     RegDeleteValueA(propkey, "DisplayName");
4485     RegDeleteValueA(propkey, "InstallDate");
4486     RegDeleteValueA(propkey, "HelpTelephone");
4487     RegDeleteValueA(propkey, "HelpLink");
4488     RegDeleteValueA(propkey, "LocalPackage");
4489     RegDeleteKeyA(propkey, "");
4490     RegCloseKey(propkey);
4491     RegDeleteKeyA(localkey, "");
4492     RegCloseKey(localkey);
4493
4494     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4495     lstrcatA(keypath, usersid);
4496     lstrcatA(keypath, "\\Installer\\Products\\");
4497     lstrcatA(keypath, prod_squashed);
4498
4499     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
4500     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4501
4502     /* user product key exists */
4503     sz = MAX_PATH;
4504     lstrcpyA(buf, "apple");
4505     r = pMsiGetProductInfoExA(prodcode, usersid,
4506                               MSIINSTALLCONTEXT_USERUNMANAGED,
4507                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4508     ok(r == ERROR_UNKNOWN_PRODUCT,
4509        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4510     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4511     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4512
4513     RegDeleteKeyA(userkey, "");
4514     RegCloseKey(userkey);
4515
4516     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4517     lstrcatA(keypath, prod_squashed);
4518
4519     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4520     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4521
4522     sz = MAX_PATH;
4523     lstrcpyA(buf, "apple");
4524     r = pMsiGetProductInfoExA(prodcode, usersid,
4525                               MSIINSTALLCONTEXT_USERUNMANAGED,
4526                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4527     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4528     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4529     ok(sz == 1, "Expected 1, got %d\n", sz);
4530
4531     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4532     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4533
4534     /* HelpLink value exists */
4535     sz = MAX_PATH;
4536     lstrcpyA(buf, "apple");
4537     r = pMsiGetProductInfoExA(prodcode, usersid,
4538                               MSIINSTALLCONTEXT_USERUNMANAGED,
4539                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4540     ok(r == ERROR_UNKNOWN_PROPERTY,
4541        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4542     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4543     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4544
4545     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4546     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4547
4548     /* HelpTelephone value exists */
4549     sz = MAX_PATH;
4550     lstrcpyA(buf, "apple");
4551     r = pMsiGetProductInfoExA(prodcode, usersid,
4552                               MSIINSTALLCONTEXT_USERUNMANAGED,
4553                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4554     ok(r == ERROR_UNKNOWN_PROPERTY,
4555        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4556     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4557     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4558
4559     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4560     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4561
4562     /* InstallDate value exists */
4563     sz = MAX_PATH;
4564     lstrcpyA(buf, "apple");
4565     r = pMsiGetProductInfoExA(prodcode, usersid,
4566                               MSIINSTALLCONTEXT_USERUNMANAGED,
4567                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4568     ok(r == ERROR_UNKNOWN_PROPERTY,
4569        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4570     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4571     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4572
4573     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4574     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4575
4576     /* DisplayName value exists */
4577     sz = MAX_PATH;
4578     lstrcpyA(buf, "apple");
4579     r = pMsiGetProductInfoExA(prodcode, usersid,
4580                               MSIINSTALLCONTEXT_USERUNMANAGED,
4581                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4582     ok(r == ERROR_UNKNOWN_PROPERTY,
4583        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4584     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4585     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4586
4587     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4589
4590     /* InstallLocation value exists */
4591     sz = MAX_PATH;
4592     lstrcpyA(buf, "apple");
4593     r = pMsiGetProductInfoExA(prodcode, usersid,
4594                               MSIINSTALLCONTEXT_USERUNMANAGED,
4595                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4596     ok(r == ERROR_UNKNOWN_PROPERTY,
4597        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4598     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4599     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4600
4601     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4602     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4603
4604     /* InstallSource value exists */
4605     sz = MAX_PATH;
4606     lstrcpyA(buf, "apple");
4607     r = pMsiGetProductInfoExA(prodcode, usersid,
4608                               MSIINSTALLCONTEXT_USERUNMANAGED,
4609                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4610     ok(r == ERROR_UNKNOWN_PROPERTY,
4611        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4612     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4613     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4614
4615     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4616     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4617
4618     /* LocalPackage value exists */
4619     sz = MAX_PATH;
4620     lstrcpyA(buf, "apple");
4621     r = pMsiGetProductInfoExA(prodcode, usersid,
4622                               MSIINSTALLCONTEXT_USERUNMANAGED,
4623                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4624     ok(r == ERROR_UNKNOWN_PROPERTY,
4625        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4626     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4627     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4628
4629     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4631
4632     /* Publisher value exists */
4633     sz = MAX_PATH;
4634     lstrcpyA(buf, "apple");
4635     r = pMsiGetProductInfoExA(prodcode, usersid,
4636                               MSIINSTALLCONTEXT_USERUNMANAGED,
4637                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4638     ok(r == ERROR_UNKNOWN_PROPERTY,
4639        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4640     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4641     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4642
4643     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4645
4646     /* URLInfoAbout value exists */
4647     sz = MAX_PATH;
4648     lstrcpyA(buf, "apple");
4649     r = pMsiGetProductInfoExA(prodcode, usersid,
4650                               MSIINSTALLCONTEXT_USERUNMANAGED,
4651                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4652     ok(r == ERROR_UNKNOWN_PROPERTY,
4653        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4654     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4655     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4656
4657     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4658     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4659
4660     /* URLUpdateInfo value exists */
4661     sz = MAX_PATH;
4662     lstrcpyA(buf, "apple");
4663     r = pMsiGetProductInfoExA(prodcode, usersid,
4664                               MSIINSTALLCONTEXT_USERUNMANAGED,
4665                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4666     ok(r == ERROR_UNKNOWN_PROPERTY,
4667        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4668     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4669     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4670
4671     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4672     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4673
4674     /* VersionMinor value exists */
4675     sz = MAX_PATH;
4676     lstrcpyA(buf, "apple");
4677     r = pMsiGetProductInfoExA(prodcode, usersid,
4678                               MSIINSTALLCONTEXT_USERUNMANAGED,
4679                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4680     ok(r == ERROR_UNKNOWN_PROPERTY,
4681        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4682     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4683     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4684
4685     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4687
4688     /* VersionMajor value exists */
4689     sz = MAX_PATH;
4690     lstrcpyA(buf, "apple");
4691     r = pMsiGetProductInfoExA(prodcode, usersid,
4692                               MSIINSTALLCONTEXT_USERUNMANAGED,
4693                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4694     ok(r == ERROR_UNKNOWN_PROPERTY,
4695        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4696     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4697     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4698
4699     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4700     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4701
4702     /* DisplayVersion value exists */
4703     sz = MAX_PATH;
4704     lstrcpyA(buf, "apple");
4705     r = pMsiGetProductInfoExA(prodcode, usersid,
4706                               MSIINSTALLCONTEXT_USERUNMANAGED,
4707                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4708     ok(r == ERROR_UNKNOWN_PROPERTY,
4709        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4710     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4711     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4712
4713     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4714     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4715
4716     /* ProductID value exists */
4717     sz = MAX_PATH;
4718     lstrcpyA(buf, "apple");
4719     r = pMsiGetProductInfoExA(prodcode, usersid,
4720                               MSIINSTALLCONTEXT_USERUNMANAGED,
4721                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4722     ok(r == ERROR_UNKNOWN_PROPERTY,
4723        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4724     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4725     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4726
4727     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4729
4730     /* RegCompany value exists */
4731     sz = MAX_PATH;
4732     lstrcpyA(buf, "apple");
4733     r = pMsiGetProductInfoExA(prodcode, usersid,
4734                               MSIINSTALLCONTEXT_USERUNMANAGED,
4735                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4736     ok(r == ERROR_UNKNOWN_PROPERTY,
4737        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4738     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4739     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4740
4741     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4742     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4743
4744     /* RegOwner value exists */
4745     sz = MAX_PATH;
4746     lstrcpyA(buf, "apple");
4747     r = pMsiGetProductInfoExA(prodcode, usersid,
4748                               MSIINSTALLCONTEXT_USERUNMANAGED,
4749                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4750     ok(r == ERROR_UNKNOWN_PROPERTY,
4751        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4752     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4753     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4754
4755     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4756     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4757
4758     /* Transforms value exists */
4759     sz = MAX_PATH;
4760     lstrcpyA(buf, "apple");
4761     r = pMsiGetProductInfoExA(prodcode, usersid,
4762                               MSIINSTALLCONTEXT_USERUNMANAGED,
4763                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4764     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4765     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
4766     ok(sz == 5, "Expected 5, got %d\n", sz);
4767
4768     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4769     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4770
4771     /* Language value exists */
4772     sz = MAX_PATH;
4773     lstrcpyA(buf, "apple");
4774     r = pMsiGetProductInfoExA(prodcode, usersid,
4775                               MSIINSTALLCONTEXT_USERUNMANAGED,
4776                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4778     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4779     ok(sz == 4, "Expected 4, got %d\n", sz);
4780
4781     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4783
4784     /* ProductName value exists */
4785     sz = MAX_PATH;
4786     lstrcpyA(buf, "apple");
4787     r = pMsiGetProductInfoExA(prodcode, usersid,
4788                               MSIINSTALLCONTEXT_USERUNMANAGED,
4789                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4790     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4791     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4792     ok(sz == 4, "Expected 4, got %d\n", sz);
4793
4794     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4795     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4796
4797     /* FIXME */
4798
4799     /* AssignmentType value exists */
4800     sz = MAX_PATH;
4801     lstrcpyA(buf, "apple");
4802     r = pMsiGetProductInfoExA(prodcode, usersid,
4803                               MSIINSTALLCONTEXT_USERUNMANAGED,
4804                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4805     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4806     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4807     ok(sz == 0, "Expected 0, got %d\n", sz);
4808
4809     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4810     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4811
4812     /* FIXME */
4813
4814     /* PackageCode value exists */
4815     sz = MAX_PATH;
4816     lstrcpyA(buf, "apple");
4817     r = pMsiGetProductInfoExA(prodcode, usersid,
4818                               MSIINSTALLCONTEXT_USERUNMANAGED,
4819                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4820     todo_wine
4821     {
4822         ok(r == ERROR_BAD_CONFIGURATION,
4823            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4824         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4825         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4826     }
4827
4828     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4829     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4830
4831     /* Version value exists */
4832     sz = MAX_PATH;
4833     lstrcpyA(buf, "apple");
4834     r = pMsiGetProductInfoExA(prodcode, usersid,
4835                               MSIINSTALLCONTEXT_USERUNMANAGED,
4836                               INSTALLPROPERTY_VERSION, buf, &sz);
4837     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4838     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4839     ok(sz == 3, "Expected 3, got %d\n", sz);
4840
4841     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4842     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4843
4844     /* ProductIcon value exists */
4845     sz = MAX_PATH;
4846     lstrcpyA(buf, "apple");
4847     r = pMsiGetProductInfoExA(prodcode, usersid,
4848                               MSIINSTALLCONTEXT_USERUNMANAGED,
4849                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4850     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4851     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
4852     ok(sz == 4, "Expected 4, got %d\n", sz);
4853
4854     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4855     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4856
4857     /* PackageName value exists */
4858     sz = MAX_PATH;
4859     lstrcpyA(buf, "apple");
4860     r = pMsiGetProductInfoExA(prodcode, usersid,
4861                               MSIINSTALLCONTEXT_USERUNMANAGED,
4862                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4863     todo_wine
4864     {
4865         ok(r == ERROR_UNKNOWN_PRODUCT,
4866            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4867         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4868         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4869     }
4870
4871     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4872     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4873
4874     /* AuthorizedLUAApp value exists */
4875     sz = MAX_PATH;
4876     lstrcpyA(buf, "apple");
4877     r = pMsiGetProductInfoExA(prodcode, usersid,
4878                               MSIINSTALLCONTEXT_USERUNMANAGED,
4879                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4880     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4881     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4882     ok(sz == 4, "Expected 4, got %d\n", sz);
4883
4884     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4885     RegDeleteValueA(prodkey, "PackageName");
4886     RegDeleteValueA(prodkey, "ProductIcon");
4887     RegDeleteValueA(prodkey, "Version");
4888     RegDeleteValueA(prodkey, "PackageCode");
4889     RegDeleteValueA(prodkey, "AssignmentType");
4890     RegDeleteValueA(prodkey, "ProductName");
4891     RegDeleteValueA(prodkey, "Language");
4892     RegDeleteValueA(prodkey, "Transforms");
4893     RegDeleteValueA(prodkey, "RegOwner");
4894     RegDeleteValueA(prodkey, "RegCompany");
4895     RegDeleteValueA(prodkey, "ProductID");
4896     RegDeleteValueA(prodkey, "DisplayVersion");
4897     RegDeleteValueA(prodkey, "VersionMajor");
4898     RegDeleteValueA(prodkey, "VersionMinor");
4899     RegDeleteValueA(prodkey, "URLUpdateInfo");
4900     RegDeleteValueA(prodkey, "URLInfoAbout");
4901     RegDeleteValueA(prodkey, "Publisher");
4902     RegDeleteValueA(prodkey, "LocalPackage");
4903     RegDeleteValueA(prodkey, "InstallSource");
4904     RegDeleteValueA(prodkey, "InstallLocation");
4905     RegDeleteValueA(prodkey, "DisplayName");
4906     RegDeleteValueA(prodkey, "InstallDate");
4907     RegDeleteValueA(prodkey, "HelpTelephone");
4908     RegDeleteValueA(prodkey, "HelpLink");
4909     RegDeleteValueA(prodkey, "LocalPackage");
4910     RegDeleteKeyA(prodkey, "");
4911     RegCloseKey(prodkey);
4912
4913     /* MSIINSTALLCONTEXT_USERMANAGED */
4914
4915     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4916     lstrcatA(keypath, usersid);
4917     lstrcatA(keypath, "\\Products\\");
4918     lstrcatA(keypath, prod_squashed);
4919
4920     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4921     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4922
4923     /* local user product key exists */
4924     sz = MAX_PATH;
4925     lstrcpyA(buf, "apple");
4926     r = pMsiGetProductInfoExA(prodcode, usersid,
4927                               MSIINSTALLCONTEXT_USERMANAGED,
4928                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4929     ok(r == ERROR_UNKNOWN_PRODUCT,
4930        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4931     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4932     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4933
4934     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4936
4937     /* InstallProperties key exists */
4938     sz = MAX_PATH;
4939     lstrcpyA(buf, "apple");
4940     r = pMsiGetProductInfoExA(prodcode, usersid,
4941                               MSIINSTALLCONTEXT_USERMANAGED,
4942                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4943     ok(r == ERROR_UNKNOWN_PRODUCT,
4944        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4945     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4946     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4947
4948     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4949     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4950
4951     /* ManagedLocalPackage value exists */
4952     sz = MAX_PATH;
4953     lstrcpyA(buf, "apple");
4954     r = pMsiGetProductInfoExA(prodcode, usersid,
4955                               MSIINSTALLCONTEXT_USERMANAGED,
4956                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4957     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4958     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4959     ok(sz == 1, "Expected 1, got %d\n", sz);
4960
4961     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4963
4964     /* HelpLink value exists */
4965     sz = MAX_PATH;
4966     lstrcpyA(buf, "apple");
4967     r = pMsiGetProductInfoExA(prodcode, usersid,
4968                               MSIINSTALLCONTEXT_USERMANAGED,
4969                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4970     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4971     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4972     ok(sz == 4, "Expected 4, got %d\n", sz);
4973
4974     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4975     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4976
4977     /* HelpTelephone value exists */
4978     sz = MAX_PATH;
4979     lstrcpyA(buf, "apple");
4980     r = pMsiGetProductInfoExA(prodcode, usersid,
4981                               MSIINSTALLCONTEXT_USERMANAGED,
4982                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4984     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4985     ok(sz == 5, "Expected 5, got %d\n", sz);
4986
4987     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4988     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4989
4990     /* InstallDate value exists */
4991     sz = MAX_PATH;
4992     lstrcpyA(buf, "apple");
4993     r = pMsiGetProductInfoExA(prodcode, usersid,
4994                               MSIINSTALLCONTEXT_USERMANAGED,
4995                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4996     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4997     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4998     ok(sz == 4, "Expected 4, got %d\n", sz);
4999
5000     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5001     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5002
5003     /* DisplayName value exists */
5004     sz = MAX_PATH;
5005     lstrcpyA(buf, "apple");
5006     r = pMsiGetProductInfoExA(prodcode, usersid,
5007                               MSIINSTALLCONTEXT_USERMANAGED,
5008                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5009     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5010     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5011     ok(sz == 4, "Expected 4, got %d\n", sz);
5012
5013     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5014     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5015
5016     /* InstallLocation value exists */
5017     sz = MAX_PATH;
5018     lstrcpyA(buf, "apple");
5019     r = pMsiGetProductInfoExA(prodcode, usersid,
5020                               MSIINSTALLCONTEXT_USERMANAGED,
5021                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5022     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5023     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5024     ok(sz == 3, "Expected 3, got %d\n", sz);
5025
5026     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5027     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5028
5029     /* InstallSource value exists */
5030     sz = MAX_PATH;
5031     lstrcpyA(buf, "apple");
5032     r = pMsiGetProductInfoExA(prodcode, usersid,
5033                               MSIINSTALLCONTEXT_USERMANAGED,
5034                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5035     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5036     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5037     ok(sz == 6, "Expected 6, got %d\n", sz);
5038
5039     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5040     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5041
5042     /* LocalPackage value exists */
5043     sz = MAX_PATH;
5044     lstrcpyA(buf, "apple");
5045     r = pMsiGetProductInfoExA(prodcode, usersid,
5046                               MSIINSTALLCONTEXT_USERMANAGED,
5047                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5048     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5049     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5050     ok(sz == 5, "Expected 5, got %d\n", sz);
5051
5052     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5053     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5054
5055     /* Publisher value exists */
5056     sz = MAX_PATH;
5057     lstrcpyA(buf, "apple");
5058     r = pMsiGetProductInfoExA(prodcode, usersid,
5059                               MSIINSTALLCONTEXT_USERMANAGED,
5060                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5062     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5063     ok(sz == 3, "Expected 3, got %d\n", sz);
5064
5065     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5067
5068     /* URLInfoAbout value exists */
5069     sz = MAX_PATH;
5070     lstrcpyA(buf, "apple");
5071     r = pMsiGetProductInfoExA(prodcode, usersid,
5072                               MSIINSTALLCONTEXT_USERMANAGED,
5073                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5074     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5075     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5076     ok(sz == 5, "Expected 5, got %d\n", sz);
5077
5078     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5080
5081     /* URLUpdateInfo value exists */
5082     sz = MAX_PATH;
5083     lstrcpyA(buf, "apple");
5084     r = pMsiGetProductInfoExA(prodcode, usersid,
5085                               MSIINSTALLCONTEXT_USERMANAGED,
5086                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5087     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5088     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5089     ok(sz == 6, "Expected 6, got %d\n", sz);
5090
5091     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5093
5094     /* VersionMinor value exists */
5095     sz = MAX_PATH;
5096     lstrcpyA(buf, "apple");
5097     r = pMsiGetProductInfoExA(prodcode, usersid,
5098                               MSIINSTALLCONTEXT_USERMANAGED,
5099                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5100     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5101     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5102     ok(sz == 1, "Expected 1, got %d\n", sz);
5103
5104     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5105     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5106
5107     /* VersionMajor value exists */
5108     sz = MAX_PATH;
5109     lstrcpyA(buf, "apple");
5110     r = pMsiGetProductInfoExA(prodcode, usersid,
5111                               MSIINSTALLCONTEXT_USERMANAGED,
5112                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5113     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5114     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5115     ok(sz == 1, "Expected 1, got %d\n", sz);
5116
5117     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5119
5120     /* DisplayVersion value exists */
5121     sz = MAX_PATH;
5122     lstrcpyA(buf, "apple");
5123     r = pMsiGetProductInfoExA(prodcode, usersid,
5124                               MSIINSTALLCONTEXT_USERMANAGED,
5125                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5126     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5127     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5128     ok(sz == 5, "Expected 5, got %d\n", sz);
5129
5130     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5131     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5132
5133     /* ProductID value exists */
5134     sz = MAX_PATH;
5135     lstrcpyA(buf, "apple");
5136     r = pMsiGetProductInfoExA(prodcode, usersid,
5137                               MSIINSTALLCONTEXT_USERMANAGED,
5138                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5139     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5140     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5141     ok(sz == 2, "Expected 2, got %d\n", sz);
5142
5143     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5144     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5145
5146     /* RegCompany value exists */
5147     sz = MAX_PATH;
5148     lstrcpyA(buf, "apple");
5149     r = pMsiGetProductInfoExA(prodcode, usersid,
5150                               MSIINSTALLCONTEXT_USERMANAGED,
5151                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5152     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5153     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5154     ok(sz == 4, "Expected 4, got %d\n", sz);
5155
5156     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5157     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5158
5159     /* RegOwner value exists */
5160     sz = MAX_PATH;
5161     lstrcpyA(buf, "apple");
5162     r = pMsiGetProductInfoExA(prodcode, usersid,
5163                               MSIINSTALLCONTEXT_USERMANAGED,
5164                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5165     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5166     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5167     ok(sz == 5, "Expected 5, got %d\n", sz);
5168
5169     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5170     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5171
5172     /* Transforms value exists */
5173     sz = MAX_PATH;
5174     lstrcpyA(buf, "apple");
5175     r = pMsiGetProductInfoExA(prodcode, usersid,
5176                               MSIINSTALLCONTEXT_USERMANAGED,
5177                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5178     ok(r == ERROR_UNKNOWN_PRODUCT,
5179        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5180     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5181     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5182
5183     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5184     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5185
5186     /* Language value exists */
5187     sz = MAX_PATH;
5188     lstrcpyA(buf, "apple");
5189     r = pMsiGetProductInfoExA(prodcode, usersid,
5190                               MSIINSTALLCONTEXT_USERMANAGED,
5191                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5192     ok(r == ERROR_UNKNOWN_PRODUCT,
5193        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5194     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5195     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5196
5197     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5199
5200     /* ProductName value exists */
5201     sz = MAX_PATH;
5202     lstrcpyA(buf, "apple");
5203     r = pMsiGetProductInfoExA(prodcode, usersid,
5204                               MSIINSTALLCONTEXT_USERMANAGED,
5205                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5206     ok(r == ERROR_UNKNOWN_PRODUCT,
5207        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5208     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5209     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5210
5211     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5213
5214     /* FIXME */
5215
5216     /* AssignmentType value exists */
5217     sz = MAX_PATH;
5218     lstrcpyA(buf, "apple");
5219     r = pMsiGetProductInfoExA(prodcode, usersid,
5220                               MSIINSTALLCONTEXT_USERMANAGED,
5221                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5222     ok(r == ERROR_UNKNOWN_PRODUCT,
5223        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5224     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5225     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5226
5227     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5228     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5229
5230     /* PackageCode value exists */
5231     sz = MAX_PATH;
5232     lstrcpyA(buf, "apple");
5233     r = pMsiGetProductInfoExA(prodcode, usersid,
5234                               MSIINSTALLCONTEXT_USERMANAGED,
5235                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5236     ok(r == ERROR_UNKNOWN_PRODUCT,
5237        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5238     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5239     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5240
5241     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5242     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5243
5244     /* Version value exists */
5245     sz = MAX_PATH;
5246     lstrcpyA(buf, "apple");
5247     r = pMsiGetProductInfoExA(prodcode, usersid,
5248                               MSIINSTALLCONTEXT_USERMANAGED,
5249                               INSTALLPROPERTY_VERSION, buf, &sz);
5250     ok(r == ERROR_UNKNOWN_PRODUCT,
5251        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5252     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5253     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5254
5255     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5257
5258     /* ProductIcon value exists */
5259     sz = MAX_PATH;
5260     lstrcpyA(buf, "apple");
5261     r = pMsiGetProductInfoExA(prodcode, usersid,
5262                               MSIINSTALLCONTEXT_USERMANAGED,
5263                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5264     ok(r == ERROR_UNKNOWN_PRODUCT,
5265        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5266     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5267     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5268
5269     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5270     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5271
5272     /* PackageName value exists */
5273     sz = MAX_PATH;
5274     lstrcpyA(buf, "apple");
5275     r = pMsiGetProductInfoExA(prodcode, usersid,
5276                               MSIINSTALLCONTEXT_USERMANAGED,
5277                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5278     ok(r == ERROR_UNKNOWN_PRODUCT,
5279        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5280     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5281     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5282
5283     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5285
5286     /* AuthorizedLUAApp value exists */
5287     sz = MAX_PATH;
5288     lstrcpyA(buf, "apple");
5289     r = pMsiGetProductInfoExA(prodcode, usersid,
5290                               MSIINSTALLCONTEXT_USERMANAGED,
5291                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5292     ok(r == ERROR_UNKNOWN_PRODUCT,
5293        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5294     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5295     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5296
5297     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5298     RegDeleteValueA(propkey, "PackageName");
5299     RegDeleteValueA(propkey, "ProductIcon");
5300     RegDeleteValueA(propkey, "Version");
5301     RegDeleteValueA(propkey, "PackageCode");
5302     RegDeleteValueA(propkey, "AssignmentType");
5303     RegDeleteValueA(propkey, "ProductName");
5304     RegDeleteValueA(propkey, "Language");
5305     RegDeleteValueA(propkey, "Transforms");
5306     RegDeleteValueA(propkey, "RegOwner");
5307     RegDeleteValueA(propkey, "RegCompany");
5308     RegDeleteValueA(propkey, "ProductID");
5309     RegDeleteValueA(propkey, "DisplayVersion");
5310     RegDeleteValueA(propkey, "VersionMajor");
5311     RegDeleteValueA(propkey, "VersionMinor");
5312     RegDeleteValueA(propkey, "URLUpdateInfo");
5313     RegDeleteValueA(propkey, "URLInfoAbout");
5314     RegDeleteValueA(propkey, "Publisher");
5315     RegDeleteValueA(propkey, "LocalPackage");
5316     RegDeleteValueA(propkey, "InstallSource");
5317     RegDeleteValueA(propkey, "InstallLocation");
5318     RegDeleteValueA(propkey, "DisplayName");
5319     RegDeleteValueA(propkey, "InstallDate");
5320     RegDeleteValueA(propkey, "HelpTelephone");
5321     RegDeleteValueA(propkey, "HelpLink");
5322     RegDeleteValueA(propkey, "ManagedLocalPackage");
5323     RegDeleteKeyA(propkey, "");
5324     RegCloseKey(propkey);
5325     RegDeleteKeyA(localkey, "");
5326     RegCloseKey(localkey);
5327
5328     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5329     lstrcatA(keypath, usersid);
5330     lstrcatA(keypath, "\\Installer\\Products\\");
5331     lstrcatA(keypath, prod_squashed);
5332
5333     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5334     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5335
5336     /* user product key exists */
5337     sz = MAX_PATH;
5338     lstrcpyA(buf, "apple");
5339     r = pMsiGetProductInfoExA(prodcode, usersid,
5340                               MSIINSTALLCONTEXT_USERMANAGED,
5341                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5342     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5343     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5344     ok(sz == 1, "Expected 1, got %d\n", sz);
5345
5346     RegDeleteKeyA(userkey, "");
5347     RegCloseKey(userkey);
5348
5349     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5350     lstrcatA(keypath, prod_squashed);
5351
5352     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5353     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5354
5355     /* current user product key exists */
5356     sz = MAX_PATH;
5357     lstrcpyA(buf, "apple");
5358     r = pMsiGetProductInfoExA(prodcode, usersid,
5359                               MSIINSTALLCONTEXT_USERMANAGED,
5360                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5361     ok(r == ERROR_UNKNOWN_PRODUCT,
5362        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5363     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5364     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5365
5366     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5368
5369     /* HelpLink value exists, user product key does not exist */
5370     sz = MAX_PATH;
5371     lstrcpyA(buf, "apple");
5372     r = pMsiGetProductInfoExA(prodcode, usersid,
5373                               MSIINSTALLCONTEXT_USERMANAGED,
5374                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5375     ok(r == ERROR_UNKNOWN_PRODUCT,
5376        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5377     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5378     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5379
5380     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5381     lstrcatA(keypath, usersid);
5382     lstrcatA(keypath, "\\Installer\\Products\\");
5383     lstrcatA(keypath, prod_squashed);
5384
5385     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5386     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5387
5388     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5389     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5390
5391     /* HelpLink value exists, user product key does exist */
5392     sz = MAX_PATH;
5393     lstrcpyA(buf, "apple");
5394     r = pMsiGetProductInfoExA(prodcode, usersid,
5395                               MSIINSTALLCONTEXT_USERMANAGED,
5396                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5397     ok(r == ERROR_UNKNOWN_PROPERTY,
5398        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5399     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5400     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5401
5402     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5404
5405     /* HelpTelephone value exists */
5406     sz = MAX_PATH;
5407     lstrcpyA(buf, "apple");
5408     r = pMsiGetProductInfoExA(prodcode, usersid,
5409                               MSIINSTALLCONTEXT_USERMANAGED,
5410                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5411     ok(r == ERROR_UNKNOWN_PROPERTY,
5412        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5413     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5414     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5415
5416     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5418
5419     /* InstallDate value exists */
5420     sz = MAX_PATH;
5421     lstrcpyA(buf, "apple");
5422     r = pMsiGetProductInfoExA(prodcode, usersid,
5423                               MSIINSTALLCONTEXT_USERMANAGED,
5424                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5425     ok(r == ERROR_UNKNOWN_PROPERTY,
5426        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5427     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5428     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5429
5430     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5431     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5432
5433     /* DisplayName value exists */
5434     sz = MAX_PATH;
5435     lstrcpyA(buf, "apple");
5436     r = pMsiGetProductInfoExA(prodcode, usersid,
5437                               MSIINSTALLCONTEXT_USERMANAGED,
5438                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5439     ok(r == ERROR_UNKNOWN_PROPERTY,
5440        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5441     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5442     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5443
5444     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5445     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5446
5447     /* InstallLocation value exists */
5448     sz = MAX_PATH;
5449     lstrcpyA(buf, "apple");
5450     r = pMsiGetProductInfoExA(prodcode, usersid,
5451                               MSIINSTALLCONTEXT_USERMANAGED,
5452                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5453     ok(r == ERROR_UNKNOWN_PROPERTY,
5454        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5455     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5456     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5457
5458     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5460
5461     /* InstallSource value exists */
5462     sz = MAX_PATH;
5463     lstrcpyA(buf, "apple");
5464     r = pMsiGetProductInfoExA(prodcode, usersid,
5465                               MSIINSTALLCONTEXT_USERMANAGED,
5466                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5467     ok(r == ERROR_UNKNOWN_PROPERTY,
5468        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5469     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5470     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5471
5472     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5473     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5474
5475     /* LocalPackage value exists */
5476     sz = MAX_PATH;
5477     lstrcpyA(buf, "apple");
5478     r = pMsiGetProductInfoExA(prodcode, usersid,
5479                               MSIINSTALLCONTEXT_USERMANAGED,
5480                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5481     ok(r == ERROR_UNKNOWN_PROPERTY,
5482        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5483     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5484     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5485
5486     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5487     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5488
5489     /* Publisher value exists */
5490     sz = MAX_PATH;
5491     lstrcpyA(buf, "apple");
5492     r = pMsiGetProductInfoExA(prodcode, usersid,
5493                               MSIINSTALLCONTEXT_USERMANAGED,
5494                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5495     ok(r == ERROR_UNKNOWN_PROPERTY,
5496        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5497     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5498     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5499
5500     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5501     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5502
5503     /* URLInfoAbout value exists */
5504     sz = MAX_PATH;
5505     lstrcpyA(buf, "apple");
5506     r = pMsiGetProductInfoExA(prodcode, usersid,
5507                               MSIINSTALLCONTEXT_USERMANAGED,
5508                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5509     ok(r == ERROR_UNKNOWN_PROPERTY,
5510        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5511     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5512     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5513
5514     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5516
5517     /* URLUpdateInfo value exists */
5518     sz = MAX_PATH;
5519     lstrcpyA(buf, "apple");
5520     r = pMsiGetProductInfoExA(prodcode, usersid,
5521                               MSIINSTALLCONTEXT_USERMANAGED,
5522                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5523     ok(r == ERROR_UNKNOWN_PROPERTY,
5524        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5525     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5526     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5527
5528     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5530
5531     /* VersionMinor value exists */
5532     sz = MAX_PATH;
5533     lstrcpyA(buf, "apple");
5534     r = pMsiGetProductInfoExA(prodcode, usersid,
5535                               MSIINSTALLCONTEXT_USERMANAGED,
5536                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5537     ok(r == ERROR_UNKNOWN_PROPERTY,
5538        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5539     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5540     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5541
5542     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5543     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5544
5545     /* VersionMajor value exists */
5546     sz = MAX_PATH;
5547     lstrcpyA(buf, "apple");
5548     r = pMsiGetProductInfoExA(prodcode, usersid,
5549                               MSIINSTALLCONTEXT_USERMANAGED,
5550                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5551     ok(r == ERROR_UNKNOWN_PROPERTY,
5552        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5553     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5554     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5555
5556     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5557     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5558
5559     /* DisplayVersion value exists */
5560     sz = MAX_PATH;
5561     lstrcpyA(buf, "apple");
5562     r = pMsiGetProductInfoExA(prodcode, usersid,
5563                               MSIINSTALLCONTEXT_USERMANAGED,
5564                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5565     ok(r == ERROR_UNKNOWN_PROPERTY,
5566        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5567     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5568     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5569
5570     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5572
5573     /* ProductID value exists */
5574     sz = MAX_PATH;
5575     lstrcpyA(buf, "apple");
5576     r = pMsiGetProductInfoExA(prodcode, usersid,
5577                               MSIINSTALLCONTEXT_USERMANAGED,
5578                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5579     ok(r == ERROR_UNKNOWN_PROPERTY,
5580        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5581     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5582     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5583
5584     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5585     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5586
5587     /* RegCompany value exists */
5588     sz = MAX_PATH;
5589     lstrcpyA(buf, "apple");
5590     r = pMsiGetProductInfoExA(prodcode, usersid,
5591                               MSIINSTALLCONTEXT_USERMANAGED,
5592                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5593     ok(r == ERROR_UNKNOWN_PROPERTY,
5594        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5595     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5596     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5597
5598     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5599     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5600
5601     /* RegOwner value exists */
5602     sz = MAX_PATH;
5603     lstrcpyA(buf, "apple");
5604     r = pMsiGetProductInfoExA(prodcode, usersid,
5605                               MSIINSTALLCONTEXT_USERMANAGED,
5606                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5607     ok(r == ERROR_UNKNOWN_PROPERTY,
5608        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5609     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5610     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5611
5612     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5614
5615     /* Transforms value exists */
5616     sz = MAX_PATH;
5617     lstrcpyA(buf, "apple");
5618     r = pMsiGetProductInfoExA(prodcode, usersid,
5619                               MSIINSTALLCONTEXT_USERMANAGED,
5620                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5621     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5622     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5623     ok(sz == 5, "Expected 5, got %d\n", sz);
5624
5625     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5626     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5627
5628     /* Language value exists */
5629     sz = MAX_PATH;
5630     lstrcpyA(buf, "apple");
5631     r = pMsiGetProductInfoExA(prodcode, usersid,
5632                               MSIINSTALLCONTEXT_USERMANAGED,
5633                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5634     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5635     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5636     ok(sz == 4, "Expected 4, got %d\n", sz);
5637
5638     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5639     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5640
5641     /* ProductName value exists */
5642     sz = MAX_PATH;
5643     lstrcpyA(buf, "apple");
5644     r = pMsiGetProductInfoExA(prodcode, usersid,
5645                               MSIINSTALLCONTEXT_USERMANAGED,
5646                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5647     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5648     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5649     ok(sz == 4, "Expected 4, got %d\n", sz);
5650
5651     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5653
5654     /* FIXME */
5655
5656     /* AssignmentType value exists */
5657     sz = MAX_PATH;
5658     lstrcpyA(buf, "apple");
5659     r = pMsiGetProductInfoExA(prodcode, usersid,
5660                               MSIINSTALLCONTEXT_USERMANAGED,
5661                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5662     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5663     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5664     ok(sz == 0, "Expected 0, got %d\n", sz);
5665
5666     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5668
5669     /* FIXME */
5670
5671     /* PackageCode value exists */
5672     sz = MAX_PATH;
5673     lstrcpyA(buf, "apple");
5674     r = pMsiGetProductInfoExA(prodcode, usersid,
5675                               MSIINSTALLCONTEXT_USERMANAGED,
5676                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5677     todo_wine
5678     {
5679         ok(r == ERROR_BAD_CONFIGURATION,
5680            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5681         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5682         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5683     }
5684
5685     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5687
5688     /* Version value exists */
5689     sz = MAX_PATH;
5690     lstrcpyA(buf, "apple");
5691     r = pMsiGetProductInfoExA(prodcode, usersid,
5692                               MSIINSTALLCONTEXT_USERMANAGED,
5693                               INSTALLPROPERTY_VERSION, buf, &sz);
5694     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5695     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5696     ok(sz == 3, "Expected 3, got %d\n", sz);
5697
5698     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5700
5701     /* ProductIcon value exists */
5702     sz = MAX_PATH;
5703     lstrcpyA(buf, "apple");
5704     r = pMsiGetProductInfoExA(prodcode, usersid,
5705                               MSIINSTALLCONTEXT_USERMANAGED,
5706                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5708     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5709     ok(sz == 4, "Expected 4, got %d\n", sz);
5710
5711     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5713
5714     /* PackageName value exists */
5715     sz = MAX_PATH;
5716     lstrcpyA(buf, "apple");
5717     r = pMsiGetProductInfoExA(prodcode, usersid,
5718                               MSIINSTALLCONTEXT_USERMANAGED,
5719                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5720     todo_wine
5721     {
5722         ok(r == ERROR_UNKNOWN_PRODUCT,
5723            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5724         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5725         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5726     }
5727
5728     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5729     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5730
5731     /* AuthorizedLUAApp value exists */
5732     sz = MAX_PATH;
5733     lstrcpyA(buf, "apple");
5734     r = pMsiGetProductInfoExA(prodcode, usersid,
5735                               MSIINSTALLCONTEXT_USERMANAGED,
5736                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5737     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5738     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5739     ok(sz == 4, "Expected 4, got %d\n", sz);
5740
5741     RegDeleteValueA(userkey, "AuthorizedLUAApp");
5742     RegDeleteValueA(userkey, "PackageName");
5743     RegDeleteValueA(userkey, "ProductIcon");
5744     RegDeleteValueA(userkey, "Version");
5745     RegDeleteValueA(userkey, "PackageCode");
5746     RegDeleteValueA(userkey, "AssignmentType");
5747     RegDeleteValueA(userkey, "ProductName");
5748     RegDeleteValueA(userkey, "Language");
5749     RegDeleteValueA(userkey, "Transforms");
5750     RegDeleteValueA(userkey, "RegOwner");
5751     RegDeleteValueA(userkey, "RegCompany");
5752     RegDeleteValueA(userkey, "ProductID");
5753     RegDeleteValueA(userkey, "DisplayVersion");
5754     RegDeleteValueA(userkey, "VersionMajor");
5755     RegDeleteValueA(userkey, "VersionMinor");
5756     RegDeleteValueA(userkey, "URLUpdateInfo");
5757     RegDeleteValueA(userkey, "URLInfoAbout");
5758     RegDeleteValueA(userkey, "Publisher");
5759     RegDeleteValueA(userkey, "LocalPackage");
5760     RegDeleteValueA(userkey, "InstallSource");
5761     RegDeleteValueA(userkey, "InstallLocation");
5762     RegDeleteValueA(userkey, "DisplayName");
5763     RegDeleteValueA(userkey, "InstallDate");
5764     RegDeleteValueA(userkey, "HelpTelephone");
5765     RegDeleteValueA(userkey, "HelpLink");
5766     RegDeleteKeyA(userkey, "");
5767     RegCloseKey(userkey);
5768     RegDeleteKeyA(prodkey, "");
5769     RegCloseKey(prodkey);
5770
5771     /* MSIINSTALLCONTEXT_MACHINE */
5772
5773     /* szUserSid is non-NULL */
5774     sz = MAX_PATH;
5775     lstrcpyA(buf, "apple");
5776     r = pMsiGetProductInfoExA(prodcode, usersid,
5777                               MSIINSTALLCONTEXT_MACHINE,
5778                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5779     ok(r == ERROR_INVALID_PARAMETER,
5780        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5781     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5782     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5783
5784     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
5785     lstrcatA(keypath, prod_squashed);
5786
5787     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5788     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5789
5790     /* local system product key exists */
5791     sz = MAX_PATH;
5792     lstrcpyA(buf, "apple");
5793     r = pMsiGetProductInfoExA(prodcode, NULL,
5794                               MSIINSTALLCONTEXT_MACHINE,
5795                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5796     ok(r == ERROR_UNKNOWN_PRODUCT,
5797        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5798     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5799     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5800
5801     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5803
5804     /* InstallProperties key exists */
5805     sz = MAX_PATH;
5806     lstrcpyA(buf, "apple");
5807     r = pMsiGetProductInfoExA(prodcode, NULL,
5808                               MSIINSTALLCONTEXT_MACHINE,
5809                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5810     ok(r == ERROR_UNKNOWN_PRODUCT,
5811        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5812     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5813     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5814
5815     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5816     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5817
5818     /* LocalPackage value exists */
5819     sz = MAX_PATH;
5820     lstrcpyA(buf, "apple");
5821     r = pMsiGetProductInfoExA(prodcode, NULL,
5822                               MSIINSTALLCONTEXT_MACHINE,
5823                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5824     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5825     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5826     ok(sz == 1, "Expected 1, got %d\n", sz);
5827
5828     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5829     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5830
5831     /* HelpLink value exists */
5832     sz = MAX_PATH;
5833     lstrcpyA(buf, "apple");
5834     r = pMsiGetProductInfoExA(prodcode, NULL,
5835                               MSIINSTALLCONTEXT_MACHINE,
5836                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5837     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5838     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5839     ok(sz == 4, "Expected 4, got %d\n", sz);
5840
5841     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5842     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5843
5844     /* HelpTelephone value exists */
5845     sz = MAX_PATH;
5846     lstrcpyA(buf, "apple");
5847     r = pMsiGetProductInfoExA(prodcode, NULL,
5848                               MSIINSTALLCONTEXT_MACHINE,
5849                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5850     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5851     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5852     ok(sz == 5, "Expected 5, got %d\n", sz);
5853
5854     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5855     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5856
5857     /* InstallDate value exists */
5858     sz = MAX_PATH;
5859     lstrcpyA(buf, "apple");
5860     r = pMsiGetProductInfoExA(prodcode, NULL,
5861                               MSIINSTALLCONTEXT_MACHINE,
5862                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5863     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5864     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5865     ok(sz == 4, "Expected 4, got %d\n", sz);
5866
5867     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5868     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5869
5870     /* DisplayName value exists */
5871     sz = MAX_PATH;
5872     lstrcpyA(buf, "apple");
5873     r = pMsiGetProductInfoExA(prodcode, NULL,
5874                               MSIINSTALLCONTEXT_MACHINE,
5875                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5876     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5877     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5878     ok(sz == 4, "Expected 4, got %d\n", sz);
5879
5880     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5881     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5882
5883     /* InstallLocation value exists */
5884     sz = MAX_PATH;
5885     lstrcpyA(buf, "apple");
5886     r = pMsiGetProductInfoExA(prodcode, NULL,
5887                               MSIINSTALLCONTEXT_MACHINE,
5888                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5889     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5890     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5891     ok(sz == 3, "Expected 3, got %d\n", sz);
5892
5893     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5894     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5895
5896     /* InstallSource value exists */
5897     sz = MAX_PATH;
5898     lstrcpyA(buf, "apple");
5899     r = pMsiGetProductInfoExA(prodcode, NULL,
5900                               MSIINSTALLCONTEXT_MACHINE,
5901                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5902     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5903     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5904     ok(sz == 6, "Expected 6, got %d\n", sz);
5905
5906     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5907     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5908
5909     /* LocalPackage value exists */
5910     sz = MAX_PATH;
5911     lstrcpyA(buf, "apple");
5912     r = pMsiGetProductInfoExA(prodcode, NULL,
5913                               MSIINSTALLCONTEXT_MACHINE,
5914                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5915     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5916     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5917     ok(sz == 5, "Expected 5, got %d\n", sz);
5918
5919     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5920     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5921
5922     /* Publisher value exists */
5923     sz = MAX_PATH;
5924     lstrcpyA(buf, "apple");
5925     r = pMsiGetProductInfoExA(prodcode, NULL,
5926                               MSIINSTALLCONTEXT_MACHINE,
5927                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5928     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5929     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5930     ok(sz == 3, "Expected 3, got %d\n", sz);
5931
5932     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5933     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5934
5935     /* URLInfoAbout value exists */
5936     sz = MAX_PATH;
5937     lstrcpyA(buf, "apple");
5938     r = pMsiGetProductInfoExA(prodcode, NULL,
5939                               MSIINSTALLCONTEXT_MACHINE,
5940                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5941     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5942     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5943     ok(sz == 5, "Expected 5, got %d\n", sz);
5944
5945     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5946     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5947
5948     /* URLUpdateInfo value exists */
5949     sz = MAX_PATH;
5950     lstrcpyA(buf, "apple");
5951     r = pMsiGetProductInfoExA(prodcode, NULL,
5952                               MSIINSTALLCONTEXT_MACHINE,
5953                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5954     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5955     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5956     ok(sz == 6, "Expected 6, got %d\n", sz);
5957
5958     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5959     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5960
5961     /* VersionMinor value exists */
5962     sz = MAX_PATH;
5963     lstrcpyA(buf, "apple");
5964     r = pMsiGetProductInfoExA(prodcode, NULL,
5965                               MSIINSTALLCONTEXT_MACHINE,
5966                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5967     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5968     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5969     ok(sz == 1, "Expected 1, got %d\n", sz);
5970
5971     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5972     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5973
5974     /* VersionMajor value exists */
5975     sz = MAX_PATH;
5976     lstrcpyA(buf, "apple");
5977     r = pMsiGetProductInfoExA(prodcode, NULL,
5978                               MSIINSTALLCONTEXT_MACHINE,
5979                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5980     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5981     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5982     ok(sz == 1, "Expected 1, got %d\n", sz);
5983
5984     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5986
5987     /* DisplayVersion value exists */
5988     sz = MAX_PATH;
5989     lstrcpyA(buf, "apple");
5990     r = pMsiGetProductInfoExA(prodcode, NULL,
5991                               MSIINSTALLCONTEXT_MACHINE,
5992                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5993     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5994     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5995     ok(sz == 5, "Expected 5, got %d\n", sz);
5996
5997     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5999
6000     /* ProductID value exists */
6001     sz = MAX_PATH;
6002     lstrcpyA(buf, "apple");
6003     r = pMsiGetProductInfoExA(prodcode, NULL,
6004                               MSIINSTALLCONTEXT_MACHINE,
6005                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6006     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6007     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6008     ok(sz == 2, "Expected 2, got %d\n", sz);
6009
6010     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6012
6013     /* RegCompany value exists */
6014     sz = MAX_PATH;
6015     lstrcpyA(buf, "apple");
6016     r = pMsiGetProductInfoExA(prodcode, NULL,
6017                               MSIINSTALLCONTEXT_MACHINE,
6018                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6019     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6020     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6021     ok(sz == 4, "Expected 4, got %d\n", sz);
6022
6023     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6025
6026     /* RegOwner value exists */
6027     sz = MAX_PATH;
6028     lstrcpyA(buf, "apple");
6029     r = pMsiGetProductInfoExA(prodcode, NULL,
6030                               MSIINSTALLCONTEXT_MACHINE,
6031                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6032     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6033     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6034     ok(sz == 5, "Expected 5, got %d\n", sz);
6035
6036     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6037     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6038
6039     /* Transforms value exists */
6040     sz = MAX_PATH;
6041     lstrcpyA(buf, "apple");
6042     r = pMsiGetProductInfoExA(prodcode, NULL,
6043                               MSIINSTALLCONTEXT_MACHINE,
6044                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6045     ok(r == ERROR_UNKNOWN_PRODUCT,
6046        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6047     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6048     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6049
6050     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6051     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6052
6053     /* Language value exists */
6054     sz = MAX_PATH;
6055     lstrcpyA(buf, "apple");
6056     r = pMsiGetProductInfoExA(prodcode, NULL,
6057                               MSIINSTALLCONTEXT_MACHINE,
6058                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6059     ok(r == ERROR_UNKNOWN_PRODUCT,
6060        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6061     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6062     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6063
6064     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6065     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6066
6067     /* ProductName value exists */
6068     sz = MAX_PATH;
6069     lstrcpyA(buf, "apple");
6070     r = pMsiGetProductInfoExA(prodcode, NULL,
6071                               MSIINSTALLCONTEXT_MACHINE,
6072                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6073     ok(r == ERROR_UNKNOWN_PRODUCT,
6074        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6075     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6076     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6077
6078     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6080
6081     /* FIXME */
6082
6083     /* AssignmentType value exists */
6084     sz = MAX_PATH;
6085     lstrcpyA(buf, "apple");
6086     r = pMsiGetProductInfoExA(prodcode, NULL,
6087                               MSIINSTALLCONTEXT_MACHINE,
6088                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6089     ok(r == ERROR_UNKNOWN_PRODUCT,
6090        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6091     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6092     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6093
6094     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6095     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6096
6097     /* PackageCode value exists */
6098     sz = MAX_PATH;
6099     lstrcpyA(buf, "apple");
6100     r = pMsiGetProductInfoExA(prodcode, NULL,
6101                               MSIINSTALLCONTEXT_MACHINE,
6102                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6103     ok(r == ERROR_UNKNOWN_PRODUCT,
6104        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6105     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6106     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6107
6108     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6110
6111     /* Version value exists */
6112     sz = MAX_PATH;
6113     lstrcpyA(buf, "apple");
6114     r = pMsiGetProductInfoExA(prodcode, NULL,
6115                               MSIINSTALLCONTEXT_MACHINE,
6116                               INSTALLPROPERTY_VERSION, buf, &sz);
6117     ok(r == ERROR_UNKNOWN_PRODUCT,
6118        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6119     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6120     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6121
6122     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6124
6125     /* ProductIcon value exists */
6126     sz = MAX_PATH;
6127     lstrcpyA(buf, "apple");
6128     r = pMsiGetProductInfoExA(prodcode, NULL,
6129                               MSIINSTALLCONTEXT_MACHINE,
6130                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6131     ok(r == ERROR_UNKNOWN_PRODUCT,
6132        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6133     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6134     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6135
6136     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6137     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6138
6139     /* PackageName value exists */
6140     sz = MAX_PATH;
6141     lstrcpyA(buf, "apple");
6142     r = pMsiGetProductInfoExA(prodcode, NULL,
6143                               MSIINSTALLCONTEXT_MACHINE,
6144                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6145     ok(r == ERROR_UNKNOWN_PRODUCT,
6146        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6147     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6148     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6149
6150     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6151     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6152
6153     /* AuthorizedLUAApp value exists */
6154     sz = MAX_PATH;
6155     lstrcpyA(buf, "apple");
6156     r = pMsiGetProductInfoExA(prodcode, NULL,
6157                               MSIINSTALLCONTEXT_MACHINE,
6158                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6159     ok(r == ERROR_UNKNOWN_PRODUCT,
6160        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6161     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6162     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6163
6164     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6165     RegDeleteValueA(propkey, "PackageName");
6166     RegDeleteValueA(propkey, "ProductIcon");
6167     RegDeleteValueA(propkey, "Version");
6168     RegDeleteValueA(propkey, "PackageCode");
6169     RegDeleteValueA(propkey, "AssignmentType");
6170     RegDeleteValueA(propkey, "ProductName");
6171     RegDeleteValueA(propkey, "Language");
6172     RegDeleteValueA(propkey, "Transforms");
6173     RegDeleteValueA(propkey, "RegOwner");
6174     RegDeleteValueA(propkey, "RegCompany");
6175     RegDeleteValueA(propkey, "ProductID");
6176     RegDeleteValueA(propkey, "DisplayVersion");
6177     RegDeleteValueA(propkey, "VersionMajor");
6178     RegDeleteValueA(propkey, "VersionMinor");
6179     RegDeleteValueA(propkey, "URLUpdateInfo");
6180     RegDeleteValueA(propkey, "URLInfoAbout");
6181     RegDeleteValueA(propkey, "Publisher");
6182     RegDeleteValueA(propkey, "LocalPackage");
6183     RegDeleteValueA(propkey, "InstallSource");
6184     RegDeleteValueA(propkey, "InstallLocation");
6185     RegDeleteValueA(propkey, "DisplayName");
6186     RegDeleteValueA(propkey, "InstallDate");
6187     RegDeleteValueA(propkey, "HelpTelephone");
6188     RegDeleteValueA(propkey, "HelpLink");
6189     RegDeleteValueA(propkey, "LocalPackage");
6190     RegDeleteKeyA(propkey, "");
6191     RegCloseKey(propkey);
6192     RegDeleteKeyA(localkey, "");
6193     RegCloseKey(localkey);
6194
6195     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6196     lstrcatA(keypath, prod_squashed);
6197
6198     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6199     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6200
6201     /* local classes product key exists */
6202     sz = MAX_PATH;
6203     lstrcpyA(buf, "apple");
6204     r = pMsiGetProductInfoExA(prodcode, NULL,
6205                               MSIINSTALLCONTEXT_MACHINE,
6206                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6207     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6208     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6209     ok(sz == 1, "Expected 1, got %d\n", sz);
6210
6211     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6213
6214     /* HelpLink value exists */
6215     sz = MAX_PATH;
6216     lstrcpyA(buf, "apple");
6217     r = pMsiGetProductInfoExA(prodcode, NULL,
6218                               MSIINSTALLCONTEXT_MACHINE,
6219                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6220     ok(r == ERROR_UNKNOWN_PROPERTY,
6221        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6222     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6223     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6224
6225     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6227
6228     /* HelpTelephone value exists */
6229     sz = MAX_PATH;
6230     lstrcpyA(buf, "apple");
6231     r = pMsiGetProductInfoExA(prodcode, NULL,
6232                               MSIINSTALLCONTEXT_MACHINE,
6233                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6234     ok(r == ERROR_UNKNOWN_PROPERTY,
6235        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6236     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6237     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6238
6239     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6240     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6241
6242     /* InstallDate value exists */
6243     sz = MAX_PATH;
6244     lstrcpyA(buf, "apple");
6245     r = pMsiGetProductInfoExA(prodcode, NULL,
6246                               MSIINSTALLCONTEXT_MACHINE,
6247                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6248     ok(r == ERROR_UNKNOWN_PROPERTY,
6249        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6250     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6251     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6252
6253     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6255
6256     /* DisplayName value exists */
6257     sz = MAX_PATH;
6258     lstrcpyA(buf, "apple");
6259     r = pMsiGetProductInfoExA(prodcode, NULL,
6260                               MSIINSTALLCONTEXT_MACHINE,
6261                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6262     ok(r == ERROR_UNKNOWN_PROPERTY,
6263        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6264     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6265     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6266
6267     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6268     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6269
6270     /* InstallLocation value exists */
6271     sz = MAX_PATH;
6272     lstrcpyA(buf, "apple");
6273     r = pMsiGetProductInfoExA(prodcode, NULL,
6274                               MSIINSTALLCONTEXT_MACHINE,
6275                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6276     ok(r == ERROR_UNKNOWN_PROPERTY,
6277        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6278     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6279     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6280
6281     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6283
6284     /* InstallSource value exists */
6285     sz = MAX_PATH;
6286     lstrcpyA(buf, "apple");
6287     r = pMsiGetProductInfoExA(prodcode, NULL,
6288                               MSIINSTALLCONTEXT_MACHINE,
6289                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6290     ok(r == ERROR_UNKNOWN_PROPERTY,
6291        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6292     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6293     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6294
6295     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6297
6298     /* LocalPackage value exists */
6299     sz = MAX_PATH;
6300     lstrcpyA(buf, "apple");
6301     r = pMsiGetProductInfoExA(prodcode, NULL,
6302                               MSIINSTALLCONTEXT_MACHINE,
6303                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6304     ok(r == ERROR_UNKNOWN_PROPERTY,
6305        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6306     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6307     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6308
6309     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6311
6312     /* Publisher value exists */
6313     sz = MAX_PATH;
6314     lstrcpyA(buf, "apple");
6315     r = pMsiGetProductInfoExA(prodcode, NULL,
6316                               MSIINSTALLCONTEXT_MACHINE,
6317                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6318     ok(r == ERROR_UNKNOWN_PROPERTY,
6319        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6320     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6321     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6322
6323     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6325
6326     /* URLInfoAbout value exists */
6327     sz = MAX_PATH;
6328     lstrcpyA(buf, "apple");
6329     r = pMsiGetProductInfoExA(prodcode, NULL,
6330                               MSIINSTALLCONTEXT_MACHINE,
6331                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6332     ok(r == ERROR_UNKNOWN_PROPERTY,
6333        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6334     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6335     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6336
6337     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6339
6340     /* URLUpdateInfo value exists */
6341     sz = MAX_PATH;
6342     lstrcpyA(buf, "apple");
6343     r = pMsiGetProductInfoExA(prodcode, NULL,
6344                               MSIINSTALLCONTEXT_MACHINE,
6345                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6346     ok(r == ERROR_UNKNOWN_PROPERTY,
6347        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6348     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6349     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6350
6351     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6353
6354     /* VersionMinor value exists */
6355     sz = MAX_PATH;
6356     lstrcpyA(buf, "apple");
6357     r = pMsiGetProductInfoExA(prodcode, NULL,
6358                               MSIINSTALLCONTEXT_MACHINE,
6359                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6360     ok(r == ERROR_UNKNOWN_PROPERTY,
6361        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6362     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6363     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6364
6365     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6366     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6367
6368     /* VersionMajor value exists */
6369     sz = MAX_PATH;
6370     lstrcpyA(buf, "apple");
6371     r = pMsiGetProductInfoExA(prodcode, NULL,
6372                               MSIINSTALLCONTEXT_MACHINE,
6373                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6374     ok(r == ERROR_UNKNOWN_PROPERTY,
6375        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6376     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6377     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6378
6379     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6380     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6381
6382     /* DisplayVersion value exists */
6383     sz = MAX_PATH;
6384     lstrcpyA(buf, "apple");
6385     r = pMsiGetProductInfoExA(prodcode, NULL,
6386                               MSIINSTALLCONTEXT_MACHINE,
6387                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6388     ok(r == ERROR_UNKNOWN_PROPERTY,
6389        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6390     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6391     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6392
6393     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6395
6396     /* ProductID value exists */
6397     sz = MAX_PATH;
6398     lstrcpyA(buf, "apple");
6399     r = pMsiGetProductInfoExA(prodcode, NULL,
6400                               MSIINSTALLCONTEXT_MACHINE,
6401                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6402     ok(r == ERROR_UNKNOWN_PROPERTY,
6403        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6404     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6405     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6406
6407     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6409
6410     /* RegCompany value exists */
6411     sz = MAX_PATH;
6412     lstrcpyA(buf, "apple");
6413     r = pMsiGetProductInfoExA(prodcode, NULL,
6414                               MSIINSTALLCONTEXT_MACHINE,
6415                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6416     ok(r == ERROR_UNKNOWN_PROPERTY,
6417        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6418     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6419     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6420
6421     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6423
6424     /* RegOwner value exists */
6425     sz = MAX_PATH;
6426     lstrcpyA(buf, "apple");
6427     r = pMsiGetProductInfoExA(prodcode, NULL,
6428                               MSIINSTALLCONTEXT_MACHINE,
6429                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6430     ok(r == ERROR_UNKNOWN_PROPERTY,
6431        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6432     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6433     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6434
6435     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6436     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6437
6438     /* Transforms value exists */
6439     sz = MAX_PATH;
6440     lstrcpyA(buf, "apple");
6441     r = pMsiGetProductInfoExA(prodcode, NULL,
6442                               MSIINSTALLCONTEXT_MACHINE,
6443                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6444     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6445     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6446     ok(sz == 5, "Expected 5, got %d\n", sz);
6447
6448     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6449     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6450
6451     /* Language value exists */
6452     sz = MAX_PATH;
6453     lstrcpyA(buf, "apple");
6454     r = pMsiGetProductInfoExA(prodcode, NULL,
6455                               MSIINSTALLCONTEXT_MACHINE,
6456                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6457     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6458     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6459     ok(sz == 4, "Expected 4, got %d\n", sz);
6460
6461     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6462     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6463
6464     /* ProductName value exists */
6465     sz = MAX_PATH;
6466     lstrcpyA(buf, "apple");
6467     r = pMsiGetProductInfoExA(prodcode, NULL,
6468                               MSIINSTALLCONTEXT_MACHINE,
6469                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6470     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6471     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6472     ok(sz == 4, "Expected 4, got %d\n", sz);
6473
6474     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6475     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6476
6477     /* FIXME */
6478
6479     /* AssignmentType value exists */
6480     sz = MAX_PATH;
6481     lstrcpyA(buf, "apple");
6482     r = pMsiGetProductInfoExA(prodcode, NULL,
6483                               MSIINSTALLCONTEXT_MACHINE,
6484                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6485     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6486     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6487     ok(sz == 0, "Expected 0, got %d\n", sz);
6488
6489     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6490     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6491
6492     /* FIXME */
6493
6494     /* PackageCode value exists */
6495     sz = MAX_PATH;
6496     lstrcpyA(buf, "apple");
6497     r = pMsiGetProductInfoExA(prodcode, NULL,
6498                               MSIINSTALLCONTEXT_MACHINE,
6499                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6500     todo_wine
6501     {
6502         ok(r == ERROR_BAD_CONFIGURATION,
6503            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6504         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6505         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6506     }
6507
6508     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6510
6511     /* Version value exists */
6512     sz = MAX_PATH;
6513     lstrcpyA(buf, "apple");
6514     r = pMsiGetProductInfoExA(prodcode, NULL,
6515                               MSIINSTALLCONTEXT_MACHINE,
6516                               INSTALLPROPERTY_VERSION, buf, &sz);
6517     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6518     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6519     ok(sz == 3, "Expected 3, got %d\n", sz);
6520
6521     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6522     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6523
6524     /* ProductIcon value exists */
6525     sz = MAX_PATH;
6526     lstrcpyA(buf, "apple");
6527     r = pMsiGetProductInfoExA(prodcode, NULL,
6528                               MSIINSTALLCONTEXT_MACHINE,
6529                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6530     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6531     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6532     ok(sz == 4, "Expected 4, got %d\n", sz);
6533
6534     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6535     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6536
6537     /* PackageName value exists */
6538     sz = MAX_PATH;
6539     lstrcpyA(buf, "apple");
6540     r = pMsiGetProductInfoExA(prodcode, NULL,
6541                               MSIINSTALLCONTEXT_MACHINE,
6542                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6543     todo_wine
6544     {
6545         ok(r == ERROR_UNKNOWN_PRODUCT,
6546            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6547         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6548         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6549     }
6550
6551     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6552     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6553
6554     /* AuthorizedLUAApp value exists */
6555     sz = MAX_PATH;
6556     lstrcpyA(buf, "apple");
6557     r = pMsiGetProductInfoExA(prodcode, NULL,
6558                               MSIINSTALLCONTEXT_MACHINE,
6559                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6560     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6561     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6562     ok(sz == 4, "Expected 4, got %d\n", sz);
6563
6564     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6565     RegDeleteValueA(prodkey, "PackageName");
6566     RegDeleteValueA(prodkey, "ProductIcon");
6567     RegDeleteValueA(prodkey, "Version");
6568     RegDeleteValueA(prodkey, "PackageCode");
6569     RegDeleteValueA(prodkey, "AssignmentType");
6570     RegDeleteValueA(prodkey, "ProductName");
6571     RegDeleteValueA(prodkey, "Language");
6572     RegDeleteValueA(prodkey, "Transforms");
6573     RegDeleteValueA(prodkey, "RegOwner");
6574     RegDeleteValueA(prodkey, "RegCompany");
6575     RegDeleteValueA(prodkey, "ProductID");
6576     RegDeleteValueA(prodkey, "DisplayVersion");
6577     RegDeleteValueA(prodkey, "VersionMajor");
6578     RegDeleteValueA(prodkey, "VersionMinor");
6579     RegDeleteValueA(prodkey, "URLUpdateInfo");
6580     RegDeleteValueA(prodkey, "URLInfoAbout");
6581     RegDeleteValueA(prodkey, "Publisher");
6582     RegDeleteValueA(prodkey, "LocalPackage");
6583     RegDeleteValueA(prodkey, "InstallSource");
6584     RegDeleteValueA(prodkey, "InstallLocation");
6585     RegDeleteValueA(prodkey, "DisplayName");
6586     RegDeleteValueA(prodkey, "InstallDate");
6587     RegDeleteValueA(prodkey, "HelpTelephone");
6588     RegDeleteValueA(prodkey, "HelpLink");
6589     RegDeleteKeyA(prodkey, "");
6590     RegCloseKey(prodkey);
6591     LocalFree(usersid);
6592 }
6593
6594 #define INIT_USERINFO() \
6595     lstrcpyA(user, "apple"); \
6596     lstrcpyA(org, "orange"); \
6597     lstrcpyA(serial, "banana"); \
6598     usersz = orgsz = serialsz = MAX_PATH;
6599
6600 static void test_MsiGetUserInfo(void)
6601 {
6602     USERINFOSTATE state;
6603     CHAR user[MAX_PATH];
6604     CHAR org[MAX_PATH];
6605     CHAR serial[MAX_PATH];
6606     DWORD usersz, orgsz, serialsz;
6607     CHAR keypath[MAX_PATH * 2];
6608     CHAR prodcode[MAX_PATH];
6609     CHAR prod_squashed[MAX_PATH];
6610     HKEY prodkey, userprod, props;
6611     LPSTR usersid;
6612     LONG res;
6613
6614     create_test_guid(prodcode, prod_squashed);
6615     get_user_sid(&usersid);
6616
6617     /* NULL szProduct */
6618     INIT_USERINFO();
6619     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6620     ok(state == USERINFOSTATE_INVALIDARG,
6621        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6622     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6623     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6624     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6625     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6626     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6627     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6628
6629     /* empty szProductCode */
6630     INIT_USERINFO();
6631     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6632     ok(state == USERINFOSTATE_INVALIDARG,
6633        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6634     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6635     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6636     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6637     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6638     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6639     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6640
6641     /* garbage szProductCode */
6642     INIT_USERINFO();
6643     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6644     ok(state == USERINFOSTATE_INVALIDARG,
6645        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6646     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6647     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6648     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6649     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6650     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6651     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6652
6653     /* guid without brackets */
6654     INIT_USERINFO();
6655     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6656                             user, &usersz, org, &orgsz, serial, &serialsz);
6657     ok(state == USERINFOSTATE_INVALIDARG,
6658        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6659     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6660     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6661     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6662     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6663     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6664     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6665
6666     /* guid with brackets */
6667     INIT_USERINFO();
6668     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6669                             user, &usersz, org, &orgsz, serial, &serialsz);
6670     ok(state == USERINFOSTATE_UNKNOWN,
6671        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6672     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6673     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6674     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6675     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6676     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6677     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6678
6679     /* NULL lpUserNameBuf */
6680     INIT_USERINFO();
6681     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6682     ok(state == USERINFOSTATE_UNKNOWN,
6683        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6684     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6685     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6686     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6687     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6688     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6689
6690     /* NULL pcchUserNameBuf */
6691     INIT_USERINFO();
6692     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6693     ok(state == USERINFOSTATE_INVALIDARG,
6694        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6695     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6696     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6697     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6698     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6699     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6700
6701     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6702     INIT_USERINFO();
6703     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6704     ok(state == USERINFOSTATE_UNKNOWN,
6705        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6706     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6707     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6708     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6709     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6710
6711     /* NULL lpOrgNameBuf */
6712     INIT_USERINFO();
6713     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6714     ok(state == USERINFOSTATE_UNKNOWN,
6715        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6716     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6717     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6718     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6719     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6720     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6721
6722     /* NULL pcchOrgNameBuf */
6723     INIT_USERINFO();
6724     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
6725     ok(state == USERINFOSTATE_INVALIDARG,
6726        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6727     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6728     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6729     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6730     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6731     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6732
6733     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
6734     INIT_USERINFO();
6735     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
6736     ok(state == USERINFOSTATE_UNKNOWN,
6737        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6738     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6739     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6740     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6741     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6742
6743     /* NULL lpSerialBuf */
6744     INIT_USERINFO();
6745     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
6746     ok(state == USERINFOSTATE_UNKNOWN,
6747        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6748     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6749     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6750     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6751     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6752     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6753
6754     /* NULL pcchSerialBuf */
6755     INIT_USERINFO();
6756     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
6757     ok(state == USERINFOSTATE_INVALIDARG,
6758        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6759     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6760     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6761     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6762     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6763     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6764
6765     /* both lpSerialBuf and pcchSerialBuf NULL */
6766     INIT_USERINFO();
6767     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
6768     ok(state == USERINFOSTATE_UNKNOWN,
6769        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6770     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6771     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6772     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6773     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6774
6775     /* MSIINSTALLCONTEXT_USERMANAGED */
6776
6777     /* create local system product key */
6778     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6779     lstrcatA(keypath, usersid);
6780     lstrcatA(keypath, "\\Installer\\Products\\");
6781     lstrcatA(keypath, prod_squashed);
6782
6783     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6784     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6785
6786     /* managed product key exists */
6787     INIT_USERINFO();
6788     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6789     ok(state == USERINFOSTATE_ABSENT,
6790        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6791     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6792     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6793     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6794     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6795     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6796     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6797
6798     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6799     lstrcatA(keypath, "Installer\\UserData\\");
6800     lstrcatA(keypath, usersid);
6801     lstrcatA(keypath, "\\Products\\");
6802     lstrcatA(keypath, prod_squashed);
6803
6804     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6805     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6806
6807     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6808     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6809
6810     /* InstallProperties key exists */
6811     INIT_USERINFO();
6812     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6813     ok(state == USERINFOSTATE_ABSENT,
6814        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6815     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6816     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6817     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6818     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6819     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6820     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6821
6822     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6823     INIT_USERINFO();
6824     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6825     ok(state == USERINFOSTATE_ABSENT,
6826        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6827     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6828     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6829     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6830     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6831
6832     /* RegOwner, RegCompany don't exist, out params are NULL */
6833     INIT_USERINFO();
6834     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6835     ok(state == USERINFOSTATE_ABSENT,
6836        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6837     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6838     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6839
6840     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6841     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6842
6843     /* RegOwner value exists */
6844     INIT_USERINFO();
6845     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6846     ok(state == USERINFOSTATE_ABSENT,
6847        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6848     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6849     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6850     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6851     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6852     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6853     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6854
6855     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6856     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6857
6858     /* RegCompany value exists */
6859     INIT_USERINFO();
6860     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6861     ok(state == USERINFOSTATE_ABSENT,
6862        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6863     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6864     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6865     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6866     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6867     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6868     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6869
6870     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6871     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6872
6873     /* ProductID value exists */
6874     INIT_USERINFO();
6875     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6876     ok(state == USERINFOSTATE_PRESENT,
6877        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6878     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6879     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6880     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6881     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6882     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6883     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6884
6885     /* pcchUserNameBuf is too small */
6886     INIT_USERINFO();
6887     usersz = 0;
6888     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6889     ok(state == USERINFOSTATE_MOREDATA,
6890        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6891     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6892     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6893     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6894     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6895     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6896     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6897
6898     /* pcchUserNameBuf has no room for NULL terminator */
6899     INIT_USERINFO();
6900     usersz = 5;
6901     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6902     ok(state == USERINFOSTATE_MOREDATA,
6903        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6904     todo_wine
6905     {
6906         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6907     }
6908     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6909     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6910     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6911     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6912     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6913
6914     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
6915     INIT_USERINFO();
6916     usersz = 0;
6917     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6918     ok(state == USERINFOSTATE_PRESENT,
6919        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6920     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6921     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6922     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6923     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6924     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6925     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6926
6927     RegDeleteValueA(props, "ProductID");
6928     RegDeleteValueA(props, "RegCompany");
6929     RegDeleteValueA(props, "RegOwner");
6930     RegDeleteKeyA(props, "");
6931     RegCloseKey(props);
6932     RegDeleteKeyA(userprod, "");
6933     RegCloseKey(userprod);
6934     RegDeleteKeyA(prodkey, "");
6935     RegCloseKey(prodkey);
6936
6937     /* MSIINSTALLCONTEXT_USERUNMANAGED */
6938
6939     /* create local system product key */
6940     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6941     lstrcatA(keypath, prod_squashed);
6942
6943     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6945
6946     /* product key exists */
6947     INIT_USERINFO();
6948     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6949     ok(state == USERINFOSTATE_ABSENT,
6950        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6951     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6952     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6953     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6954     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6955     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6956     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6957
6958     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6959     lstrcatA(keypath, "Installer\\UserData\\");
6960     lstrcatA(keypath, usersid);
6961     lstrcatA(keypath, "\\Products\\");
6962     lstrcatA(keypath, prod_squashed);
6963
6964     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6965     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6966
6967     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6968     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6969
6970     /* InstallProperties key exists */
6971     INIT_USERINFO();
6972     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6973     ok(state == USERINFOSTATE_ABSENT,
6974        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6975     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6976     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6977     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6978     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6979     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6980     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6981
6982     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6983     INIT_USERINFO();
6984     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6985     ok(state == USERINFOSTATE_ABSENT,
6986        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6987     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6988     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6989     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6990     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6991
6992     /* RegOwner, RegCompany don't exist, out params are NULL */
6993     INIT_USERINFO();
6994     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6995     ok(state == USERINFOSTATE_ABSENT,
6996        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6997     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6998     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6999
7000     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7001     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7002
7003     /* RegOwner value exists */
7004     INIT_USERINFO();
7005     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7006     ok(state == USERINFOSTATE_ABSENT,
7007        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7008     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7009     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7010     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7011     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7012     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7013     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7014
7015     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7016     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7017
7018     /* RegCompany value exists */
7019     INIT_USERINFO();
7020     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7021     ok(state == USERINFOSTATE_ABSENT,
7022        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7023     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7024     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7025     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7026     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7027     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7028     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7029
7030     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7032
7033     /* ProductID value exists */
7034     INIT_USERINFO();
7035     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7036     ok(state == USERINFOSTATE_PRESENT,
7037        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7038     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7039     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7040     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7041     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7042     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7043     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7044
7045     RegDeleteValueA(props, "ProductID");
7046     RegDeleteValueA(props, "RegCompany");
7047     RegDeleteValueA(props, "RegOwner");
7048     RegDeleteKeyA(props, "");
7049     RegCloseKey(props);
7050     RegDeleteKeyA(userprod, "");
7051     RegCloseKey(userprod);
7052     RegDeleteKeyA(prodkey, "");
7053     RegCloseKey(prodkey);
7054
7055     /* MSIINSTALLCONTEXT_MACHINE */
7056
7057     /* create local system product key */
7058     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7059     lstrcatA(keypath, prod_squashed);
7060
7061     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7062     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7063
7064     /* product key exists */
7065     INIT_USERINFO();
7066     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7067     ok(state == USERINFOSTATE_ABSENT,
7068        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7069     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7070     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7071     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7072     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7073     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7074     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7075
7076     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7077     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7078     lstrcatA(keypath, "\\Products\\");
7079     lstrcatA(keypath, prod_squashed);
7080
7081     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
7082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7083
7084     res = RegCreateKeyA(userprod, "InstallProperties", &props);
7085     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7086
7087     /* InstallProperties key exists */
7088     INIT_USERINFO();
7089     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7090     ok(state == USERINFOSTATE_ABSENT,
7091        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7092     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7093     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7094     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7095     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7096     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7097     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7098
7099     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7100     INIT_USERINFO();
7101     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7102     ok(state == USERINFOSTATE_ABSENT,
7103        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7104     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7105     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7106     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7107     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7108
7109     /* RegOwner, RegCompany don't exist, out params are NULL */
7110     INIT_USERINFO();
7111     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7112     ok(state == USERINFOSTATE_ABSENT,
7113        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7114     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7115     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7116
7117     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7119
7120     /* RegOwner value exists */
7121     INIT_USERINFO();
7122     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7123     ok(state == USERINFOSTATE_ABSENT,
7124        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7125     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7126     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7127     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7128     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7129     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7130     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7131
7132     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7133     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7134
7135     /* RegCompany value exists */
7136     INIT_USERINFO();
7137     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7138     ok(state == USERINFOSTATE_ABSENT,
7139        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7140     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7141     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7142     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7143     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7144     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7145     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7146
7147     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7148     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7149
7150     /* ProductID value exists */
7151     INIT_USERINFO();
7152     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7153     ok(state == USERINFOSTATE_PRESENT,
7154        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7155     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7156     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7157     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7158     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7159     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7160     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7161
7162     RegDeleteValueA(props, "ProductID");
7163     RegDeleteValueA(props, "RegCompany");
7164     RegDeleteValueA(props, "RegOwner");
7165     RegDeleteKeyA(props, "");
7166     RegCloseKey(props);
7167     RegDeleteKeyA(userprod, "");
7168     RegCloseKey(userprod);
7169     RegDeleteKeyA(prodkey, "");
7170     RegCloseKey(prodkey);
7171     LocalFree(usersid);
7172 }
7173
7174 static void test_MsiOpenProduct(void)
7175 {
7176     MSIHANDLE hprod, hdb;
7177     CHAR val[MAX_PATH];
7178     CHAR path[MAX_PATH];
7179     CHAR keypath[MAX_PATH*2];
7180     CHAR prodcode[MAX_PATH];
7181     CHAR prod_squashed[MAX_PATH];
7182     HKEY prodkey, userkey, props;
7183     LPSTR usersid;
7184     DWORD size;
7185     LONG res;
7186     UINT r;
7187
7188     GetCurrentDirectoryA(MAX_PATH, path);
7189     lstrcatA(path, "\\");
7190
7191     create_test_guid(prodcode, prod_squashed);
7192     get_user_sid(&usersid);
7193
7194     hdb = create_package_db(prodcode);
7195     MsiCloseHandle(hdb);
7196
7197     /* NULL szProduct */
7198     hprod = 0xdeadbeef;
7199     r = MsiOpenProductA(NULL, &hprod);
7200     ok(r == ERROR_INVALID_PARAMETER,
7201        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7202     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7203
7204     /* empty szProduct */
7205     hprod = 0xdeadbeef;
7206     r = MsiOpenProductA("", &hprod);
7207     ok(r == ERROR_INVALID_PARAMETER,
7208        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7209     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7210
7211     /* garbage szProduct */
7212     hprod = 0xdeadbeef;
7213     r = MsiOpenProductA("garbage", &hprod);
7214     ok(r == ERROR_INVALID_PARAMETER,
7215        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7216     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7217
7218     /* guid without brackets */
7219     hprod = 0xdeadbeef;
7220     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7221     ok(r == ERROR_INVALID_PARAMETER,
7222        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7223     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7224
7225     /* guid with brackets */
7226     hprod = 0xdeadbeef;
7227     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7228     ok(r == ERROR_UNKNOWN_PRODUCT,
7229        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7230     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7231
7232     /* same length as guid, but random */
7233     hprod = 0xdeadbeef;
7234     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7235     ok(r == ERROR_INVALID_PARAMETER,
7236        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7237     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7238
7239     /* hProduct is NULL */
7240     hprod = 0xdeadbeef;
7241     r = MsiOpenProductA(prodcode, NULL);
7242     ok(r == ERROR_INVALID_PARAMETER,
7243        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7244     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7245
7246     /* MSIINSTALLCONTEXT_USERMANAGED */
7247
7248     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7249     lstrcatA(keypath, "Installer\\Managed\\");
7250     lstrcatA(keypath, usersid);
7251     lstrcatA(keypath, "\\Installer\\Products\\");
7252     lstrcatA(keypath, prod_squashed);
7253
7254     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7255     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7256
7257     /* managed product key exists */
7258     hprod = 0xdeadbeef;
7259     r = MsiOpenProductA(prodcode, &hprod);
7260     ok(r == ERROR_UNKNOWN_PRODUCT,
7261        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7262     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7263
7264     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7265     lstrcatA(keypath, "Installer\\UserData\\");
7266     lstrcatA(keypath, usersid);
7267     lstrcatA(keypath, "\\Products\\");
7268     lstrcatA(keypath, prod_squashed);
7269
7270     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7271     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7272
7273     /* user product key exists */
7274     hprod = 0xdeadbeef;
7275     r = MsiOpenProductA(prodcode, &hprod);
7276     ok(r == ERROR_UNKNOWN_PRODUCT,
7277        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7278     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7279
7280     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7281     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7282
7283     /* InstallProperties key exists */
7284     hprod = 0xdeadbeef;
7285     r = MsiOpenProductA(prodcode, &hprod);
7286     ok(r == ERROR_UNKNOWN_PRODUCT,
7287        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7288     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7289
7290     lstrcpyA(val, path);
7291     lstrcatA(val, "\\winetest.msi");
7292     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7293                          (const BYTE *)val, lstrlenA(val) + 1);
7294     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7295
7296     /* ManagedLocalPackage value exists */
7297     hprod = 0xdeadbeef;
7298     r = MsiOpenProductA(prodcode, &hprod);
7299     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7300     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7301
7302     size = MAX_PATH;
7303     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7304     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7305     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7306     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7307
7308     MsiCloseHandle(hprod);
7309
7310     RegDeleteValueA(props, "ManagedLocalPackage");
7311     RegDeleteKeyA(props, "");
7312     RegCloseKey(props);
7313     RegDeleteKeyA(userkey, "");
7314     RegCloseKey(userkey);
7315     RegDeleteKeyA(prodkey, "");
7316     RegCloseKey(prodkey);
7317
7318     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7319
7320     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7321     lstrcatA(keypath, prod_squashed);
7322
7323     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7325
7326     /* unmanaged product key exists */
7327     hprod = 0xdeadbeef;
7328     r = MsiOpenProductA(prodcode, &hprod);
7329     ok(r == ERROR_UNKNOWN_PRODUCT,
7330        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7331     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7332
7333     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7334     lstrcatA(keypath, "Installer\\UserData\\");
7335     lstrcatA(keypath, usersid);
7336     lstrcatA(keypath, "\\Products\\");
7337     lstrcatA(keypath, prod_squashed);
7338
7339     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7340     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7341
7342     /* user product key exists */
7343     hprod = 0xdeadbeef;
7344     r = MsiOpenProductA(prodcode, &hprod);
7345     ok(r == ERROR_UNKNOWN_PRODUCT,
7346        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7347     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7348
7349     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7351
7352     /* InstallProperties key exists */
7353     hprod = 0xdeadbeef;
7354     r = MsiOpenProductA(prodcode, &hprod);
7355     ok(r == ERROR_UNKNOWN_PRODUCT,
7356        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7357     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7358
7359     lstrcpyA(val, path);
7360     lstrcatA(val, "\\winetest.msi");
7361     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7362                          (const BYTE *)val, lstrlenA(val) + 1);
7363     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7364
7365     /* LocalPackage value exists */
7366     hprod = 0xdeadbeef;
7367     r = MsiOpenProductA(prodcode, &hprod);
7368     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7369     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7370
7371     size = MAX_PATH;
7372     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7373     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7374     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7375     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7376
7377     MsiCloseHandle(hprod);
7378
7379     RegDeleteValueA(props, "LocalPackage");
7380     RegDeleteKeyA(props, "");
7381     RegCloseKey(props);
7382     RegDeleteKeyA(userkey, "");
7383     RegCloseKey(userkey);
7384     RegDeleteKeyA(prodkey, "");
7385     RegCloseKey(prodkey);
7386
7387     /* MSIINSTALLCONTEXT_MACHINE */
7388
7389     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7390     lstrcatA(keypath, prod_squashed);
7391
7392     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7393     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7394
7395     /* managed product key exists */
7396     hprod = 0xdeadbeef;
7397     r = MsiOpenProductA(prodcode, &hprod);
7398     ok(r == ERROR_UNKNOWN_PRODUCT,
7399        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7400     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7401
7402     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7403     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7404     lstrcatA(keypath, prod_squashed);
7405
7406     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7407     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7408
7409     /* user product key exists */
7410     hprod = 0xdeadbeef;
7411     r = MsiOpenProductA(prodcode, &hprod);
7412     ok(r == ERROR_UNKNOWN_PRODUCT,
7413        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7414     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7415
7416     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7418
7419     /* InstallProperties key exists */
7420     hprod = 0xdeadbeef;
7421     r = MsiOpenProductA(prodcode, &hprod);
7422     ok(r == ERROR_UNKNOWN_PRODUCT,
7423        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7424     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7425
7426     lstrcpyA(val, path);
7427     lstrcatA(val, "\\winetest.msi");
7428     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7429                          (const BYTE *)val, lstrlenA(val) + 1);
7430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7431
7432     /* LocalPackage value exists */
7433     hprod = 0xdeadbeef;
7434     r = MsiOpenProductA(prodcode, &hprod);
7435     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7436     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7437
7438     size = MAX_PATH;
7439     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7441     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7442     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7443
7444     MsiCloseHandle(hprod);
7445
7446     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7447                          (const BYTE *)"winetest.msi", 13);
7448     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7449
7450     /* LocalPackage has just the package name */
7451     hprod = 0xdeadbeef;
7452     r = MsiOpenProductA(prodcode, &hprod);
7453     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7454        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7455     if (r == ERROR_SUCCESS)
7456         MsiCloseHandle(hprod);
7457     else
7458         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7459
7460     lstrcpyA(val, path);
7461     lstrcatA(val, "\\winetest.msi");
7462     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7463                          (const BYTE *)val, lstrlenA(val) + 1);
7464     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7465
7466     DeleteFileA(msifile);
7467
7468     /* local package does not exist */
7469     hprod = 0xdeadbeef;
7470     r = MsiOpenProductA(prodcode, &hprod);
7471     ok(r == ERROR_UNKNOWN_PRODUCT,
7472        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7473     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7474
7475     RegDeleteValueA(props, "LocalPackage");
7476     RegDeleteKeyA(props, "");
7477     RegCloseKey(props);
7478     RegDeleteKeyA(userkey, "");
7479     RegCloseKey(userkey);
7480     RegDeleteKeyA(prodkey, "");
7481     RegCloseKey(prodkey);
7482
7483     DeleteFileA(msifile);
7484     LocalFree(usersid);
7485 }
7486
7487 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7488 {
7489     MSIINSTALLCONTEXT context;
7490     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7491     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7492     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7493     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7494     HKEY prodkey, patches, udprod, udpatch, hpatch;
7495     DWORD size, data;
7496     LONG res;
7497     UINT r;
7498
7499     create_test_guid(prodcode, prod_squashed);
7500     create_test_guid(patch, patch_squashed);
7501
7502     /* MSIPATCHSTATE_APPLIED */
7503
7504     lstrcpyA(patchcode, "apple");
7505     lstrcpyA(targetprod, "banana");
7506     context = 0xdeadbeef;
7507     lstrcpyA(targetsid, "kiwi");
7508     size = MAX_PATH;
7509     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7510                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7511                            &context, targetsid, &size);
7512     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7513     ok(!lstrcmpA(patchcode, "apple"),
7514        "Expected patchcode to be unchanged, got %s\n", patchcode);
7515     ok(!lstrcmpA(targetprod, "banana"),
7516        "Expected targetprod to be unchanged, got %s\n", targetprod);
7517     ok(context == 0xdeadbeef,
7518        "Expected context to be unchanged, got %d\n", context);
7519     ok(!lstrcmpA(targetsid, "kiwi"),
7520        "Expected targetsid to be unchanged, got %s\n", targetsid);
7521     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7522
7523     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7524     lstrcatA(keypath, expectedsid);
7525     lstrcatA(keypath, "\\Installer\\Products\\");
7526     lstrcatA(keypath, prod_squashed);
7527
7528     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7530
7531     /* managed product key exists */
7532     lstrcpyA(patchcode, "apple");
7533     lstrcpyA(targetprod, "banana");
7534     context = 0xdeadbeef;
7535     lstrcpyA(targetsid, "kiwi");
7536     size = MAX_PATH;
7537     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7538                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7539                            &context, targetsid, &size);
7540     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7541     ok(!lstrcmpA(patchcode, "apple"),
7542        "Expected patchcode to be unchanged, got %s\n", patchcode);
7543     ok(!lstrcmpA(targetprod, "banana"),
7544        "Expected targetprod to be unchanged, got %s\n", targetprod);
7545     ok(context == 0xdeadbeef,
7546        "Expected context to be unchanged, got %d\n", context);
7547     ok(!lstrcmpA(targetsid, "kiwi"),
7548        "Expected targetsid to be unchanged, got %s\n", targetsid);
7549     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7550
7551     res = RegCreateKeyA(prodkey, "Patches", &patches);
7552     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7553
7554     /* patches key exists */
7555     lstrcpyA(patchcode, "apple");
7556     lstrcpyA(targetprod, "banana");
7557     context = 0xdeadbeef;
7558     lstrcpyA(targetsid, "kiwi");
7559     size = MAX_PATH;
7560     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7561                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7562                            &context, targetsid, &size);
7563     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7564     ok(!lstrcmpA(patchcode, "apple"),
7565        "Expected patchcode to be unchanged, got %s\n", patchcode);
7566     ok(!lstrcmpA(targetprod, "banana"),
7567        "Expected targetprod to be unchanged, got %s\n", targetprod);
7568     ok(context == 0xdeadbeef,
7569        "Expected context to be unchanged, got %d\n", context);
7570     ok(!lstrcmpA(targetsid, "kiwi"),
7571        "Expected targetsid to be unchanged, got %s\n", targetsid);
7572     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7573
7574     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7575                          (const BYTE *)patch_squashed,
7576                          lstrlenA(patch_squashed) + 1);
7577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7578
7579     /* Patches value exists, is not REG_MULTI_SZ */
7580     lstrcpyA(patchcode, "apple");
7581     lstrcpyA(targetprod, "banana");
7582     context = 0xdeadbeef;
7583     lstrcpyA(targetsid, "kiwi");
7584     size = MAX_PATH;
7585     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7586                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7587                            &context, targetsid, &size);
7588     ok(r == ERROR_BAD_CONFIGURATION,
7589        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7590     ok(!lstrcmpA(patchcode, "apple"),
7591        "Expected patchcode to be unchanged, got %s\n", patchcode);
7592     ok(!lstrcmpA(targetprod, "banana"),
7593        "Expected targetprod to be unchanged, got %s\n", targetprod);
7594     ok(context == 0xdeadbeef,
7595        "Expected context to be unchanged, got %d\n", context);
7596     ok(!lstrcmpA(targetsid, "kiwi"),
7597        "Expected targetsid to be unchanged, got %s\n", targetsid);
7598     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7599
7600     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7601                          (const BYTE *)"a\0b\0c\0\0", 7);
7602     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7603
7604     /* Patches value exists, is not a squashed guid */
7605     lstrcpyA(patchcode, "apple");
7606     lstrcpyA(targetprod, "banana");
7607     context = 0xdeadbeef;
7608     lstrcpyA(targetsid, "kiwi");
7609     size = MAX_PATH;
7610     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7611                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7612                            &context, targetsid, &size);
7613     ok(r == ERROR_BAD_CONFIGURATION,
7614        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7615     ok(!lstrcmpA(patchcode, "apple"),
7616        "Expected patchcode to be unchanged, got %s\n", patchcode);
7617     ok(!lstrcmpA(targetprod, "banana"),
7618        "Expected targetprod to be unchanged, got %s\n", targetprod);
7619     ok(context == 0xdeadbeef,
7620        "Expected context to be unchanged, got %d\n", context);
7621     ok(!lstrcmpA(targetsid, "kiwi"),
7622        "Expected targetsid to be unchanged, got %s\n", targetsid);
7623     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7624
7625     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
7626     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7627                          (const BYTE *)patch_squashed,
7628                          lstrlenA(patch_squashed) + 2);
7629     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7630
7631     /* Patches value exists */
7632     lstrcpyA(patchcode, "apple");
7633     lstrcpyA(targetprod, "banana");
7634     context = 0xdeadbeef;
7635     lstrcpyA(targetsid, "kiwi");
7636     size = MAX_PATH;
7637     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7638                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7639                            &context, targetsid, &size);
7640     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7641     ok(!lstrcmpA(patchcode, "apple"),
7642        "Expected patchcode to be unchanged, got %s\n", patchcode);
7643     ok(!lstrcmpA(targetprod, "banana"),
7644        "Expected targetprod to be unchanged, got %s\n", targetprod);
7645     ok(context == 0xdeadbeef,
7646        "Expected context to be unchanged, got %d\n", context);
7647     ok(!lstrcmpA(targetsid, "kiwi"),
7648        "Expected targetsid to be unchanged, got %s\n", targetsid);
7649     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7650
7651     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7652                          (const BYTE *)"whatever", 9);
7653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7654
7655     /* patch squashed value exists */
7656     lstrcpyA(patchcode, "apple");
7657     lstrcpyA(targetprod, "banana");
7658     context = 0xdeadbeef;
7659     lstrcpyA(targetsid, "kiwi");
7660     size = MAX_PATH;
7661     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7662                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
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(!lstrcmpA(targetprod, prodcode),
7668        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7669     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7670        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7671     ok(!lstrcmpA(targetsid, expectedsid),
7672        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7673     ok(size == lstrlenA(expectedsid),
7674        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7675
7676     /* increase the index */
7677     lstrcpyA(patchcode, "apple");
7678     lstrcpyA(targetprod, "banana");
7679     context = 0xdeadbeef;
7680     lstrcpyA(targetsid, "kiwi");
7681     size = MAX_PATH;
7682     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7683                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7684                            &context, targetsid, &size);
7685     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7686     ok(!lstrcmpA(patchcode, "apple"),
7687        "Expected patchcode to be unchanged, got %s\n", patchcode);
7688     ok(!lstrcmpA(targetprod, "banana"),
7689        "Expected targetprod to be unchanged, got %s\n", targetprod);
7690     ok(context == 0xdeadbeef,
7691        "Expected context to be unchanged, got %d\n", context);
7692     ok(!lstrcmpA(targetsid, "kiwi"),
7693        "Expected targetsid to be unchanged, got %s\n", targetsid);
7694     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7695
7696     /* increase again */
7697     lstrcpyA(patchcode, "apple");
7698     lstrcpyA(targetprod, "banana");
7699     context = 0xdeadbeef;
7700     lstrcpyA(targetsid, "kiwi");
7701     size = MAX_PATH;
7702     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7703                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
7704                            &context, targetsid, &size);
7705     ok(r == ERROR_INVALID_PARAMETER,
7706        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7707     ok(!lstrcmpA(patchcode, "apple"),
7708        "Expected patchcode to be unchanged, got %s\n", patchcode);
7709     ok(!lstrcmpA(targetprod, "banana"),
7710        "Expected targetprod to be unchanged, got %s\n", targetprod);
7711     ok(context == 0xdeadbeef,
7712        "Expected context to be unchanged, got %d\n", context);
7713     ok(!lstrcmpA(targetsid, "kiwi"),
7714        "Expected targetsid to be unchanged, got %s\n", targetsid);
7715     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7716
7717     /* szPatchCode is NULL */
7718     lstrcpyA(targetprod, "banana");
7719     context = 0xdeadbeef;
7720     lstrcpyA(targetsid, "kiwi");
7721     size = MAX_PATH;
7722     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7723                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
7724                            &context, targetsid, &size);
7725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7726     ok(!lstrcmpA(targetprod, prodcode),
7727        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7728     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7729        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7730     ok(!lstrcmpA(targetsid, expectedsid),
7731        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7732     ok(size == lstrlenA(expectedsid),
7733        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7734
7735     /* szTargetProductCode is NULL */
7736     lstrcpyA(patchcode, "apple");
7737     context = 0xdeadbeef;
7738     lstrcpyA(targetsid, "kiwi");
7739     size = MAX_PATH;
7740     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7741                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
7742                            &context, targetsid, &size);
7743     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7744     ok(!lstrcmpA(patchcode, patch),
7745        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7746     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7747        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7748     ok(!lstrcmpA(targetsid, expectedsid),
7749        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7750     ok(size == lstrlenA(expectedsid),
7751        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7752
7753     /* pdwTargetProductContext is NULL */
7754     lstrcpyA(patchcode, "apple");
7755     lstrcpyA(targetprod, "banana");
7756     lstrcpyA(targetsid, "kiwi");
7757     size = MAX_PATH;
7758     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7759                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7760                            NULL, targetsid, &size);
7761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7762     ok(!lstrcmpA(patchcode, patch),
7763        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7764     ok(!lstrcmpA(targetprod, prodcode),
7765        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7766     ok(!lstrcmpA(targetsid, expectedsid),
7767        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7768     ok(size == lstrlenA(expectedsid),
7769        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7770
7771     /* szTargetUserSid is NULL */
7772     lstrcpyA(patchcode, "apple");
7773     lstrcpyA(targetprod, "banana");
7774     context = 0xdeadbeef;
7775     size = MAX_PATH;
7776     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7777                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7778                            &context, NULL, &size);
7779     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7780     ok(!lstrcmpA(patchcode, patch),
7781        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7782     ok(!lstrcmpA(targetprod, prodcode),
7783        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7784     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7785        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7786     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7787        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
7788
7789     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
7790     lstrcpyA(patchcode, "apple");
7791     lstrcpyA(targetprod, "banana");
7792     context = 0xdeadbeef;
7793     lstrcpyA(targetsid, "kiwi");
7794     size = lstrlenA(expectedsid);
7795     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7796                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7797                            &context, targetsid, &size);
7798     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
7799     ok(!lstrcmpA(patchcode, patch),
7800        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7801     ok(!lstrcmpA(targetprod, prodcode),
7802        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7803     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7804        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7805     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
7806        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7807     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7808        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
7809
7810     /* pcchTargetUserSid has enough room for NULL terminator */
7811     lstrcpyA(patchcode, "apple");
7812     lstrcpyA(targetprod, "banana");
7813     context = 0xdeadbeef;
7814     lstrcpyA(targetsid, "kiwi");
7815     size = lstrlenA(expectedsid) + 1;
7816     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7817                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7818                            &context, targetsid, &size);
7819     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7820     ok(!lstrcmpA(patchcode, patch),
7821        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7822     ok(!lstrcmpA(targetprod, prodcode),
7823        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7824     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7825        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7826     ok(!lstrcmpA(targetsid, expectedsid),
7827        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7828     ok(size == lstrlenA(expectedsid),
7829        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7830
7831     /* both szTargetuserSid and pcchTargetUserSid are NULL */
7832     lstrcpyA(patchcode, "apple");
7833     lstrcpyA(targetprod, "banana");
7834     context = 0xdeadbeef;
7835     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7836                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7837                            &context, NULL, NULL);
7838     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7839     ok(!lstrcmpA(patchcode, patch),
7840        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7841     ok(!lstrcmpA(targetprod, prodcode),
7842        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7843     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7844        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7845
7846     /* MSIPATCHSTATE_SUPERSEDED */
7847
7848     lstrcpyA(patchcode, "apple");
7849     lstrcpyA(targetprod, "banana");
7850     context = 0xdeadbeef;
7851     lstrcpyA(targetsid, "kiwi");
7852     size = MAX_PATH;
7853     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7854                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7855                            &context, targetsid, &size);
7856     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7857     ok(!lstrcmpA(patchcode, "apple"),
7858        "Expected patchcode to be unchanged, got %s\n", patchcode);
7859     ok(!lstrcmpA(targetprod, "banana"),
7860        "Expected targetprod to be unchanged, got %s\n", targetprod);
7861     ok(context == 0xdeadbeef,
7862        "Expected context to be unchanged, got %d\n", context);
7863     ok(!lstrcmpA(targetsid, "kiwi"),
7864        "Expected targetsid to be unchanged, got %s\n", targetsid);
7865     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7866
7867     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
7868     lstrcatA(keypath, expectedsid);
7869     lstrcatA(keypath, "\\Products\\");
7870     lstrcatA(keypath, prod_squashed);
7871
7872     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
7873     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7874
7875     /* UserData product key exists */
7876     lstrcpyA(patchcode, "apple");
7877     lstrcpyA(targetprod, "banana");
7878     context = 0xdeadbeef;
7879     lstrcpyA(targetsid, "kiwi");
7880     size = MAX_PATH;
7881     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7882                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7883                            &context, targetsid, &size);
7884     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7885     ok(!lstrcmpA(patchcode, "apple"),
7886        "Expected patchcode to be unchanged, got %s\n", patchcode);
7887     ok(!lstrcmpA(targetprod, "banana"),
7888        "Expected targetprod to be unchanged, got %s\n", targetprod);
7889     ok(context == 0xdeadbeef,
7890        "Expected context to be unchanged, got %d\n", context);
7891     ok(!lstrcmpA(targetsid, "kiwi"),
7892        "Expected targetsid to be unchanged, got %s\n", targetsid);
7893     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7894
7895     res = RegCreateKeyA(udprod, "Patches", &udpatch);
7896     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7897
7898     /* UserData patches key exists */
7899     lstrcpyA(patchcode, "apple");
7900     lstrcpyA(targetprod, "banana");
7901     context = 0xdeadbeef;
7902     lstrcpyA(targetsid, "kiwi");
7903     size = MAX_PATH;
7904     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7905                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7906                            &context, targetsid, &size);
7907     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7908     ok(!lstrcmpA(patchcode, "apple"),
7909        "Expected patchcode to be unchanged, got %s\n", patchcode);
7910     ok(!lstrcmpA(targetprod, "banana"),
7911        "Expected targetprod to be unchanged, got %s\n", targetprod);
7912     ok(context == 0xdeadbeef,
7913        "Expected context to be unchanged, got %d\n", context);
7914     ok(!lstrcmpA(targetsid, "kiwi"),
7915        "Expected targetsid to be unchanged, got %s\n", targetsid);
7916     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7917
7918     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
7919     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7920
7921     /* specific UserData patch key exists */
7922     lstrcpyA(patchcode, "apple");
7923     lstrcpyA(targetprod, "banana");
7924     context = 0xdeadbeef;
7925     lstrcpyA(targetsid, "kiwi");
7926     size = MAX_PATH;
7927     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7928                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7929                            &context, targetsid, &size);
7930     ok(r == ERROR_BAD_CONFIGURATION,
7931        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7932     ok(!lstrcmpA(patchcode, "apple"),
7933        "Expected patchcode to be unchanged, got %s\n", patchcode);
7934     ok(!lstrcmpA(targetprod, "banana"),
7935        "Expected targetprod to be unchanged, got %s\n", targetprod);
7936     ok(context == 0xdeadbeef,
7937        "Expected context to be unchanged, got %d\n", context);
7938     ok(!lstrcmpA(targetsid, "kiwi"),
7939        "Expected targetsid to be unchanged, got %s\n", targetsid);
7940     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7941
7942     data = MSIPATCHSTATE_SUPERSEDED;
7943     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
7944                          (const BYTE *)&data, sizeof(DWORD));
7945     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7946
7947     /* State value exists */
7948     lstrcpyA(patchcode, "apple");
7949     lstrcpyA(targetprod, "banana");
7950     context = 0xdeadbeef;
7951     lstrcpyA(targetsid, "kiwi");
7952     size = MAX_PATH;
7953     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7954                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7955                            &context, targetsid, &size);
7956     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7957     ok(!lstrcmpA(patchcode, patch),
7958        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7959     ok(!lstrcmpA(targetprod, prodcode),
7960        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7961     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7962        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7963     ok(!lstrcmpA(targetsid, expectedsid),
7964        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7965     ok(size == lstrlenA(expectedsid),
7966        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7967
7968     /* MSIPATCHSTATE_OBSOLETED */
7969
7970     lstrcpyA(patchcode, "apple");
7971     lstrcpyA(targetprod, "banana");
7972     context = 0xdeadbeef;
7973     lstrcpyA(targetsid, "kiwi");
7974     size = MAX_PATH;
7975     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7976                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
7977                            &context, targetsid, &size);
7978     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7979     ok(!lstrcmpA(patchcode, "apple"),
7980        "Expected patchcode to be unchanged, got %s\n", patchcode);
7981     ok(!lstrcmpA(targetprod, "banana"),
7982        "Expected targetprod to be unchanged, got %s\n", targetprod);
7983     ok(context == 0xdeadbeef,
7984        "Expected context to be unchanged, got %d\n", context);
7985     ok(!lstrcmpA(targetsid, "kiwi"),
7986        "Expected targetsid to be unchanged, got %s\n", targetsid);
7987     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7988
7989     data = MSIPATCHSTATE_OBSOLETED;
7990     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
7991                          (const BYTE *)&data, sizeof(DWORD));
7992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7993
7994     /* State value is obsoleted */
7995     lstrcpyA(patchcode, "apple");
7996     lstrcpyA(targetprod, "banana");
7997     context = 0xdeadbeef;
7998     lstrcpyA(targetsid, "kiwi");
7999     size = MAX_PATH;
8000     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8001                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8002                            &context, targetsid, &size);
8003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8004     ok(!lstrcmpA(patchcode, patch),
8005        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8006     ok(!lstrcmpA(targetprod, prodcode),
8007        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8008     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8009        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8010     ok(!lstrcmpA(targetsid, expectedsid),
8011        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8012     ok(size == lstrlenA(expectedsid),
8013        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8014
8015     /* MSIPATCHSTATE_REGISTERED */
8016     /* FIXME */
8017
8018     /* MSIPATCHSTATE_ALL */
8019
8020     /* 1st */
8021     lstrcpyA(patchcode, "apple");
8022     lstrcpyA(targetprod, "banana");
8023     context = 0xdeadbeef;
8024     lstrcpyA(targetsid, "kiwi");
8025     size = MAX_PATH;
8026     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8027                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8028                            &context, targetsid, &size);
8029     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8030     ok(!lstrcmpA(patchcode, patch),
8031        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8032     ok(!lstrcmpA(targetprod, prodcode),
8033        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8034     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8035        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8036     ok(!lstrcmpA(targetsid, expectedsid),
8037        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8038     ok(size == lstrlenA(expectedsid),
8039        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8040
8041     /* same patch in multiple places, only one is enumerated */
8042     lstrcpyA(patchcode, "apple");
8043     lstrcpyA(targetprod, "banana");
8044     context = 0xdeadbeef;
8045     lstrcpyA(targetsid, "kiwi");
8046     size = MAX_PATH;
8047     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8048                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8049                            &context, targetsid, &size);
8050     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8051     ok(!lstrcmpA(patchcode, "apple"),
8052        "Expected patchcode to be unchanged, got %s\n", patchcode);
8053     ok(!lstrcmpA(targetprod, "banana"),
8054        "Expected targetprod to be unchanged, got %s\n", targetprod);
8055     ok(context == 0xdeadbeef,
8056        "Expected context to be unchanged, got %d\n", context);
8057     ok(!lstrcmpA(targetsid, "kiwi"),
8058        "Expected targetsid to be unchanged, got %s\n", targetsid);
8059     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8060
8061     RegDeleteValueA(hpatch, "State");
8062     RegDeleteKeyA(hpatch, "");
8063     RegCloseKey(hpatch);
8064     RegDeleteKeyA(udpatch, "");
8065     RegCloseKey(udpatch);
8066     RegDeleteKeyA(udprod, "");
8067     RegCloseKey(udprod);
8068     RegDeleteValueA(patches, "Patches");
8069     RegDeleteKeyA(patches, "");
8070     RegCloseKey(patches);
8071     RegDeleteKeyA(prodkey, "");
8072     RegCloseKey(prodkey);
8073 }
8074
8075 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8076 {
8077     MSIINSTALLCONTEXT context;
8078     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8079     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8080     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8081     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8082     HKEY prodkey, patches, udprod, udpatch;
8083     HKEY userkey, hpatch;
8084     DWORD size, data;
8085     LONG res;
8086     UINT r;
8087
8088     create_test_guid(prodcode, prod_squashed);
8089     create_test_guid(patch, patch_squashed);
8090
8091     /* MSIPATCHSTATE_APPLIED */
8092
8093     lstrcpyA(patchcode, "apple");
8094     lstrcpyA(targetprod, "banana");
8095     context = 0xdeadbeef;
8096     lstrcpyA(targetsid, "kiwi");
8097     size = MAX_PATH;
8098     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8099                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8100                            &context, targetsid, &size);
8101     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8102     ok(!lstrcmpA(patchcode, "apple"),
8103        "Expected patchcode to be unchanged, got %s\n", patchcode);
8104     ok(!lstrcmpA(targetprod, "banana"),
8105        "Expected targetprod to be unchanged, got %s\n", targetprod);
8106     ok(context == 0xdeadbeef,
8107        "Expected context to be unchanged, got %d\n", context);
8108     ok(!lstrcmpA(targetsid, "kiwi"),
8109        "Expected targetsid to be unchanged, got %s\n", targetsid);
8110     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8111
8112     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8113     lstrcatA(keypath, prod_squashed);
8114
8115     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8117
8118     /* current user product key exists */
8119     lstrcpyA(patchcode, "apple");
8120     lstrcpyA(targetprod, "banana");
8121     context = 0xdeadbeef;
8122     lstrcpyA(targetsid, "kiwi");
8123     size = MAX_PATH;
8124     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8125                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8126                            &context, targetsid, &size);
8127     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8128     ok(!lstrcmpA(patchcode, "apple"),
8129        "Expected patchcode to be unchanged, got %s\n", patchcode);
8130     ok(!lstrcmpA(targetprod, "banana"),
8131        "Expected targetprod to be unchanged, got %s\n", targetprod);
8132     ok(context == 0xdeadbeef,
8133        "Expected context to be unchanged, got %d\n", context);
8134     ok(!lstrcmpA(targetsid, "kiwi"),
8135        "Expected targetsid to be unchanged, got %s\n", targetsid);
8136     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8137
8138     res = RegCreateKeyA(prodkey, "Patches", &patches);
8139     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8140
8141     /* Patches key exists */
8142     lstrcpyA(patchcode, "apple");
8143     lstrcpyA(targetprod, "banana");
8144     context = 0xdeadbeef;
8145     lstrcpyA(targetsid, "kiwi");
8146     size = MAX_PATH;
8147     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8148                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8149                            &context, targetsid, &size);
8150     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8151     ok(!lstrcmpA(patchcode, "apple"),
8152        "Expected patchcode to be unchanged, got %s\n", patchcode);
8153     ok(!lstrcmpA(targetprod, "banana"),
8154        "Expected targetprod to be unchanged, got %s\n", targetprod);
8155     ok(context == 0xdeadbeef,
8156        "Expected context to be unchanged, got %d\n", context);
8157     ok(!lstrcmpA(targetsid, "kiwi"),
8158        "Expected targetsid to be unchanged, got %s\n", targetsid);
8159     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8160
8161     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8162                          (const BYTE *)patch_squashed,
8163                          lstrlenA(patch_squashed) + 1);
8164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8165
8166     /* Patches value exists, is not REG_MULTI_SZ */
8167     lstrcpyA(patchcode, "apple");
8168     lstrcpyA(targetprod, "banana");
8169     context = 0xdeadbeef;
8170     lstrcpyA(targetsid, "kiwi");
8171     size = MAX_PATH;
8172     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8173                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8174                            &context, targetsid, &size);
8175     ok(r == ERROR_BAD_CONFIGURATION,
8176        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8177     ok(!lstrcmpA(patchcode, "apple"),
8178        "Expected patchcode to be unchanged, got %s\n", patchcode);
8179     ok(!lstrcmpA(targetprod, "banana"),
8180        "Expected targetprod to be unchanged, got %s\n", targetprod);
8181     ok(context == 0xdeadbeef,
8182        "Expected context to be unchanged, got %d\n", context);
8183     ok(!lstrcmpA(targetsid, "kiwi"),
8184        "Expected targetsid to be unchanged, got %s\n", targetsid);
8185     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8186
8187     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8188                          (const BYTE *)"a\0b\0c\0\0", 7);
8189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8190
8191     /* Patches value exists, is not a squashed guid */
8192     lstrcpyA(patchcode, "apple");
8193     lstrcpyA(targetprod, "banana");
8194     context = 0xdeadbeef;
8195     lstrcpyA(targetsid, "kiwi");
8196     size = MAX_PATH;
8197     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8198                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8199                            &context, targetsid, &size);
8200     ok(r == ERROR_BAD_CONFIGURATION,
8201        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8202     ok(!lstrcmpA(patchcode, "apple"),
8203        "Expected patchcode to be unchanged, got %s\n", patchcode);
8204     ok(!lstrcmpA(targetprod, "banana"),
8205        "Expected targetprod to be unchanged, got %s\n", targetprod);
8206     ok(context == 0xdeadbeef,
8207        "Expected context to be unchanged, got %d\n", context);
8208     ok(!lstrcmpA(targetsid, "kiwi"),
8209        "Expected targetsid to be unchanged, got %s\n", targetsid);
8210     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8211
8212     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8213                          (const BYTE *)patch_squashed,
8214                          lstrlenA(patch_squashed) + 1);
8215     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8216
8217     /* Patches value exists */
8218     lstrcpyA(patchcode, "apple");
8219     lstrcpyA(targetprod, "banana");
8220     context = 0xdeadbeef;
8221     lstrcpyA(targetsid, "kiwi");
8222     size = MAX_PATH;
8223     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8224                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8225                            &context, targetsid, &size);
8226     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8227     ok(!lstrcmpA(patchcode, "apple"),
8228        "Expected patchcode to be unchanged, got %s\n", patchcode);
8229     ok(!lstrcmpA(targetprod, "banana"),
8230        "Expected targetprod to be unchanged, got %s\n", targetprod);
8231     ok(context == 0xdeadbeef,
8232        "Expected context to be unchanged, got %d\n", context);
8233     ok(!lstrcmpA(targetsid, "kiwi"),
8234        "Expected targetsid to be unchanged, got %s\n", targetsid);
8235     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8236
8237     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8238                          (const BYTE *)"whatever", 9);
8239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8240
8241     /* patch code value exists */
8242     lstrcpyA(patchcode, "apple");
8243     lstrcpyA(targetprod, "banana");
8244     context = 0xdeadbeef;
8245     lstrcpyA(targetsid, "kiwi");
8246     size = MAX_PATH;
8247     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8248                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8249                            &context, targetsid, &size);
8250     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8251     ok(!lstrcmpA(patchcode, "apple"),
8252        "Expected patchcode to be unchanged, got %s\n", patchcode);
8253     ok(!lstrcmpA(targetprod, "banana"),
8254        "Expected targetprod to be unchanged, got %s\n", targetprod);
8255     ok(context == 0xdeadbeef,
8256        "Expected context to be unchanged, got %d\n", context);
8257     ok(!lstrcmpA(targetsid, "kiwi"),
8258        "Expected targetsid to be unchanged, got %s\n", targetsid);
8259     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8260
8261     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8262     lstrcatA(keypath, expectedsid);
8263     lstrcatA(keypath, "\\Patches\\");
8264     lstrcatA(keypath, patch_squashed);
8265
8266     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
8267     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8268
8269     /* userdata patch key exists */
8270     lstrcpyA(patchcode, "apple");
8271     lstrcpyA(targetprod, "banana");
8272     context = 0xdeadbeef;
8273     lstrcpyA(targetsid, "kiwi");
8274     size = MAX_PATH;
8275     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8276                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8277                            &context, targetsid, &size);
8278     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8279     ok(!lstrcmpA(patchcode, patch),
8280        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8281     ok(!lstrcmpA(targetprod, prodcode),
8282        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8283     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8284        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8285     ok(!lstrcmpA(targetsid, expectedsid),
8286        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8287     ok(size == lstrlenA(expectedsid),
8288        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8289
8290     /* MSIPATCHSTATE_SUPERSEDED */
8291
8292     lstrcpyA(patchcode, "apple");
8293     lstrcpyA(targetprod, "banana");
8294     context = 0xdeadbeef;
8295     lstrcpyA(targetsid, "kiwi");
8296     size = MAX_PATH;
8297     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8298                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8299                            &context, targetsid, &size);
8300     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8301     ok(!lstrcmpA(patchcode, "apple"),
8302        "Expected patchcode to be unchanged, got %s\n", patchcode);
8303     ok(!lstrcmpA(targetprod, "banana"),
8304        "Expected targetprod to be unchanged, got %s\n", targetprod);
8305     ok(context == 0xdeadbeef,
8306        "Expected context to be unchanged, got %d\n", context);
8307     ok(!lstrcmpA(targetsid, "kiwi"),
8308        "Expected targetsid to be unchanged, got %s\n", targetsid);
8309     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8310
8311     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8312     lstrcatA(keypath, expectedsid);
8313     lstrcatA(keypath, "\\Products\\");
8314     lstrcatA(keypath, prod_squashed);
8315
8316     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8317     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8318
8319     /* UserData product key exists */
8320     lstrcpyA(patchcode, "apple");
8321     lstrcpyA(targetprod, "banana");
8322     context = 0xdeadbeef;
8323     lstrcpyA(targetsid, "kiwi");
8324     size = MAX_PATH;
8325     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8326                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8327                            &context, targetsid, &size);
8328     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8329     ok(!lstrcmpA(patchcode, "apple"),
8330        "Expected patchcode to be unchanged, got %s\n", patchcode);
8331     ok(!lstrcmpA(targetprod, "banana"),
8332        "Expected targetprod to be unchanged, got %s\n", targetprod);
8333     ok(context == 0xdeadbeef,
8334        "Expected context to be unchanged, got %d\n", context);
8335     ok(!lstrcmpA(targetsid, "kiwi"),
8336        "Expected targetsid to be unchanged, got %s\n", targetsid);
8337     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8338
8339     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8340     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8341
8342     /* UserData patches key exists */
8343     lstrcpyA(patchcode, "apple");
8344     lstrcpyA(targetprod, "banana");
8345     context = 0xdeadbeef;
8346     lstrcpyA(targetsid, "kiwi");
8347     size = MAX_PATH;
8348     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8349                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8350                            &context, targetsid, &size);
8351     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8352     ok(!lstrcmpA(patchcode, "apple"),
8353        "Expected patchcode to be unchanged, got %s\n", patchcode);
8354     ok(!lstrcmpA(targetprod, "banana"),
8355        "Expected targetprod to be unchanged, got %s\n", targetprod);
8356     ok(context == 0xdeadbeef,
8357        "Expected context to be unchanged, got %d\n", context);
8358     ok(!lstrcmpA(targetsid, "kiwi"),
8359        "Expected targetsid to be unchanged, got %s\n", targetsid);
8360     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8361
8362     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8363     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8364
8365     /* specific UserData patch key exists */
8366     lstrcpyA(patchcode, "apple");
8367     lstrcpyA(targetprod, "banana");
8368     context = 0xdeadbeef;
8369     lstrcpyA(targetsid, "kiwi");
8370     size = MAX_PATH;
8371     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8372                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8373                            &context, targetsid, &size);
8374     ok(r == ERROR_BAD_CONFIGURATION,
8375        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8376     ok(!lstrcmpA(patchcode, "apple"),
8377        "Expected patchcode to be unchanged, got %s\n", patchcode);
8378     ok(!lstrcmpA(targetprod, "banana"),
8379        "Expected targetprod to be unchanged, got %s\n", targetprod);
8380     ok(context == 0xdeadbeef,
8381        "Expected context to be unchanged, got %d\n", context);
8382     ok(!lstrcmpA(targetsid, "kiwi"),
8383        "Expected targetsid to be unchanged, got %s\n", targetsid);
8384     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8385
8386     data = MSIPATCHSTATE_SUPERSEDED;
8387     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8388                          (const BYTE *)&data, sizeof(DWORD));
8389     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8390
8391     /* State value exists */
8392     lstrcpyA(patchcode, "apple");
8393     lstrcpyA(targetprod, "banana");
8394     context = 0xdeadbeef;
8395     lstrcpyA(targetsid, "kiwi");
8396     size = MAX_PATH;
8397     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8398                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8399                            &context, targetsid, &size);
8400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8401     ok(!lstrcmpA(patchcode, patch),
8402        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8403     ok(!lstrcmpA(targetprod, prodcode),
8404        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8405     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8406        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8407     ok(!lstrcmpA(targetsid, expectedsid),
8408        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8409     ok(size == lstrlenA(expectedsid),
8410        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8411
8412     /* MSIPATCHSTATE_OBSOLETED */
8413
8414     lstrcpyA(patchcode, "apple");
8415     lstrcpyA(targetprod, "banana");
8416     context = 0xdeadbeef;
8417     lstrcpyA(targetsid, "kiwi");
8418     size = MAX_PATH;
8419     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8420                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8421                            &context, targetsid, &size);
8422     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8423     ok(!lstrcmpA(patchcode, "apple"),
8424        "Expected patchcode to be unchanged, got %s\n", patchcode);
8425     ok(!lstrcmpA(targetprod, "banana"),
8426        "Expected targetprod to be unchanged, got %s\n", targetprod);
8427     ok(context == 0xdeadbeef,
8428        "Expected context to be unchanged, got %d\n", context);
8429     ok(!lstrcmpA(targetsid, "kiwi"),
8430        "Expected targetsid to be unchanged, got %s\n", targetsid);
8431     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8432
8433     data = MSIPATCHSTATE_OBSOLETED;
8434     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8435                          (const BYTE *)&data, sizeof(DWORD));
8436     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8437
8438     /* State value is obsoleted */
8439     lstrcpyA(patchcode, "apple");
8440     lstrcpyA(targetprod, "banana");
8441     context = 0xdeadbeef;
8442     lstrcpyA(targetsid, "kiwi");
8443     size = MAX_PATH;
8444     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8445                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8446                            &context, targetsid, &size);
8447     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8448     ok(!lstrcmpA(patchcode, patch),
8449        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8450     ok(!lstrcmpA(targetprod, prodcode),
8451        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8452     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8453        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8454     ok(!lstrcmpA(targetsid, expectedsid),
8455        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8456     ok(size == lstrlenA(expectedsid),
8457        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8458
8459     /* MSIPATCHSTATE_REGISTERED */
8460     /* FIXME */
8461
8462     /* MSIPATCHSTATE_ALL */
8463
8464     /* 1st */
8465     lstrcpyA(patchcode, "apple");
8466     lstrcpyA(targetprod, "banana");
8467     context = 0xdeadbeef;
8468     lstrcpyA(targetsid, "kiwi");
8469     size = MAX_PATH;
8470     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8471                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8472                            &context, targetsid, &size);
8473     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8474     ok(!lstrcmpA(patchcode, patch),
8475        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8476     ok(!lstrcmpA(targetprod, prodcode),
8477        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8478     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8479        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8480     ok(!lstrcmpA(targetsid, expectedsid),
8481        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8482     ok(size == lstrlenA(expectedsid),
8483        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8484
8485     /* same patch in multiple places, only one is enumerated */
8486     lstrcpyA(patchcode, "apple");
8487     lstrcpyA(targetprod, "banana");
8488     context = 0xdeadbeef;
8489     lstrcpyA(targetsid, "kiwi");
8490     size = MAX_PATH;
8491     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8492                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8493                            &context, targetsid, &size);
8494     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8495     ok(!lstrcmpA(patchcode, "apple"),
8496        "Expected patchcode to be unchanged, got %s\n", patchcode);
8497     ok(!lstrcmpA(targetprod, "banana"),
8498        "Expected targetprod to be unchanged, got %s\n", targetprod);
8499     ok(context == 0xdeadbeef,
8500        "Expected context to be unchanged, got %d\n", context);
8501     ok(!lstrcmpA(targetsid, "kiwi"),
8502        "Expected targetsid to be unchanged, got %s\n", targetsid);
8503     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8504
8505     RegDeleteValueA(hpatch, "State");
8506     RegDeleteKeyA(hpatch, "");
8507     RegCloseKey(hpatch);
8508     RegDeleteKeyA(udpatch, "");
8509     RegCloseKey(udpatch);
8510     RegDeleteKeyA(udprod, "");
8511     RegCloseKey(udprod);
8512     RegDeleteKeyA(userkey, "");
8513     RegCloseKey(userkey);
8514     RegDeleteValueA(patches, patch_squashed);
8515     RegDeleteValueA(patches, "Patches");
8516     RegDeleteKeyA(patches, "");
8517     RegCloseKey(patches);
8518     RegDeleteKeyA(prodkey, "");
8519     RegCloseKey(prodkey);
8520 }
8521
8522 static void test_MsiEnumPatchesEx_machine(void)
8523 {
8524     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8525     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8526     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8527     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8528     HKEY prodkey, patches, udprod, udpatch;
8529     HKEY hpatch;
8530     MSIINSTALLCONTEXT context;
8531     DWORD size, data;
8532     LONG res;
8533     UINT r;
8534
8535     create_test_guid(prodcode, prod_squashed);
8536     create_test_guid(patch, patch_squashed);
8537
8538     /* MSIPATCHSTATE_APPLIED */
8539
8540     lstrcpyA(patchcode, "apple");
8541     lstrcpyA(targetprod, "banana");
8542     context = 0xdeadbeef;
8543     lstrcpyA(targetsid, "kiwi");
8544     size = MAX_PATH;
8545     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8546                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8547                            &context, targetsid, &size);
8548     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8549     ok(!lstrcmpA(patchcode, "apple"),
8550        "Expected patchcode to be unchanged, got %s\n", patchcode);
8551     ok(!lstrcmpA(targetprod, "banana"),
8552        "Expected targetprod to be unchanged, got %s\n", targetprod);
8553     ok(context == 0xdeadbeef,
8554        "Expected context to be unchanged, got %d\n", context);
8555     ok(!lstrcmpA(targetsid, "kiwi"),
8556        "Expected targetsid to be unchanged, got %s\n", targetsid);
8557     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8558
8559     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8560     lstrcatA(keypath, prod_squashed);
8561
8562     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
8563     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8564
8565     /* local product key exists */
8566     lstrcpyA(patchcode, "apple");
8567     lstrcpyA(targetprod, "banana");
8568     context = 0xdeadbeef;
8569     lstrcpyA(targetsid, "kiwi");
8570     size = MAX_PATH;
8571     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8572                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8573                            &context, targetsid, &size);
8574     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8575     ok(!lstrcmpA(patchcode, "apple"),
8576        "Expected patchcode to be unchanged, got %s\n", patchcode);
8577     ok(!lstrcmpA(targetprod, "banana"),
8578        "Expected targetprod to be unchanged, got %s\n", targetprod);
8579     ok(context == 0xdeadbeef,
8580        "Expected context to be unchanged, got %d\n", context);
8581     ok(!lstrcmpA(targetsid, "kiwi"),
8582        "Expected targetsid to be unchanged, got %s\n", targetsid);
8583     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8584
8585     res = RegCreateKeyA(prodkey, "Patches", &patches);
8586     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8587
8588     /* Patches key exists */
8589     lstrcpyA(patchcode, "apple");
8590     lstrcpyA(targetprod, "banana");
8591     context = 0xdeadbeef;
8592     lstrcpyA(targetsid, "kiwi");
8593     size = MAX_PATH;
8594     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8595                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8596                            &context, targetsid, &size);
8597     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8598     ok(!lstrcmpA(patchcode, "apple"),
8599        "Expected patchcode to be unchanged, got %s\n", patchcode);
8600     ok(!lstrcmpA(targetprod, "banana"),
8601        "Expected targetprod to be unchanged, got %s\n", targetprod);
8602     ok(context == 0xdeadbeef,
8603        "Expected context to be unchanged, got %d\n", context);
8604     ok(!lstrcmpA(targetsid, "kiwi"),
8605        "Expected targetsid to be unchanged, got %s\n", targetsid);
8606     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8607
8608     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8609                          (const BYTE *)patch_squashed,
8610                          lstrlenA(patch_squashed) + 1);
8611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8612
8613     /* Patches value exists, is not REG_MULTI_SZ */
8614     lstrcpyA(patchcode, "apple");
8615     lstrcpyA(targetprod, "banana");
8616     context = 0xdeadbeef;
8617     lstrcpyA(targetsid, "kiwi");
8618     size = MAX_PATH;
8619     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8620                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8621                            &context, targetsid, &size);
8622     ok(r == ERROR_BAD_CONFIGURATION,
8623        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8624     ok(!lstrcmpA(patchcode, "apple"),
8625        "Expected patchcode to be unchanged, got %s\n", patchcode);
8626     ok(!lstrcmpA(targetprod, "banana"),
8627        "Expected targetprod to be unchanged, got %s\n", targetprod);
8628     ok(context == 0xdeadbeef,
8629        "Expected context to be unchanged, got %d\n", context);
8630     ok(!lstrcmpA(targetsid, "kiwi"),
8631        "Expected targetsid to be unchanged, got %s\n", targetsid);
8632     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8633
8634     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8635                          (const BYTE *)"a\0b\0c\0\0", 7);
8636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8637
8638     /* Patches value exists, is not a squashed guid */
8639     lstrcpyA(patchcode, "apple");
8640     lstrcpyA(targetprod, "banana");
8641     context = 0xdeadbeef;
8642     lstrcpyA(targetsid, "kiwi");
8643     size = MAX_PATH;
8644     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8645                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8646                            &context, targetsid, &size);
8647     ok(r == ERROR_BAD_CONFIGURATION,
8648        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8649     ok(!lstrcmpA(patchcode, "apple"),
8650        "Expected patchcode to be unchanged, got %s\n", patchcode);
8651     ok(!lstrcmpA(targetprod, "banana"),
8652        "Expected targetprod to be unchanged, got %s\n", targetprod);
8653     ok(context == 0xdeadbeef,
8654        "Expected context to be unchanged, got %d\n", context);
8655     ok(!lstrcmpA(targetsid, "kiwi"),
8656        "Expected targetsid to be unchanged, got %s\n", targetsid);
8657     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8658
8659     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8660     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8661                          (const BYTE *)patch_squashed,
8662                          lstrlenA(patch_squashed) + 2);
8663     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8664
8665     /* Patches value exists */
8666     lstrcpyA(patchcode, "apple");
8667     lstrcpyA(targetprod, "banana");
8668     context = 0xdeadbeef;
8669     lstrcpyA(targetsid, "kiwi");
8670     size = MAX_PATH;
8671     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8672                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8673                            &context, targetsid, &size);
8674     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8675     ok(!lstrcmpA(patchcode, "apple"),
8676        "Expected patchcode to be unchanged, got %s\n", patchcode);
8677     ok(!lstrcmpA(targetprod, "banana"),
8678        "Expected targetprod to be unchanged, got %s\n", targetprod);
8679     ok(context == 0xdeadbeef,
8680        "Expected context to be unchanged, got %d\n", context);
8681     ok(!lstrcmpA(targetsid, "kiwi"),
8682        "Expected targetsid to be unchanged, got %s\n", targetsid);
8683     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8684
8685     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8686                          (const BYTE *)"whatever", 9);
8687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8688
8689     /* patch code value exists */
8690     lstrcpyA(patchcode, "apple");
8691     lstrcpyA(targetprod, "banana");
8692     context = 0xdeadbeef;
8693     lstrcpyA(targetsid, "kiwi");
8694     size = MAX_PATH;
8695     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8696                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8697                            &context, targetsid, &size);
8698     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8699     ok(!lstrcmpA(patchcode, patch),
8700        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8701     ok(!lstrcmpA(targetprod, prodcode),
8702        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8703     ok(context == MSIINSTALLCONTEXT_MACHINE,
8704        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8705     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8706     ok(size == 0, "Expected 0, got %d\n", size);
8707
8708     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8709     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8710     lstrcatA(keypath, prod_squashed);
8711
8712     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8714
8715     /* local UserData product key exists */
8716     lstrcpyA(patchcode, "apple");
8717     lstrcpyA(targetprod, "banana");
8718     context = 0xdeadbeef;
8719     lstrcpyA(targetsid, "kiwi");
8720     size = MAX_PATH;
8721     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8722                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8723                            &context, targetsid, &size);
8724     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8725     ok(!lstrcmpA(patchcode, patch),
8726        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8727     ok(!lstrcmpA(targetprod, prodcode),
8728        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8729     ok(context == MSIINSTALLCONTEXT_MACHINE,
8730        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8731     ok(!lstrcmpA(targetsid, ""),
8732        "Expected \"\", got \"%s\"\n", targetsid);
8733     ok(size == 0, "Expected 0, got %d\n", size);
8734
8735     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8737
8738     /* local UserData Patches key exists */
8739     lstrcpyA(patchcode, "apple");
8740     lstrcpyA(targetprod, "banana");
8741     context = 0xdeadbeef;
8742     lstrcpyA(targetsid, "kiwi");
8743     size = MAX_PATH;
8744     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8745                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8746                            &context, targetsid, &size);
8747     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8748     ok(!lstrcmpA(patchcode, patch),
8749        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8750     ok(!lstrcmpA(targetprod, prodcode),
8751        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8752     ok(context == MSIINSTALLCONTEXT_MACHINE,
8753        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8754     ok(!lstrcmpA(targetsid, ""),
8755        "Expected \"\", got \"%s\"\n", targetsid);
8756     ok(size == 0, "Expected 0, got %d\n", size);
8757
8758     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8759     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8760
8761     /* local UserData Product patch key exists */
8762     lstrcpyA(patchcode, "apple");
8763     lstrcpyA(targetprod, "banana");
8764     context = 0xdeadbeef;
8765     lstrcpyA(targetsid, "kiwi");
8766     size = MAX_PATH;
8767     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8768                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8769                            &context, targetsid, &size);
8770     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8771     ok(!lstrcmpA(patchcode, "apple"),
8772        "Expected patchcode to be unchanged, got %s\n", patchcode);
8773     ok(!lstrcmpA(targetprod, "banana"),
8774        "Expected targetprod to be unchanged, got %s\n", targetprod);
8775     ok(context == 0xdeadbeef,
8776        "Expected context to be unchanged, got %d\n", context);
8777     ok(!lstrcmpA(targetsid, "kiwi"),
8778        "Expected targetsid to be unchanged, got %s\n", targetsid);
8779     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8780
8781     data = MSIPATCHSTATE_APPLIED;
8782     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8783                          (const BYTE *)&data, sizeof(DWORD));
8784     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8785
8786     /* State value exists */
8787     lstrcpyA(patchcode, "apple");
8788     lstrcpyA(targetprod, "banana");
8789     context = 0xdeadbeef;
8790     lstrcpyA(targetsid, "kiwi");
8791     size = MAX_PATH;
8792     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8793                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8794                            &context, targetsid, &size);
8795     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8796     ok(!lstrcmpA(patchcode, patch),
8797        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8798     ok(!lstrcmpA(targetprod, prodcode),
8799        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8800     ok(context == MSIINSTALLCONTEXT_MACHINE,
8801        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8802     ok(!lstrcmpA(targetsid, ""),
8803        "Expected \"\", got \"%s\"\n", targetsid);
8804     ok(size == 0, "Expected 0, got %d\n", size);
8805
8806     /* MSIPATCHSTATE_SUPERSEDED */
8807
8808     lstrcpyA(patchcode, "apple");
8809     lstrcpyA(targetprod, "banana");
8810     context = 0xdeadbeef;
8811     lstrcpyA(targetsid, "kiwi");
8812     size = MAX_PATH;
8813     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8814                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8815                            &context, targetsid, &size);
8816     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8817     ok(!lstrcmpA(patchcode, "apple"),
8818        "Expected patchcode to be unchanged, got %s\n", patchcode);
8819     ok(!lstrcmpA(targetprod, "banana"),
8820        "Expected targetprod to be unchanged, got %s\n", targetprod);
8821     ok(context == 0xdeadbeef,
8822        "Expected context to be unchanged, got %d\n", context);
8823     ok(!lstrcmpA(targetsid, "kiwi"),
8824        "Expected targetsid to be unchanged, got %s\n", targetsid);
8825     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8826
8827     data = MSIPATCHSTATE_SUPERSEDED;
8828     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8829                          (const BYTE *)&data, sizeof(DWORD));
8830     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8831
8832     /* State value is MSIPATCHSTATE_SUPERSEDED */
8833     lstrcpyA(patchcode, "apple");
8834     lstrcpyA(targetprod, "banana");
8835     context = 0xdeadbeef;
8836     lstrcpyA(targetsid, "kiwi");
8837     size = MAX_PATH;
8838     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8839                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8840                            &context, targetsid, &size);
8841     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8842     ok(!lstrcmpA(patchcode, patch),
8843        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8844     ok(!lstrcmpA(targetprod, prodcode),
8845        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8846     ok(context == MSIINSTALLCONTEXT_MACHINE,
8847        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8848     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8849     ok(size == 0, "Expected 0, got %d\n", size);
8850
8851     /* MSIPATCHSTATE_OBSOLETED */
8852
8853     lstrcpyA(patchcode, "apple");
8854     lstrcpyA(targetprod, "banana");
8855     context = 0xdeadbeef;
8856     lstrcpyA(targetsid, "kiwi");
8857     size = MAX_PATH;
8858     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8859                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8860                            &context, targetsid, &size);
8861     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8862     ok(!lstrcmpA(patchcode, "apple"),
8863        "Expected patchcode to be unchanged, got %s\n", patchcode);
8864     ok(!lstrcmpA(targetprod, "banana"),
8865        "Expected targetprod to be unchanged, got %s\n", targetprod);
8866     ok(context == 0xdeadbeef,
8867        "Expected context to be unchanged, got %d\n", context);
8868     ok(!lstrcmpA(targetsid, "kiwi"),
8869        "Expected targetsid to be unchanged, got %s\n", targetsid);
8870     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8871
8872     data = MSIPATCHSTATE_OBSOLETED;
8873     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8874                          (const BYTE *)&data, sizeof(DWORD));
8875     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8876
8877     /* State value is obsoleted */
8878     lstrcpyA(patchcode, "apple");
8879     lstrcpyA(targetprod, "banana");
8880     context = 0xdeadbeef;
8881     lstrcpyA(targetsid, "kiwi");
8882     size = MAX_PATH;
8883     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8884                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8885                            &context, targetsid, &size);
8886     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8887     ok(!lstrcmpA(patchcode, patch),
8888        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8889     ok(!lstrcmpA(targetprod, prodcode),
8890        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8891     ok(context == MSIINSTALLCONTEXT_MACHINE,
8892        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8893     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8894     ok(size == 0, "Expected 0, got %d\n", size);
8895
8896     /* MSIPATCHSTATE_REGISTERED */
8897     /* FIXME */
8898
8899     /* MSIPATCHSTATE_ALL */
8900
8901     /* 1st */
8902     lstrcpyA(patchcode, "apple");
8903     lstrcpyA(targetprod, "banana");
8904     context = 0xdeadbeef;
8905     lstrcpyA(targetsid, "kiwi");
8906     size = MAX_PATH;
8907     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8908                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8909                            &context, targetsid, &size);
8910     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8911     ok(!lstrcmpA(patchcode, patch),
8912        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8913     ok(!lstrcmpA(targetprod, prodcode),
8914        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8915     ok(context == MSIINSTALLCONTEXT_MACHINE,
8916        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8917     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8918     ok(size == 0, "Expected 0, got %d\n", size);
8919
8920     /* same patch in multiple places, only one is enumerated */
8921     lstrcpyA(patchcode, "apple");
8922     lstrcpyA(targetprod, "banana");
8923     context = 0xdeadbeef;
8924     lstrcpyA(targetsid, "kiwi");
8925     size = MAX_PATH;
8926     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8927                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8928                            &context, targetsid, &size);
8929     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8930     ok(!lstrcmpA(patchcode, "apple"),
8931        "Expected patchcode to be unchanged, got %s\n", patchcode);
8932     ok(!lstrcmpA(targetprod, "banana"),
8933        "Expected targetprod to be unchanged, got %s\n", targetprod);
8934     ok(context == 0xdeadbeef,
8935        "Expected context to be unchanged, got %d\n", context);
8936     ok(!lstrcmpA(targetsid, "kiwi"),
8937        "Expected targetsid to be unchanged, got %s\n", targetsid);
8938     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8939
8940     RegDeleteValueA(patches, patch_squashed);
8941     RegDeleteValueA(patches, "Patches");
8942     RegDeleteKeyA(patches, "");
8943     RegCloseKey(patches);
8944     RegDeleteValueA(hpatch, "State");
8945     RegDeleteKeyA(hpatch, "");
8946     RegCloseKey(hpatch);
8947     RegDeleteKeyA(udpatch, "");
8948     RegCloseKey(udpatch);
8949     RegDeleteKeyA(udprod, "");
8950     RegCloseKey(udprod);
8951     RegDeleteKeyA(prodkey, "");
8952     RegCloseKey(prodkey);
8953 }
8954
8955 static void test_MsiEnumPatchesEx(void)
8956 {
8957     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8958     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8959     CHAR patchcode[MAX_PATH];
8960     MSIINSTALLCONTEXT context;
8961     LPSTR usersid;
8962     DWORD size;
8963     UINT r;
8964
8965     if (!pMsiEnumPatchesExA)
8966     {
8967         win_skip("MsiEnumPatchesExA not implemented\n");
8968         return;
8969     }
8970
8971     create_test_guid(prodcode, prod_squashed);
8972     get_user_sid(&usersid);
8973
8974     /* empty szProductCode */
8975     lstrcpyA(patchcode, "apple");
8976     lstrcpyA(targetprod, "banana");
8977     context = 0xdeadbeef;
8978     lstrcpyA(targetsid, "kiwi");
8979     size = MAX_PATH;
8980     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8981                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
8982                            targetsid, &size);
8983     ok(r == ERROR_INVALID_PARAMETER,
8984        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8985     ok(!lstrcmpA(patchcode, "apple"),
8986        "Expected patchcode to be unchanged, got %s\n", patchcode);
8987     ok(!lstrcmpA(targetprod, "banana"),
8988        "Expected targetprod to be unchanged, got %s\n", targetprod);
8989     ok(context == 0xdeadbeef,
8990        "Expected context to be unchanged, got %d\n", context);
8991     ok(!lstrcmpA(targetsid, "kiwi"),
8992        "Expected targetsid to be unchanged, got %s\n", targetsid);
8993     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8994
8995     /* garbage szProductCode */
8996     lstrcpyA(patchcode, "apple");
8997     lstrcpyA(targetprod, "banana");
8998     context = 0xdeadbeef;
8999     lstrcpyA(targetsid, "kiwi");
9000     size = MAX_PATH;
9001     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9002                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9003                            targetsid, &size);
9004     ok(r == ERROR_INVALID_PARAMETER,
9005        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9006     ok(!lstrcmpA(patchcode, "apple"),
9007        "Expected patchcode to be unchanged, got %s\n", patchcode);
9008     ok(!lstrcmpA(targetprod, "banana"),
9009        "Expected targetprod to be unchanged, got %s\n", targetprod);
9010     ok(context == 0xdeadbeef,
9011        "Expected context to be unchanged, got %d\n", context);
9012     ok(!lstrcmpA(targetsid, "kiwi"),
9013        "Expected targetsid to be unchanged, got %s\n", targetsid);
9014     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9015
9016     /* guid without brackets */
9017     lstrcpyA(patchcode, "apple");
9018     lstrcpyA(targetprod, "banana");
9019     context = 0xdeadbeef;
9020     lstrcpyA(targetsid, "kiwi");
9021     size = MAX_PATH;
9022     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9023                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9024                            0, patchcode, targetprod, &context,
9025                            targetsid, &size);
9026     ok(r == ERROR_INVALID_PARAMETER,
9027        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9028     ok(!lstrcmpA(patchcode, "apple"),
9029        "Expected patchcode to be unchanged, got %s\n", patchcode);
9030     ok(!lstrcmpA(targetprod, "banana"),
9031        "Expected targetprod to be unchanged, got %s\n", targetprod);
9032     ok(context == 0xdeadbeef,
9033        "Expected context to be unchanged, got %d\n", context);
9034     ok(!lstrcmpA(targetsid, "kiwi"),
9035        "Expected targetsid to be unchanged, got %s\n", targetsid);
9036     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9037
9038     /* guid with brackets */
9039     lstrcpyA(patchcode, "apple");
9040     lstrcpyA(targetprod, "banana");
9041     context = 0xdeadbeef;
9042     lstrcpyA(targetsid, "kiwi");
9043     size = MAX_PATH;
9044     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9045                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9046                            0, patchcode, targetprod, &context,
9047                            targetsid, &size);
9048     ok(r == ERROR_NO_MORE_ITEMS,
9049        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9050     ok(!lstrcmpA(patchcode, "apple"),
9051        "Expected patchcode to be unchanged, got %s\n", patchcode);
9052     ok(!lstrcmpA(targetprod, "banana"),
9053        "Expected targetprod to be unchanged, got %s\n", targetprod);
9054     ok(context == 0xdeadbeef,
9055        "Expected context to be unchanged, got %d\n", context);
9056     ok(!lstrcmpA(targetsid, "kiwi"),
9057        "Expected targetsid to be unchanged, got %s\n", targetsid);
9058     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9059
9060     /* szUserSid is S-1-5-18 */
9061     lstrcpyA(patchcode, "apple");
9062     lstrcpyA(targetprod, "banana");
9063     context = 0xdeadbeef;
9064     lstrcpyA(targetsid, "kiwi");
9065     size = MAX_PATH;
9066     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9067                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9068                            0, patchcode, targetprod, &context,
9069                            targetsid, &size);
9070     ok(r == ERROR_INVALID_PARAMETER,
9071        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9072     ok(!lstrcmpA(patchcode, "apple"),
9073        "Expected patchcode to be unchanged, got %s\n", patchcode);
9074     ok(!lstrcmpA(targetprod, "banana"),
9075        "Expected targetprod to be unchanged, got %s\n", targetprod);
9076     ok(context == 0xdeadbeef,
9077        "Expected context to be unchanged, got %d\n", context);
9078     ok(!lstrcmpA(targetsid, "kiwi"),
9079        "Expected targetsid to be unchanged, got %s\n", targetsid);
9080     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9081
9082     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9083     lstrcpyA(patchcode, "apple");
9084     lstrcpyA(targetprod, "banana");
9085     context = 0xdeadbeef;
9086     lstrcpyA(targetsid, "kiwi");
9087     size = MAX_PATH;
9088     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9089                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9090                            &context, targetsid, &size);
9091     ok(r == ERROR_INVALID_PARAMETER,
9092        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9093     ok(!lstrcmpA(patchcode, "apple"),
9094        "Expected patchcode to be unchanged, got %s\n", patchcode);
9095     ok(!lstrcmpA(targetprod, "banana"),
9096        "Expected targetprod to be unchanged, got %s\n", targetprod);
9097     ok(context == 0xdeadbeef,
9098        "Expected context to be unchanged, got %d\n", context);
9099     ok(!lstrcmpA(targetsid, "kiwi"),
9100        "Expected targetsid to be unchanged, got %s\n", targetsid);
9101     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9102
9103     /* dwContext is out of bounds */
9104     lstrcpyA(patchcode, "apple");
9105     lstrcpyA(targetprod, "banana");
9106     context = 0xdeadbeef;
9107     lstrcpyA(targetsid, "kiwi");
9108     size = MAX_PATH;
9109     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9110                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9111                            &context, targetsid, &size);
9112     ok(r == ERROR_INVALID_PARAMETER,
9113        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9114     ok(!lstrcmpA(patchcode, "apple"),
9115        "Expected patchcode to be unchanged, got %s\n", patchcode);
9116     ok(!lstrcmpA(targetprod, "banana"),
9117        "Expected targetprod to be unchanged, got %s\n", targetprod);
9118     ok(context == 0xdeadbeef,
9119        "Expected context to be unchanged, got %d\n", context);
9120     ok(!lstrcmpA(targetsid, "kiwi"),
9121        "Expected targetsid to be unchanged, got %s\n", targetsid);
9122     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9123
9124     /* dwContext is out of bounds */
9125     lstrcpyA(patchcode, "apple");
9126     lstrcpyA(targetprod, "banana");
9127     context = 0xdeadbeef;
9128     lstrcpyA(targetsid, "kiwi");
9129     size = MAX_PATH;
9130     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9131                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9132                            &context, targetsid, &size);
9133     ok(r == ERROR_INVALID_PARAMETER,
9134        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9135     ok(!lstrcmpA(patchcode, "apple"),
9136        "Expected patchcode to be unchanged, got %s\n", patchcode);
9137     ok(!lstrcmpA(targetprod, "banana"),
9138        "Expected targetprod to be unchanged, got %s\n", targetprod);
9139     ok(context == 0xdeadbeef,
9140        "Expected context to be unchanged, got %d\n", context);
9141     ok(!lstrcmpA(targetsid, "kiwi"),
9142        "Expected targetsid to be unchanged, got %s\n", targetsid);
9143     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9144
9145     /* dwFilter is out of bounds */
9146     lstrcpyA(patchcode, "apple");
9147     lstrcpyA(targetprod, "banana");
9148     context = 0xdeadbeef;
9149     lstrcpyA(targetsid, "kiwi");
9150     size = MAX_PATH;
9151     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9152                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9153                            &context, targetsid, &size);
9154     ok(r == ERROR_INVALID_PARAMETER,
9155        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9156     ok(!lstrcmpA(patchcode, "apple"),
9157        "Expected patchcode to be unchanged, got %s\n", patchcode);
9158     ok(!lstrcmpA(targetprod, "banana"),
9159        "Expected targetprod to be unchanged, got %s\n", targetprod);
9160     ok(context == 0xdeadbeef,
9161        "Expected context to be unchanged, got %d\n", context);
9162     ok(!lstrcmpA(targetsid, "kiwi"),
9163        "Expected targetsid to be unchanged, got %s\n", targetsid);
9164     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9165
9166     /* dwFilter is out of bounds */
9167     lstrcpyA(patchcode, "apple");
9168     lstrcpyA(targetprod, "banana");
9169     context = 0xdeadbeef;
9170     lstrcpyA(targetsid, "kiwi");
9171     size = MAX_PATH;
9172     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9173                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9174                            &context, targetsid, &size);
9175     ok(r == ERROR_INVALID_PARAMETER,
9176        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9177     ok(!lstrcmpA(patchcode, "apple"),
9178        "Expected patchcode to be unchanged, got %s\n", patchcode);
9179     ok(!lstrcmpA(targetprod, "banana"),
9180        "Expected targetprod to be unchanged, got %s\n", targetprod);
9181     ok(context == 0xdeadbeef,
9182        "Expected context to be unchanged, got %d\n", context);
9183     ok(!lstrcmpA(targetsid, "kiwi"),
9184        "Expected targetsid to be unchanged, got %s\n", targetsid);
9185     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9186
9187     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9188     lstrcpyA(patchcode, "apple");
9189     lstrcpyA(targetprod, "banana");
9190     context = 0xdeadbeef;
9191     lstrcpyA(targetsid, "kiwi");
9192     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9193                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9194                            &context, targetsid, NULL);
9195     ok(r == ERROR_INVALID_PARAMETER,
9196        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9197     ok(!lstrcmpA(patchcode, "apple"),
9198        "Expected patchcode to be unchanged, got %s\n", patchcode);
9199     ok(!lstrcmpA(targetprod, "banana"),
9200        "Expected targetprod to be unchanged, got %s\n", targetprod);
9201     ok(context == 0xdeadbeef,
9202        "Expected context to be unchanged, got %d\n", context);
9203     ok(!lstrcmpA(targetsid, "kiwi"),
9204        "Expected targetsid to be unchanged, got %s\n", targetsid);
9205
9206     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9207     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9208     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9209     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9210     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9211     /* FIXME: Successfully test userunmanaged with a different user */
9212     test_MsiEnumPatchesEx_machine();
9213     LocalFree(usersid);
9214 }
9215
9216 static void test_MsiEnumPatches(void)
9217 {
9218     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9219     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9220     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9221     CHAR transforms[MAX_PATH];
9222     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9223     HKEY prodkey, patches, udprod;
9224     HKEY userkey, hpatch, udpatch;
9225     DWORD size, data;
9226     LPSTR usersid;
9227     LONG res;
9228     UINT r;
9229
9230     create_test_guid(prodcode, prod_squashed);
9231     create_test_guid(patchcode, patch_squashed);
9232     get_user_sid(&usersid);
9233
9234     /* NULL szProduct */
9235     size = MAX_PATH;
9236     lstrcpyA(patch, "apple");
9237     lstrcpyA(transforms, "banana");
9238     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9239     ok(r == ERROR_INVALID_PARAMETER,
9240        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9241     ok(!lstrcmpA(patch, "apple"),
9242        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9243     ok(!lstrcmpA(transforms, "banana"),
9244        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9245     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9246
9247     /* empty szProduct */
9248     size = MAX_PATH;
9249     lstrcpyA(patch, "apple");
9250     lstrcpyA(transforms, "banana");
9251     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9252     ok(r == ERROR_INVALID_PARAMETER,
9253        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9254     ok(!lstrcmpA(patch, "apple"),
9255        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9256     ok(!lstrcmpA(transforms, "banana"),
9257        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9258     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9259
9260     /* garbage szProduct */
9261     size = MAX_PATH;
9262     lstrcpyA(patch, "apple");
9263     lstrcpyA(transforms, "banana");
9264     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9265     ok(r == ERROR_INVALID_PARAMETER,
9266        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9267     ok(!lstrcmpA(patch, "apple"),
9268        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9269     ok(!lstrcmpA(transforms, "banana"),
9270        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9271     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9272
9273     /* guid without brackets */
9274     size = MAX_PATH;
9275     lstrcpyA(patch, "apple");
9276     lstrcpyA(transforms, "banana");
9277     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9278                         transforms, &size);
9279     ok(r == ERROR_INVALID_PARAMETER,
9280        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9281     ok(!lstrcmpA(patch, "apple"),
9282        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9283     ok(!lstrcmpA(transforms, "banana"),
9284        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9285     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9286
9287     /* guid with brackets */
9288     size = MAX_PATH;
9289     lstrcpyA(patch, "apple");
9290     lstrcpyA(transforms, "banana");
9291     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9292                         transforms, &size);
9293     ok(r == ERROR_UNKNOWN_PRODUCT,
9294        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9295     ok(!lstrcmpA(patch, "apple"),
9296        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9297     ok(!lstrcmpA(transforms, "banana"),
9298        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9299     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9300
9301     /* same length as guid, but random */
9302     size = MAX_PATH;
9303     lstrcpyA(patch, "apple");
9304     lstrcpyA(transforms, "banana");
9305     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9306                         transforms, &size);
9307     ok(r == ERROR_INVALID_PARAMETER,
9308        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9309     ok(!lstrcmpA(patch, "apple"),
9310        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9311     ok(!lstrcmpA(transforms, "banana"),
9312        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9313     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9314
9315     /* MSIINSTALLCONTEXT_USERMANAGED */
9316
9317     size = MAX_PATH;
9318     lstrcpyA(patch, "apple");
9319     lstrcpyA(transforms, "banana");
9320     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9321     ok(r == ERROR_UNKNOWN_PRODUCT,
9322        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9323     ok(!lstrcmpA(patch, "apple"),
9324        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9325     ok(!lstrcmpA(transforms, "banana"),
9326        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9327     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9328
9329     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9330     lstrcatA(keypath, usersid);
9331     lstrcatA(keypath, "\\Installer\\Products\\");
9332     lstrcatA(keypath, prod_squashed);
9333
9334     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9335     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9336
9337     /* managed product key exists */
9338     size = MAX_PATH;
9339     lstrcpyA(patch, "apple");
9340     lstrcpyA(transforms, "banana");
9341     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9342     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9343     ok(!lstrcmpA(patch, "apple"),
9344        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9345     ok(!lstrcmpA(transforms, "banana"),
9346        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9347     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9348
9349     res = RegCreateKeyA(prodkey, "Patches", &patches);
9350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9351
9352     /* patches key exists */
9353     size = MAX_PATH;
9354     lstrcpyA(patch, "apple");
9355     lstrcpyA(transforms, "banana");
9356     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9357     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9358     ok(!lstrcmpA(patch, "apple"),
9359        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9360     ok(!lstrcmpA(transforms, "banana"),
9361        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9362     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9363
9364     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9365                          (const BYTE *)patch_squashed,
9366                          lstrlenA(patch_squashed) + 1);
9367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9368
9369     /* Patches value exists, is not REG_MULTI_SZ */
9370     size = MAX_PATH;
9371     lstrcpyA(patch, "apple");
9372     lstrcpyA(transforms, "banana");
9373     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9374     ok(r == ERROR_BAD_CONFIGURATION,
9375        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9376     ok(!lstrcmpA(patch, "apple"),
9377        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9378     ok(!lstrcmpA(transforms, "banana"),
9379        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9380     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9381
9382     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9383                          (const BYTE *)"a\0b\0c\0\0", 7);
9384     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9385
9386     /* Patches value exists, is not a squashed guid */
9387     size = MAX_PATH;
9388     lstrcpyA(patch, "apple");
9389     lstrcpyA(transforms, "banana");
9390     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9391     ok(r == ERROR_BAD_CONFIGURATION,
9392        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9393     ok(!lstrcmpA(patch, "apple"),
9394        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9395     ok(!lstrcmpA(transforms, "banana"),
9396        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9397     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9398
9399     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9400     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9401                          (const BYTE *)patch_squashed,
9402                          lstrlenA(patch_squashed) + 2);
9403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9404
9405     /* Patches value exists */
9406     size = MAX_PATH;
9407     lstrcpyA(patch, "apple");
9408     lstrcpyA(transforms, "banana");
9409     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9410     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9411     ok(!lstrcmpA(patch, "apple"),
9412        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9413     ok(!lstrcmpA(transforms, "banana"),
9414        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9415     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9416
9417     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9418                          (const BYTE *)"whatever", 9);
9419     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9420
9421     /* patch squashed value exists */
9422     size = MAX_PATH;
9423     lstrcpyA(patch, "apple");
9424     lstrcpyA(transforms, "banana");
9425     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9426     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9427     ok(!lstrcmpA(patch, patchcode),
9428        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9429     ok(!lstrcmpA(transforms, "whatever"),
9430        "Expected \"whatever\", got \"%s\"\n", transforms);
9431     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9432
9433     /* lpPatchBuf is NULL */
9434     size = MAX_PATH;
9435     lstrcpyA(transforms, "banana");
9436     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9437     ok(r == ERROR_INVALID_PARAMETER,
9438        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9439     ok(!lstrcmpA(transforms, "banana"),
9440        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9441     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9442
9443     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9444     size = MAX_PATH;
9445     lstrcpyA(patch, "apple");
9446     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9447     ok(r == ERROR_INVALID_PARAMETER,
9448        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9449     ok(!lstrcmpA(patch, "apple"),
9450        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9451     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9452
9453     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9454     lstrcpyA(patch, "apple");
9455     lstrcpyA(transforms, "banana");
9456     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9457     ok(r == ERROR_INVALID_PARAMETER,
9458        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9459     ok(!lstrcmpA(patch, "apple"),
9460        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9461     ok(!lstrcmpA(transforms, "banana"),
9462        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9463
9464     /* pcchTransformsBuf is too small */
9465     size = 6;
9466     lstrcpyA(patch, "apple");
9467     lstrcpyA(transforms, "banana");
9468     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9469     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9470     ok(!lstrcmpA(patch, patchcode),
9471        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9472     ok(!lstrcmpA(transforms, "whate"),
9473        "Expected \"whate\", got \"%s\"\n", transforms);
9474     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
9475
9476     /* increase the index */
9477     size = MAX_PATH;
9478     lstrcpyA(patch, "apple");
9479     lstrcpyA(transforms, "banana");
9480     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9481     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9482     ok(!lstrcmpA(patch, "apple"),
9483        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9484     ok(!lstrcmpA(transforms, "banana"),
9485        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9486     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9487
9488     /* increase again */
9489     size = MAX_PATH;
9490     lstrcpyA(patch, "apple");
9491     lstrcpyA(transforms, "banana");
9492     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9493     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9494     ok(!lstrcmpA(patch, "apple"),
9495        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9496     ok(!lstrcmpA(transforms, "banana"),
9497        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9498     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9499
9500     RegDeleteValueA(patches, "Patches");
9501     RegDeleteKeyA(patches, "");
9502     RegCloseKey(patches);
9503     RegDeleteKeyA(prodkey, "");
9504     RegCloseKey(prodkey);
9505
9506     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9507
9508     size = MAX_PATH;
9509     lstrcpyA(patch, "apple");
9510     lstrcpyA(transforms, "banana");
9511     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9512     ok(r == ERROR_UNKNOWN_PRODUCT,
9513        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9514     ok(!lstrcmpA(patch, "apple"),
9515        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9516     ok(!lstrcmpA(transforms, "banana"),
9517        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9518     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9519
9520     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9521     lstrcatA(keypath, prod_squashed);
9522
9523     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9524     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9525
9526     /* current user product key exists */
9527     size = MAX_PATH;
9528     lstrcpyA(patch, "apple");
9529     lstrcpyA(transforms, "banana");
9530     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9531     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9532     ok(!lstrcmpA(patch, "apple"),
9533        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9534     ok(!lstrcmpA(transforms, "banana"),
9535        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9536     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9537
9538     res = RegCreateKeyA(prodkey, "Patches", &patches);
9539     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9540
9541     /* Patches key exists */
9542     size = MAX_PATH;
9543     lstrcpyA(patch, "apple");
9544     lstrcpyA(transforms, "banana");
9545     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9546     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9547     ok(!lstrcmpA(patch, "apple"),
9548        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9549     ok(!lstrcmpA(transforms, "banana"),
9550        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9551     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9552
9553     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9554                          (const BYTE *)patch_squashed,
9555                          lstrlenA(patch_squashed) + 1);
9556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9557
9558     /* Patches value exists, is not REG_MULTI_SZ */
9559     size = MAX_PATH;
9560     lstrcpyA(patch, "apple");
9561     lstrcpyA(transforms, "banana");
9562     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9563     ok(r == ERROR_BAD_CONFIGURATION,
9564        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9565     ok(!lstrcmpA(patch, "apple"),
9566        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9567     ok(!lstrcmpA(transforms, "banana"),
9568        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9569     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9570
9571     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9572                          (const BYTE *)"a\0b\0c\0\0", 7);
9573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9574
9575     /* Patches value exists, is not a squashed guid */
9576     size = MAX_PATH;
9577     lstrcpyA(patch, "apple");
9578     lstrcpyA(transforms, "banana");
9579     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9580     ok(r == ERROR_BAD_CONFIGURATION,
9581        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9582     ok(!lstrcmpA(patch, "apple"),
9583        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9584     ok(!lstrcmpA(transforms, "banana"),
9585        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9586     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9587
9588     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9589     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9590                          (const BYTE *)patch_squashed,
9591                          lstrlenA(patch_squashed) + 2);
9592     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9593
9594     /* Patches value exists */
9595     size = MAX_PATH;
9596     lstrcpyA(patch, "apple");
9597     lstrcpyA(transforms, "banana");
9598     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9599     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9600     ok(!lstrcmpA(patch, "apple"),
9601        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9602     ok(!lstrcmpA(transforms, "banana"),
9603        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9604     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9605
9606     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9607                          (const BYTE *)"whatever", 9);
9608     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9609
9610     /* patch code value exists */
9611     size = MAX_PATH;
9612     lstrcpyA(patch, "apple");
9613     lstrcpyA(transforms, "banana");
9614     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9615     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9616     ok(!lstrcmpA(patch, "apple"),
9617        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9618     ok(!lstrcmpA(transforms, "banana"),
9619        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9620     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9621
9622     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9623     lstrcatA(keypath, usersid);
9624     lstrcatA(keypath, "\\Patches\\");
9625     lstrcatA(keypath, patch_squashed);
9626
9627     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
9628     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9629
9630     /* userdata patch key exists */
9631     size = MAX_PATH;
9632     lstrcpyA(patch, "apple");
9633     lstrcpyA(transforms, "banana");
9634     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9635     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9636     ok(!lstrcmpA(patch, patchcode),
9637        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9638     ok(!lstrcmpA(transforms, "whatever"),
9639        "Expected \"whatever\", got \"%s\"\n", transforms);
9640     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9641
9642     RegDeleteKeyA(userkey, "");
9643     RegCloseKey(userkey);
9644     RegDeleteValueA(patches, patch_squashed);
9645     RegDeleteValueA(patches, "Patches");
9646     RegDeleteKeyA(patches, "");
9647     RegCloseKey(patches);
9648     RegDeleteKeyA(prodkey, "");
9649     RegCloseKey(prodkey);
9650
9651     /* MSIINSTALLCONTEXT_MACHINE */
9652
9653     size = MAX_PATH;
9654     lstrcpyA(patch, "apple");
9655     lstrcpyA(transforms, "banana");
9656     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9657     ok(r == ERROR_UNKNOWN_PRODUCT,
9658        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9659     ok(!lstrcmpA(patch, "apple"),
9660        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9661     ok(!lstrcmpA(transforms, "banana"),
9662        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9663     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9664
9665     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9666     lstrcatA(keypath, prod_squashed);
9667
9668     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9669     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9670
9671     /* local product key exists */
9672     size = MAX_PATH;
9673     lstrcpyA(patch, "apple");
9674     lstrcpyA(transforms, "banana");
9675     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9676     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9677     ok(!lstrcmpA(patch, "apple"),
9678        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9679     ok(!lstrcmpA(transforms, "banana"),
9680        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9681     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9682
9683     res = RegCreateKeyA(prodkey, "Patches", &patches);
9684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9685
9686     /* Patches key exists */
9687     size = MAX_PATH;
9688     lstrcpyA(patch, "apple");
9689     lstrcpyA(transforms, "banana");
9690     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9691     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9692     ok(!lstrcmpA(patch, "apple"),
9693        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9694     ok(!lstrcmpA(transforms, "banana"),
9695        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9696     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9697
9698     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9699                          (const BYTE *)patch_squashed,
9700                          lstrlenA(patch_squashed) + 1);
9701     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9702
9703     /* Patches value exists, is not REG_MULTI_SZ */
9704     size = MAX_PATH;
9705     lstrcpyA(patch, "apple");
9706     lstrcpyA(transforms, "banana");
9707     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9708     ok(r == ERROR_BAD_CONFIGURATION,
9709        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9710     ok(!lstrcmpA(patch, "apple"),
9711        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9712     ok(!lstrcmpA(transforms, "banana"),
9713        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9714     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9715
9716     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9717                          (const BYTE *)"a\0b\0c\0\0", 7);
9718     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9719
9720     /* Patches value exists, is not a squashed guid */
9721     size = MAX_PATH;
9722     lstrcpyA(patch, "apple");
9723     lstrcpyA(transforms, "banana");
9724     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9725     ok(r == ERROR_BAD_CONFIGURATION,
9726        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9727     ok(!lstrcmpA(patch, "apple"),
9728        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9729     ok(!lstrcmpA(transforms, "banana"),
9730        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9731     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9732
9733     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9734     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9735                          (const BYTE *)patch_squashed,
9736                          lstrlenA(patch_squashed) + 2);
9737     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9738
9739     /* Patches value exists */
9740     size = MAX_PATH;
9741     lstrcpyA(patch, "apple");
9742     lstrcpyA(transforms, "banana");
9743     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9744     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9745     ok(!lstrcmpA(patch, "apple"),
9746        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9747     ok(!lstrcmpA(transforms, "banana"),
9748        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9749     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9750
9751     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9752                          (const BYTE *)"whatever", 9);
9753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9754
9755     /* patch code value exists */
9756     size = MAX_PATH;
9757     lstrcpyA(patch, "apple");
9758     lstrcpyA(transforms, "banana");
9759     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9760     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9761     ok(!lstrcmpA(patch, patchcode),
9762        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9763     ok(!lstrcmpA(transforms, "whatever"),
9764        "Expected \"whatever\", got \"%s\"\n", transforms);
9765     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9766
9767     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9768     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9769     lstrcatA(keypath, prod_squashed);
9770
9771     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9772     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9773
9774     /* local UserData product key exists */
9775     size = MAX_PATH;
9776     lstrcpyA(patch, "apple");
9777     lstrcpyA(transforms, "banana");
9778     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9779     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9780     ok(!lstrcmpA(patch, patchcode),
9781        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9782     ok(!lstrcmpA(transforms, "whatever"),
9783        "Expected \"whatever\", got \"%s\"\n", transforms);
9784     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9785
9786     res = RegCreateKeyA(udprod, "Patches", &udpatch);
9787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9788
9789     /* local UserData Patches key exists */
9790     size = MAX_PATH;
9791     lstrcpyA(patch, "apple");
9792     lstrcpyA(transforms, "banana");
9793     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9794     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9795     ok(!lstrcmpA(patch, patchcode),
9796        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9797     ok(!lstrcmpA(transforms, "whatever"),
9798        "Expected \"whatever\", got \"%s\"\n", transforms);
9799     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9800
9801     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
9802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9803
9804     /* local UserData Product patch key exists */
9805     size = MAX_PATH;
9806     lstrcpyA(patch, "apple");
9807     lstrcpyA(transforms, "banana");
9808     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9809     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9810     ok(!lstrcmpA(patch, "apple"),
9811        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9812     ok(!lstrcmpA(transforms, "banana"),
9813        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9814     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9815
9816     data = MSIPATCHSTATE_APPLIED;
9817     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9818                          (const BYTE *)&data, sizeof(DWORD));
9819     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9820
9821     /* State value exists */
9822     size = MAX_PATH;
9823     lstrcpyA(patch, "apple");
9824     lstrcpyA(transforms, "banana");
9825     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9826     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9827     ok(!lstrcmpA(patch, patchcode),
9828        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9829     ok(!lstrcmpA(transforms, "whatever"),
9830        "Expected \"whatever\", got \"%s\"\n", transforms);
9831     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9832
9833     /* now duplicate some of the tests for the W version */
9834
9835     /* pcchTransformsBuf is too small */
9836     size = 6;
9837     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
9838     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9839     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9840     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9841     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9842     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9843     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
9844     ok(!lstrcmpA(patch, patchcode),
9845        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9846     ok(!lstrcmpA(transforms, "whate"),
9847        "Expected \"whate\", got \"%s\"\n", transforms);
9848     ok(size == 8, "Expected 8, got %d\n", size);
9849
9850     /* patch code value exists */
9851     size = MAX_PATH;
9852     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9853     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9854     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9855     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9856     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9857     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
9858     ok(!lstrcmpA(patch, patchcode),
9859        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9860     ok(!lstrcmpA(transforms, "whatever"),
9861        "Expected \"whatever\", got \"%s\"\n", transforms);
9862     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9863
9864     RegDeleteValueA(patches, patch_squashed);
9865     RegDeleteValueA(patches, "Patches");
9866     RegDeleteKeyA(patches, "");
9867     RegCloseKey(patches);
9868     RegDeleteValueA(hpatch, "State");
9869     RegDeleteKeyA(hpatch, "");
9870     RegCloseKey(hpatch);
9871     RegDeleteKeyA(udpatch, "");
9872     RegCloseKey(udpatch);
9873     RegDeleteKeyA(udprod, "");
9874     RegCloseKey(udprod);
9875     RegDeleteKeyA(prodkey, "");
9876     RegCloseKey(prodkey);
9877     LocalFree(usersid);
9878 }
9879
9880 static void test_MsiGetPatchInfoEx(void)
9881 {
9882     CHAR keypath[MAX_PATH], val[MAX_PATH];
9883     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9884     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9885     HKEY prodkey, patches, udprod, props;
9886     HKEY hpatch, udpatch, prodpatches;
9887     LPSTR usersid;
9888     DWORD size;
9889     LONG res;
9890     UINT r;
9891
9892     if (!pMsiGetPatchInfoExA)
9893     {
9894         win_skip("MsiGetPatchInfoEx not implemented\n");
9895         return;
9896     }
9897
9898     create_test_guid(prodcode, prod_squashed);
9899     create_test_guid(patchcode, patch_squashed);
9900     get_user_sid(&usersid);
9901
9902     /* NULL szPatchCode */
9903     lstrcpyA(val, "apple");
9904     size = MAX_PATH;
9905     r = pMsiGetPatchInfoExA(NULL, prodcode, 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     /* empty szPatchCode */
9914     size = MAX_PATH;
9915     lstrcpyA(val, "apple");
9916     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9917                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9918     ok(r == ERROR_INVALID_PARAMETER,
9919        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9920     ok(!lstrcmpA(val, "apple"),
9921        "Expected val to be unchanged, got \"%s\"\n", val);
9922     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9923
9924     /* garbage szPatchCode */
9925     size = MAX_PATH;
9926     lstrcpyA(val, "apple");
9927     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
9928                             MSIINSTALLCONTEXT_USERMANAGED,
9929                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9930     ok(r == ERROR_INVALID_PARAMETER,
9931        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9932     ok(!lstrcmpA(val, "apple"),
9933        "Expected val to be unchanged, got \"%s\"\n", val);
9934     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9935
9936     /* guid without brackets */
9937     size = MAX_PATH;
9938     lstrcpyA(val, "apple");
9939     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
9940                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9941                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9942     ok(r == ERROR_INVALID_PARAMETER,
9943        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9944     ok(!lstrcmpA(val, "apple"),
9945        "Expected val to be unchanged, got \"%s\"\n", val);
9946     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9947
9948     /* guid with brackets */
9949     size = MAX_PATH;
9950     lstrcpyA(val, "apple");
9951     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
9952                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9953                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9954     ok(r == ERROR_UNKNOWN_PRODUCT,
9955        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9956     ok(!lstrcmpA(val, "apple"),
9957        "Expected val to be unchanged, got \"%s\"\n", val);
9958     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9959
9960     /* same length as guid, but random */
9961     size = MAX_PATH;
9962     lstrcpyA(val, "apple");
9963     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
9964                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9965                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9966     ok(r == ERROR_INVALID_PARAMETER,
9967        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9968     ok(!lstrcmpA(val, "apple"),
9969        "Expected val to be unchanged, got \"%s\"\n", val);
9970     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9971
9972     /* NULL szProductCode */
9973     lstrcpyA(val, "apple");
9974     size = MAX_PATH;
9975     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9976                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9977     ok(r == ERROR_INVALID_PARAMETER,
9978        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9979     ok(!lstrcmpA(val, "apple"),
9980        "Expected val to be unchanged, got \"%s\"\n", val);
9981     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9982
9983     /* empty szProductCode */
9984     size = MAX_PATH;
9985     lstrcpyA(val, "apple");
9986     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
9987                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9988     ok(r == ERROR_INVALID_PARAMETER,
9989        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9990     ok(!lstrcmpA(val, "apple"),
9991        "Expected val to be unchanged, got \"%s\"\n", val);
9992     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9993
9994     /* garbage szProductCode */
9995     size = MAX_PATH;
9996     lstrcpyA(val, "apple");
9997     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
9998                             MSIINSTALLCONTEXT_USERMANAGED,
9999                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10000     ok(r == ERROR_INVALID_PARAMETER,
10001        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10002     ok(!lstrcmpA(val, "apple"),
10003        "Expected val to be unchanged, got \"%s\"\n", val);
10004     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10005
10006     /* guid without brackets */
10007     size = MAX_PATH;
10008     lstrcpyA(val, "apple");
10009     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10010                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10011                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10012     ok(r == ERROR_INVALID_PARAMETER,
10013        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10014     ok(!lstrcmpA(val, "apple"),
10015        "Expected val to be unchanged, got \"%s\"\n", val);
10016     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10017
10018     /* guid with brackets */
10019     size = MAX_PATH;
10020     lstrcpyA(val, "apple");
10021     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10022                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10023                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10024     ok(r == ERROR_UNKNOWN_PRODUCT,
10025        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10026     ok(!lstrcmpA(val, "apple"),
10027        "Expected val to be unchanged, got \"%s\"\n", val);
10028     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10029
10030     /* same length as guid, but random */
10031     size = MAX_PATH;
10032     lstrcpyA(val, "apple");
10033     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10034                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10035                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10036     ok(r == ERROR_INVALID_PARAMETER,
10037        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10038     ok(!lstrcmpA(val, "apple"),
10039        "Expected val to be unchanged, got \"%s\"\n", val);
10040     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10041
10042     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10043     size = MAX_PATH;
10044     lstrcpyA(val, "apple");
10045     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10046                             MSIINSTALLCONTEXT_USERMANAGED,
10047                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10048     ok(r == ERROR_INVALID_PARAMETER,
10049        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10050     ok(!lstrcmpA(val, "apple"),
10051        "Expected val to be unchanged, got \"%s\"\n", val);
10052     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10053
10054     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10055     size = MAX_PATH;
10056     lstrcpyA(val, "apple");
10057     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10058                             MSIINSTALLCONTEXT_USERUNMANAGED,
10059                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10060     ok(r == ERROR_INVALID_PARAMETER,
10061        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10062     ok(!lstrcmpA(val, "apple"),
10063        "Expected val to be unchanged, got \"%s\"\n", val);
10064     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10065
10066     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10067     size = MAX_PATH;
10068     lstrcpyA(val, "apple");
10069     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10070                             MSIINSTALLCONTEXT_MACHINE,
10071                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10072     ok(r == ERROR_INVALID_PARAMETER,
10073        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10074     ok(!lstrcmpA(val, "apple"),
10075        "Expected val to be unchanged, got \"%s\"\n", val);
10076     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10077
10078     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10079     size = MAX_PATH;
10080     lstrcpyA(val, "apple");
10081     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10082                             MSIINSTALLCONTEXT_MACHINE,
10083                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10084     ok(r == ERROR_INVALID_PARAMETER,
10085        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10086     ok(!lstrcmpA(val, "apple"),
10087        "Expected val to be unchanged, got \"%s\"\n", val);
10088     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10089
10090     /* dwContext is out of range */
10091     size = MAX_PATH;
10092     lstrcpyA(val, "apple");
10093     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10094                             MSIINSTALLCONTEXT_NONE,
10095                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10096     ok(r == ERROR_INVALID_PARAMETER,
10097        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10098     ok(!lstrcmpA(val, "apple"),
10099        "Expected val to be unchanged, got \"%s\"\n", val);
10100     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10101
10102     /* dwContext is out of range */
10103     size = MAX_PATH;
10104     lstrcpyA(val, "apple");
10105     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10106                             MSIINSTALLCONTEXT_ALL,
10107                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10108     ok(r == ERROR_INVALID_PARAMETER,
10109        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10110     ok(!lstrcmpA(val, "apple"),
10111        "Expected val to be unchanged, got \"%s\"\n", val);
10112     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10113
10114     /* dwContext is invalid */
10115     size = MAX_PATH;
10116     lstrcpyA(val, "apple");
10117     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10118                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10119     ok(r == ERROR_INVALID_PARAMETER,
10120        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10121     ok(!lstrcmpA(val, "apple"),
10122        "Expected val to be unchanged, got \"%s\"\n", val);
10123     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10124
10125     /* MSIINSTALLCONTEXT_USERMANAGED */
10126
10127     size = MAX_PATH;
10128     lstrcpyA(val, "apple");
10129     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10130                             MSIINSTALLCONTEXT_USERMANAGED,
10131                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10132     ok(r == ERROR_UNKNOWN_PRODUCT,
10133        "Expected ERROR_UNKNOWN_PRODUCT, 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     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10139     lstrcatA(keypath, usersid);
10140     lstrcatA(keypath, "\\Products\\");
10141     lstrcatA(keypath, prod_squashed);
10142
10143     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10144     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10145
10146     /* local UserData product key exists */
10147     size = MAX_PATH;
10148     lstrcpyA(val, "apple");
10149     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10150                             MSIINSTALLCONTEXT_USERMANAGED,
10151                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10152     ok(r == ERROR_UNKNOWN_PRODUCT,
10153        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10154     ok(!lstrcmpA(val, "apple"),
10155        "Expected val to be unchanged, got \"%s\"\n", val);
10156     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10157
10158     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10159     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10160
10161     /* InstallProperties key exists */
10162     size = MAX_PATH;
10163     lstrcpyA(val, "apple");
10164     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10165                             MSIINSTALLCONTEXT_USERMANAGED,
10166                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10167     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10168     ok(!lstrcmpA(val, "apple"),
10169        "Expected val to be unchanged, got \"%s\"\n", val);
10170     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10171
10172     res = RegCreateKeyA(udprod, "Patches", &patches);
10173     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10174
10175     /* 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_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10182     ok(!lstrcmpA(val, "apple"),
10183        "Expected val to be unchanged, got \"%s\"\n", val);
10184     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10185
10186     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10188
10189     /* Patches key 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_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10196     ok(!lstrcmpA(val, "apple"),
10197        "Expected val to be unchanged, got \"%s\"\n", val);
10198     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10199
10200     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10201     lstrcatA(keypath, usersid);
10202     lstrcatA(keypath, "\\Installer\\Products\\");
10203     lstrcatA(keypath, prod_squashed);
10204
10205     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10206     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10207
10208     /* managed product key exists */
10209     size = MAX_PATH;
10210     lstrcpyA(val, "apple");
10211     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10212                             MSIINSTALLCONTEXT_USERMANAGED,
10213                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10214     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10215     ok(!lstrcmpA(val, "apple"),
10216        "Expected val to be unchanged, got \"%s\"\n", val);
10217     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10218
10219     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10220     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10221
10222     /* Patches key exists */
10223     size = MAX_PATH;
10224     lstrcpyA(val, "apple");
10225     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10226                             MSIINSTALLCONTEXT_USERMANAGED,
10227                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10228     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10229     ok(!lstrcmpA(val, "apple"),
10230        "Expected val to be unchanged, got \"%s\"\n", val);
10231     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10232
10233     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10234                          (const BYTE *)"transforms", 11);
10235     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10236
10237     /* specific patch value exists */
10238     size = MAX_PATH;
10239     lstrcpyA(val, "apple");
10240     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10241                             MSIINSTALLCONTEXT_USERMANAGED,
10242                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10243     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10244     ok(!lstrcmpA(val, "apple"),
10245        "Expected val to be unchanged, got \"%s\"\n", val);
10246     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10247
10248     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10249     lstrcatA(keypath, usersid);
10250     lstrcatA(keypath, "\\Patches\\");
10251     lstrcatA(keypath, patch_squashed);
10252
10253     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10255
10256     /* UserData Patches key exists */
10257     size = MAX_PATH;
10258     lstrcpyA(val, "apple");
10259     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10260                             MSIINSTALLCONTEXT_USERMANAGED,
10261                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10262     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10263     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10264     ok(size == 0, "Expected 0, got %d\n", size);
10265
10266     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10267                          (const BYTE *)"pack", 5);
10268     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10269
10270     /* ManagedLocalPatch value exists */
10271     size = MAX_PATH;
10272     lstrcpyA(val, "apple");
10273     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10274                             MSIINSTALLCONTEXT_USERMANAGED,
10275                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10276     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10277     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10278     ok(size == 4, "Expected 4, got %d\n", size);
10279
10280     size = MAX_PATH;
10281     lstrcpyA(val, "apple");
10282     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10283                             MSIINSTALLCONTEXT_USERMANAGED,
10284                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10285     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10286     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10287     ok(size == 10, "Expected 10, got %d\n", size);
10288
10289     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10290                          (const BYTE *)"mydate", 7);
10291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10292
10293     /* Installed value exists */
10294     size = MAX_PATH;
10295     lstrcpyA(val, "apple");
10296     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10297                             MSIINSTALLCONTEXT_USERMANAGED,
10298                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10299     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10300     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10301     ok(size == 6, "Expected 6, got %d\n", size);
10302
10303     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10304                          (const BYTE *)"yes", 4);
10305     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10306
10307     /* Uninstallable value exists */
10308     size = MAX_PATH;
10309     lstrcpyA(val, "apple");
10310     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10311                             MSIINSTALLCONTEXT_USERMANAGED,
10312                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10314     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10315     ok(size == 3, "Expected 3, got %d\n", size);
10316
10317     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10318                          (const BYTE *)"good", 5);
10319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10320
10321     /* State value exists */
10322     size = MAX_PATH;
10323     lstrcpyA(val, "apple");
10324     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10325                             MSIINSTALLCONTEXT_USERMANAGED,
10326                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10327     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10328     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10329     ok(size == 4, "Expected 4, got %d\n", size);
10330
10331     size = 1;
10332     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10333                          (const BYTE *)&size, sizeof(DWORD));
10334     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10335
10336     /* State value exists */
10337     size = MAX_PATH;
10338     lstrcpyA(val, "apple");
10339     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10340                             MSIINSTALLCONTEXT_USERMANAGED,
10341                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10342     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10343     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10344     ok(size == 1, "Expected 1, got %d\n", size);
10345
10346     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10347                          (const BYTE *)"display", 8);
10348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10349
10350     /* DisplayName value exists */
10351     size = MAX_PATH;
10352     lstrcpyA(val, "apple");
10353     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10354                             MSIINSTALLCONTEXT_USERMANAGED,
10355                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10357     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10358     ok(size == 7, "Expected 7, got %d\n", size);
10359
10360     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10361                          (const BYTE *)"moreinfo", 9);
10362     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10363
10364     /* MoreInfoURL value exists */
10365     size = MAX_PATH;
10366     lstrcpyA(val, "apple");
10367     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10368                             MSIINSTALLCONTEXT_USERMANAGED,
10369                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10370     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10371     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10372     ok(size == 8, "Expected 8, got %d\n", size);
10373
10374     /* szProperty is invalid */
10375     size = MAX_PATH;
10376     lstrcpyA(val, "apple");
10377     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10378                             MSIINSTALLCONTEXT_USERMANAGED,
10379                             "IDontExist", val, &size);
10380     ok(r == ERROR_UNKNOWN_PROPERTY,
10381        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10382     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10383     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10384
10385     /* lpValue is NULL, while pcchValue is non-NULL */
10386     size = MAX_PATH;
10387     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10388                             MSIINSTALLCONTEXT_USERMANAGED,
10389                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10390     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10391     ok(size == 16, "Expected 16, got %d\n", size);
10392
10393     /* pcchValue is NULL, while lpValue is non-NULL */
10394     lstrcpyA(val, "apple");
10395     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10396                             MSIINSTALLCONTEXT_USERMANAGED,
10397                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10398     ok(r == ERROR_INVALID_PARAMETER,
10399        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10400     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10401
10402     /* both lpValue and pcchValue are NULL */
10403     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10404                             MSIINSTALLCONTEXT_USERMANAGED,
10405                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10406     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10407
10408     /* pcchValue doesn't have enough room for NULL terminator */
10409     size = 8;
10410     lstrcpyA(val, "apple");
10411     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10412                             MSIINSTALLCONTEXT_USERMANAGED,
10413                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10414     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10415     ok(!lstrcmpA(val, "moreinf"),
10416        "Expected \"moreinf\", got \"%s\"\n", val);
10417     ok(size == 16, "Expected 16, got %d\n", size);
10418
10419     /* pcchValue has exactly enough room for NULL terminator */
10420     size = 9;
10421     lstrcpyA(val, "apple");
10422     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10423                             MSIINSTALLCONTEXT_USERMANAGED,
10424                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10425     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10426     ok(!lstrcmpA(val, "moreinfo"),
10427        "Expected \"moreinfo\", got \"%s\"\n", val);
10428     ok(size == 8, "Expected 8, got %d\n", size);
10429
10430     /* pcchValue is too small, lpValue is NULL */
10431     size = 0;
10432     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10433                             MSIINSTALLCONTEXT_USERMANAGED,
10434                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10435     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10436     ok(size == 16, "Expected 16, got %d\n", size);
10437
10438     RegDeleteValueA(prodpatches, patch_squashed);
10439     RegDeleteKeyA(prodpatches, "");
10440     RegCloseKey(prodpatches);
10441     RegDeleteKeyA(prodkey, "");
10442     RegCloseKey(prodkey);
10443
10444     /* UserData is sufficient for all properties
10445      * except INSTALLPROPERTY_TRANSFORMS
10446      */
10447     size = MAX_PATH;
10448     lstrcpyA(val, "apple");
10449     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10450                             MSIINSTALLCONTEXT_USERMANAGED,
10451                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10452     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10453     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10454     ok(size == 4, "Expected 4, got %d\n", size);
10455
10456     /* UserData is sufficient for all properties
10457      * except INSTALLPROPERTY_TRANSFORMS
10458      */
10459     size = MAX_PATH;
10460     lstrcpyA(val, "apple");
10461     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10462                             MSIINSTALLCONTEXT_USERMANAGED,
10463                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10464     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10465     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10466     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10467
10468     RegDeleteValueA(hpatch, "MoreInfoURL");
10469     RegDeleteValueA(hpatch, "Display");
10470     RegDeleteValueA(hpatch, "State");
10471     RegDeleteValueA(hpatch, "Uninstallable");
10472     RegDeleteValueA(hpatch, "Installed");
10473     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10474     RegDeleteKeyA(udpatch, "");
10475     RegCloseKey(udpatch);
10476     RegDeleteKeyA(hpatch, "");
10477     RegCloseKey(hpatch);
10478     RegDeleteKeyA(patches, "");
10479     RegCloseKey(patches);
10480     RegDeleteKeyA(props, "");
10481     RegCloseKey(props);
10482     RegDeleteKeyA(udprod, "");
10483     RegCloseKey(udprod);
10484
10485     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10486
10487     size = MAX_PATH;
10488     lstrcpyA(val, "apple");
10489     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10490                             MSIINSTALLCONTEXT_USERUNMANAGED,
10491                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10492     ok(r == ERROR_UNKNOWN_PRODUCT,
10493        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10494     ok(!lstrcmpA(val, "apple"),
10495        "Expected val to be unchanged, got \"%s\"\n", val);
10496     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10497
10498     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10499     lstrcatA(keypath, usersid);
10500     lstrcatA(keypath, "\\Products\\");
10501     lstrcatA(keypath, prod_squashed);
10502
10503     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10504     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10505
10506     /* local UserData product key exists */
10507     size = MAX_PATH;
10508     lstrcpyA(val, "apple");
10509     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10510                             MSIINSTALLCONTEXT_USERUNMANAGED,
10511                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10512     ok(r == ERROR_UNKNOWN_PRODUCT,
10513        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10514     ok(!lstrcmpA(val, "apple"),
10515        "Expected val to be unchanged, got \"%s\"\n", val);
10516     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10517
10518     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10519     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10520
10521     /* InstallProperties key exists */
10522     size = MAX_PATH;
10523     lstrcpyA(val, "apple");
10524     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10525                             MSIINSTALLCONTEXT_USERUNMANAGED,
10526                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10527     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10528     ok(!lstrcmpA(val, "apple"),
10529        "Expected val to be unchanged, got \"%s\"\n", val);
10530     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10531
10532     res = RegCreateKeyA(udprod, "Patches", &patches);
10533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10534
10535     /* Patches key exists */
10536     size = MAX_PATH;
10537     lstrcpyA(val, "apple");
10538     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10539                             MSIINSTALLCONTEXT_USERUNMANAGED,
10540                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10541     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10542     ok(!lstrcmpA(val, "apple"),
10543        "Expected val to be unchanged, got \"%s\"\n", val);
10544     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10545
10546     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10547     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10548
10549     /* Patches key exists */
10550     size = MAX_PATH;
10551     lstrcpyA(val, "apple");
10552     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10553                             MSIINSTALLCONTEXT_USERUNMANAGED,
10554                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10555     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10556     ok(!lstrcmpA(val, "apple"),
10557        "Expected val to be unchanged, got \"%s\"\n", val);
10558     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10559
10560     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10561     lstrcatA(keypath, prod_squashed);
10562
10563     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10564     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10565
10566     /* current user product key exists */
10567     size = MAX_PATH;
10568     lstrcpyA(val, "apple");
10569     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10570                             MSIINSTALLCONTEXT_USERUNMANAGED,
10571                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10572     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10573     ok(!lstrcmpA(val, "apple"),
10574        "Expected val to be unchanged, got \"%s\"\n", val);
10575     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10576
10577     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10578     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10579
10580     /* Patches key exists */
10581     size = MAX_PATH;
10582     lstrcpyA(val, "apple");
10583     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10584                             MSIINSTALLCONTEXT_USERUNMANAGED,
10585                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10586     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10587     ok(!lstrcmpA(val, "apple"),
10588        "Expected val to be unchanged, got \"%s\"\n", val);
10589     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10590
10591     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10592                          (const BYTE *)"transforms", 11);
10593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10594
10595     /* specific patch value exists */
10596     size = MAX_PATH;
10597     lstrcpyA(val, "apple");
10598     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10599                             MSIINSTALLCONTEXT_USERUNMANAGED,
10600                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10601     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10602     ok(!lstrcmpA(val, "apple"),
10603        "Expected val to be unchanged, got \"%s\"\n", val);
10604     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10605
10606     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10607     lstrcatA(keypath, usersid);
10608     lstrcatA(keypath, "\\Patches\\");
10609     lstrcatA(keypath, patch_squashed);
10610
10611     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10612     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10613
10614     /* UserData Patches key exists */
10615     size = MAX_PATH;
10616     lstrcpyA(val, "apple");
10617     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10618                             MSIINSTALLCONTEXT_USERUNMANAGED,
10619                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10620     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10621     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10622     ok(size == 0, "Expected 0, got %d\n", size);
10623
10624     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10625                          (const BYTE *)"pack", 5);
10626     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10627
10628     /* LocalPatch value exists */
10629     size = MAX_PATH;
10630     lstrcpyA(val, "apple");
10631     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10632                             MSIINSTALLCONTEXT_USERUNMANAGED,
10633                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10634     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10635     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10636     ok(size == 4, "Expected 4, got %d\n", size);
10637
10638     size = MAX_PATH;
10639     lstrcpyA(val, "apple");
10640     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10641                             MSIINSTALLCONTEXT_USERUNMANAGED,
10642                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10643     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10644     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10645     ok(size == 10, "Expected 10, got %d\n", size);
10646
10647     RegDeleteValueA(prodpatches, patch_squashed);
10648     RegDeleteKeyA(prodpatches, "");
10649     RegCloseKey(prodpatches);
10650     RegDeleteKeyA(prodkey, "");
10651     RegCloseKey(prodkey);
10652
10653     /* UserData is sufficient for all properties
10654      * except INSTALLPROPERTY_TRANSFORMS
10655      */
10656     size = MAX_PATH;
10657     lstrcpyA(val, "apple");
10658     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10659                             MSIINSTALLCONTEXT_USERUNMANAGED,
10660                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10661     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10662     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10663     ok(size == 4, "Expected 4, got %d\n", size);
10664
10665     /* UserData is sufficient for all properties
10666      * except INSTALLPROPERTY_TRANSFORMS
10667      */
10668     size = MAX_PATH;
10669     lstrcpyA(val, "apple");
10670     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10671                             MSIINSTALLCONTEXT_USERUNMANAGED,
10672                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10673     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10674     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10675     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10676
10677     RegDeleteValueA(udpatch, "LocalPackage");
10678     RegDeleteKeyA(udpatch, "");
10679     RegCloseKey(udpatch);
10680     RegDeleteKeyA(hpatch, "");
10681     RegCloseKey(hpatch);
10682     RegDeleteKeyA(patches, "");
10683     RegCloseKey(patches);
10684     RegDeleteKeyA(props, "");
10685     RegCloseKey(props);
10686     RegDeleteKeyA(udprod, "");
10687     RegCloseKey(udprod);
10688
10689     /* MSIINSTALLCONTEXT_MACHINE */
10690
10691     size = MAX_PATH;
10692     lstrcpyA(val, "apple");
10693     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10694                             MSIINSTALLCONTEXT_MACHINE,
10695                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10696     ok(r == ERROR_UNKNOWN_PRODUCT,
10697        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10698     ok(!lstrcmpA(val, "apple"),
10699        "Expected val to be unchanged, got \"%s\"\n", val);
10700     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10701
10702     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10703     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10704     lstrcatA(keypath, prod_squashed);
10705
10706     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10707     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10708
10709     /* local UserData product key exists */
10710     size = MAX_PATH;
10711     lstrcpyA(val, "apple");
10712     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10713                             MSIINSTALLCONTEXT_MACHINE,
10714                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10715     ok(r == ERROR_UNKNOWN_PRODUCT,
10716        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10717     ok(!lstrcmpA(val, "apple"),
10718        "Expected val to be unchanged, got \"%s\"\n", val);
10719     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10720
10721     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10723
10724     /* InstallProperties key exists */
10725     size = MAX_PATH;
10726     lstrcpyA(val, "apple");
10727     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10728                             MSIINSTALLCONTEXT_MACHINE,
10729                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10730     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10731     ok(!lstrcmpA(val, "apple"),
10732        "Expected val to be unchanged, got \"%s\"\n", val);
10733     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10734
10735     res = RegCreateKeyA(udprod, "Patches", &patches);
10736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10737
10738     /* Patches key exists */
10739     size = MAX_PATH;
10740     lstrcpyA(val, "apple");
10741     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10742                             MSIINSTALLCONTEXT_MACHINE,
10743                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10744     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10745     ok(!lstrcmpA(val, "apple"),
10746        "Expected val to be unchanged, got \"%s\"\n", val);
10747     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10748
10749     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10750     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10751
10752     /* Patches key exists */
10753     size = MAX_PATH;
10754     lstrcpyA(val, "apple");
10755     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10756                             MSIINSTALLCONTEXT_MACHINE,
10757                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10758     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10759     ok(!lstrcmpA(val, "apple"),
10760        "Expected val to be unchanged, got \"%s\"\n", val);
10761     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10762
10763     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10764     lstrcatA(keypath, prod_squashed);
10765
10766     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10767     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10768
10769     /* local product key exists */
10770     size = MAX_PATH;
10771     lstrcpyA(val, "apple");
10772     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10773                             MSIINSTALLCONTEXT_MACHINE,
10774                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10775     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10776     ok(!lstrcmpA(val, "apple"),
10777        "Expected val to be unchanged, got \"%s\"\n", val);
10778     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10779
10780     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10781     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10782
10783     /* Patches key exists */
10784     size = MAX_PATH;
10785     lstrcpyA(val, "apple");
10786     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10787                             MSIINSTALLCONTEXT_MACHINE,
10788                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10789     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10790     ok(!lstrcmpA(val, "apple"),
10791        "Expected val to be unchanged, got \"%s\"\n", val);
10792     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10793
10794     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10795                          (const BYTE *)"transforms", 11);
10796     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10797
10798     /* specific patch value exists */
10799     size = MAX_PATH;
10800     lstrcpyA(val, "apple");
10801     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10802                             MSIINSTALLCONTEXT_MACHINE,
10803                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10804     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10805     ok(!lstrcmpA(val, "apple"),
10806        "Expected val to be unchanged, got \"%s\"\n", val);
10807     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10808
10809     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10810     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
10811     lstrcatA(keypath, patch_squashed);
10812
10813     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10814     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10815
10816     /* UserData Patches key exists */
10817     size = MAX_PATH;
10818     lstrcpyA(val, "apple");
10819     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10820                             MSIINSTALLCONTEXT_MACHINE,
10821                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10822     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10823     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10824     ok(size == 0, "Expected 0, got %d\n", size);
10825
10826     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10827                          (const BYTE *)"pack", 5);
10828     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10829
10830     /* LocalPatch value exists */
10831     size = MAX_PATH;
10832     lstrcpyA(val, "apple");
10833     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10834                             MSIINSTALLCONTEXT_MACHINE,
10835                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10836     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10837     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10838     ok(size == 4, "Expected 4, got %d\n", size);
10839
10840     size = MAX_PATH;
10841     lstrcpyA(val, "apple");
10842     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10843                             MSIINSTALLCONTEXT_MACHINE,
10844                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10845     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10846     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10847     ok(size == 10, "Expected 10, got %d\n", size);
10848
10849     RegDeleteValueA(prodpatches, patch_squashed);
10850     RegDeleteKeyA(prodpatches, "");
10851     RegCloseKey(prodpatches);
10852     RegDeleteKeyA(prodkey, "");
10853     RegCloseKey(prodkey);
10854
10855     /* UserData is sufficient for all properties
10856      * except INSTALLPROPERTY_TRANSFORMS
10857      */
10858     size = MAX_PATH;
10859     lstrcpyA(val, "apple");
10860     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10861                             MSIINSTALLCONTEXT_MACHINE,
10862                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10863     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10864     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10865     ok(size == 4, "Expected 4, got %d\n", size);
10866
10867     /* UserData is sufficient for all properties
10868      * except INSTALLPROPERTY_TRANSFORMS
10869      */
10870     size = MAX_PATH;
10871     lstrcpyA(val, "apple");
10872     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10873                             MSIINSTALLCONTEXT_MACHINE,
10874                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10875     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10876     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10877     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10878
10879     RegDeleteValueA(udpatch, "LocalPackage");
10880     RegDeleteKeyA(udpatch, "");
10881     RegCloseKey(udpatch);
10882     RegDeleteKeyA(hpatch, "");
10883     RegCloseKey(hpatch);
10884     RegDeleteKeyA(patches, "");
10885     RegCloseKey(patches);
10886     RegDeleteKeyA(props, "");
10887     RegCloseKey(props);
10888     RegDeleteKeyA(udprod, "");
10889     RegCloseKey(udprod);
10890     LocalFree(usersid);
10891 }
10892
10893 static void test_MsiEnumProducts(void)
10894 {
10895     UINT r;
10896     int found1, found2, found3;
10897     DWORD index;
10898     char product1[39], product2[39], product3[39], guid[39];
10899     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
10900     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
10901     char *usersid;
10902     HKEY key1, key2, key3;
10903
10904     create_test_guid(product1, product_squashed1);
10905     create_test_guid(product2, product_squashed2);
10906     create_test_guid(product3, product_squashed3);
10907     get_user_sid(&usersid);
10908
10909     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
10910     strcat(keypath1, product_squashed1);
10911
10912     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath1, &key1);
10913     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10914
10915     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10916     strcat(keypath2, usersid);
10917     strcat(keypath2, "\\Installer\\Products\\");
10918     strcat(keypath2, product_squashed2);
10919
10920     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath2, &key2);
10921     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10922
10923     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
10924     strcat(keypath3, product_squashed3);
10925
10926     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
10927     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10928
10929     index = 0;
10930     r = MsiEnumProductsA(index, NULL);
10931     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
10932
10933     index = 2;
10934     r = MsiEnumProductsA(index, guid);
10935     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
10936
10937     index = 0;
10938     r = MsiEnumProductsA(index, guid);
10939     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
10940
10941     found1 = found2 = found3 = 0;
10942     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
10943     {
10944         if (!strcmp(product1, guid)) found1 = 1;
10945         if (!strcmp(product2, guid)) found2 = 1;
10946         if (!strcmp(product3, guid)) found3 = 1;
10947         index++;
10948     }
10949     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
10950     ok(found1, "product1 not found\n");
10951     ok(found2, "product2 not found\n");
10952     ok(found3, "product3 not found\n");
10953
10954     RegDeleteKeyA(key1, "");
10955     RegDeleteKeyA(key2, "");
10956     RegDeleteKeyA(key3, "");
10957     RegCloseKey(key1);
10958     RegCloseKey(key2);
10959     RegCloseKey(key3);
10960     LocalFree(usersid);
10961 }
10962
10963 START_TEST(msi)
10964 {
10965     init_functionpointers();
10966
10967     test_usefeature();
10968     test_null();
10969     test_getcomponentpath();
10970     test_MsiGetFileHash();
10971
10972     if (!pConvertSidToStringSidA)
10973         win_skip("ConvertSidToStringSidA not implemented\n");
10974     else
10975     {
10976         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
10977         test_MsiQueryProductState();
10978         test_MsiQueryFeatureState();
10979         test_MsiQueryComponentState();
10980         test_MsiGetComponentPath();
10981         test_MsiGetProductCode();
10982         test_MsiEnumClients();
10983         test_MsiGetProductInfo();
10984         test_MsiGetProductInfoEx();
10985         test_MsiGetUserInfo();
10986         test_MsiOpenProduct();
10987         test_MsiEnumPatchesEx();
10988         test_MsiEnumPatches();
10989         test_MsiGetPatchInfoEx();
10990         test_MsiEnumProducts();
10991     }
10992
10993     test_MsiGetFileVersion();
10994 }