comctl32/listview: Fix hittesting for LVS_REPORT subitems.
[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 }
1205
1206 static void test_MsiQueryComponentState(void)
1207 {
1208     HKEY compkey, prodkey;
1209     CHAR prodcode[MAX_PATH];
1210     CHAR prod_squashed[MAX_PATH];
1211     CHAR component[MAX_PATH];
1212     CHAR comp_base85[MAX_PATH];
1213     CHAR comp_squashed[MAX_PATH];
1214     CHAR keypath[MAX_PATH];
1215     INSTALLSTATE state;
1216     LPSTR usersid;
1217     LONG res;
1218     UINT r;
1219
1220     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1221
1222     if (!pMsiQueryComponentStateA)
1223     {
1224         win_skip("MsiQueryComponentStateA not implemented\n");
1225         return;
1226     }
1227
1228     create_test_guid(prodcode, prod_squashed);
1229     compose_base85_guid(component, comp_base85, comp_squashed);
1230     get_user_sid(&usersid);
1231
1232     /* NULL szProductCode */
1233     state = MAGIC_ERROR;
1234     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1235     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1236     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1237
1238     /* empty szProductCode */
1239     state = MAGIC_ERROR;
1240     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1241     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1242     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1243
1244     /* random szProductCode */
1245     state = MAGIC_ERROR;
1246     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1247     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1248     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1249
1250     /* GUID-length szProductCode */
1251     state = MAGIC_ERROR;
1252     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1253     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1254     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1255
1256     /* GUID-length with brackets */
1257     state = MAGIC_ERROR;
1258     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1259     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1260     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1261
1262     /* actual GUID */
1263     state = MAGIC_ERROR;
1264     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1265     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1266     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1267
1268     state = MAGIC_ERROR;
1269     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1270     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1271     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1272
1273     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1274     lstrcatA(keypath, prod_squashed);
1275
1276     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1277     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1278
1279     state = MAGIC_ERROR;
1280     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1281     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1282     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1283
1284     RegDeleteKeyA(prodkey, "");
1285     RegCloseKey(prodkey);
1286
1287     /* create local system product key */
1288     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1289     lstrcatA(keypath, prod_squashed);
1290     lstrcatA(keypath, "\\InstallProperties");
1291
1292     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1294
1295     /* local system product key exists */
1296     state = MAGIC_ERROR;
1297     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1298     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1299     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1300
1301     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1303
1304     /* LocalPackage value exists */
1305     state = MAGIC_ERROR;
1306     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1307     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1308     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1309
1310     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1311     lstrcatA(keypath, comp_squashed);
1312
1313     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1314     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1315
1316     /* component key exists */
1317     state = MAGIC_ERROR;
1318     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1319     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1320     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1321
1322     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1323     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1324
1325     /* component\product exists */
1326     state = MAGIC_ERROR;
1327     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1328     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1329     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1330        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1331
1332     /* NULL component, product exists */
1333     state = MAGIC_ERROR;
1334     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1335     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1336     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1337
1338     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1339     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1340
1341     /* INSTALLSTATE_LOCAL */
1342     state = MAGIC_ERROR;
1343     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1344     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1345     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1346
1347     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1349
1350     /* INSTALLSTATE_SOURCE */
1351     state = MAGIC_ERROR;
1352     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1353     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1354     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1355
1356     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1357     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1358
1359     /* bad INSTALLSTATE_SOURCE */
1360     state = MAGIC_ERROR;
1361     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1362     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1363     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1364
1365     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1366     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1367
1368     /* INSTALLSTATE_SOURCE */
1369     state = MAGIC_ERROR;
1370     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1372     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1373
1374     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1375     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1376
1377     /* bad INSTALLSTATE_SOURCE */
1378     state = MAGIC_ERROR;
1379     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1380     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1381     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1382
1383     RegDeleteValueA(prodkey, "LocalPackage");
1384     RegDeleteKeyA(prodkey, "");
1385     RegDeleteValueA(compkey, prod_squashed);
1386     RegDeleteKeyA(prodkey, "");
1387     RegCloseKey(prodkey);
1388     RegCloseKey(compkey);
1389
1390     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1391
1392     state = MAGIC_ERROR;
1393     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1394     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1395     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1396
1397     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1398     lstrcatA(keypath, prod_squashed);
1399
1400     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1401     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1402
1403     state = MAGIC_ERROR;
1404     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1405     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1406     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1407
1408     RegDeleteKeyA(prodkey, "");
1409     RegCloseKey(prodkey);
1410
1411     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1412     lstrcatA(keypath, usersid);
1413     lstrcatA(keypath, "\\Products\\");
1414     lstrcatA(keypath, prod_squashed);
1415     lstrcatA(keypath, "\\InstallProperties");
1416
1417     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1418     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1419
1420     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1421     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1422
1423     RegCloseKey(prodkey);
1424
1425     state = MAGIC_ERROR;
1426     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1427     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1428     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1429
1430     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1431     lstrcatA(keypath, usersid);
1432     lstrcatA(keypath, "\\Components\\");
1433     lstrcatA(keypath, comp_squashed);
1434
1435     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1436     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1437
1438     /* component key exists */
1439     state = MAGIC_ERROR;
1440     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1441     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1442     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1443
1444     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1445     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1446
1447     /* component\product exists */
1448     state = MAGIC_ERROR;
1449     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1450     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1451     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1452        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1453
1454     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1455     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1456
1457     state = MAGIC_ERROR;
1458     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1459     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1460     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1461
1462     /* MSIINSTALLCONTEXT_USERMANAGED */
1463
1464     state = MAGIC_ERROR;
1465     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1466     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1467     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1468
1469     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1470     lstrcatA(keypath, prod_squashed);
1471
1472     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1473     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1474
1475     state = MAGIC_ERROR;
1476     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1477     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1478     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1479
1480     RegDeleteKeyA(prodkey, "");
1481     RegCloseKey(prodkey);
1482
1483     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1484     lstrcatA(keypath, usersid);
1485     lstrcatA(keypath, "\\Installer\\Products\\");
1486     lstrcatA(keypath, prod_squashed);
1487
1488     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1489     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1490
1491     state = MAGIC_ERROR;
1492     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1493     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1494     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1495
1496     RegDeleteKeyA(prodkey, "");
1497     RegCloseKey(prodkey);
1498
1499     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1500     lstrcatA(keypath, usersid);
1501     lstrcatA(keypath, "\\Products\\");
1502     lstrcatA(keypath, prod_squashed);
1503     lstrcatA(keypath, "\\InstallProperties");
1504
1505     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1506     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1507
1508     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1510
1511     state = MAGIC_ERROR;
1512     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1513     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1514     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1515
1516     RegDeleteValueA(prodkey, "LocalPackage");
1517     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1518     RegDeleteKeyA(prodkey, "");
1519     RegDeleteValueA(compkey, prod_squashed);
1520     RegDeleteKeyA(compkey, "");
1521     RegCloseKey(prodkey);
1522     RegCloseKey(compkey);
1523 }
1524
1525 static void test_MsiGetComponentPath(void)
1526 {
1527     HKEY compkey, prodkey, installprop;
1528     CHAR prodcode[MAX_PATH];
1529     CHAR prod_squashed[MAX_PATH];
1530     CHAR component[MAX_PATH];
1531     CHAR comp_base85[MAX_PATH];
1532     CHAR comp_squashed[MAX_PATH];
1533     CHAR keypath[MAX_PATH];
1534     CHAR path[MAX_PATH];
1535     INSTALLSTATE state;
1536     LPSTR usersid;
1537     DWORD size, val;
1538     LONG res;
1539
1540     create_test_guid(prodcode, prod_squashed);
1541     compose_base85_guid(component, comp_base85, comp_squashed);
1542     get_user_sid(&usersid);
1543
1544     /* NULL szProduct */
1545     size = MAX_PATH;
1546     state = MsiGetComponentPathA(NULL, component, path, &size);
1547     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1548     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1549
1550     /* NULL szComponent */
1551     size = MAX_PATH;
1552     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1553     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1554     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1555
1556     /* NULL lpPathBuf */
1557     size = MAX_PATH;
1558     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1559     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1560     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1561
1562     /* NULL pcchBuf */
1563     size = MAX_PATH;
1564     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1565     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1566     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1567
1568     /* all params valid */
1569     size = MAX_PATH;
1570     state = MsiGetComponentPathA(prodcode, component, path, &size);
1571     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1572     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1573
1574     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1575     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1576     lstrcatA(keypath, comp_squashed);
1577
1578     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1580
1581     /* local system component key exists */
1582     size = MAX_PATH;
1583     state = MsiGetComponentPathA(prodcode, component, path, &size);
1584     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1585     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1586
1587     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1589
1590     /* product value exists */
1591     size = MAX_PATH;
1592     state = MsiGetComponentPathA(prodcode, component, path, &size);
1593     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1594     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1595     ok(size == 10, "Expected 10, got %d\n", size);
1596
1597     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1598     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1599     lstrcatA(keypath, prod_squashed);
1600     lstrcatA(keypath, "\\InstallProperties");
1601
1602     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1603     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1604
1605     val = 1;
1606     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1608
1609     /* install properties key exists */
1610     size = MAX_PATH;
1611     state = MsiGetComponentPathA(prodcode, component, path, &size);
1612     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1613     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1614     ok(size == 10, "Expected 10, got %d\n", size);
1615
1616     create_file("C:\\imapath", "C:\\imapath", 11);
1617
1618     /* file exists */
1619     size = MAX_PATH;
1620     state = MsiGetComponentPathA(prodcode, component, path, &size);
1621     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1622     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1623     ok(size == 10, "Expected 10, got %d\n", size);
1624
1625     RegDeleteValueA(compkey, prod_squashed);
1626     RegDeleteKeyA(compkey, "");
1627     RegDeleteValueA(installprop, "WindowsInstaller");
1628     RegDeleteKeyA(installprop, "");
1629     RegCloseKey(compkey);
1630     RegCloseKey(installprop);
1631     DeleteFileA("C:\\imapath");
1632
1633     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1634     lstrcatA(keypath, "Installer\\UserData\\");
1635     lstrcatA(keypath, usersid);
1636     lstrcatA(keypath, "\\Components\\");
1637     lstrcatA(keypath, comp_squashed);
1638
1639     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1640     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1641
1642     /* user managed component key exists */
1643     size = MAX_PATH;
1644     state = MsiGetComponentPathA(prodcode, component, path, &size);
1645     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1646     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1647
1648     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1649     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1650
1651     /* product value exists */
1652     size = MAX_PATH;
1653     state = MsiGetComponentPathA(prodcode, component, path, &size);
1654     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1655     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1656     ok(size == 10, "Expected 10, got %d\n", size);
1657
1658     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1659     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1660     lstrcatA(keypath, prod_squashed);
1661     lstrcatA(keypath, "\\InstallProperties");
1662
1663     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1664     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1665
1666     val = 1;
1667     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1668     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1669
1670     /* install properties key exists */
1671     size = MAX_PATH;
1672     state = MsiGetComponentPathA(prodcode, component, path, &size);
1673     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1674     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1675     ok(size == 10, "Expected 10, got %d\n", size);
1676
1677     create_file("C:\\imapath", "C:\\imapath", 11);
1678
1679     /* file exists */
1680     size = MAX_PATH;
1681     state = MsiGetComponentPathA(prodcode, component, path, &size);
1682     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1683     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1684     ok(size == 10, "Expected 10, got %d\n", size);
1685
1686     RegDeleteValueA(compkey, prod_squashed);
1687     RegDeleteKeyA(compkey, "");
1688     RegDeleteValueA(installprop, "WindowsInstaller");
1689     RegDeleteKeyA(installprop, "");
1690     RegCloseKey(compkey);
1691     RegCloseKey(installprop);
1692     DeleteFileA("C:\\imapath");
1693
1694     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1695     lstrcatA(keypath, "Installer\\Managed\\");
1696     lstrcatA(keypath, usersid);
1697     lstrcatA(keypath, "\\Installer\\Products\\");
1698     lstrcatA(keypath, prod_squashed);
1699
1700     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1701     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1702
1703     /* user managed product key exists */
1704     size = MAX_PATH;
1705     state = MsiGetComponentPathA(prodcode, component, path, &size);
1706     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1707     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1708
1709     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1710     lstrcatA(keypath, "Installer\\UserData\\");
1711     lstrcatA(keypath, usersid);
1712     lstrcatA(keypath, "\\Components\\");
1713     lstrcatA(keypath, comp_squashed);
1714
1715     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1717
1718     /* user managed component key exists */
1719     size = MAX_PATH;
1720     state = MsiGetComponentPathA(prodcode, component, path, &size);
1721     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1722     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1723
1724     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1726
1727     /* product value exists */
1728     size = MAX_PATH;
1729     state = MsiGetComponentPathA(prodcode, component, path, &size);
1730     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1731     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1732     ok(size == 10, "Expected 10, got %d\n", size);
1733
1734     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1735     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1736     lstrcatA(keypath, prod_squashed);
1737     lstrcatA(keypath, "\\InstallProperties");
1738
1739     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1741
1742     val = 1;
1743     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1744     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1745
1746     /* install properties key exists */
1747     size = MAX_PATH;
1748     state = MsiGetComponentPathA(prodcode, component, path, &size);
1749     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1750     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1751     ok(size == 10, "Expected 10, got %d\n", size);
1752
1753     create_file("C:\\imapath", "C:\\imapath", 11);
1754
1755     /* file exists */
1756     size = MAX_PATH;
1757     state = MsiGetComponentPathA(prodcode, component, path, &size);
1758     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1759     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1760     ok(size == 10, "Expected 10, got %d\n", size);
1761
1762     RegDeleteValueA(compkey, prod_squashed);
1763     RegDeleteKeyA(prodkey, "");
1764     RegDeleteKeyA(compkey, "");
1765     RegDeleteValueA(installprop, "WindowsInstaller");
1766     RegDeleteKeyA(installprop, "");
1767     RegCloseKey(prodkey);
1768     RegCloseKey(compkey);
1769     RegCloseKey(installprop);
1770     DeleteFileA("C:\\imapath");
1771
1772     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1773     lstrcatA(keypath, prod_squashed);
1774
1775     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1776     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1777
1778     /* user unmanaged product key exists */
1779     size = MAX_PATH;
1780     state = MsiGetComponentPathA(prodcode, component, path, &size);
1781     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1782     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1783
1784     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1785     lstrcatA(keypath, "Installer\\UserData\\");
1786     lstrcatA(keypath, usersid);
1787     lstrcatA(keypath, "\\Components\\");
1788     lstrcatA(keypath, comp_squashed);
1789
1790     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1792
1793     /* user unmanaged component key exists */
1794     size = MAX_PATH;
1795     state = MsiGetComponentPathA(prodcode, component, path, &size);
1796     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1797     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1798
1799     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1800     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1801
1802     /* product value exists */
1803     size = MAX_PATH;
1804     state = MsiGetComponentPathA(prodcode, component, path, &size);
1805     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1806     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1807     ok(size == 10, "Expected 10, got %d\n", size);
1808
1809     create_file("C:\\imapath", "C:\\imapath", 11);
1810
1811     /* file exists */
1812     size = MAX_PATH;
1813     state = MsiGetComponentPathA(prodcode, component, path, &size);
1814     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1815     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1816     ok(size == 10, "Expected 10, got %d\n", size);
1817
1818     RegDeleteValueA(compkey, prod_squashed);
1819     RegDeleteKeyA(prodkey, "");
1820     RegDeleteKeyA(compkey, "");
1821     RegCloseKey(prodkey);
1822     RegCloseKey(compkey);
1823     DeleteFileA("C:\\imapath");
1824
1825     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1826     lstrcatA(keypath, prod_squashed);
1827
1828     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1829     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1830
1831     /* local classes product key exists */
1832     size = MAX_PATH;
1833     state = MsiGetComponentPathA(prodcode, component, path, &size);
1834     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1835     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1836
1837     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1838     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1839     lstrcatA(keypath, comp_squashed);
1840
1841     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1842     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1843
1844     /* local user component key exists */
1845     size = MAX_PATH;
1846     state = MsiGetComponentPathA(prodcode, component, path, &size);
1847     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1848     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1849
1850     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1851     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1852
1853     /* product value exists */
1854     size = MAX_PATH;
1855     state = MsiGetComponentPathA(prodcode, component, path, &size);
1856     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1857     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1858     ok(size == 10, "Expected 10, got %d\n", size);
1859
1860     create_file("C:\\imapath", "C:\\imapath", 11);
1861
1862     /* file exists */
1863     size = MAX_PATH;
1864     state = MsiGetComponentPathA(prodcode, component, path, &size);
1865     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1866     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1867     ok(size == 10, "Expected 10, got %d\n", size);
1868
1869     RegDeleteValueA(compkey, prod_squashed);
1870     RegDeleteKeyA(prodkey, "");
1871     RegDeleteKeyA(compkey, "");
1872     RegCloseKey(prodkey);
1873     RegCloseKey(compkey);
1874     DeleteFileA("C:\\imapath");
1875 }
1876
1877 static void test_MsiGetProductCode(void)
1878 {
1879     HKEY compkey, prodkey;
1880     CHAR prodcode[MAX_PATH];
1881     CHAR prod_squashed[MAX_PATH];
1882     CHAR prodcode2[MAX_PATH];
1883     CHAR prod2_squashed[MAX_PATH];
1884     CHAR component[MAX_PATH];
1885     CHAR comp_base85[MAX_PATH];
1886     CHAR comp_squashed[MAX_PATH];
1887     CHAR keypath[MAX_PATH];
1888     CHAR product[MAX_PATH];
1889     LPSTR usersid;
1890     LONG res;
1891     UINT r;
1892
1893     create_test_guid(prodcode, prod_squashed);
1894     create_test_guid(prodcode2, prod2_squashed);
1895     compose_base85_guid(component, comp_base85, comp_squashed);
1896     get_user_sid(&usersid);
1897
1898     /* szComponent is NULL */
1899     lstrcpyA(product, "prod");
1900     r = MsiGetProductCodeA(NULL, product);
1901     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1902     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1903
1904     /* szComponent is empty */
1905     lstrcpyA(product, "prod");
1906     r = MsiGetProductCodeA("", product);
1907     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1908     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1909
1910     /* garbage szComponent */
1911     lstrcpyA(product, "prod");
1912     r = MsiGetProductCodeA("garbage", product);
1913     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1914     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1915
1916     /* guid without brackets */
1917     lstrcpyA(product, "prod");
1918     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
1919     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1920     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1921
1922     /* guid with brackets */
1923     lstrcpyA(product, "prod");
1924     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
1925     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1926     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1927
1928     /* same length as guid, but random */
1929     lstrcpyA(product, "prod");
1930     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
1931     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1932     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1933
1934     /* all params correct, szComponent not published */
1935     lstrcpyA(product, "prod");
1936     r = MsiGetProductCodeA(component, product);
1937     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1938     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1939
1940     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1941     lstrcatA(keypath, "Installer\\UserData\\");
1942     lstrcatA(keypath, usersid);
1943     lstrcatA(keypath, "\\Components\\");
1944     lstrcatA(keypath, comp_squashed);
1945
1946     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1947     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1948
1949     /* user unmanaged component key exists */
1950     lstrcpyA(product, "prod");
1951     r = MsiGetProductCodeA(component, product);
1952     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1953     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1954
1955     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1957
1958     /* product value exists */
1959     lstrcpyA(product, "prod");
1960     r = MsiGetProductCodeA(component, product);
1961     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1962     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1963
1964     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1965     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1966
1967     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1968     lstrcatA(keypath, "Installer\\Managed\\");
1969     lstrcatA(keypath, usersid);
1970     lstrcatA(keypath, "\\Installer\\Products\\");
1971     lstrcatA(keypath, prod_squashed);
1972
1973     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1974     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1975
1976     /* user managed product key of first product exists */
1977     lstrcpyA(product, "prod");
1978     r = MsiGetProductCodeA(component, product);
1979     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1980     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1981
1982     RegDeleteKeyA(prodkey, "");
1983     RegCloseKey(prodkey);
1984
1985     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1986     lstrcatA(keypath, prod_squashed);
1987
1988     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1989     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1990
1991     /* user unmanaged product key exists */
1992     lstrcpyA(product, "prod");
1993     r = MsiGetProductCodeA(component, product);
1994     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1995     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1996
1997     RegDeleteKeyA(prodkey, "");
1998     RegCloseKey(prodkey);
1999
2000     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2001     lstrcatA(keypath, prod_squashed);
2002
2003     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2005
2006     /* local classes product key exists */
2007     lstrcpyA(product, "prod");
2008     r = MsiGetProductCodeA(component, product);
2009     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2010     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2011
2012     RegDeleteKeyA(prodkey, "");
2013     RegCloseKey(prodkey);
2014
2015     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2016     lstrcatA(keypath, "Installer\\Managed\\");
2017     lstrcatA(keypath, usersid);
2018     lstrcatA(keypath, "\\Installer\\Products\\");
2019     lstrcatA(keypath, prod2_squashed);
2020
2021     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2022     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2023
2024     /* user managed product key of second product exists */
2025     lstrcpyA(product, "prod");
2026     r = MsiGetProductCodeA(component, product);
2027     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2028     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2029
2030     RegDeleteKeyA(prodkey, "");
2031     RegCloseKey(prodkey);
2032     RegDeleteValueA(compkey, prod_squashed);
2033     RegDeleteValueA(compkey, prod2_squashed);
2034     RegDeleteKeyA(compkey, "");
2035     RegCloseKey(compkey);
2036
2037     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2038     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2039     lstrcatA(keypath, comp_squashed);
2040
2041     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2042     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2043
2044     /* local user component key exists */
2045     lstrcpyA(product, "prod");
2046     r = MsiGetProductCodeA(component, product);
2047     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2048     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2049
2050     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2051     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2052
2053     /* product value exists */
2054     lstrcpyA(product, "prod");
2055     r = MsiGetProductCodeA(component, product);
2056     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2057     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2058
2059     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2061
2062     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2063     lstrcatA(keypath, "Installer\\Managed\\");
2064     lstrcatA(keypath, usersid);
2065     lstrcatA(keypath, "\\Installer\\Products\\");
2066     lstrcatA(keypath, prod_squashed);
2067
2068     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2069     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2070
2071     /* user managed product key of first product exists */
2072     lstrcpyA(product, "prod");
2073     r = MsiGetProductCodeA(component, product);
2074     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2075     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2076
2077     RegDeleteKeyA(prodkey, "");
2078     RegCloseKey(prodkey);
2079
2080     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2081     lstrcatA(keypath, prod_squashed);
2082
2083     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2084     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2085
2086     /* user unmanaged product key exists */
2087     lstrcpyA(product, "prod");
2088     r = MsiGetProductCodeA(component, product);
2089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2090     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2091
2092     RegDeleteKeyA(prodkey, "");
2093     RegCloseKey(prodkey);
2094
2095     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2096     lstrcatA(keypath, prod_squashed);
2097
2098     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2099     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2100
2101     /* local classes product key exists */
2102     lstrcpyA(product, "prod");
2103     r = MsiGetProductCodeA(component, product);
2104     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2105     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2106
2107     RegDeleteKeyA(prodkey, "");
2108     RegCloseKey(prodkey);
2109
2110     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2111     lstrcatA(keypath, "Installer\\Managed\\");
2112     lstrcatA(keypath, usersid);
2113     lstrcatA(keypath, "\\Installer\\Products\\");
2114     lstrcatA(keypath, prod2_squashed);
2115
2116     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2117     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2118
2119     /* user managed product key of second product exists */
2120     lstrcpyA(product, "prod");
2121     r = MsiGetProductCodeA(component, product);
2122     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2123     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2124
2125     RegDeleteKeyA(prodkey, "");
2126     RegCloseKey(prodkey);
2127     RegDeleteValueA(compkey, prod_squashed);
2128     RegDeleteValueA(compkey, prod2_squashed);
2129     RegDeleteKeyA(compkey, "");
2130     RegCloseKey(compkey);
2131 }
2132
2133 static void test_MsiEnumClients(void)
2134 {
2135     HKEY compkey;
2136     CHAR prodcode[MAX_PATH];
2137     CHAR prod_squashed[MAX_PATH];
2138     CHAR prodcode2[MAX_PATH];
2139     CHAR prod2_squashed[MAX_PATH];
2140     CHAR component[MAX_PATH];
2141     CHAR comp_base85[MAX_PATH];
2142     CHAR comp_squashed[MAX_PATH];
2143     CHAR product[MAX_PATH];
2144     CHAR keypath[MAX_PATH];
2145     LPSTR usersid;
2146     LONG res;
2147     UINT r;
2148
2149     create_test_guid(prodcode, prod_squashed);
2150     create_test_guid(prodcode2, prod2_squashed);
2151     compose_base85_guid(component, comp_base85, comp_squashed);
2152     get_user_sid(&usersid);
2153
2154     /* NULL szComponent */
2155     product[0] = '\0';
2156     r = MsiEnumClientsA(NULL, 0, product);
2157     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2158     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2159
2160     /* empty szComponent */
2161     product[0] = '\0';
2162     r = MsiEnumClientsA("", 0, product);
2163     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2164     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2165
2166     /* NULL lpProductBuf */
2167     r = MsiEnumClientsA(component, 0, NULL);
2168     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2169
2170     /* all params correct, component missing */
2171     product[0] = '\0';
2172     r = MsiEnumClientsA(component, 0, product);
2173     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2174     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2175
2176     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2177     lstrcatA(keypath, "Installer\\UserData\\");
2178     lstrcatA(keypath, usersid);
2179     lstrcatA(keypath, "\\Components\\");
2180     lstrcatA(keypath, comp_squashed);
2181
2182     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2183     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2184
2185     /* user unmanaged component key exists */
2186     product[0] = '\0';
2187     r = MsiEnumClientsA(component, 0, product);
2188     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2189     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2190
2191     /* index > 0, no products exist */
2192     product[0] = '\0';
2193     r = MsiEnumClientsA(component, 1, product);
2194     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2195     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2196
2197     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2199
2200     /* product value exists */
2201     r = MsiEnumClientsA(component, 0, product);
2202     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2203     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2204
2205     /* try index 0 again */
2206     product[0] = '\0';
2207     r = MsiEnumClientsA(component, 0, product);
2208     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2209     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2210
2211     /* try index 1, second product value does not exist */
2212     product[0] = '\0';
2213     r = MsiEnumClientsA(component, 1, product);
2214     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2215     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2216
2217     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2218     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2219
2220     /* try index 1, second product value does exist */
2221     product[0] = '\0';
2222     r = MsiEnumClientsA(component, 1, product);
2223     todo_wine
2224     {
2225         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2226         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2227     }
2228
2229     /* start the enumeration over */
2230     product[0] = '\0';
2231     r = MsiEnumClientsA(component, 0, product);
2232     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2233     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2234        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2235
2236     /* correctly query second product */
2237     product[0] = '\0';
2238     r = MsiEnumClientsA(component, 1, product);
2239     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2240     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2241        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2242
2243     RegDeleteValueA(compkey, prod_squashed);
2244     RegDeleteValueA(compkey, prod2_squashed);
2245     RegDeleteKeyA(compkey, "");
2246     RegCloseKey(compkey);
2247
2248     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2249     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2250     lstrcatA(keypath, comp_squashed);
2251
2252     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2253     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2254
2255     /* user local component key exists */
2256     product[0] = '\0';
2257     r = MsiEnumClientsA(component, 0, product);
2258     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2259     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2260
2261     /* index > 0, no products exist */
2262     product[0] = '\0';
2263     r = MsiEnumClientsA(component, 1, product);
2264     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2265     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2266
2267     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2268     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2269
2270     /* product value exists */
2271     product[0] = '\0';
2272     r = MsiEnumClientsA(component, 0, product);
2273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2274     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2275
2276     /* try index 0 again */
2277     product[0] = '\0';
2278     r = MsiEnumClientsA(component, 0, product);
2279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2280
2281     /* try index 1, second product value does not exist */
2282     product[0] = '\0';
2283     r = MsiEnumClientsA(component, 1, product);
2284     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2285     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2286
2287     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2289
2290     /* try index 1, second product value does exist */
2291     product[0] = '\0';
2292     r = MsiEnumClientsA(component, 1, product);
2293     todo_wine
2294     {
2295         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2296         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2297     }
2298
2299     /* start the enumeration over */
2300     product[0] = '\0';
2301     r = MsiEnumClientsA(component, 0, product);
2302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2303     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2304        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2305
2306     /* correctly query second product */
2307     product[0] = '\0';
2308     r = MsiEnumClientsA(component, 1, product);
2309     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2310     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2311        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2312
2313     RegDeleteValueA(compkey, prod_squashed);
2314     RegDeleteValueA(compkey, prod2_squashed);
2315     RegDeleteKeyA(compkey, "");
2316     RegCloseKey(compkey);
2317 }
2318
2319 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2320                              LPSTR *langcheck, LPDWORD langchecksz)
2321 {
2322     LPSTR version;
2323     VS_FIXEDFILEINFO *ffi;
2324     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2325     USHORT *lang;
2326
2327     version = HeapAlloc(GetProcessHeap(), 0, size);
2328     GetFileVersionInfoA(path, 0, size, version);
2329
2330     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2331     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2332     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2333             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2334             LOWORD(ffi->dwFileVersionLS));
2335     *verchecksz = lstrlenA(*vercheck);
2336
2337     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2338     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2339     sprintf(*langcheck, "%d", *lang);
2340     *langchecksz = lstrlenA(*langcheck);
2341
2342     HeapFree(GetProcessHeap(), 0, version);
2343 }
2344
2345 static void test_MsiGetFileVersion(void)
2346 {
2347     UINT r;
2348     DWORD versz, langsz;
2349     char version[MAX_PATH];
2350     char lang[MAX_PATH];
2351     char path[MAX_PATH];
2352     LPSTR vercheck, langcheck;
2353     DWORD verchecksz, langchecksz;
2354
2355     /* NULL szFilePath */
2356     versz = MAX_PATH;
2357     langsz = MAX_PATH;
2358     lstrcpyA(version, "version");
2359     lstrcpyA(lang, "lang");
2360     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2361     ok(r == ERROR_INVALID_PARAMETER,
2362        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2363     ok(!lstrcmpA(version, "version"),
2364        "Expected version to be unchanged, got %s\n", version);
2365     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2366     ok(!lstrcmpA(lang, "lang"),
2367        "Expected lang to be unchanged, got %s\n", lang);
2368     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2369
2370     /* empty szFilePath */
2371     versz = MAX_PATH;
2372     langsz = MAX_PATH;
2373     lstrcpyA(version, "version");
2374     lstrcpyA(lang, "lang");
2375     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2376     ok(r == ERROR_FILE_NOT_FOUND,
2377        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2378     ok(!lstrcmpA(version, "version"),
2379        "Expected version to be unchanged, got %s\n", version);
2380     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2381     ok(!lstrcmpA(lang, "lang"),
2382        "Expected lang to be unchanged, got %s\n", lang);
2383     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2384
2385     /* nonexistent szFilePath */
2386     versz = MAX_PATH;
2387     langsz = MAX_PATH;
2388     lstrcpyA(version, "version");
2389     lstrcpyA(lang, "lang");
2390     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2391     ok(r == ERROR_FILE_NOT_FOUND,
2392        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2393     ok(!lstrcmpA(version, "version"),
2394        "Expected version to be unchanged, got %s\n", version);
2395     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2396     ok(!lstrcmpA(lang, "lang"),
2397        "Expected lang to be unchanged, got %s\n", lang);
2398     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2399
2400     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2401     versz = MAX_PATH;
2402     langsz = MAX_PATH;
2403     lstrcpyA(version, "version");
2404     lstrcpyA(lang, "lang");
2405     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2406     ok(r == ERROR_INVALID_PARAMETER,
2407        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2408     ok(!lstrcmpA(version, "version"),
2409        "Expected version to be unchanged, got %s\n", version);
2410     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2411     ok(!lstrcmpA(lang, "lang"),
2412        "Expected lang to be unchanged, got %s\n", lang);
2413     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2414
2415     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2416     versz = MAX_PATH;
2417     langsz = MAX_PATH;
2418     lstrcpyA(version, "version");
2419     lstrcpyA(lang, "lang");
2420     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2421     ok(r == ERROR_INVALID_PARAMETER,
2422        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2423     ok(!lstrcmpA(version, "version"),
2424        "Expected version to be unchanged, got %s\n", version);
2425     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2426     ok(!lstrcmpA(lang, "lang"),
2427        "Expected lang to be unchanged, got %s\n", lang);
2428     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2429
2430     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2431     versz = 0;
2432     langsz = MAX_PATH;
2433     lstrcpyA(version, "version");
2434     lstrcpyA(lang, "lang");
2435     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2436     ok(r == ERROR_FILE_NOT_FOUND,
2437        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2438     ok(!lstrcmpA(version, "version"),
2439        "Expected version to be unchanged, got %s\n", version);
2440     ok(versz == 0, "Expected 0, got %d\n", versz);
2441     ok(!lstrcmpA(lang, "lang"),
2442        "Expected lang to be unchanged, got %s\n", lang);
2443     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2444
2445     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2446     versz = MAX_PATH;
2447     langsz = 0;
2448     lstrcpyA(version, "version");
2449     lstrcpyA(lang, "lang");
2450     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2451     ok(r == ERROR_FILE_NOT_FOUND,
2452        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2453     ok(!lstrcmpA(version, "version"),
2454        "Expected version to be unchanged, got %s\n", version);
2455     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2456     ok(!lstrcmpA(lang, "lang"),
2457        "Expected lang to be unchanged, got %s\n", lang);
2458     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2459
2460     /* nonexistent szFilePath, rest NULL */
2461     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2462     ok(r == ERROR_FILE_NOT_FOUND,
2463        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2464
2465     create_file("ver.txt", "ver.txt", 20);
2466
2467     /* file exists, no version information */
2468     versz = MAX_PATH;
2469     langsz = MAX_PATH;
2470     lstrcpyA(version, "version");
2471     lstrcpyA(lang, "lang");
2472     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2473     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2474     ok(!lstrcmpA(version, "version"),
2475        "Expected version to be unchanged, got %s\n", version);
2476     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2477     ok(!lstrcmpA(lang, "lang"),
2478        "Expected lang to be unchanged, got %s\n", lang);
2479     ok(r == ERROR_FILE_INVALID,
2480        "Expected ERROR_FILE_INVALID, got %d\n", r);
2481
2482     DeleteFileA("ver.txt");
2483
2484     /* relative path, has version information */
2485     versz = MAX_PATH;
2486     langsz = MAX_PATH;
2487     lstrcpyA(version, "version");
2488     lstrcpyA(lang, "lang");
2489     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2490     todo_wine
2491     {
2492         ok(r == ERROR_FILE_NOT_FOUND,
2493            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2494         ok(!lstrcmpA(version, "version"),
2495            "Expected version to be unchanged, got %s\n", version);
2496         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2497         ok(!lstrcmpA(lang, "lang"),
2498            "Expected lang to be unchanged, got %s\n", lang);
2499         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2500     }
2501
2502     GetSystemDirectoryA(path, MAX_PATH);
2503     lstrcatA(path, "\\kernel32.dll");
2504
2505     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2506
2507     /* absolute path, has version information */
2508     versz = MAX_PATH;
2509     langsz = MAX_PATH;
2510     lstrcpyA(version, "version");
2511     lstrcpyA(lang, "lang");
2512     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2513     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2514     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2515     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2516     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2517     ok(!lstrcmpA(version, vercheck),
2518         "Expected %s, got %s\n", vercheck, version);
2519
2520     /* only check version */
2521     versz = MAX_PATH;
2522     lstrcpyA(version, "version");
2523     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2524     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2525     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2526     ok(!lstrcmpA(version, vercheck),
2527        "Expected %s, got %s\n", vercheck, version);
2528
2529     /* only check language */
2530     langsz = MAX_PATH;
2531     lstrcpyA(lang, "lang");
2532     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2533     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2534     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2535     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2536
2537     /* check neither version nor language */
2538     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2539     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2540
2541     /* get pcchVersionBuf */
2542     versz = MAX_PATH;
2543     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2544     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2545     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2546
2547     /* get pcchLangBuf */
2548     langsz = MAX_PATH;
2549     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2551     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2552
2553     /* pcchVersionBuf not big enough */
2554     versz = 5;
2555     lstrcpyA(version, "version");
2556     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2557     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2558     ok(!strncmp(version, vercheck, 4),
2559        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2560     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2561
2562     /* pcchLangBuf not big enough */
2563     langsz = 3;
2564     lstrcpyA(lang, "lang");
2565     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2566     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2567     ok(!strncmp(lang, langcheck, 2),
2568        "Expected first character of %s, got %s\n", langcheck, lang);
2569     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2570
2571     HeapFree(GetProcessHeap(), 0, vercheck);
2572     HeapFree(GetProcessHeap(), 0, langcheck);
2573 }
2574
2575 static void test_MsiGetProductInfo(void)
2576 {
2577     UINT r;
2578     LONG res;
2579     HKEY propkey, source;
2580     HKEY prodkey, localkey;
2581     CHAR prodcode[MAX_PATH];
2582     CHAR prod_squashed[MAX_PATH];
2583     CHAR packcode[MAX_PATH];
2584     CHAR pack_squashed[MAX_PATH];
2585     CHAR buf[MAX_PATH];
2586     CHAR keypath[MAX_PATH];
2587     LPSTR usersid;
2588     DWORD sz, val = 42;
2589
2590     create_test_guid(prodcode, prod_squashed);
2591     create_test_guid(packcode, pack_squashed);
2592     get_user_sid(&usersid);
2593
2594     /* NULL szProduct */
2595     sz = MAX_PATH;
2596     lstrcpyA(buf, "apple");
2597     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2598     ok(r == ERROR_INVALID_PARAMETER,
2599        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2600     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2601     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2602
2603     /* empty szProduct */
2604     sz = MAX_PATH;
2605     lstrcpyA(buf, "apple");
2606     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2607     ok(r == ERROR_INVALID_PARAMETER,
2608        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2609     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2610     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2611
2612     /* garbage szProduct */
2613     sz = MAX_PATH;
2614     lstrcpyA(buf, "apple");
2615     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2616     ok(r == ERROR_INVALID_PARAMETER,
2617        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2618     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2619     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2620
2621     /* guid without brackets */
2622     sz = MAX_PATH;
2623     lstrcpyA(buf, "apple");
2624     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2625                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2626     ok(r == ERROR_INVALID_PARAMETER,
2627        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2628     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2629     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2630
2631     /* guid with brackets */
2632     sz = MAX_PATH;
2633     lstrcpyA(buf, "apple");
2634     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2635                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2636     ok(r == ERROR_UNKNOWN_PRODUCT,
2637        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2638     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2639     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2640
2641     /* same length as guid, but random */
2642     sz = MAX_PATH;
2643     lstrcpyA(buf, "apple");
2644     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2645                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2646     ok(r == ERROR_INVALID_PARAMETER,
2647        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2648     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2649     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2650
2651     /* not installed, NULL szAttribute */
2652     sz = MAX_PATH;
2653     lstrcpyA(buf, "apple");
2654     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2655     ok(r == ERROR_INVALID_PARAMETER,
2656        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2657     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2658     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2659
2660     /* not installed, NULL lpValueBuf */
2661     sz = MAX_PATH;
2662     lstrcpyA(buf, "apple");
2663     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2664     ok(r == ERROR_UNKNOWN_PRODUCT,
2665        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2666     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2667     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2668
2669     /* not installed, NULL pcchValueBuf */
2670     sz = MAX_PATH;
2671     lstrcpyA(buf, "apple");
2672     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2673     ok(r == ERROR_INVALID_PARAMETER,
2674        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2675     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2676     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2677
2678     /* created guid cannot possibly be an installed product code */
2679     sz = MAX_PATH;
2680     lstrcpyA(buf, "apple");
2681     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2682     ok(r == ERROR_UNKNOWN_PRODUCT,
2683        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2684     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2685     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2686
2687     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2688     lstrcatA(keypath, usersid);
2689     lstrcatA(keypath, "\\Installer\\Products\\");
2690     lstrcatA(keypath, prod_squashed);
2691
2692     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2694
2695     /* managed product code exists */
2696     sz = MAX_PATH;
2697     lstrcpyA(buf, "apple");
2698     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2699     ok(r == ERROR_UNKNOWN_PROPERTY,
2700        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2701     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2702     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2703
2704     RegDeleteKeyA(prodkey, "");
2705     RegCloseKey(prodkey);
2706
2707     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2708     lstrcatA(keypath, usersid);
2709     lstrcatA(keypath, "\\Products\\");
2710     lstrcatA(keypath, prod_squashed);
2711
2712     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2714
2715     /* local user product code exists */
2716     sz = MAX_PATH;
2717     lstrcpyA(buf, "apple");
2718     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2719     ok(r == ERROR_UNKNOWN_PRODUCT,
2720        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2721     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2722     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2723
2724     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2725     lstrcatA(keypath, usersid);
2726     lstrcatA(keypath, "\\Installer\\Products\\");
2727     lstrcatA(keypath, prod_squashed);
2728
2729     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2730     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2731
2732     /* both local and managed product code exist */
2733     sz = MAX_PATH;
2734     lstrcpyA(buf, "apple");
2735     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2736     ok(r == ERROR_UNKNOWN_PROPERTY,
2737        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2738     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2739     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2740
2741     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2742     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2743
2744     /* InstallProperties key exists */
2745     sz = MAX_PATH;
2746     lstrcpyA(buf, "apple");
2747     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2748     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2749     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2750     ok(sz == 0, "Expected 0, got %d\n", sz);
2751
2752     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2754
2755     /* HelpLink value exists */
2756     sz = MAX_PATH;
2757     lstrcpyA(buf, "apple");
2758     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2759     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2760     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2761     ok(sz == 4, "Expected 4, got %d\n", sz);
2762
2763     /* pcchBuf is NULL */
2764     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
2765     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2766
2767     /* lpValueBuf is NULL */
2768     sz = MAX_PATH;
2769     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2770     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2771     ok(sz == 4, "Expected 4, got %d\n", sz);
2772
2773     /* lpValueBuf is NULL, pcchValueBuf is too small */
2774     sz = 2;
2775     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2776     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2777     ok(sz == 4, "Expected 4, got %d\n", sz);
2778
2779     /* lpValueBuf is NULL, pcchValueBuf is too small */
2780     sz = 2;
2781     lstrcpyA(buf, "apple");
2782     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2783     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
2784     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2785     ok(sz == 4, "Expected 4, got %d\n", sz);
2786
2787     /* lpValueBuf is NULL, pcchValueBuf is exactly 4 */
2788     sz = 4;
2789     lstrcpyA(buf, "apple");
2790     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2791     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2792     ok(!lstrcmpA(buf, "apple"),
2793        "Expected buf to remain unchanged, got \"%s\"\n", buf);
2794     ok(sz == 4, "Expected 4, got %d\n", sz);
2795
2796     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
2797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2798
2799     /* random property not supported by MSI, value exists */
2800     sz = MAX_PATH;
2801     lstrcpyA(buf, "apple");
2802     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
2803     ok(r == ERROR_UNKNOWN_PROPERTY,
2804        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2805     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2806     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2807
2808     RegDeleteValueA(propkey, "IMadeThis");
2809     RegDeleteValueA(propkey, "HelpLink");
2810     RegDeleteKeyA(propkey, "");
2811     RegDeleteKeyA(localkey, "");
2812     RegDeleteKeyA(prodkey, "");
2813     RegCloseKey(propkey);
2814     RegCloseKey(localkey);
2815     RegCloseKey(prodkey);
2816
2817     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2818     lstrcatA(keypath, prod_squashed);
2819
2820     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2821     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2822
2823     /* user product key exists */
2824     sz = MAX_PATH;
2825     lstrcpyA(buf, "apple");
2826     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2827     ok(r == ERROR_UNKNOWN_PROPERTY,
2828        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2829     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2830     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2831
2832     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2833     lstrcatA(keypath, usersid);
2834     lstrcatA(keypath, "\\Products\\");
2835     lstrcatA(keypath, prod_squashed);
2836
2837     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2838     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2839
2840     /* local user product key exists */
2841     sz = MAX_PATH;
2842     lstrcpyA(buf, "apple");
2843     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2844     ok(r == ERROR_UNKNOWN_PROPERTY,
2845        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2846     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2847     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2848
2849     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2850     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2851
2852     /* InstallProperties key exists */
2853     sz = MAX_PATH;
2854     lstrcpyA(buf, "apple");
2855     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2856     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2857     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2858     ok(sz == 0, "Expected 0, got %d\n", sz);
2859
2860     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2861     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2862
2863     /* HelpLink value exists */
2864     sz = MAX_PATH;
2865     lstrcpyA(buf, "apple");
2866     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2867     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2868     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2869     ok(sz == 4, "Expected 4, got %d\n", sz);
2870
2871     RegDeleteValueA(propkey, "HelpLink");
2872     RegDeleteKeyA(propkey, "");
2873     RegDeleteKeyA(localkey, "");
2874     RegDeleteKeyA(prodkey, "");
2875     RegCloseKey(propkey);
2876     RegCloseKey(localkey);
2877     RegCloseKey(prodkey);
2878
2879     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2880     lstrcatA(keypath, prod_squashed);
2881
2882     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2883     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2884
2885     /* classes product key exists */
2886     sz = MAX_PATH;
2887     lstrcpyA(buf, "apple");
2888     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2889     ok(r == ERROR_UNKNOWN_PROPERTY,
2890        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2891     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2892     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2893
2894     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2895     lstrcatA(keypath, usersid);
2896     lstrcatA(keypath, "\\Products\\");
2897     lstrcatA(keypath, prod_squashed);
2898
2899     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2900     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2901
2902     /* local user product key exists */
2903     sz = MAX_PATH;
2904     lstrcpyA(buf, "apple");
2905     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2906     ok(r == ERROR_UNKNOWN_PROPERTY,
2907        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2908     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2909     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2910
2911     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2913
2914     /* InstallProperties key exists */
2915     sz = MAX_PATH;
2916     lstrcpyA(buf, "apple");
2917     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2918     ok(r == ERROR_UNKNOWN_PROPERTY,
2919        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2920     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2921     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2922
2923     RegDeleteKeyA(propkey, "");
2924     RegDeleteKeyA(localkey, "");
2925     RegCloseKey(propkey);
2926     RegCloseKey(localkey);
2927
2928     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2929     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
2930     lstrcatA(keypath, prod_squashed);
2931
2932     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2933     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2934
2935     /* Local System product key exists */
2936     sz = MAX_PATH;
2937     lstrcpyA(buf, "apple");
2938     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2939     ok(r == ERROR_UNKNOWN_PROPERTY,
2940         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2941     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2942     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2943
2944     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2945     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2946
2947     /* InstallProperties key exists */
2948     sz = MAX_PATH;
2949     lstrcpyA(buf, "apple");
2950     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2951     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2952     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2953     ok(sz == 0, "Expected 0, got %d\n", sz);
2954
2955     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2957
2958     /* HelpLink value exists */
2959     sz = MAX_PATH;
2960     lstrcpyA(buf, "apple");
2961     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2962     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2963     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2964     ok(sz == 4, "Expected 4, got %d\n", sz);
2965
2966     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
2967                          (const BYTE *)&val, sizeof(DWORD));
2968     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2969
2970     /* HelpLink type is REG_DWORD */
2971     sz = MAX_PATH;
2972     lstrcpyA(buf, "apple");
2973     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2975     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2976     ok(sz == 2, "Expected 2, got %d\n", sz);
2977
2978     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
2979     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2980
2981     /* DisplayName value exists */
2982     sz = MAX_PATH;
2983     lstrcpyA(buf, "apple");
2984     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2985     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2986     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
2987     ok(sz == 4, "Expected 4, got %d\n", sz);
2988
2989     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
2990                          (const BYTE *)&val, sizeof(DWORD));
2991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2992
2993     /* DisplayName type is REG_DWORD */
2994     sz = MAX_PATH;
2995     lstrcpyA(buf, "apple");
2996     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2997     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2998     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2999     ok(sz == 2, "Expected 2, got %d\n", sz);
3000
3001     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3002     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3003
3004     /* DisplayVersion value exists */
3005     sz = MAX_PATH;
3006     lstrcpyA(buf, "apple");
3007     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3008     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3009     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3010     ok(sz == 5, "Expected 5, got %d\n", sz);
3011
3012     res = RegSetValueExA(propkey, "DisplayVersion", 0,
3013                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3014     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3015
3016     /* DisplayVersion type is REG_DWORD */
3017     sz = MAX_PATH;
3018     lstrcpyA(buf, "apple");
3019     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3020     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3021     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3022     ok(sz == 2, "Expected 2, got %d\n", sz);
3023
3024     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3026
3027     /* HelpTelephone value exists */
3028     sz = MAX_PATH;
3029     lstrcpyA(buf, "apple");
3030     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3031     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3032     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3033     ok(sz == 4, "Expected 4, got %d\n", sz);
3034
3035     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3036                          (const BYTE *)&val, sizeof(DWORD));
3037     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3038
3039     /* HelpTelephone type is REG_DWORD */
3040     sz = MAX_PATH;
3041     lstrcpyA(buf, "apple");
3042     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3044     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3045     ok(sz == 2, "Expected 2, got %d\n", sz);
3046
3047     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3049
3050     /* InstallLocation value exists */
3051     sz = MAX_PATH;
3052     lstrcpyA(buf, "apple");
3053     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3054     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3055     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3056     ok(sz == 3, "Expected 3, got %d\n", sz);
3057
3058     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3059                          (const BYTE *)&val, sizeof(DWORD));
3060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3061
3062     /* InstallLocation type is REG_DWORD */
3063     sz = MAX_PATH;
3064     lstrcpyA(buf, "apple");
3065     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3066     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3067     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3068     ok(sz == 2, "Expected 2, got %d\n", sz);
3069
3070     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3071     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3072
3073     /* InstallSource value exists */
3074     sz = MAX_PATH;
3075     lstrcpyA(buf, "apple");
3076     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3077     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3078     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3079     ok(sz == 6, "Expected 6, got %d\n", sz);
3080
3081     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3082                          (const BYTE *)&val, sizeof(DWORD));
3083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3084
3085     /* InstallSource type is REG_DWORD */
3086     sz = MAX_PATH;
3087     lstrcpyA(buf, "apple");
3088     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3090     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3091     ok(sz == 2, "Expected 2, got %d\n", sz);
3092
3093     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3094     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3095
3096     /* InstallDate value exists */
3097     sz = MAX_PATH;
3098     lstrcpyA(buf, "apple");
3099     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3100     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3101     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3102     ok(sz == 4, "Expected 4, got %d\n", sz);
3103
3104     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3105                          (const BYTE *)&val, sizeof(DWORD));
3106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3107
3108     /* InstallDate type is REG_DWORD */
3109     sz = MAX_PATH;
3110     lstrcpyA(buf, "apple");
3111     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3112     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3113     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3114     ok(sz == 2, "Expected 2, got %d\n", sz);
3115
3116     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3117     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3118
3119     /* Publisher value exists */
3120     sz = MAX_PATH;
3121     lstrcpyA(buf, "apple");
3122     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3123     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3124     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3125     ok(sz == 3, "Expected 3, got %d\n", sz);
3126
3127     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3128                          (const BYTE *)&val, sizeof(DWORD));
3129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3130
3131     /* Publisher type is REG_DWORD */
3132     sz = MAX_PATH;
3133     lstrcpyA(buf, "apple");
3134     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3135     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3136     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3137     ok(sz == 2, "Expected 2, got %d\n", sz);
3138
3139     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3140     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3141
3142     /* LocalPackage value exists */
3143     sz = MAX_PATH;
3144     lstrcpyA(buf, "apple");
3145     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3146     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3147     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3148     ok(sz == 4, "Expected 4, got %d\n", sz);
3149
3150     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3151                          (const BYTE *)&val, sizeof(DWORD));
3152     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3153
3154     /* LocalPackage type is REG_DWORD */
3155     sz = MAX_PATH;
3156     lstrcpyA(buf, "apple");
3157     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3158     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3159     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3160     ok(sz == 2, "Expected 2, got %d\n", sz);
3161
3162     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3163     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3164
3165     /* UrlInfoAbout value exists */
3166     sz = MAX_PATH;
3167     lstrcpyA(buf, "apple");
3168     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3169     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3170     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3171     ok(sz == 5, "Expected 5, got %d\n", sz);
3172
3173     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3174                          (const BYTE *)&val, sizeof(DWORD));
3175     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3176
3177     /* UrlInfoAbout type is REG_DWORD */
3178     sz = MAX_PATH;
3179     lstrcpyA(buf, "apple");
3180     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3182     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3183     ok(sz == 2, "Expected 2, got %d\n", sz);
3184
3185     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3186     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3187
3188     /* UrlUpdateInfo value exists */
3189     sz = MAX_PATH;
3190     lstrcpyA(buf, "apple");
3191     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3192     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3193     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3194     ok(sz == 4, "Expected 4, got %d\n", sz);
3195
3196     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3197                          (const BYTE *)&val, sizeof(DWORD));
3198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3199
3200     /* UrlUpdateInfo type is REG_DWORD */
3201     sz = MAX_PATH;
3202     lstrcpyA(buf, "apple");
3203     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3204     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3205     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3206     ok(sz == 2, "Expected 2, got %d\n", sz);
3207
3208     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3209     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3210
3211     /* VersionMinor value exists */
3212     sz = MAX_PATH;
3213     lstrcpyA(buf, "apple");
3214     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3215     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3216     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3217     ok(sz == 1, "Expected 1, got %d\n", sz);
3218
3219     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3220                          (const BYTE *)&val, sizeof(DWORD));
3221     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3222
3223     /* VersionMinor type is REG_DWORD */
3224     sz = MAX_PATH;
3225     lstrcpyA(buf, "apple");
3226     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3227     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3228     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3229     ok(sz == 2, "Expected 2, got %d\n", sz);
3230
3231     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3232     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3233
3234     /* VersionMajor value exists */
3235     sz = MAX_PATH;
3236     lstrcpyA(buf, "apple");
3237     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3239     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3240     ok(sz == 1, "Expected 1, got %d\n", sz);
3241
3242     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3243                          (const BYTE *)&val, sizeof(DWORD));
3244     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3245
3246     /* VersionMajor type is REG_DWORD */
3247     sz = MAX_PATH;
3248     lstrcpyA(buf, "apple");
3249     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3250     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3251     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3252     ok(sz == 2, "Expected 2, got %d\n", sz);
3253
3254     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3255     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3256
3257     /* ProductID value exists */
3258     sz = MAX_PATH;
3259     lstrcpyA(buf, "apple");
3260     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3262     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3263     ok(sz == 2, "Expected 2, got %d\n", sz);
3264
3265     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3266                          (const BYTE *)&val, sizeof(DWORD));
3267     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3268
3269     /* ProductID type is REG_DWORD */
3270     sz = MAX_PATH;
3271     lstrcpyA(buf, "apple");
3272     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3274     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3275     ok(sz == 2, "Expected 2, got %d\n", sz);
3276
3277     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3279
3280     /* RegCompany value exists */
3281     sz = MAX_PATH;
3282     lstrcpyA(buf, "apple");
3283     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3284     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3285     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3286     ok(sz == 4, "Expected 4, got %d\n", sz);
3287
3288     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3289                          (const BYTE *)&val, sizeof(DWORD));
3290     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3291
3292     /* RegCompany type is REG_DWORD */
3293     sz = MAX_PATH;
3294     lstrcpyA(buf, "apple");
3295     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3296     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3297     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3298     ok(sz == 2, "Expected 2, got %d\n", sz);
3299
3300     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3301     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3302
3303     /* RegOwner value exists */
3304     sz = MAX_PATH;
3305     lstrcpyA(buf, "apple");
3306     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3307     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3308     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3309     ok(sz == 3, "Expected 3, got %d\n", sz);
3310
3311     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3312                          (const BYTE *)&val, sizeof(DWORD));
3313     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3314
3315     /* RegOwner type is REG_DWORD */
3316     sz = MAX_PATH;
3317     lstrcpyA(buf, "apple");
3318     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3319     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3320     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3321     ok(sz == 2, "Expected 2, got %d\n", sz);
3322
3323     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3325
3326     /* InstanceType value exists */
3327     sz = MAX_PATH;
3328     lstrcpyA(buf, "apple");
3329     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3330     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3331     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3332     ok(sz == 0, "Expected 0, got %d\n", sz);
3333
3334     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3335                          (const BYTE *)&val, sizeof(DWORD));
3336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3337
3338     /* InstanceType type is REG_DWORD */
3339     sz = MAX_PATH;
3340     lstrcpyA(buf, "apple");
3341     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3342     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3343     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3344     ok(sz == 0, "Expected 0, got %d\n", sz);
3345
3346     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3347     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3348
3349     /* InstanceType value exists */
3350     sz = MAX_PATH;
3351     lstrcpyA(buf, "apple");
3352     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3353     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3354     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3355     ok(sz == 4, "Expected 4, got %d\n", sz);
3356
3357     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3358                          (const BYTE *)&val, sizeof(DWORD));
3359     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3360
3361     /* InstanceType type is REG_DWORD */
3362     sz = MAX_PATH;
3363     lstrcpyA(buf, "apple");
3364     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3365     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3366     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3367     ok(sz == 2, "Expected 2, got %d\n", sz);
3368
3369     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3371
3372     /* Transforms value exists */
3373     sz = MAX_PATH;
3374     lstrcpyA(buf, "apple");
3375     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3376     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3377     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3378     ok(sz == 0, "Expected 0, got %d\n", sz);
3379
3380     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3381                          (const BYTE *)&val, sizeof(DWORD));
3382     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3383
3384     /* Transforms type is REG_DWORD */
3385     sz = MAX_PATH;
3386     lstrcpyA(buf, "apple");
3387     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3388     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3389     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3390     ok(sz == 0, "Expected 0, got %d\n", sz);
3391
3392     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3393     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3394
3395     /* Transforms value exists */
3396     sz = MAX_PATH;
3397     lstrcpyA(buf, "apple");
3398     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3399     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3400     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3401     ok(sz == 6, "Expected 6, got %d\n", sz);
3402
3403     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3404                          (const BYTE *)&val, sizeof(DWORD));
3405     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3406
3407     /* Transforms type is REG_DWORD */
3408     sz = MAX_PATH;
3409     lstrcpyA(buf, "apple");
3410     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3411     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3412     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3413     ok(sz == 2, "Expected 2, got %d\n", sz);
3414
3415     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3417
3418     /* Language value exists */
3419     sz = MAX_PATH;
3420     lstrcpyA(buf, "apple");
3421     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3422     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3423     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3424     ok(sz == 0, "Expected 0, got %d\n", sz);
3425
3426     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3427                          (const BYTE *)&val, sizeof(DWORD));
3428     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3429
3430     /* Language type is REG_DWORD */
3431     sz = MAX_PATH;
3432     lstrcpyA(buf, "apple");
3433     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3434     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3435     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3436     ok(sz == 0, "Expected 0, got %d\n", sz);
3437
3438     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3439     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3440
3441     /* Language value exists */
3442     sz = MAX_PATH;
3443     lstrcpyA(buf, "apple");
3444     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3446     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3447     ok(sz == 4, "Expected 4, got %d\n", sz);
3448
3449     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3450                          (const BYTE *)&val, sizeof(DWORD));
3451     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3452
3453     /* Language type is REG_DWORD */
3454     sz = MAX_PATH;
3455     lstrcpyA(buf, "apple");
3456     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3457     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3458     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3459     ok(sz == 2, "Expected 2, got %d\n", sz);
3460
3461     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3462     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3463
3464     /* ProductName value exists */
3465     sz = MAX_PATH;
3466     lstrcpyA(buf, "apple");
3467     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3468     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3469     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3470     ok(sz == 0, "Expected 0, got %d\n", sz);
3471
3472     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3473                          (const BYTE *)&val, sizeof(DWORD));
3474     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3475
3476     /* ProductName type is REG_DWORD */
3477     sz = MAX_PATH;
3478     lstrcpyA(buf, "apple");
3479     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3480     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3481     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3482     ok(sz == 0, "Expected 0, got %d\n", sz);
3483
3484     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3485     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3486
3487     /* ProductName value exists */
3488     sz = MAX_PATH;
3489     lstrcpyA(buf, "apple");
3490     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3491     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3492     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3493     ok(sz == 4, "Expected 4, got %d\n", sz);
3494
3495     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3496                          (const BYTE *)&val, sizeof(DWORD));
3497     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3498
3499     /* ProductName type is REG_DWORD */
3500     sz = MAX_PATH;
3501     lstrcpyA(buf, "apple");
3502     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3503     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3504     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3505     ok(sz == 2, "Expected 2, got %d\n", sz);
3506
3507     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3508     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3509
3510     /* Assignment value exists */
3511     sz = MAX_PATH;
3512     lstrcpyA(buf, "apple");
3513     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3514     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3515     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3516     ok(sz == 0, "Expected 0, got %d\n", sz);
3517
3518     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3519                          (const BYTE *)&val, sizeof(DWORD));
3520     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3521
3522     /* Assignment type is REG_DWORD */
3523     sz = MAX_PATH;
3524     lstrcpyA(buf, "apple");
3525     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3526     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3527     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3528     ok(sz == 0, "Expected 0, got %d\n", sz);
3529
3530     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3531     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3532
3533     /* Assignment value exists */
3534     sz = MAX_PATH;
3535     lstrcpyA(buf, "apple");
3536     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3537     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3538     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3539     ok(sz == 2, "Expected 2, got %d\n", sz);
3540
3541     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3542                          (const BYTE *)&val, sizeof(DWORD));
3543     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3544
3545     /* Assignment type is REG_DWORD */
3546     sz = MAX_PATH;
3547     lstrcpyA(buf, "apple");
3548     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3549     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3550     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3551     ok(sz == 2, "Expected 2, got %d\n", sz);
3552
3553     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3555
3556     /* PackageCode value exists */
3557     sz = MAX_PATH;
3558     lstrcpyA(buf, "apple");
3559     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3560     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3561     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3562     ok(sz == 0, "Expected 0, got %d\n", sz);
3563
3564     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3565                          (const BYTE *)&val, sizeof(DWORD));
3566     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3567
3568     /* PackageCode type is REG_DWORD */
3569     sz = MAX_PATH;
3570     lstrcpyA(buf, "apple");
3571     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3572     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3573     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3574     ok(sz == 0, "Expected 0, got %d\n", sz);
3575
3576     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3578
3579     /* PackageCode value exists */
3580     sz = MAX_PATH;
3581     lstrcpyA(buf, "apple");
3582     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3583     ok(r == ERROR_BAD_CONFIGURATION,
3584        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3585     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3586     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3587
3588     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3589                          (const BYTE *)&val, sizeof(DWORD));
3590     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3591
3592     /* PackageCode type is REG_DWORD */
3593     sz = MAX_PATH;
3594     lstrcpyA(buf, "apple");
3595     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3596     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3597     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3598     ok(sz == 2, "Expected 2, got %d\n", sz);
3599
3600     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3602
3603     /* PackageCode value exists */
3604     sz = MAX_PATH;
3605     lstrcpyA(buf, "apple");
3606     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3607     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3608     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3609     ok(sz == 38, "Expected 38, got %d\n", sz);
3610
3611     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3612     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3613
3614     /* Version value exists */
3615     sz = MAX_PATH;
3616     lstrcpyA(buf, "apple");
3617     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3619     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3620     ok(sz == 0, "Expected 0, got %d\n", sz);
3621
3622     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3623                          (const BYTE *)&val, sizeof(DWORD));
3624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3625
3626     /* Version type is REG_DWORD */
3627     sz = MAX_PATH;
3628     lstrcpyA(buf, "apple");
3629     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3630     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3631     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3632     ok(sz == 0, "Expected 0, got %d\n", sz);
3633
3634     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3635     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3636
3637     /* Version value exists */
3638     sz = MAX_PATH;
3639     lstrcpyA(buf, "apple");
3640     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3641     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3642     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3643     ok(sz == 3, "Expected 3, got %d\n", sz);
3644
3645     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3646                          (const BYTE *)&val, sizeof(DWORD));
3647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3648
3649     /* Version type is REG_DWORD */
3650     sz = MAX_PATH;
3651     lstrcpyA(buf, "apple");
3652     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3653     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3654     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3655     ok(sz == 2, "Expected 2, got %d\n", sz);
3656
3657     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3658     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3659
3660     /* ProductIcon value exists */
3661     sz = MAX_PATH;
3662     lstrcpyA(buf, "apple");
3663     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3665     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3666     ok(sz == 0, "Expected 0, got %d\n", sz);
3667
3668     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3669                          (const BYTE *)&val, sizeof(DWORD));
3670     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3671
3672     /* ProductIcon type is REG_DWORD */
3673     sz = MAX_PATH;
3674     lstrcpyA(buf, "apple");
3675     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3676     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3677     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3678     ok(sz == 0, "Expected 0, got %d\n", sz);
3679
3680     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3681     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3682
3683     /* ProductIcon value exists */
3684     sz = MAX_PATH;
3685     lstrcpyA(buf, "apple");
3686     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3687     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3688     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3689     ok(sz == 3, "Expected 3, got %d\n", sz);
3690
3691     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3692                          (const BYTE *)&val, sizeof(DWORD));
3693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3694
3695     /* ProductIcon type is REG_DWORD */
3696     sz = MAX_PATH;
3697     lstrcpyA(buf, "apple");
3698     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3699     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3700     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3701     ok(sz == 2, "Expected 2, got %d\n", sz);
3702
3703     /* SourceList key does not exist */
3704     sz = MAX_PATH;
3705     lstrcpyA(buf, "apple");
3706     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3707     ok(r == ERROR_UNKNOWN_PRODUCT,
3708        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3709     ok(!lstrcmpA(buf, "apple"),
3710        "Expected buf to be unchanged, got \"%s\"\n", buf);
3711     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
3712
3713     res = RegCreateKeyA(prodkey, "SourceList", &source);
3714     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3715
3716     /* SourceList key exists, but PackageName val does not exist */
3717     sz = MAX_PATH;
3718     lstrcpyA(buf, "apple");
3719     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3720     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3721     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3722     ok(sz == 0, "Expected 0, got %d\n", sz);
3723
3724     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3726
3727     /* PackageName val exists */
3728     sz = MAX_PATH;
3729     lstrcpyA(buf, "apple");
3730     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3731     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3732     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
3733     ok(sz == 8, "Expected 8, got %d\n", sz);
3734
3735     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
3736                          (const BYTE *)&val, sizeof(DWORD));
3737     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3738
3739     /* PackageName type is REG_DWORD */
3740     sz = MAX_PATH;
3741     lstrcpyA(buf, "apple");
3742     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3743     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3744     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3745     ok(sz == 2, "Expected 2, got %d\n", sz);
3746
3747     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3748     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3749
3750     /* Authorized value exists */
3751     sz = MAX_PATH;
3752     lstrcpyA(buf, "apple");
3753     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3754     if (r != ERROR_UNKNOWN_PROPERTY)
3755     {
3756         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3757         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3758         ok(sz == 0, "Expected 0, got %d\n", sz);
3759     }
3760
3761     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
3762                          (const BYTE *)&val, sizeof(DWORD));
3763     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3764
3765     /* AuthorizedLUAApp type is REG_DWORD */
3766     sz = MAX_PATH;
3767     lstrcpyA(buf, "apple");
3768     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3769     if (r != ERROR_UNKNOWN_PROPERTY)
3770     {
3771         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3772         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3773         ok(sz == 0, "Expected 0, got %d\n", sz);
3774     }
3775
3776     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3778
3779     /* Authorized value exists */
3780     sz = MAX_PATH;
3781     lstrcpyA(buf, "apple");
3782     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3783     if (r != ERROR_UNKNOWN_PROPERTY)
3784     {
3785         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3786         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
3787         ok(sz == 4, "Expected 4, got %d\n", sz);
3788     }
3789
3790     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
3791                          (const BYTE *)&val, sizeof(DWORD));
3792     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3793
3794     /* AuthorizedLUAApp type is REG_DWORD */
3795     sz = MAX_PATH;
3796     lstrcpyA(buf, "apple");
3797     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3798     if (r != ERROR_UNKNOWN_PROPERTY)
3799     {
3800         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3801         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3802         ok(sz == 2, "Expected 2, got %d\n", sz);
3803     }
3804
3805     RegDeleteValueA(propkey, "HelpLink");
3806     RegDeleteValueA(propkey, "DisplayName");
3807     RegDeleteValueA(propkey, "DisplayVersion");
3808     RegDeleteValueA(propkey, "HelpTelephone");
3809     RegDeleteValueA(propkey, "InstallLocation");
3810     RegDeleteValueA(propkey, "InstallSource");
3811     RegDeleteValueA(propkey, "InstallDate");
3812     RegDeleteValueA(propkey, "Publisher");
3813     RegDeleteValueA(propkey, "LocalPackage");
3814     RegDeleteValueA(propkey, "UrlInfoAbout");
3815     RegDeleteValueA(propkey, "UrlUpdateInfo");
3816     RegDeleteValueA(propkey, "VersionMinor");
3817     RegDeleteValueA(propkey, "VersionMajor");
3818     RegDeleteValueA(propkey, "ProductID");
3819     RegDeleteValueA(propkey, "RegCompany");
3820     RegDeleteValueA(propkey, "RegOwner");
3821     RegDeleteValueA(propkey, "InstanceType");
3822     RegDeleteValueA(propkey, "Transforms");
3823     RegDeleteValueA(propkey, "Language");
3824     RegDeleteValueA(propkey, "ProductName");
3825     RegDeleteValueA(propkey, "Assignment");
3826     RegDeleteValueA(propkey, "PackageCode");
3827     RegDeleteValueA(propkey, "Version");
3828     RegDeleteValueA(propkey, "ProductIcon");
3829     RegDeleteValueA(propkey, "AuthorizedLUAApp");
3830     RegDeleteKeyA(propkey, "");
3831     RegDeleteKeyA(localkey, "");
3832     RegDeleteValueA(prodkey, "InstanceType");
3833     RegDeleteValueA(prodkey, "Transforms");
3834     RegDeleteValueA(prodkey, "Language");
3835     RegDeleteValueA(prodkey, "ProductName");
3836     RegDeleteValueA(prodkey, "Assignment");
3837     RegDeleteValueA(prodkey, "PackageCode");
3838     RegDeleteValueA(prodkey, "Version");
3839     RegDeleteValueA(prodkey, "ProductIcon");
3840     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
3841     RegDeleteValueA(source, "PackageName");
3842     RegDeleteKeyA(source, "");
3843     RegDeleteKeyA(prodkey, "");
3844     RegCloseKey(propkey);
3845     RegCloseKey(localkey);
3846     RegCloseKey(source);
3847     RegCloseKey(prodkey);
3848 }
3849
3850 static void test_MsiGetProductInfoEx(void)
3851 {
3852     UINT r;
3853     LONG res;
3854     HKEY propkey, userkey;
3855     HKEY prodkey, localkey;
3856     CHAR prodcode[MAX_PATH];
3857     CHAR prod_squashed[MAX_PATH];
3858     CHAR packcode[MAX_PATH];
3859     CHAR pack_squashed[MAX_PATH];
3860     CHAR buf[MAX_PATH];
3861     CHAR keypath[MAX_PATH];
3862     LPSTR usersid;
3863     DWORD sz;
3864
3865     if (!pMsiGetProductInfoExA)
3866     {
3867         win_skip("MsiGetProductInfoExA is not available\n");
3868         return;
3869     }
3870
3871     create_test_guid(prodcode, prod_squashed);
3872     create_test_guid(packcode, pack_squashed);
3873     get_user_sid(&usersid);
3874
3875     /* NULL szProductCode */
3876     sz = MAX_PATH;
3877     lstrcpyA(buf, "apple");
3878     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3879                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3880     ok(r == ERROR_INVALID_PARAMETER,
3881        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3882     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3883     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3884
3885     /* empty szProductCode */
3886     sz = MAX_PATH;
3887     lstrcpyA(buf, "apple");
3888     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3889                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3890     ok(r == ERROR_INVALID_PARAMETER,
3891        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3892     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3893     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3894
3895     /* garbage szProductCode */
3896     sz = MAX_PATH;
3897     lstrcpyA(buf, "apple");
3898     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3899                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3900     ok(r == ERROR_INVALID_PARAMETER,
3901        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3902     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3903     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3904
3905     /* guid without brackets */
3906     sz = MAX_PATH;
3907     lstrcpyA(buf, "apple");
3908     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
3909                               MSIINSTALLCONTEXT_USERUNMANAGED,
3910                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3911     ok(r == ERROR_INVALID_PARAMETER,
3912        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3913     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3914     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3915
3916     /* guid with brackets */
3917     sz = MAX_PATH;
3918     lstrcpyA(buf, "apple");
3919     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
3920                               MSIINSTALLCONTEXT_USERUNMANAGED,
3921                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3922     ok(r == ERROR_UNKNOWN_PRODUCT,
3923        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3924     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3925     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3926
3927     /* szValue is non-NULL while pcchValue is NULL */
3928     lstrcpyA(buf, "apple");
3929     r = pMsiGetProductInfoExA(prodcode, usersid,
3930                               MSIINSTALLCONTEXT_USERUNMANAGED,
3931                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
3932     ok(r == ERROR_INVALID_PARAMETER,
3933        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3934     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3935
3936     /* dwContext is out of range */
3937     sz = MAX_PATH;
3938     lstrcpyA(buf, "apple");
3939     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
3940                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3941     ok(r == ERROR_INVALID_PARAMETER,
3942        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3943     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3944     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3945
3946     /* szProperty is NULL */
3947     sz = MAX_PATH;
3948     lstrcpyA(buf, "apple");
3949     r = pMsiGetProductInfoExA(prodcode, usersid,
3950                               MSIINSTALLCONTEXT_USERUNMANAGED,
3951                               NULL, buf, &sz);
3952     ok(r == ERROR_INVALID_PARAMETER,
3953        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3954     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3955     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3956
3957     /* szProperty is empty */
3958     sz = MAX_PATH;
3959     lstrcpyA(buf, "apple");
3960     r = pMsiGetProductInfoExA(prodcode, usersid,
3961                               MSIINSTALLCONTEXT_USERUNMANAGED,
3962                               "", buf, &sz);
3963     ok(r == ERROR_INVALID_PARAMETER,
3964        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3965     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3966     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3967
3968     /* szProperty is not a valid property */
3969     sz = MAX_PATH;
3970     lstrcpyA(buf, "apple");
3971     r = pMsiGetProductInfoExA(prodcode, usersid,
3972                               MSIINSTALLCONTEXT_USERUNMANAGED,
3973                               "notvalid", buf, &sz);
3974     ok(r == ERROR_UNKNOWN_PRODUCT,
3975        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3976     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3977     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3978
3979     /* same length as guid, but random */
3980     sz = MAX_PATH;
3981     lstrcpyA(buf, "apple");
3982     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
3983                               MSIINSTALLCONTEXT_USERUNMANAGED,
3984                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3985     ok(r == ERROR_INVALID_PARAMETER,
3986        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3987     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3988     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3989
3990     /* MSIINSTALLCONTEXT_USERUNMANAGED */
3991
3992     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3993     lstrcatA(keypath, usersid);
3994     lstrcatA(keypath, "\\Products\\");
3995     lstrcatA(keypath, prod_squashed);
3996
3997     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
3998     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3999
4000     /* local user product key exists */
4001     sz = MAX_PATH;
4002     lstrcpyA(buf, "apple");
4003     r = pMsiGetProductInfoExA(prodcode, usersid,
4004                               MSIINSTALLCONTEXT_USERUNMANAGED,
4005                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4006     ok(r == ERROR_UNKNOWN_PRODUCT,
4007        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4008     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4009     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4010
4011     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4012     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4013
4014     /* InstallProperties key exists */
4015     sz = MAX_PATH;
4016     lstrcpyA(buf, "apple");
4017     r = pMsiGetProductInfoExA(prodcode, usersid,
4018                               MSIINSTALLCONTEXT_USERUNMANAGED,
4019                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4020     ok(r == ERROR_UNKNOWN_PRODUCT,
4021        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4022     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4023     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4024
4025     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4026     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4027
4028     /* LocalPackage value exists */
4029     sz = MAX_PATH;
4030     lstrcpyA(buf, "apple");
4031     r = pMsiGetProductInfoExA(prodcode, usersid,
4032                               MSIINSTALLCONTEXT_USERUNMANAGED,
4033                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4034     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4035     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4036     ok(sz == 1, "Expected 1, got %d\n", sz);
4037
4038     RegDeleteValueA(propkey, "LocalPackage");
4039
4040     /* LocalPackage value must exist */
4041     sz = MAX_PATH;
4042     lstrcpyA(buf, "apple");
4043     r = pMsiGetProductInfoExA(prodcode, usersid,
4044                               MSIINSTALLCONTEXT_USERUNMANAGED,
4045                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4046     ok(r == ERROR_UNKNOWN_PRODUCT,
4047        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4048     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4049     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4050
4051     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4052     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4053
4054     /* LocalPackage exists, but HelpLink does not exist */
4055     sz = MAX_PATH;
4056     lstrcpyA(buf, "apple");
4057     r = pMsiGetProductInfoExA(prodcode, usersid,
4058                               MSIINSTALLCONTEXT_USERUNMANAGED,
4059                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4060     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4061     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4062     ok(sz == 0, "Expected 0, got %d\n", sz);
4063
4064     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4065     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4066
4067     /* HelpLink value exists */
4068     sz = MAX_PATH;
4069     lstrcpyA(buf, "apple");
4070     r = pMsiGetProductInfoExA(prodcode, usersid,
4071                               MSIINSTALLCONTEXT_USERUNMANAGED,
4072                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4073     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4074     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4075     ok(sz == 4, "Expected 4, got %d\n", sz);
4076
4077     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4079
4080     /* HelpTelephone value exists */
4081     sz = MAX_PATH;
4082     lstrcpyA(buf, "apple");
4083     r = pMsiGetProductInfoExA(prodcode, usersid,
4084                               MSIINSTALLCONTEXT_USERUNMANAGED,
4085                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4086     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4087     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4088     ok(sz == 5, "Expected 5, got %d\n", sz);
4089
4090     /* szValue and pcchValue are NULL */
4091     r = pMsiGetProductInfoExA(prodcode, usersid,
4092                               MSIINSTALLCONTEXT_USERUNMANAGED,
4093                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4094     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4095
4096     /* pcchValue is exactly 5 */
4097     sz = 5;
4098     lstrcpyA(buf, "apple");
4099     r = pMsiGetProductInfoExA(prodcode, usersid,
4100                               MSIINSTALLCONTEXT_USERUNMANAGED,
4101                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4102     ok(r == ERROR_MORE_DATA,
4103        "Expected ERROR_MORE_DATA, got %d\n", r);
4104     ok(sz == 10, "Expected 10, got %d\n", sz);
4105
4106     /* szValue is NULL, pcchValue is exactly 5 */
4107     sz = 5;
4108     r = pMsiGetProductInfoExA(prodcode, usersid,
4109                               MSIINSTALLCONTEXT_USERUNMANAGED,
4110                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4111     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4112     ok(sz == 10, "Expected 10, got %d\n", sz);
4113
4114     /* szValue is NULL, pcchValue is MAX_PATH */
4115     sz = MAX_PATH;
4116     r = pMsiGetProductInfoExA(prodcode, usersid,
4117                               MSIINSTALLCONTEXT_USERUNMANAGED,
4118                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4119     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4120     ok(sz == 10, "Expected 10, got %d\n", sz);
4121
4122     /* pcchValue is exactly 0 */
4123     sz = 0;
4124     lstrcpyA(buf, "apple");
4125     r = pMsiGetProductInfoExA(prodcode, usersid,
4126                               MSIINSTALLCONTEXT_USERUNMANAGED,
4127                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4128     ok(r == ERROR_MORE_DATA,
4129        "Expected ERROR_MORE_DATA, got %d\n", r);
4130     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4131     ok(sz == 10, "Expected 10, got %d\n", sz);
4132
4133     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4135
4136     /* szProperty is not a valid property */
4137     sz = MAX_PATH;
4138     lstrcpyA(buf, "apple");
4139     r = pMsiGetProductInfoExA(prodcode, usersid,
4140                               MSIINSTALLCONTEXT_USERUNMANAGED,
4141                               "notvalid", buf, &sz);
4142     ok(r == ERROR_UNKNOWN_PROPERTY,
4143        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4144     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4145     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4146
4147     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4148     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4149
4150     /* InstallDate value exists */
4151     sz = MAX_PATH;
4152     lstrcpyA(buf, "apple");
4153     r = pMsiGetProductInfoExA(prodcode, usersid,
4154                               MSIINSTALLCONTEXT_USERUNMANAGED,
4155                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4156     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4157     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4158     ok(sz == 4, "Expected 4, got %d\n", sz);
4159
4160     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4161     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4162
4163     /* DisplayName value exists */
4164     sz = MAX_PATH;
4165     lstrcpyA(buf, "apple");
4166     r = pMsiGetProductInfoExA(prodcode, usersid,
4167                               MSIINSTALLCONTEXT_USERUNMANAGED,
4168                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4169     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4170     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4171     ok(sz == 4, "Expected 4, got %d\n", sz);
4172
4173     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4174     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4175
4176     /* InstallLocation value exists */
4177     sz = MAX_PATH;
4178     lstrcpyA(buf, "apple");
4179     r = pMsiGetProductInfoExA(prodcode, usersid,
4180                               MSIINSTALLCONTEXT_USERUNMANAGED,
4181                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4182     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4183     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4184     ok(sz == 3, "Expected 3, got %d\n", sz);
4185
4186     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4188
4189     /* InstallSource value exists */
4190     sz = MAX_PATH;
4191     lstrcpyA(buf, "apple");
4192     r = pMsiGetProductInfoExA(prodcode, usersid,
4193                               MSIINSTALLCONTEXT_USERUNMANAGED,
4194                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4195     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4196     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4197     ok(sz == 6, "Expected 6, got %d\n", sz);
4198
4199     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4200     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4201
4202     /* LocalPackage value exists */
4203     sz = MAX_PATH;
4204     lstrcpyA(buf, "apple");
4205     r = pMsiGetProductInfoExA(prodcode, usersid,
4206                               MSIINSTALLCONTEXT_USERUNMANAGED,
4207                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4208     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4209     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4210     ok(sz == 5, "Expected 5, got %d\n", sz);
4211
4212     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4213     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4214
4215     /* Publisher value exists */
4216     sz = MAX_PATH;
4217     lstrcpyA(buf, "apple");
4218     r = pMsiGetProductInfoExA(prodcode, usersid,
4219                               MSIINSTALLCONTEXT_USERUNMANAGED,
4220                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4221     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4222     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4223     ok(sz == 3, "Expected 3, got %d\n", sz);
4224
4225     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4227
4228     /* URLInfoAbout value exists */
4229     sz = MAX_PATH;
4230     lstrcpyA(buf, "apple");
4231     r = pMsiGetProductInfoExA(prodcode, usersid,
4232                               MSIINSTALLCONTEXT_USERUNMANAGED,
4233                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4234     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4235     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4236     ok(sz == 5, "Expected 5, got %d\n", sz);
4237
4238     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4240
4241     /* URLUpdateInfo value exists */
4242     sz = MAX_PATH;
4243     lstrcpyA(buf, "apple");
4244     r = pMsiGetProductInfoExA(prodcode, usersid,
4245                               MSIINSTALLCONTEXT_USERUNMANAGED,
4246                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4247     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4248     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4249     ok(sz == 6, "Expected 6, got %d\n", sz);
4250
4251     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4252     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4253
4254     /* VersionMinor value exists */
4255     sz = MAX_PATH;
4256     lstrcpyA(buf, "apple");
4257     r = pMsiGetProductInfoExA(prodcode, usersid,
4258                               MSIINSTALLCONTEXT_USERUNMANAGED,
4259                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4260     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4261     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4262     ok(sz == 1, "Expected 1, got %d\n", sz);
4263
4264     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4266
4267     /* VersionMajor value exists */
4268     sz = MAX_PATH;
4269     lstrcpyA(buf, "apple");
4270     r = pMsiGetProductInfoExA(prodcode, usersid,
4271                               MSIINSTALLCONTEXT_USERUNMANAGED,
4272                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4274     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4275     ok(sz == 1, "Expected 1, got %d\n", sz);
4276
4277     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4279
4280     /* DisplayVersion value exists */
4281     sz = MAX_PATH;
4282     lstrcpyA(buf, "apple");
4283     r = pMsiGetProductInfoExA(prodcode, usersid,
4284                               MSIINSTALLCONTEXT_USERUNMANAGED,
4285                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4286     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4287     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4288     ok(sz == 5, "Expected 5, got %d\n", sz);
4289
4290     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4292
4293     /* ProductID value exists */
4294     sz = MAX_PATH;
4295     lstrcpyA(buf, "apple");
4296     r = pMsiGetProductInfoExA(prodcode, usersid,
4297                               MSIINSTALLCONTEXT_USERUNMANAGED,
4298                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4299     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4300     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4301     ok(sz == 2, "Expected 2, got %d\n", sz);
4302
4303     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4305
4306     /* RegCompany value exists */
4307     sz = MAX_PATH;
4308     lstrcpyA(buf, "apple");
4309     r = pMsiGetProductInfoExA(prodcode, usersid,
4310                               MSIINSTALLCONTEXT_USERUNMANAGED,
4311                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4312     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4313     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4314     ok(sz == 4, "Expected 4, got %d\n", sz);
4315
4316     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4317     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4318
4319     /* RegOwner value exists */
4320     sz = MAX_PATH;
4321     lstrcpyA(buf, "apple");
4322     r = pMsiGetProductInfoExA(prodcode, usersid,
4323                               MSIINSTALLCONTEXT_USERUNMANAGED,
4324                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4326     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4327     ok(sz == 5, "Expected 5, got %d\n", sz);
4328
4329     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4330     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4331
4332     /* Transforms value exists */
4333     sz = MAX_PATH;
4334     lstrcpyA(buf, "apple");
4335     r = pMsiGetProductInfoExA(prodcode, usersid,
4336                               MSIINSTALLCONTEXT_USERUNMANAGED,
4337                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4338     ok(r == ERROR_UNKNOWN_PRODUCT,
4339        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4340     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4341     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4342
4343     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4344     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4345
4346     /* Language value exists */
4347     sz = MAX_PATH;
4348     lstrcpyA(buf, "apple");
4349     r = pMsiGetProductInfoExA(prodcode, usersid,
4350                               MSIINSTALLCONTEXT_USERUNMANAGED,
4351                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4352     ok(r == ERROR_UNKNOWN_PRODUCT,
4353        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4354     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4355     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4356
4357     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4358     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4359
4360     /* ProductName value exists */
4361     sz = MAX_PATH;
4362     lstrcpyA(buf, "apple");
4363     r = pMsiGetProductInfoExA(prodcode, usersid,
4364                               MSIINSTALLCONTEXT_USERUNMANAGED,
4365                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4366     ok(r == ERROR_UNKNOWN_PRODUCT,
4367        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4368     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4369     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4370
4371     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4372     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4373
4374     /* FIXME */
4375
4376     /* AssignmentType value exists */
4377     sz = MAX_PATH;
4378     lstrcpyA(buf, "apple");
4379     r = pMsiGetProductInfoExA(prodcode, usersid,
4380                               MSIINSTALLCONTEXT_USERUNMANAGED,
4381                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4382     ok(r == ERROR_UNKNOWN_PRODUCT,
4383        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4384     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4385     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4386
4387     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4389
4390     /* PackageCode value exists */
4391     sz = MAX_PATH;
4392     lstrcpyA(buf, "apple");
4393     r = pMsiGetProductInfoExA(prodcode, usersid,
4394                               MSIINSTALLCONTEXT_USERUNMANAGED,
4395                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4396     ok(r == ERROR_UNKNOWN_PRODUCT,
4397        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4398     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4399     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4400
4401     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4403
4404     /* Version value exists */
4405     sz = MAX_PATH;
4406     lstrcpyA(buf, "apple");
4407     r = pMsiGetProductInfoExA(prodcode, usersid,
4408                               MSIINSTALLCONTEXT_USERUNMANAGED,
4409                               INSTALLPROPERTY_VERSION, buf, &sz);
4410     ok(r == ERROR_UNKNOWN_PRODUCT,
4411        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4412     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4413     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4414
4415     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4417
4418     /* ProductIcon value exists */
4419     sz = MAX_PATH;
4420     lstrcpyA(buf, "apple");
4421     r = pMsiGetProductInfoExA(prodcode, usersid,
4422                               MSIINSTALLCONTEXT_USERUNMANAGED,
4423                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4424     ok(r == ERROR_UNKNOWN_PRODUCT,
4425        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4426     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4427     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4428
4429     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4431
4432     /* PackageName value exists */
4433     sz = MAX_PATH;
4434     lstrcpyA(buf, "apple");
4435     r = pMsiGetProductInfoExA(prodcode, usersid,
4436                               MSIINSTALLCONTEXT_USERUNMANAGED,
4437                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4438     ok(r == ERROR_UNKNOWN_PRODUCT,
4439        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4440     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4441     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4442
4443     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4445
4446     /* AuthorizedLUAApp value exists */
4447     sz = MAX_PATH;
4448     lstrcpyA(buf, "apple");
4449     r = pMsiGetProductInfoExA(prodcode, usersid,
4450                               MSIINSTALLCONTEXT_USERUNMANAGED,
4451                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4452     ok(r == ERROR_UNKNOWN_PRODUCT,
4453        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4454     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4455     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4456
4457     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4458     RegDeleteValueA(propkey, "PackageName");
4459     RegDeleteValueA(propkey, "ProductIcon");
4460     RegDeleteValueA(propkey, "Version");
4461     RegDeleteValueA(propkey, "PackageCode");
4462     RegDeleteValueA(propkey, "AssignmentType");
4463     RegDeleteValueA(propkey, "ProductName");
4464     RegDeleteValueA(propkey, "Language");
4465     RegDeleteValueA(propkey, "Transforms");
4466     RegDeleteValueA(propkey, "RegOwner");
4467     RegDeleteValueA(propkey, "RegCompany");
4468     RegDeleteValueA(propkey, "ProductID");
4469     RegDeleteValueA(propkey, "DisplayVersion");
4470     RegDeleteValueA(propkey, "VersionMajor");
4471     RegDeleteValueA(propkey, "VersionMinor");
4472     RegDeleteValueA(propkey, "URLUpdateInfo");
4473     RegDeleteValueA(propkey, "URLInfoAbout");
4474     RegDeleteValueA(propkey, "Publisher");
4475     RegDeleteValueA(propkey, "LocalPackage");
4476     RegDeleteValueA(propkey, "InstallSource");
4477     RegDeleteValueA(propkey, "InstallLocation");
4478     RegDeleteValueA(propkey, "DisplayName");
4479     RegDeleteValueA(propkey, "InstallDate");
4480     RegDeleteValueA(propkey, "HelpTelephone");
4481     RegDeleteValueA(propkey, "HelpLink");
4482     RegDeleteValueA(propkey, "LocalPackage");
4483     RegDeleteKeyA(propkey, "");
4484     RegCloseKey(propkey);
4485     RegDeleteKeyA(localkey, "");
4486     RegCloseKey(localkey);
4487
4488     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4489     lstrcatA(keypath, usersid);
4490     lstrcatA(keypath, "\\Installer\\Products\\");
4491     lstrcatA(keypath, prod_squashed);
4492
4493     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
4494     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4495
4496     /* user product key exists */
4497     sz = MAX_PATH;
4498     lstrcpyA(buf, "apple");
4499     r = pMsiGetProductInfoExA(prodcode, usersid,
4500                               MSIINSTALLCONTEXT_USERUNMANAGED,
4501                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4502     ok(r == ERROR_UNKNOWN_PRODUCT,
4503        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4504     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4505     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4506
4507     RegDeleteKeyA(userkey, "");
4508     RegCloseKey(userkey);
4509
4510     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4511     lstrcatA(keypath, prod_squashed);
4512
4513     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4514     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4515
4516     sz = MAX_PATH;
4517     lstrcpyA(buf, "apple");
4518     r = pMsiGetProductInfoExA(prodcode, usersid,
4519                               MSIINSTALLCONTEXT_USERUNMANAGED,
4520                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4522     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4523     ok(sz == 1, "Expected 1, got %d\n", sz);
4524
4525     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4527
4528     /* HelpLink value exists */
4529     sz = MAX_PATH;
4530     lstrcpyA(buf, "apple");
4531     r = pMsiGetProductInfoExA(prodcode, usersid,
4532                               MSIINSTALLCONTEXT_USERUNMANAGED,
4533                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4534     ok(r == ERROR_UNKNOWN_PROPERTY,
4535        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4536     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4537     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4538
4539     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4541
4542     /* HelpTelephone value exists */
4543     sz = MAX_PATH;
4544     lstrcpyA(buf, "apple");
4545     r = pMsiGetProductInfoExA(prodcode, usersid,
4546                               MSIINSTALLCONTEXT_USERUNMANAGED,
4547                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4548     ok(r == ERROR_UNKNOWN_PROPERTY,
4549        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4550     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4551     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4552
4553     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4555
4556     /* InstallDate value exists */
4557     sz = MAX_PATH;
4558     lstrcpyA(buf, "apple");
4559     r = pMsiGetProductInfoExA(prodcode, usersid,
4560                               MSIINSTALLCONTEXT_USERUNMANAGED,
4561                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4562     ok(r == ERROR_UNKNOWN_PROPERTY,
4563        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4564     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4565     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4566
4567     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4569
4570     /* DisplayName value exists */
4571     sz = MAX_PATH;
4572     lstrcpyA(buf, "apple");
4573     r = pMsiGetProductInfoExA(prodcode, usersid,
4574                               MSIINSTALLCONTEXT_USERUNMANAGED,
4575                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4576     ok(r == ERROR_UNKNOWN_PROPERTY,
4577        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4578     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4579     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4580
4581     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4583
4584     /* InstallLocation value exists */
4585     sz = MAX_PATH;
4586     lstrcpyA(buf, "apple");
4587     r = pMsiGetProductInfoExA(prodcode, usersid,
4588                               MSIINSTALLCONTEXT_USERUNMANAGED,
4589                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4590     ok(r == ERROR_UNKNOWN_PROPERTY,
4591        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4592     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4593     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4594
4595     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4596     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4597
4598     /* InstallSource value exists */
4599     sz = MAX_PATH;
4600     lstrcpyA(buf, "apple");
4601     r = pMsiGetProductInfoExA(prodcode, usersid,
4602                               MSIINSTALLCONTEXT_USERUNMANAGED,
4603                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4604     ok(r == ERROR_UNKNOWN_PROPERTY,
4605        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4606     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4607     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4608
4609     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4611
4612     /* LocalPackage value exists */
4613     sz = MAX_PATH;
4614     lstrcpyA(buf, "apple");
4615     r = pMsiGetProductInfoExA(prodcode, usersid,
4616                               MSIINSTALLCONTEXT_USERUNMANAGED,
4617                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4618     ok(r == ERROR_UNKNOWN_PROPERTY,
4619        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4620     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4621     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4622
4623     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4625
4626     /* Publisher value exists */
4627     sz = MAX_PATH;
4628     lstrcpyA(buf, "apple");
4629     r = pMsiGetProductInfoExA(prodcode, usersid,
4630                               MSIINSTALLCONTEXT_USERUNMANAGED,
4631                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4632     ok(r == ERROR_UNKNOWN_PROPERTY,
4633        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4634     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4635     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4636
4637     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4639
4640     /* URLInfoAbout value exists */
4641     sz = MAX_PATH;
4642     lstrcpyA(buf, "apple");
4643     r = pMsiGetProductInfoExA(prodcode, usersid,
4644                               MSIINSTALLCONTEXT_USERUNMANAGED,
4645                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4646     ok(r == ERROR_UNKNOWN_PROPERTY,
4647        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4648     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4649     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4650
4651     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4653
4654     /* URLUpdateInfo value exists */
4655     sz = MAX_PATH;
4656     lstrcpyA(buf, "apple");
4657     r = pMsiGetProductInfoExA(prodcode, usersid,
4658                               MSIINSTALLCONTEXT_USERUNMANAGED,
4659                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4660     ok(r == ERROR_UNKNOWN_PROPERTY,
4661        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4662     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4663     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4664
4665     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4667
4668     /* VersionMinor value exists */
4669     sz = MAX_PATH;
4670     lstrcpyA(buf, "apple");
4671     r = pMsiGetProductInfoExA(prodcode, usersid,
4672                               MSIINSTALLCONTEXT_USERUNMANAGED,
4673                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4674     ok(r == ERROR_UNKNOWN_PROPERTY,
4675        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4676     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4677     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4678
4679     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4681
4682     /* VersionMajor value exists */
4683     sz = MAX_PATH;
4684     lstrcpyA(buf, "apple");
4685     r = pMsiGetProductInfoExA(prodcode, usersid,
4686                               MSIINSTALLCONTEXT_USERUNMANAGED,
4687                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4688     ok(r == ERROR_UNKNOWN_PROPERTY,
4689        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4690     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4691     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4692
4693     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4694     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4695
4696     /* DisplayVersion value exists */
4697     sz = MAX_PATH;
4698     lstrcpyA(buf, "apple");
4699     r = pMsiGetProductInfoExA(prodcode, usersid,
4700                               MSIINSTALLCONTEXT_USERUNMANAGED,
4701                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4702     ok(r == ERROR_UNKNOWN_PROPERTY,
4703        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4704     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4705     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4706
4707     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4709
4710     /* ProductID value exists */
4711     sz = MAX_PATH;
4712     lstrcpyA(buf, "apple");
4713     r = pMsiGetProductInfoExA(prodcode, usersid,
4714                               MSIINSTALLCONTEXT_USERUNMANAGED,
4715                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4716     ok(r == ERROR_UNKNOWN_PROPERTY,
4717        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4718     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4719     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4720
4721     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4723
4724     /* RegCompany value exists */
4725     sz = MAX_PATH;
4726     lstrcpyA(buf, "apple");
4727     r = pMsiGetProductInfoExA(prodcode, usersid,
4728                               MSIINSTALLCONTEXT_USERUNMANAGED,
4729                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4730     ok(r == ERROR_UNKNOWN_PROPERTY,
4731        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4732     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4733     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4734
4735     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4737
4738     /* RegOwner value exists */
4739     sz = MAX_PATH;
4740     lstrcpyA(buf, "apple");
4741     r = pMsiGetProductInfoExA(prodcode, usersid,
4742                               MSIINSTALLCONTEXT_USERUNMANAGED,
4743                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4744     ok(r == ERROR_UNKNOWN_PROPERTY,
4745        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4746     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4747     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4748
4749     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4750     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4751
4752     /* Transforms value exists */
4753     sz = MAX_PATH;
4754     lstrcpyA(buf, "apple");
4755     r = pMsiGetProductInfoExA(prodcode, usersid,
4756                               MSIINSTALLCONTEXT_USERUNMANAGED,
4757                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4758     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4759     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
4760     ok(sz == 5, "Expected 5, got %d\n", sz);
4761
4762     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4763     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4764
4765     /* Language value exists */
4766     sz = MAX_PATH;
4767     lstrcpyA(buf, "apple");
4768     r = pMsiGetProductInfoExA(prodcode, usersid,
4769                               MSIINSTALLCONTEXT_USERUNMANAGED,
4770                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4771     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4772     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4773     ok(sz == 4, "Expected 4, got %d\n", sz);
4774
4775     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4776     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4777
4778     /* ProductName value exists */
4779     sz = MAX_PATH;
4780     lstrcpyA(buf, "apple");
4781     r = pMsiGetProductInfoExA(prodcode, usersid,
4782                               MSIINSTALLCONTEXT_USERUNMANAGED,
4783                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4784     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4785     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4786     ok(sz == 4, "Expected 4, got %d\n", sz);
4787
4788     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4789     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4790
4791     /* FIXME */
4792
4793     /* AssignmentType value exists */
4794     sz = MAX_PATH;
4795     lstrcpyA(buf, "apple");
4796     r = pMsiGetProductInfoExA(prodcode, usersid,
4797                               MSIINSTALLCONTEXT_USERUNMANAGED,
4798                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4799     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4800     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4801     ok(sz == 0, "Expected 0, got %d\n", sz);
4802
4803     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4804     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4805
4806     /* FIXME */
4807
4808     /* PackageCode value exists */
4809     sz = MAX_PATH;
4810     lstrcpyA(buf, "apple");
4811     r = pMsiGetProductInfoExA(prodcode, usersid,
4812                               MSIINSTALLCONTEXT_USERUNMANAGED,
4813                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4814     todo_wine
4815     {
4816         ok(r == ERROR_BAD_CONFIGURATION,
4817            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4818         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4819         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4820     }
4821
4822     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4823     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4824
4825     /* Version value exists */
4826     sz = MAX_PATH;
4827     lstrcpyA(buf, "apple");
4828     r = pMsiGetProductInfoExA(prodcode, usersid,
4829                               MSIINSTALLCONTEXT_USERUNMANAGED,
4830                               INSTALLPROPERTY_VERSION, buf, &sz);
4831     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4832     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4833     ok(sz == 3, "Expected 3, got %d\n", sz);
4834
4835     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4836     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4837
4838     /* ProductIcon value exists */
4839     sz = MAX_PATH;
4840     lstrcpyA(buf, "apple");
4841     r = pMsiGetProductInfoExA(prodcode, usersid,
4842                               MSIINSTALLCONTEXT_USERUNMANAGED,
4843                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4844     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4845     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
4846     ok(sz == 4, "Expected 4, got %d\n", sz);
4847
4848     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4849     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4850
4851     /* PackageName value exists */
4852     sz = MAX_PATH;
4853     lstrcpyA(buf, "apple");
4854     r = pMsiGetProductInfoExA(prodcode, usersid,
4855                               MSIINSTALLCONTEXT_USERUNMANAGED,
4856                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4857     todo_wine
4858     {
4859         ok(r == ERROR_UNKNOWN_PRODUCT,
4860            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4861         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4862         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4863     }
4864
4865     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4867
4868     /* AuthorizedLUAApp value exists */
4869     sz = MAX_PATH;
4870     lstrcpyA(buf, "apple");
4871     r = pMsiGetProductInfoExA(prodcode, usersid,
4872                               MSIINSTALLCONTEXT_USERUNMANAGED,
4873                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4875     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4876     ok(sz == 4, "Expected 4, got %d\n", sz);
4877
4878     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4879     RegDeleteValueA(prodkey, "PackageName");
4880     RegDeleteValueA(prodkey, "ProductIcon");
4881     RegDeleteValueA(prodkey, "Version");
4882     RegDeleteValueA(prodkey, "PackageCode");
4883     RegDeleteValueA(prodkey, "AssignmentType");
4884     RegDeleteValueA(prodkey, "ProductName");
4885     RegDeleteValueA(prodkey, "Language");
4886     RegDeleteValueA(prodkey, "Transforms");
4887     RegDeleteValueA(prodkey, "RegOwner");
4888     RegDeleteValueA(prodkey, "RegCompany");
4889     RegDeleteValueA(prodkey, "ProductID");
4890     RegDeleteValueA(prodkey, "DisplayVersion");
4891     RegDeleteValueA(prodkey, "VersionMajor");
4892     RegDeleteValueA(prodkey, "VersionMinor");
4893     RegDeleteValueA(prodkey, "URLUpdateInfo");
4894     RegDeleteValueA(prodkey, "URLInfoAbout");
4895     RegDeleteValueA(prodkey, "Publisher");
4896     RegDeleteValueA(prodkey, "LocalPackage");
4897     RegDeleteValueA(prodkey, "InstallSource");
4898     RegDeleteValueA(prodkey, "InstallLocation");
4899     RegDeleteValueA(prodkey, "DisplayName");
4900     RegDeleteValueA(prodkey, "InstallDate");
4901     RegDeleteValueA(prodkey, "HelpTelephone");
4902     RegDeleteValueA(prodkey, "HelpLink");
4903     RegDeleteValueA(prodkey, "LocalPackage");
4904     RegDeleteKeyA(prodkey, "");
4905     RegCloseKey(prodkey);
4906
4907     /* MSIINSTALLCONTEXT_USERMANAGED */
4908
4909     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4910     lstrcatA(keypath, usersid);
4911     lstrcatA(keypath, "\\Products\\");
4912     lstrcatA(keypath, prod_squashed);
4913
4914     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4915     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4916
4917     /* local user product key exists */
4918     sz = MAX_PATH;
4919     lstrcpyA(buf, "apple");
4920     r = pMsiGetProductInfoExA(prodcode, usersid,
4921                               MSIINSTALLCONTEXT_USERMANAGED,
4922                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4923     ok(r == ERROR_UNKNOWN_PRODUCT,
4924        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4925     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4926     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4927
4928     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4930
4931     /* InstallProperties key exists */
4932     sz = MAX_PATH;
4933     lstrcpyA(buf, "apple");
4934     r = pMsiGetProductInfoExA(prodcode, usersid,
4935                               MSIINSTALLCONTEXT_USERMANAGED,
4936                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4937     ok(r == ERROR_UNKNOWN_PRODUCT,
4938        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4939     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4940     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4941
4942     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4943     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4944
4945     /* ManagedLocalPackage value exists */
4946     sz = MAX_PATH;
4947     lstrcpyA(buf, "apple");
4948     r = pMsiGetProductInfoExA(prodcode, usersid,
4949                               MSIINSTALLCONTEXT_USERMANAGED,
4950                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4951     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4952     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4953     ok(sz == 1, "Expected 1, got %d\n", sz);
4954
4955     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4957
4958     /* HelpLink value exists */
4959     sz = MAX_PATH;
4960     lstrcpyA(buf, "apple");
4961     r = pMsiGetProductInfoExA(prodcode, usersid,
4962                               MSIINSTALLCONTEXT_USERMANAGED,
4963                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4965     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4966     ok(sz == 4, "Expected 4, got %d\n", sz);
4967
4968     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4970
4971     /* HelpTelephone value exists */
4972     sz = MAX_PATH;
4973     lstrcpyA(buf, "apple");
4974     r = pMsiGetProductInfoExA(prodcode, usersid,
4975                               MSIINSTALLCONTEXT_USERMANAGED,
4976                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4978     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4979     ok(sz == 5, "Expected 5, got %d\n", sz);
4980
4981     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4982     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4983
4984     /* InstallDate value exists */
4985     sz = MAX_PATH;
4986     lstrcpyA(buf, "apple");
4987     r = pMsiGetProductInfoExA(prodcode, usersid,
4988                               MSIINSTALLCONTEXT_USERMANAGED,
4989                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4990     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4991     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4992     ok(sz == 4, "Expected 4, got %d\n", sz);
4993
4994     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4996
4997     /* DisplayName value exists */
4998     sz = MAX_PATH;
4999     lstrcpyA(buf, "apple");
5000     r = pMsiGetProductInfoExA(prodcode, usersid,
5001                               MSIINSTALLCONTEXT_USERMANAGED,
5002                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5004     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5005     ok(sz == 4, "Expected 4, got %d\n", sz);
5006
5007     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5009
5010     /* InstallLocation value exists */
5011     sz = MAX_PATH;
5012     lstrcpyA(buf, "apple");
5013     r = pMsiGetProductInfoExA(prodcode, usersid,
5014                               MSIINSTALLCONTEXT_USERMANAGED,
5015                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5016     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5017     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5018     ok(sz == 3, "Expected 3, got %d\n", sz);
5019
5020     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5021     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5022
5023     /* InstallSource value exists */
5024     sz = MAX_PATH;
5025     lstrcpyA(buf, "apple");
5026     r = pMsiGetProductInfoExA(prodcode, usersid,
5027                               MSIINSTALLCONTEXT_USERMANAGED,
5028                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5029     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5030     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5031     ok(sz == 6, "Expected 6, got %d\n", sz);
5032
5033     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5035
5036     /* LocalPackage value exists */
5037     sz = MAX_PATH;
5038     lstrcpyA(buf, "apple");
5039     r = pMsiGetProductInfoExA(prodcode, usersid,
5040                               MSIINSTALLCONTEXT_USERMANAGED,
5041                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5042     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5043     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5044     ok(sz == 5, "Expected 5, got %d\n", sz);
5045
5046     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5047     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5048
5049     /* Publisher value exists */
5050     sz = MAX_PATH;
5051     lstrcpyA(buf, "apple");
5052     r = pMsiGetProductInfoExA(prodcode, usersid,
5053                               MSIINSTALLCONTEXT_USERMANAGED,
5054                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5055     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5056     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5057     ok(sz == 3, "Expected 3, got %d\n", sz);
5058
5059     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5061
5062     /* URLInfoAbout value exists */
5063     sz = MAX_PATH;
5064     lstrcpyA(buf, "apple");
5065     r = pMsiGetProductInfoExA(prodcode, usersid,
5066                               MSIINSTALLCONTEXT_USERMANAGED,
5067                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5068     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5069     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5070     ok(sz == 5, "Expected 5, got %d\n", sz);
5071
5072     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5073     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5074
5075     /* URLUpdateInfo value exists */
5076     sz = MAX_PATH;
5077     lstrcpyA(buf, "apple");
5078     r = pMsiGetProductInfoExA(prodcode, usersid,
5079                               MSIINSTALLCONTEXT_USERMANAGED,
5080                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5081     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5082     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5083     ok(sz == 6, "Expected 6, got %d\n", sz);
5084
5085     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5087
5088     /* VersionMinor value exists */
5089     sz = MAX_PATH;
5090     lstrcpyA(buf, "apple");
5091     r = pMsiGetProductInfoExA(prodcode, usersid,
5092                               MSIINSTALLCONTEXT_USERMANAGED,
5093                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5094     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5095     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5096     ok(sz == 1, "Expected 1, got %d\n", sz);
5097
5098     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5099     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5100
5101     /* VersionMajor value exists */
5102     sz = MAX_PATH;
5103     lstrcpyA(buf, "apple");
5104     r = pMsiGetProductInfoExA(prodcode, usersid,
5105                               MSIINSTALLCONTEXT_USERMANAGED,
5106                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5107     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5108     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5109     ok(sz == 1, "Expected 1, got %d\n", sz);
5110
5111     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5113
5114     /* DisplayVersion value exists */
5115     sz = MAX_PATH;
5116     lstrcpyA(buf, "apple");
5117     r = pMsiGetProductInfoExA(prodcode, usersid,
5118                               MSIINSTALLCONTEXT_USERMANAGED,
5119                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5120     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5121     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5122     ok(sz == 5, "Expected 5, got %d\n", sz);
5123
5124     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5125     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5126
5127     /* ProductID value exists */
5128     sz = MAX_PATH;
5129     lstrcpyA(buf, "apple");
5130     r = pMsiGetProductInfoExA(prodcode, usersid,
5131                               MSIINSTALLCONTEXT_USERMANAGED,
5132                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5133     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5134     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5135     ok(sz == 2, "Expected 2, got %d\n", sz);
5136
5137     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5138     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5139
5140     /* RegCompany value exists */
5141     sz = MAX_PATH;
5142     lstrcpyA(buf, "apple");
5143     r = pMsiGetProductInfoExA(prodcode, usersid,
5144                               MSIINSTALLCONTEXT_USERMANAGED,
5145                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5146     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5147     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5148     ok(sz == 4, "Expected 4, got %d\n", sz);
5149
5150     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5151     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5152
5153     /* RegOwner value exists */
5154     sz = MAX_PATH;
5155     lstrcpyA(buf, "apple");
5156     r = pMsiGetProductInfoExA(prodcode, usersid,
5157                               MSIINSTALLCONTEXT_USERMANAGED,
5158                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5159     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5160     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5161     ok(sz == 5, "Expected 5, got %d\n", sz);
5162
5163     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5165
5166     /* Transforms value exists */
5167     sz = MAX_PATH;
5168     lstrcpyA(buf, "apple");
5169     r = pMsiGetProductInfoExA(prodcode, usersid,
5170                               MSIINSTALLCONTEXT_USERMANAGED,
5171                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5172     ok(r == ERROR_UNKNOWN_PRODUCT,
5173        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5174     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5175     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5176
5177     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5179
5180     /* Language value exists */
5181     sz = MAX_PATH;
5182     lstrcpyA(buf, "apple");
5183     r = pMsiGetProductInfoExA(prodcode, usersid,
5184                               MSIINSTALLCONTEXT_USERMANAGED,
5185                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5186     ok(r == ERROR_UNKNOWN_PRODUCT,
5187        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5188     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5189     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5190
5191     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5192     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5193
5194     /* ProductName value exists */
5195     sz = MAX_PATH;
5196     lstrcpyA(buf, "apple");
5197     r = pMsiGetProductInfoExA(prodcode, usersid,
5198                               MSIINSTALLCONTEXT_USERMANAGED,
5199                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5200     ok(r == ERROR_UNKNOWN_PRODUCT,
5201        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5202     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5203     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5204
5205     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5206     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5207
5208     /* FIXME */
5209
5210     /* AssignmentType value exists */
5211     sz = MAX_PATH;
5212     lstrcpyA(buf, "apple");
5213     r = pMsiGetProductInfoExA(prodcode, usersid,
5214                               MSIINSTALLCONTEXT_USERMANAGED,
5215                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5216     ok(r == ERROR_UNKNOWN_PRODUCT,
5217        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5218     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5219     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5220
5221     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5222     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5223
5224     /* PackageCode value exists */
5225     sz = MAX_PATH;
5226     lstrcpyA(buf, "apple");
5227     r = pMsiGetProductInfoExA(prodcode, usersid,
5228                               MSIINSTALLCONTEXT_USERMANAGED,
5229                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5230     ok(r == ERROR_UNKNOWN_PRODUCT,
5231        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5232     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5233     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5234
5235     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5236     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5237
5238     /* Version value exists */
5239     sz = MAX_PATH;
5240     lstrcpyA(buf, "apple");
5241     r = pMsiGetProductInfoExA(prodcode, usersid,
5242                               MSIINSTALLCONTEXT_USERMANAGED,
5243                               INSTALLPROPERTY_VERSION, buf, &sz);
5244     ok(r == ERROR_UNKNOWN_PRODUCT,
5245        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5246     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5247     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5248
5249     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5251
5252     /* ProductIcon value exists */
5253     sz = MAX_PATH;
5254     lstrcpyA(buf, "apple");
5255     r = pMsiGetProductInfoExA(prodcode, usersid,
5256                               MSIINSTALLCONTEXT_USERMANAGED,
5257                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5258     ok(r == ERROR_UNKNOWN_PRODUCT,
5259        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5260     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5261     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5262
5263     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5264     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5265
5266     /* PackageName value exists */
5267     sz = MAX_PATH;
5268     lstrcpyA(buf, "apple");
5269     r = pMsiGetProductInfoExA(prodcode, usersid,
5270                               MSIINSTALLCONTEXT_USERMANAGED,
5271                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5272     ok(r == ERROR_UNKNOWN_PRODUCT,
5273        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5274     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5275     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5276
5277     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5279
5280     /* AuthorizedLUAApp value exists */
5281     sz = MAX_PATH;
5282     lstrcpyA(buf, "apple");
5283     r = pMsiGetProductInfoExA(prodcode, usersid,
5284                               MSIINSTALLCONTEXT_USERMANAGED,
5285                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5286     ok(r == ERROR_UNKNOWN_PRODUCT,
5287        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5288     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5289     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5290
5291     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5292     RegDeleteValueA(propkey, "PackageName");
5293     RegDeleteValueA(propkey, "ProductIcon");
5294     RegDeleteValueA(propkey, "Version");
5295     RegDeleteValueA(propkey, "PackageCode");
5296     RegDeleteValueA(propkey, "AssignmentType");
5297     RegDeleteValueA(propkey, "ProductName");
5298     RegDeleteValueA(propkey, "Language");
5299     RegDeleteValueA(propkey, "Transforms");
5300     RegDeleteValueA(propkey, "RegOwner");
5301     RegDeleteValueA(propkey, "RegCompany");
5302     RegDeleteValueA(propkey, "ProductID");
5303     RegDeleteValueA(propkey, "DisplayVersion");
5304     RegDeleteValueA(propkey, "VersionMajor");
5305     RegDeleteValueA(propkey, "VersionMinor");
5306     RegDeleteValueA(propkey, "URLUpdateInfo");
5307     RegDeleteValueA(propkey, "URLInfoAbout");
5308     RegDeleteValueA(propkey, "Publisher");
5309     RegDeleteValueA(propkey, "LocalPackage");
5310     RegDeleteValueA(propkey, "InstallSource");
5311     RegDeleteValueA(propkey, "InstallLocation");
5312     RegDeleteValueA(propkey, "DisplayName");
5313     RegDeleteValueA(propkey, "InstallDate");
5314     RegDeleteValueA(propkey, "HelpTelephone");
5315     RegDeleteValueA(propkey, "HelpLink");
5316     RegDeleteValueA(propkey, "ManagedLocalPackage");
5317     RegDeleteKeyA(propkey, "");
5318     RegCloseKey(propkey);
5319     RegDeleteKeyA(localkey, "");
5320     RegCloseKey(localkey);
5321
5322     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5323     lstrcatA(keypath, usersid);
5324     lstrcatA(keypath, "\\Installer\\Products\\");
5325     lstrcatA(keypath, prod_squashed);
5326
5327     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5328     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5329
5330     /* user product key exists */
5331     sz = MAX_PATH;
5332     lstrcpyA(buf, "apple");
5333     r = pMsiGetProductInfoExA(prodcode, usersid,
5334                               MSIINSTALLCONTEXT_USERMANAGED,
5335                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5336     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5337     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5338     ok(sz == 1, "Expected 1, got %d\n", sz);
5339
5340     RegDeleteKeyA(userkey, "");
5341     RegCloseKey(userkey);
5342
5343     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5344     lstrcatA(keypath, prod_squashed);
5345
5346     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5347     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5348
5349     /* current user product key exists */
5350     sz = MAX_PATH;
5351     lstrcpyA(buf, "apple");
5352     r = pMsiGetProductInfoExA(prodcode, usersid,
5353                               MSIINSTALLCONTEXT_USERMANAGED,
5354                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5355     ok(r == ERROR_UNKNOWN_PRODUCT,
5356        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5357     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5358     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5359
5360     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5362
5363     /* HelpLink value exists, user product key does not exist */
5364     sz = MAX_PATH;
5365     lstrcpyA(buf, "apple");
5366     r = pMsiGetProductInfoExA(prodcode, usersid,
5367                               MSIINSTALLCONTEXT_USERMANAGED,
5368                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5369     ok(r == ERROR_UNKNOWN_PRODUCT,
5370        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5371     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5372     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5373
5374     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5375     lstrcatA(keypath, usersid);
5376     lstrcatA(keypath, "\\Installer\\Products\\");
5377     lstrcatA(keypath, prod_squashed);
5378
5379     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5380     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5381
5382     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5383     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5384
5385     /* HelpLink value exists, user product key does exist */
5386     sz = MAX_PATH;
5387     lstrcpyA(buf, "apple");
5388     r = pMsiGetProductInfoExA(prodcode, usersid,
5389                               MSIINSTALLCONTEXT_USERMANAGED,
5390                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5391     ok(r == ERROR_UNKNOWN_PROPERTY,
5392        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5393     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5394     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5395
5396     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5397     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5398
5399     /* HelpTelephone value exists */
5400     sz = MAX_PATH;
5401     lstrcpyA(buf, "apple");
5402     r = pMsiGetProductInfoExA(prodcode, usersid,
5403                               MSIINSTALLCONTEXT_USERMANAGED,
5404                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5405     ok(r == ERROR_UNKNOWN_PROPERTY,
5406        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5407     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5408     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5409
5410     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5412
5413     /* InstallDate value exists */
5414     sz = MAX_PATH;
5415     lstrcpyA(buf, "apple");
5416     r = pMsiGetProductInfoExA(prodcode, usersid,
5417                               MSIINSTALLCONTEXT_USERMANAGED,
5418                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5419     ok(r == ERROR_UNKNOWN_PROPERTY,
5420        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5421     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5422     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5423
5424     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5425     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5426
5427     /* DisplayName value exists */
5428     sz = MAX_PATH;
5429     lstrcpyA(buf, "apple");
5430     r = pMsiGetProductInfoExA(prodcode, usersid,
5431                               MSIINSTALLCONTEXT_USERMANAGED,
5432                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5433     ok(r == ERROR_UNKNOWN_PROPERTY,
5434        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5435     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5436     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5437
5438     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5439     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5440
5441     /* InstallLocation value exists */
5442     sz = MAX_PATH;
5443     lstrcpyA(buf, "apple");
5444     r = pMsiGetProductInfoExA(prodcode, usersid,
5445                               MSIINSTALLCONTEXT_USERMANAGED,
5446                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5447     ok(r == ERROR_UNKNOWN_PROPERTY,
5448        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5449     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5450     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5451
5452     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5453     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5454
5455     /* InstallSource value exists */
5456     sz = MAX_PATH;
5457     lstrcpyA(buf, "apple");
5458     r = pMsiGetProductInfoExA(prodcode, usersid,
5459                               MSIINSTALLCONTEXT_USERMANAGED,
5460                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5461     ok(r == ERROR_UNKNOWN_PROPERTY,
5462        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5463     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5464     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5465
5466     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5467     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5468
5469     /* LocalPackage value exists */
5470     sz = MAX_PATH;
5471     lstrcpyA(buf, "apple");
5472     r = pMsiGetProductInfoExA(prodcode, usersid,
5473                               MSIINSTALLCONTEXT_USERMANAGED,
5474                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5475     ok(r == ERROR_UNKNOWN_PROPERTY,
5476        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5477     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5478     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5479
5480     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5481     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5482
5483     /* Publisher value exists */
5484     sz = MAX_PATH;
5485     lstrcpyA(buf, "apple");
5486     r = pMsiGetProductInfoExA(prodcode, usersid,
5487                               MSIINSTALLCONTEXT_USERMANAGED,
5488                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5489     ok(r == ERROR_UNKNOWN_PROPERTY,
5490        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5491     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5492     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5493
5494     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5495     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5496
5497     /* URLInfoAbout value exists */
5498     sz = MAX_PATH;
5499     lstrcpyA(buf, "apple");
5500     r = pMsiGetProductInfoExA(prodcode, usersid,
5501                               MSIINSTALLCONTEXT_USERMANAGED,
5502                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5503     ok(r == ERROR_UNKNOWN_PROPERTY,
5504        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5505     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5506     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5507
5508     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5510
5511     /* URLUpdateInfo value exists */
5512     sz = MAX_PATH;
5513     lstrcpyA(buf, "apple");
5514     r = pMsiGetProductInfoExA(prodcode, usersid,
5515                               MSIINSTALLCONTEXT_USERMANAGED,
5516                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5517     ok(r == ERROR_UNKNOWN_PROPERTY,
5518        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5519     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5520     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5521
5522     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5524
5525     /* VersionMinor value exists */
5526     sz = MAX_PATH;
5527     lstrcpyA(buf, "apple");
5528     r = pMsiGetProductInfoExA(prodcode, usersid,
5529                               MSIINSTALLCONTEXT_USERMANAGED,
5530                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5531     ok(r == ERROR_UNKNOWN_PROPERTY,
5532        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5533     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5534     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5535
5536     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5537     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5538
5539     /* VersionMajor value exists */
5540     sz = MAX_PATH;
5541     lstrcpyA(buf, "apple");
5542     r = pMsiGetProductInfoExA(prodcode, usersid,
5543                               MSIINSTALLCONTEXT_USERMANAGED,
5544                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5545     ok(r == ERROR_UNKNOWN_PROPERTY,
5546        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5547     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5548     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5549
5550     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5551     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5552
5553     /* DisplayVersion value exists */
5554     sz = MAX_PATH;
5555     lstrcpyA(buf, "apple");
5556     r = pMsiGetProductInfoExA(prodcode, usersid,
5557                               MSIINSTALLCONTEXT_USERMANAGED,
5558                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5559     ok(r == ERROR_UNKNOWN_PROPERTY,
5560        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5561     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5562     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5563
5564     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5565     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5566
5567     /* ProductID value exists */
5568     sz = MAX_PATH;
5569     lstrcpyA(buf, "apple");
5570     r = pMsiGetProductInfoExA(prodcode, usersid,
5571                               MSIINSTALLCONTEXT_USERMANAGED,
5572                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5573     ok(r == ERROR_UNKNOWN_PROPERTY,
5574        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5575     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5576     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5577
5578     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5580
5581     /* RegCompany value exists */
5582     sz = MAX_PATH;
5583     lstrcpyA(buf, "apple");
5584     r = pMsiGetProductInfoExA(prodcode, usersid,
5585                               MSIINSTALLCONTEXT_USERMANAGED,
5586                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5587     ok(r == ERROR_UNKNOWN_PROPERTY,
5588        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5589     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5590     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5591
5592     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5594
5595     /* RegOwner value exists */
5596     sz = MAX_PATH;
5597     lstrcpyA(buf, "apple");
5598     r = pMsiGetProductInfoExA(prodcode, usersid,
5599                               MSIINSTALLCONTEXT_USERMANAGED,
5600                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5601     ok(r == ERROR_UNKNOWN_PROPERTY,
5602        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5603     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5604     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5605
5606     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5608
5609     /* Transforms value exists */
5610     sz = MAX_PATH;
5611     lstrcpyA(buf, "apple");
5612     r = pMsiGetProductInfoExA(prodcode, usersid,
5613                               MSIINSTALLCONTEXT_USERMANAGED,
5614                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5615     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5616     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5617     ok(sz == 5, "Expected 5, got %d\n", sz);
5618
5619     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5620     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5621
5622     /* Language value exists */
5623     sz = MAX_PATH;
5624     lstrcpyA(buf, "apple");
5625     r = pMsiGetProductInfoExA(prodcode, usersid,
5626                               MSIINSTALLCONTEXT_USERMANAGED,
5627                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5628     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5629     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5630     ok(sz == 4, "Expected 4, got %d\n", sz);
5631
5632     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5633     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5634
5635     /* ProductName value exists */
5636     sz = MAX_PATH;
5637     lstrcpyA(buf, "apple");
5638     r = pMsiGetProductInfoExA(prodcode, usersid,
5639                               MSIINSTALLCONTEXT_USERMANAGED,
5640                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5641     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5642     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5643     ok(sz == 4, "Expected 4, got %d\n", sz);
5644
5645     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5646     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5647
5648     /* FIXME */
5649
5650     /* AssignmentType value exists */
5651     sz = MAX_PATH;
5652     lstrcpyA(buf, "apple");
5653     r = pMsiGetProductInfoExA(prodcode, usersid,
5654                               MSIINSTALLCONTEXT_USERMANAGED,
5655                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5656     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5657     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5658     ok(sz == 0, "Expected 0, got %d\n", sz);
5659
5660     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5661     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5662
5663     /* FIXME */
5664
5665     /* PackageCode value exists */
5666     sz = MAX_PATH;
5667     lstrcpyA(buf, "apple");
5668     r = pMsiGetProductInfoExA(prodcode, usersid,
5669                               MSIINSTALLCONTEXT_USERMANAGED,
5670                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5671     todo_wine
5672     {
5673         ok(r == ERROR_BAD_CONFIGURATION,
5674            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5675         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5676         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5677     }
5678
5679     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5681
5682     /* Version value exists */
5683     sz = MAX_PATH;
5684     lstrcpyA(buf, "apple");
5685     r = pMsiGetProductInfoExA(prodcode, usersid,
5686                               MSIINSTALLCONTEXT_USERMANAGED,
5687                               INSTALLPROPERTY_VERSION, buf, &sz);
5688     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5689     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5690     ok(sz == 3, "Expected 3, got %d\n", sz);
5691
5692     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5694
5695     /* ProductIcon value exists */
5696     sz = MAX_PATH;
5697     lstrcpyA(buf, "apple");
5698     r = pMsiGetProductInfoExA(prodcode, usersid,
5699                               MSIINSTALLCONTEXT_USERMANAGED,
5700                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5702     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5703     ok(sz == 4, "Expected 4, got %d\n", sz);
5704
5705     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5706     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5707
5708     /* PackageName value exists */
5709     sz = MAX_PATH;
5710     lstrcpyA(buf, "apple");
5711     r = pMsiGetProductInfoExA(prodcode, usersid,
5712                               MSIINSTALLCONTEXT_USERMANAGED,
5713                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5714     todo_wine
5715     {
5716         ok(r == ERROR_UNKNOWN_PRODUCT,
5717            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5718         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5719         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5720     }
5721
5722     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5723     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5724
5725     /* AuthorizedLUAApp value exists */
5726     sz = MAX_PATH;
5727     lstrcpyA(buf, "apple");
5728     r = pMsiGetProductInfoExA(prodcode, usersid,
5729                               MSIINSTALLCONTEXT_USERMANAGED,
5730                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5731     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5732     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5733     ok(sz == 4, "Expected 4, got %d\n", sz);
5734
5735     RegDeleteValueA(userkey, "AuthorizedLUAApp");
5736     RegDeleteValueA(userkey, "PackageName");
5737     RegDeleteValueA(userkey, "ProductIcon");
5738     RegDeleteValueA(userkey, "Version");
5739     RegDeleteValueA(userkey, "PackageCode");
5740     RegDeleteValueA(userkey, "AssignmentType");
5741     RegDeleteValueA(userkey, "ProductName");
5742     RegDeleteValueA(userkey, "Language");
5743     RegDeleteValueA(userkey, "Transforms");
5744     RegDeleteValueA(userkey, "RegOwner");
5745     RegDeleteValueA(userkey, "RegCompany");
5746     RegDeleteValueA(userkey, "ProductID");
5747     RegDeleteValueA(userkey, "DisplayVersion");
5748     RegDeleteValueA(userkey, "VersionMajor");
5749     RegDeleteValueA(userkey, "VersionMinor");
5750     RegDeleteValueA(userkey, "URLUpdateInfo");
5751     RegDeleteValueA(userkey, "URLInfoAbout");
5752     RegDeleteValueA(userkey, "Publisher");
5753     RegDeleteValueA(userkey, "LocalPackage");
5754     RegDeleteValueA(userkey, "InstallSource");
5755     RegDeleteValueA(userkey, "InstallLocation");
5756     RegDeleteValueA(userkey, "DisplayName");
5757     RegDeleteValueA(userkey, "InstallDate");
5758     RegDeleteValueA(userkey, "HelpTelephone");
5759     RegDeleteValueA(userkey, "HelpLink");
5760     RegDeleteKeyA(userkey, "");
5761     RegCloseKey(userkey);
5762     RegDeleteKeyA(prodkey, "");
5763     RegCloseKey(prodkey);
5764
5765     /* MSIINSTALLCONTEXT_MACHINE */
5766
5767     /* szUserSid is non-NULL */
5768     sz = MAX_PATH;
5769     lstrcpyA(buf, "apple");
5770     r = pMsiGetProductInfoExA(prodcode, usersid,
5771                               MSIINSTALLCONTEXT_MACHINE,
5772                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5773     ok(r == ERROR_INVALID_PARAMETER,
5774        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5775     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5776     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5777
5778     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
5779     lstrcatA(keypath, prod_squashed);
5780
5781     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5783
5784     /* local system product key exists */
5785     sz = MAX_PATH;
5786     lstrcpyA(buf, "apple");
5787     r = pMsiGetProductInfoExA(prodcode, NULL,
5788                               MSIINSTALLCONTEXT_MACHINE,
5789                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5790     ok(r == ERROR_UNKNOWN_PRODUCT,
5791        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5792     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5793     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5794
5795     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5796     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5797
5798     /* InstallProperties key exists */
5799     sz = MAX_PATH;
5800     lstrcpyA(buf, "apple");
5801     r = pMsiGetProductInfoExA(prodcode, NULL,
5802                               MSIINSTALLCONTEXT_MACHINE,
5803                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5804     ok(r == ERROR_UNKNOWN_PRODUCT,
5805        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5806     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5807     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5808
5809     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5810     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5811
5812     /* LocalPackage value exists */
5813     sz = MAX_PATH;
5814     lstrcpyA(buf, "apple");
5815     r = pMsiGetProductInfoExA(prodcode, NULL,
5816                               MSIINSTALLCONTEXT_MACHINE,
5817                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5818     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5819     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5820     ok(sz == 1, "Expected 1, got %d\n", sz);
5821
5822     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5823     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5824
5825     /* HelpLink value exists */
5826     sz = MAX_PATH;
5827     lstrcpyA(buf, "apple");
5828     r = pMsiGetProductInfoExA(prodcode, NULL,
5829                               MSIINSTALLCONTEXT_MACHINE,
5830                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5831     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5832     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5833     ok(sz == 4, "Expected 4, got %d\n", sz);
5834
5835     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5836     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5837
5838     /* HelpTelephone value exists */
5839     sz = MAX_PATH;
5840     lstrcpyA(buf, "apple");
5841     r = pMsiGetProductInfoExA(prodcode, NULL,
5842                               MSIINSTALLCONTEXT_MACHINE,
5843                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5844     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5845     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5846     ok(sz == 5, "Expected 5, got %d\n", sz);
5847
5848     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5849     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5850
5851     /* InstallDate value exists */
5852     sz = MAX_PATH;
5853     lstrcpyA(buf, "apple");
5854     r = pMsiGetProductInfoExA(prodcode, NULL,
5855                               MSIINSTALLCONTEXT_MACHINE,
5856                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5857     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5858     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5859     ok(sz == 4, "Expected 4, got %d\n", sz);
5860
5861     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5863
5864     /* DisplayName value exists */
5865     sz = MAX_PATH;
5866     lstrcpyA(buf, "apple");
5867     r = pMsiGetProductInfoExA(prodcode, NULL,
5868                               MSIINSTALLCONTEXT_MACHINE,
5869                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5871     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5872     ok(sz == 4, "Expected 4, got %d\n", sz);
5873
5874     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5875     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5876
5877     /* InstallLocation value exists */
5878     sz = MAX_PATH;
5879     lstrcpyA(buf, "apple");
5880     r = pMsiGetProductInfoExA(prodcode, NULL,
5881                               MSIINSTALLCONTEXT_MACHINE,
5882                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5883     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5884     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5885     ok(sz == 3, "Expected 3, got %d\n", sz);
5886
5887     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5889
5890     /* InstallSource value exists */
5891     sz = MAX_PATH;
5892     lstrcpyA(buf, "apple");
5893     r = pMsiGetProductInfoExA(prodcode, NULL,
5894                               MSIINSTALLCONTEXT_MACHINE,
5895                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5896     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5897     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5898     ok(sz == 6, "Expected 6, got %d\n", sz);
5899
5900     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5901     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5902
5903     /* LocalPackage value exists */
5904     sz = MAX_PATH;
5905     lstrcpyA(buf, "apple");
5906     r = pMsiGetProductInfoExA(prodcode, NULL,
5907                               MSIINSTALLCONTEXT_MACHINE,
5908                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5909     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5910     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5911     ok(sz == 5, "Expected 5, got %d\n", sz);
5912
5913     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5915
5916     /* Publisher value exists */
5917     sz = MAX_PATH;
5918     lstrcpyA(buf, "apple");
5919     r = pMsiGetProductInfoExA(prodcode, NULL,
5920                               MSIINSTALLCONTEXT_MACHINE,
5921                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5922     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5923     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5924     ok(sz == 3, "Expected 3, got %d\n", sz);
5925
5926     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5927     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5928
5929     /* URLInfoAbout value exists */
5930     sz = MAX_PATH;
5931     lstrcpyA(buf, "apple");
5932     r = pMsiGetProductInfoExA(prodcode, NULL,
5933                               MSIINSTALLCONTEXT_MACHINE,
5934                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5935     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5936     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5937     ok(sz == 5, "Expected 5, got %d\n", sz);
5938
5939     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5940     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5941
5942     /* URLUpdateInfo value exists */
5943     sz = MAX_PATH;
5944     lstrcpyA(buf, "apple");
5945     r = pMsiGetProductInfoExA(prodcode, NULL,
5946                               MSIINSTALLCONTEXT_MACHINE,
5947                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5948     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5949     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5950     ok(sz == 6, "Expected 6, got %d\n", sz);
5951
5952     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5953     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5954
5955     /* VersionMinor value exists */
5956     sz = MAX_PATH;
5957     lstrcpyA(buf, "apple");
5958     r = pMsiGetProductInfoExA(prodcode, NULL,
5959                               MSIINSTALLCONTEXT_MACHINE,
5960                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5961     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5962     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5963     ok(sz == 1, "Expected 1, got %d\n", sz);
5964
5965     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5966     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5967
5968     /* VersionMajor value exists */
5969     sz = MAX_PATH;
5970     lstrcpyA(buf, "apple");
5971     r = pMsiGetProductInfoExA(prodcode, NULL,
5972                               MSIINSTALLCONTEXT_MACHINE,
5973                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5975     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5976     ok(sz == 1, "Expected 1, got %d\n", sz);
5977
5978     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5979     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5980
5981     /* DisplayVersion value exists */
5982     sz = MAX_PATH;
5983     lstrcpyA(buf, "apple");
5984     r = pMsiGetProductInfoExA(prodcode, NULL,
5985                               MSIINSTALLCONTEXT_MACHINE,
5986                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5987     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5988     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5989     ok(sz == 5, "Expected 5, got %d\n", sz);
5990
5991     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5993
5994     /* ProductID value exists */
5995     sz = MAX_PATH;
5996     lstrcpyA(buf, "apple");
5997     r = pMsiGetProductInfoExA(prodcode, NULL,
5998                               MSIINSTALLCONTEXT_MACHINE,
5999                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6000     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6001     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6002     ok(sz == 2, "Expected 2, got %d\n", sz);
6003
6004     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6006
6007     /* RegCompany value exists */
6008     sz = MAX_PATH;
6009     lstrcpyA(buf, "apple");
6010     r = pMsiGetProductInfoExA(prodcode, NULL,
6011                               MSIINSTALLCONTEXT_MACHINE,
6012                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6013     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6014     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6015     ok(sz == 4, "Expected 4, got %d\n", sz);
6016
6017     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6019
6020     /* RegOwner value exists */
6021     sz = MAX_PATH;
6022     lstrcpyA(buf, "apple");
6023     r = pMsiGetProductInfoExA(prodcode, NULL,
6024                               MSIINSTALLCONTEXT_MACHINE,
6025                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6027     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6028     ok(sz == 5, "Expected 5, got %d\n", sz);
6029
6030     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6032
6033     /* Transforms value exists */
6034     sz = MAX_PATH;
6035     lstrcpyA(buf, "apple");
6036     r = pMsiGetProductInfoExA(prodcode, NULL,
6037                               MSIINSTALLCONTEXT_MACHINE,
6038                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6039     ok(r == ERROR_UNKNOWN_PRODUCT,
6040        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6041     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6042     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6043
6044     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6045     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6046
6047     /* Language value exists */
6048     sz = MAX_PATH;
6049     lstrcpyA(buf, "apple");
6050     r = pMsiGetProductInfoExA(prodcode, NULL,
6051                               MSIINSTALLCONTEXT_MACHINE,
6052                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6053     ok(r == ERROR_UNKNOWN_PRODUCT,
6054        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6055     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6056     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6057
6058     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6059     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6060
6061     /* ProductName value exists */
6062     sz = MAX_PATH;
6063     lstrcpyA(buf, "apple");
6064     r = pMsiGetProductInfoExA(prodcode, NULL,
6065                               MSIINSTALLCONTEXT_MACHINE,
6066                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6067     ok(r == ERROR_UNKNOWN_PRODUCT,
6068        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6069     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6070     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6071
6072     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6073     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6074
6075     /* FIXME */
6076
6077     /* AssignmentType value exists */
6078     sz = MAX_PATH;
6079     lstrcpyA(buf, "apple");
6080     r = pMsiGetProductInfoExA(prodcode, NULL,
6081                               MSIINSTALLCONTEXT_MACHINE,
6082                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6083     ok(r == ERROR_UNKNOWN_PRODUCT,
6084        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6085     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6086     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6087
6088     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6089     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6090
6091     /* PackageCode value exists */
6092     sz = MAX_PATH;
6093     lstrcpyA(buf, "apple");
6094     r = pMsiGetProductInfoExA(prodcode, NULL,
6095                               MSIINSTALLCONTEXT_MACHINE,
6096                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6097     ok(r == ERROR_UNKNOWN_PRODUCT,
6098        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6099     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6100     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6101
6102     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6103     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6104
6105     /* Version value exists */
6106     sz = MAX_PATH;
6107     lstrcpyA(buf, "apple");
6108     r = pMsiGetProductInfoExA(prodcode, NULL,
6109                               MSIINSTALLCONTEXT_MACHINE,
6110                               INSTALLPROPERTY_VERSION, buf, &sz);
6111     ok(r == ERROR_UNKNOWN_PRODUCT,
6112        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6113     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6114     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6115
6116     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6117     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6118
6119     /* ProductIcon value exists */
6120     sz = MAX_PATH;
6121     lstrcpyA(buf, "apple");
6122     r = pMsiGetProductInfoExA(prodcode, NULL,
6123                               MSIINSTALLCONTEXT_MACHINE,
6124                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6125     ok(r == ERROR_UNKNOWN_PRODUCT,
6126        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6127     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6128     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6129
6130     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6131     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6132
6133     /* PackageName value exists */
6134     sz = MAX_PATH;
6135     lstrcpyA(buf, "apple");
6136     r = pMsiGetProductInfoExA(prodcode, NULL,
6137                               MSIINSTALLCONTEXT_MACHINE,
6138                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6139     ok(r == ERROR_UNKNOWN_PRODUCT,
6140        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6141     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6142     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6143
6144     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6145     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6146
6147     /* AuthorizedLUAApp value exists */
6148     sz = MAX_PATH;
6149     lstrcpyA(buf, "apple");
6150     r = pMsiGetProductInfoExA(prodcode, NULL,
6151                               MSIINSTALLCONTEXT_MACHINE,
6152                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6153     ok(r == ERROR_UNKNOWN_PRODUCT,
6154        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6155     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6156     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6157
6158     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6159     RegDeleteValueA(propkey, "PackageName");
6160     RegDeleteValueA(propkey, "ProductIcon");
6161     RegDeleteValueA(propkey, "Version");
6162     RegDeleteValueA(propkey, "PackageCode");
6163     RegDeleteValueA(propkey, "AssignmentType");
6164     RegDeleteValueA(propkey, "ProductName");
6165     RegDeleteValueA(propkey, "Language");
6166     RegDeleteValueA(propkey, "Transforms");
6167     RegDeleteValueA(propkey, "RegOwner");
6168     RegDeleteValueA(propkey, "RegCompany");
6169     RegDeleteValueA(propkey, "ProductID");
6170     RegDeleteValueA(propkey, "DisplayVersion");
6171     RegDeleteValueA(propkey, "VersionMajor");
6172     RegDeleteValueA(propkey, "VersionMinor");
6173     RegDeleteValueA(propkey, "URLUpdateInfo");
6174     RegDeleteValueA(propkey, "URLInfoAbout");
6175     RegDeleteValueA(propkey, "Publisher");
6176     RegDeleteValueA(propkey, "LocalPackage");
6177     RegDeleteValueA(propkey, "InstallSource");
6178     RegDeleteValueA(propkey, "InstallLocation");
6179     RegDeleteValueA(propkey, "DisplayName");
6180     RegDeleteValueA(propkey, "InstallDate");
6181     RegDeleteValueA(propkey, "HelpTelephone");
6182     RegDeleteValueA(propkey, "HelpLink");
6183     RegDeleteValueA(propkey, "LocalPackage");
6184     RegDeleteKeyA(propkey, "");
6185     RegCloseKey(propkey);
6186     RegDeleteKeyA(localkey, "");
6187     RegCloseKey(localkey);
6188
6189     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6190     lstrcatA(keypath, prod_squashed);
6191
6192     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6194
6195     /* local classes product key exists */
6196     sz = MAX_PATH;
6197     lstrcpyA(buf, "apple");
6198     r = pMsiGetProductInfoExA(prodcode, NULL,
6199                               MSIINSTALLCONTEXT_MACHINE,
6200                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6201     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6202     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6203     ok(sz == 1, "Expected 1, got %d\n", sz);
6204
6205     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6206     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6207
6208     /* HelpLink value exists */
6209     sz = MAX_PATH;
6210     lstrcpyA(buf, "apple");
6211     r = pMsiGetProductInfoExA(prodcode, NULL,
6212                               MSIINSTALLCONTEXT_MACHINE,
6213                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6214     ok(r == ERROR_UNKNOWN_PROPERTY,
6215        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6216     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6217     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6218
6219     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6220     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6221
6222     /* HelpTelephone value exists */
6223     sz = MAX_PATH;
6224     lstrcpyA(buf, "apple");
6225     r = pMsiGetProductInfoExA(prodcode, NULL,
6226                               MSIINSTALLCONTEXT_MACHINE,
6227                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6228     ok(r == ERROR_UNKNOWN_PROPERTY,
6229        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6230     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6231     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6232
6233     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6234     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6235
6236     /* InstallDate value exists */
6237     sz = MAX_PATH;
6238     lstrcpyA(buf, "apple");
6239     r = pMsiGetProductInfoExA(prodcode, NULL,
6240                               MSIINSTALLCONTEXT_MACHINE,
6241                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6242     ok(r == ERROR_UNKNOWN_PROPERTY,
6243        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6244     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6245     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6246
6247     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6248     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6249
6250     /* DisplayName value exists */
6251     sz = MAX_PATH;
6252     lstrcpyA(buf, "apple");
6253     r = pMsiGetProductInfoExA(prodcode, NULL,
6254                               MSIINSTALLCONTEXT_MACHINE,
6255                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6256     ok(r == ERROR_UNKNOWN_PROPERTY,
6257        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6258     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6259     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6260
6261     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6263
6264     /* InstallLocation value exists */
6265     sz = MAX_PATH;
6266     lstrcpyA(buf, "apple");
6267     r = pMsiGetProductInfoExA(prodcode, NULL,
6268                               MSIINSTALLCONTEXT_MACHINE,
6269                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6270     ok(r == ERROR_UNKNOWN_PROPERTY,
6271        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6272     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6273     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6274
6275     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6276     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6277
6278     /* InstallSource value exists */
6279     sz = MAX_PATH;
6280     lstrcpyA(buf, "apple");
6281     r = pMsiGetProductInfoExA(prodcode, NULL,
6282                               MSIINSTALLCONTEXT_MACHINE,
6283                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6284     ok(r == ERROR_UNKNOWN_PROPERTY,
6285        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6286     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6287     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6288
6289     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6290     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6291
6292     /* LocalPackage value exists */
6293     sz = MAX_PATH;
6294     lstrcpyA(buf, "apple");
6295     r = pMsiGetProductInfoExA(prodcode, NULL,
6296                               MSIINSTALLCONTEXT_MACHINE,
6297                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6298     ok(r == ERROR_UNKNOWN_PROPERTY,
6299        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6300     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6301     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6302
6303     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6305
6306     /* Publisher value exists */
6307     sz = MAX_PATH;
6308     lstrcpyA(buf, "apple");
6309     r = pMsiGetProductInfoExA(prodcode, NULL,
6310                               MSIINSTALLCONTEXT_MACHINE,
6311                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6312     ok(r == ERROR_UNKNOWN_PROPERTY,
6313        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6314     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6315     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6316
6317     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6319
6320     /* URLInfoAbout value exists */
6321     sz = MAX_PATH;
6322     lstrcpyA(buf, "apple");
6323     r = pMsiGetProductInfoExA(prodcode, NULL,
6324                               MSIINSTALLCONTEXT_MACHINE,
6325                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6326     ok(r == ERROR_UNKNOWN_PROPERTY,
6327        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6328     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6329     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6330
6331     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6333
6334     /* URLUpdateInfo value exists */
6335     sz = MAX_PATH;
6336     lstrcpyA(buf, "apple");
6337     r = pMsiGetProductInfoExA(prodcode, NULL,
6338                               MSIINSTALLCONTEXT_MACHINE,
6339                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6340     ok(r == ERROR_UNKNOWN_PROPERTY,
6341        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6342     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6343     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6344
6345     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6347
6348     /* VersionMinor value exists */
6349     sz = MAX_PATH;
6350     lstrcpyA(buf, "apple");
6351     r = pMsiGetProductInfoExA(prodcode, NULL,
6352                               MSIINSTALLCONTEXT_MACHINE,
6353                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6354     ok(r == ERROR_UNKNOWN_PROPERTY,
6355        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6356     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6357     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6358
6359     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6361
6362     /* VersionMajor value exists */
6363     sz = MAX_PATH;
6364     lstrcpyA(buf, "apple");
6365     r = pMsiGetProductInfoExA(prodcode, NULL,
6366                               MSIINSTALLCONTEXT_MACHINE,
6367                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6368     ok(r == ERROR_UNKNOWN_PROPERTY,
6369        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6370     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6371     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6372
6373     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6374     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6375
6376     /* DisplayVersion value exists */
6377     sz = MAX_PATH;
6378     lstrcpyA(buf, "apple");
6379     r = pMsiGetProductInfoExA(prodcode, NULL,
6380                               MSIINSTALLCONTEXT_MACHINE,
6381                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6382     ok(r == ERROR_UNKNOWN_PROPERTY,
6383        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6384     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6385     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6386
6387     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6389
6390     /* ProductID value exists */
6391     sz = MAX_PATH;
6392     lstrcpyA(buf, "apple");
6393     r = pMsiGetProductInfoExA(prodcode, NULL,
6394                               MSIINSTALLCONTEXT_MACHINE,
6395                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6396     ok(r == ERROR_UNKNOWN_PROPERTY,
6397        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6398     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6399     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6400
6401     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6403
6404     /* RegCompany value exists */
6405     sz = MAX_PATH;
6406     lstrcpyA(buf, "apple");
6407     r = pMsiGetProductInfoExA(prodcode, NULL,
6408                               MSIINSTALLCONTEXT_MACHINE,
6409                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6410     ok(r == ERROR_UNKNOWN_PROPERTY,
6411        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6412     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6413     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6414
6415     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6417
6418     /* RegOwner value exists */
6419     sz = MAX_PATH;
6420     lstrcpyA(buf, "apple");
6421     r = pMsiGetProductInfoExA(prodcode, NULL,
6422                               MSIINSTALLCONTEXT_MACHINE,
6423                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6424     ok(r == ERROR_UNKNOWN_PROPERTY,
6425        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6426     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6427     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6428
6429     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6431
6432     /* Transforms value exists */
6433     sz = MAX_PATH;
6434     lstrcpyA(buf, "apple");
6435     r = pMsiGetProductInfoExA(prodcode, NULL,
6436                               MSIINSTALLCONTEXT_MACHINE,
6437                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6438     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6439     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6440     ok(sz == 5, "Expected 5, got %d\n", sz);
6441
6442     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6443     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6444
6445     /* Language value exists */
6446     sz = MAX_PATH;
6447     lstrcpyA(buf, "apple");
6448     r = pMsiGetProductInfoExA(prodcode, NULL,
6449                               MSIINSTALLCONTEXT_MACHINE,
6450                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6452     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6453     ok(sz == 4, "Expected 4, got %d\n", sz);
6454
6455     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6457
6458     /* ProductName value exists */
6459     sz = MAX_PATH;
6460     lstrcpyA(buf, "apple");
6461     r = pMsiGetProductInfoExA(prodcode, NULL,
6462                               MSIINSTALLCONTEXT_MACHINE,
6463                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6464     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6465     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6466     ok(sz == 4, "Expected 4, got %d\n", sz);
6467
6468     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6469     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6470
6471     /* FIXME */
6472
6473     /* AssignmentType value exists */
6474     sz = MAX_PATH;
6475     lstrcpyA(buf, "apple");
6476     r = pMsiGetProductInfoExA(prodcode, NULL,
6477                               MSIINSTALLCONTEXT_MACHINE,
6478                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6479     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6480     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6481     ok(sz == 0, "Expected 0, got %d\n", sz);
6482
6483     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6484     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6485
6486     /* FIXME */
6487
6488     /* PackageCode value exists */
6489     sz = MAX_PATH;
6490     lstrcpyA(buf, "apple");
6491     r = pMsiGetProductInfoExA(prodcode, NULL,
6492                               MSIINSTALLCONTEXT_MACHINE,
6493                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6494     todo_wine
6495     {
6496         ok(r == ERROR_BAD_CONFIGURATION,
6497            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6498         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6499         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6500     }
6501
6502     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6504
6505     /* Version value exists */
6506     sz = MAX_PATH;
6507     lstrcpyA(buf, "apple");
6508     r = pMsiGetProductInfoExA(prodcode, NULL,
6509                               MSIINSTALLCONTEXT_MACHINE,
6510                               INSTALLPROPERTY_VERSION, buf, &sz);
6511     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6512     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6513     ok(sz == 3, "Expected 3, got %d\n", sz);
6514
6515     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6516     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6517
6518     /* ProductIcon value exists */
6519     sz = MAX_PATH;
6520     lstrcpyA(buf, "apple");
6521     r = pMsiGetProductInfoExA(prodcode, NULL,
6522                               MSIINSTALLCONTEXT_MACHINE,
6523                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6524     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6525     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6526     ok(sz == 4, "Expected 4, got %d\n", sz);
6527
6528     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6530
6531     /* PackageName value exists */
6532     sz = MAX_PATH;
6533     lstrcpyA(buf, "apple");
6534     r = pMsiGetProductInfoExA(prodcode, NULL,
6535                               MSIINSTALLCONTEXT_MACHINE,
6536                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6537     todo_wine
6538     {
6539         ok(r == ERROR_UNKNOWN_PRODUCT,
6540            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6541         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6542         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6543     }
6544
6545     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6546     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6547
6548     /* AuthorizedLUAApp value exists */
6549     sz = MAX_PATH;
6550     lstrcpyA(buf, "apple");
6551     r = pMsiGetProductInfoExA(prodcode, NULL,
6552                               MSIINSTALLCONTEXT_MACHINE,
6553                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6554     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6555     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6556     ok(sz == 4, "Expected 4, got %d\n", sz);
6557
6558     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6559     RegDeleteValueA(prodkey, "PackageName");
6560     RegDeleteValueA(prodkey, "ProductIcon");
6561     RegDeleteValueA(prodkey, "Version");
6562     RegDeleteValueA(prodkey, "PackageCode");
6563     RegDeleteValueA(prodkey, "AssignmentType");
6564     RegDeleteValueA(prodkey, "ProductName");
6565     RegDeleteValueA(prodkey, "Language");
6566     RegDeleteValueA(prodkey, "Transforms");
6567     RegDeleteValueA(prodkey, "RegOwner");
6568     RegDeleteValueA(prodkey, "RegCompany");
6569     RegDeleteValueA(prodkey, "ProductID");
6570     RegDeleteValueA(prodkey, "DisplayVersion");
6571     RegDeleteValueA(prodkey, "VersionMajor");
6572     RegDeleteValueA(prodkey, "VersionMinor");
6573     RegDeleteValueA(prodkey, "URLUpdateInfo");
6574     RegDeleteValueA(prodkey, "URLInfoAbout");
6575     RegDeleteValueA(prodkey, "Publisher");
6576     RegDeleteValueA(prodkey, "LocalPackage");
6577     RegDeleteValueA(prodkey, "InstallSource");
6578     RegDeleteValueA(prodkey, "InstallLocation");
6579     RegDeleteValueA(prodkey, "DisplayName");
6580     RegDeleteValueA(prodkey, "InstallDate");
6581     RegDeleteValueA(prodkey, "HelpTelephone");
6582     RegDeleteValueA(prodkey, "HelpLink");
6583     RegDeleteKeyA(prodkey, "");
6584     RegCloseKey(prodkey);
6585 }
6586
6587 #define INIT_USERINFO() \
6588     lstrcpyA(user, "apple"); \
6589     lstrcpyA(org, "orange"); \
6590     lstrcpyA(serial, "banana"); \
6591     usersz = orgsz = serialsz = MAX_PATH;
6592
6593 static void test_MsiGetUserInfo(void)
6594 {
6595     USERINFOSTATE state;
6596     CHAR user[MAX_PATH];
6597     CHAR org[MAX_PATH];
6598     CHAR serial[MAX_PATH];
6599     DWORD usersz, orgsz, serialsz;
6600     CHAR keypath[MAX_PATH * 2];
6601     CHAR prodcode[MAX_PATH];
6602     CHAR prod_squashed[MAX_PATH];
6603     HKEY prodkey, userprod, props;
6604     LPSTR usersid;
6605     LONG res;
6606
6607     create_test_guid(prodcode, prod_squashed);
6608     get_user_sid(&usersid);
6609
6610     /* NULL szProduct */
6611     INIT_USERINFO();
6612     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6613     ok(state == USERINFOSTATE_INVALIDARG,
6614        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6615     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6616     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6617     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6618     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6619     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6620     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6621
6622     /* empty szProductCode */
6623     INIT_USERINFO();
6624     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6625     ok(state == USERINFOSTATE_INVALIDARG,
6626        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6627     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6628     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6629     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6630     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6631     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6632     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6633
6634     /* garbage szProductCode */
6635     INIT_USERINFO();
6636     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6637     ok(state == USERINFOSTATE_INVALIDARG,
6638        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6639     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6640     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6641     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6642     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6643     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6644     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6645
6646     /* guid without brackets */
6647     INIT_USERINFO();
6648     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6649                             user, &usersz, org, &orgsz, serial, &serialsz);
6650     ok(state == USERINFOSTATE_INVALIDARG,
6651        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6652     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6653     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6654     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6655     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6656     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6657     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6658
6659     /* guid with brackets */
6660     INIT_USERINFO();
6661     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6662                             user, &usersz, org, &orgsz, serial, &serialsz);
6663     ok(state == USERINFOSTATE_UNKNOWN,
6664        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6665     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6666     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6667     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6668     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6669     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6670     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6671
6672     /* NULL lpUserNameBuf */
6673     INIT_USERINFO();
6674     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6675     ok(state == USERINFOSTATE_UNKNOWN,
6676        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6677     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6678     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6679     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6680     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6681     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6682
6683     /* NULL pcchUserNameBuf */
6684     INIT_USERINFO();
6685     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6686     ok(state == USERINFOSTATE_INVALIDARG,
6687        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6688     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6689     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6690     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6691     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6692     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6693
6694     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6695     INIT_USERINFO();
6696     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6697     ok(state == USERINFOSTATE_UNKNOWN,
6698        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6699     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6700     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6701     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6702     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6703
6704     /* NULL lpOrgNameBuf */
6705     INIT_USERINFO();
6706     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6707     ok(state == USERINFOSTATE_UNKNOWN,
6708        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6709     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6710     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6711     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6712     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6713     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6714
6715     /* NULL pcchOrgNameBuf */
6716     INIT_USERINFO();
6717     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
6718     ok(state == USERINFOSTATE_INVALIDARG,
6719        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6720     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6721     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6722     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6723     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6724     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6725
6726     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
6727     INIT_USERINFO();
6728     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
6729     ok(state == USERINFOSTATE_UNKNOWN,
6730        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6731     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6732     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6733     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6734     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6735
6736     /* NULL lpSerialBuf */
6737     INIT_USERINFO();
6738     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
6739     ok(state == USERINFOSTATE_UNKNOWN,
6740        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6741     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6742     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6743     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6744     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6745     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6746
6747     /* NULL pcchSerialBuf */
6748     INIT_USERINFO();
6749     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
6750     ok(state == USERINFOSTATE_INVALIDARG,
6751        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6752     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6753     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6754     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6755     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6756     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6757
6758     /* both lpSerialBuf and pcchSerialBuf NULL */
6759     INIT_USERINFO();
6760     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
6761     ok(state == USERINFOSTATE_UNKNOWN,
6762        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6763     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6764     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6765     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6766     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6767
6768     /* MSIINSTALLCONTEXT_USERMANAGED */
6769
6770     /* create local system product key */
6771     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6772     lstrcatA(keypath, usersid);
6773     lstrcatA(keypath, "\\Installer\\Products\\");
6774     lstrcatA(keypath, prod_squashed);
6775
6776     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6778
6779     /* managed product key exists */
6780     INIT_USERINFO();
6781     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6782     ok(state == USERINFOSTATE_ABSENT,
6783        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6784     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6785     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6786     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6787     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6788     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6789     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6790
6791     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6792     lstrcatA(keypath, "Installer\\UserData\\");
6793     lstrcatA(keypath, usersid);
6794     lstrcatA(keypath, "\\Products\\");
6795     lstrcatA(keypath, prod_squashed);
6796
6797     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6798     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6799
6800     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6801     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6802
6803     /* InstallProperties key exists */
6804     INIT_USERINFO();
6805     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6806     ok(state == USERINFOSTATE_ABSENT,
6807        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6808     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6809     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6810     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6811     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6812     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6813     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6814
6815     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6816     INIT_USERINFO();
6817     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6818     ok(state == USERINFOSTATE_ABSENT,
6819        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6820     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6821     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6822     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6823     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6824
6825     /* RegOwner, RegCompany don't exist, out params are NULL */
6826     INIT_USERINFO();
6827     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6828     ok(state == USERINFOSTATE_ABSENT,
6829        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6830     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6831     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6832
6833     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6834     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6835
6836     /* RegOwner value exists */
6837     INIT_USERINFO();
6838     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6839     ok(state == USERINFOSTATE_ABSENT,
6840        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6841     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6842     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6843     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6844     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6845     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6846     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6847
6848     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6849     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6850
6851     /* RegCompany value exists */
6852     INIT_USERINFO();
6853     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6854     ok(state == USERINFOSTATE_ABSENT,
6855        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6856     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6857     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6858     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6859     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6860     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6861     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6862
6863     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6864     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6865
6866     /* ProductID value exists */
6867     INIT_USERINFO();
6868     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6869     ok(state == USERINFOSTATE_PRESENT,
6870        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6871     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6872     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6873     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6874     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6875     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6876     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6877
6878     /* pcchUserNameBuf is too small */
6879     INIT_USERINFO();
6880     usersz = 0;
6881     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6882     ok(state == USERINFOSTATE_MOREDATA,
6883        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6884     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6885     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6886     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6887     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6888     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6889     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6890
6891     /* pcchUserNameBuf has no room for NULL terminator */
6892     INIT_USERINFO();
6893     usersz = 5;
6894     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6895     ok(state == USERINFOSTATE_MOREDATA,
6896        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6897     todo_wine
6898     {
6899         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6900     }
6901     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6902     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6903     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6904     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6905     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6906
6907     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
6908     INIT_USERINFO();
6909     usersz = 0;
6910     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6911     ok(state == USERINFOSTATE_PRESENT,
6912        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6913     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6914     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6915     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6916     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6917     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6918     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6919
6920     RegDeleteValueA(props, "ProductID");
6921     RegDeleteValueA(props, "RegCompany");
6922     RegDeleteValueA(props, "RegOwner");
6923     RegDeleteKeyA(props, "");
6924     RegCloseKey(props);
6925     RegDeleteKeyA(userprod, "");
6926     RegCloseKey(userprod);
6927     RegDeleteKeyA(prodkey, "");
6928     RegCloseKey(prodkey);
6929
6930     /* MSIINSTALLCONTEXT_USERUNMANAGED */
6931
6932     /* create local system product key */
6933     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6934     lstrcatA(keypath, prod_squashed);
6935
6936     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6937     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6938
6939     /* product key exists */
6940     INIT_USERINFO();
6941     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6942     ok(state == USERINFOSTATE_ABSENT,
6943        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6944     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6945     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6946     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6947     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6948     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6949     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6950
6951     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6952     lstrcatA(keypath, "Installer\\UserData\\");
6953     lstrcatA(keypath, usersid);
6954     lstrcatA(keypath, "\\Products\\");
6955     lstrcatA(keypath, prod_squashed);
6956
6957     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6958     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6959
6960     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6962
6963     /* InstallProperties key exists */
6964     INIT_USERINFO();
6965     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6966     ok(state == USERINFOSTATE_ABSENT,
6967        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6968     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6969     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6970     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6971     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6972     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6973     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6974
6975     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6976     INIT_USERINFO();
6977     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6978     ok(state == USERINFOSTATE_ABSENT,
6979        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6980     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6981     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6982     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6983     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6984
6985     /* RegOwner, RegCompany don't exist, out params are NULL */
6986     INIT_USERINFO();
6987     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6988     ok(state == USERINFOSTATE_ABSENT,
6989        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6990     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6991     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6992
6993     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6994     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6995
6996     /* RegOwner value exists */
6997     INIT_USERINFO();
6998     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6999     ok(state == USERINFOSTATE_ABSENT,
7000        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7001     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7002     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7003     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7004     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7005     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7006     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7007
7008     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7010
7011     /* RegCompany value exists */
7012     INIT_USERINFO();
7013     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7014     ok(state == USERINFOSTATE_ABSENT,
7015        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7016     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7017     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7018     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7019     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7020     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7021     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7022
7023     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7025
7026     /* ProductID value exists */
7027     INIT_USERINFO();
7028     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7029     ok(state == USERINFOSTATE_PRESENT,
7030        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7031     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7032     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7033     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7034     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7035     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7036     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7037
7038     RegDeleteValueA(props, "ProductID");
7039     RegDeleteValueA(props, "RegCompany");
7040     RegDeleteValueA(props, "RegOwner");
7041     RegDeleteKeyA(props, "");
7042     RegCloseKey(props);
7043     RegDeleteKeyA(userprod, "");
7044     RegCloseKey(userprod);
7045     RegDeleteKeyA(prodkey, "");
7046     RegCloseKey(prodkey);
7047
7048     /* MSIINSTALLCONTEXT_MACHINE */
7049
7050     /* create local system product key */
7051     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7052     lstrcatA(keypath, prod_squashed);
7053
7054     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7055     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7056
7057     /* product key exists */
7058     INIT_USERINFO();
7059     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7060     ok(state == USERINFOSTATE_ABSENT,
7061        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7062     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7063     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7064     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7065     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7066     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7067     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7068
7069     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7070     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7071     lstrcatA(keypath, "\\Products\\");
7072     lstrcatA(keypath, prod_squashed);
7073
7074     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
7075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7076
7077     res = RegCreateKeyA(userprod, "InstallProperties", &props);
7078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7079
7080     /* InstallProperties key exists */
7081     INIT_USERINFO();
7082     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7083     ok(state == USERINFOSTATE_ABSENT,
7084        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7085     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7086     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7087     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7088     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7089     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7090     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7091
7092     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7093     INIT_USERINFO();
7094     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7095     ok(state == USERINFOSTATE_ABSENT,
7096        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7097     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7098     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7099     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7100     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7101
7102     /* RegOwner, RegCompany don't exist, out params are NULL */
7103     INIT_USERINFO();
7104     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7105     ok(state == USERINFOSTATE_ABSENT,
7106        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7107     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7108     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7109
7110     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7111     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7112
7113     /* RegOwner value exists */
7114     INIT_USERINFO();
7115     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7116     ok(state == USERINFOSTATE_ABSENT,
7117        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7118     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7119     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7120     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7121     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7122     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7123     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7124
7125     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7126     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7127
7128     /* RegCompany value exists */
7129     INIT_USERINFO();
7130     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7131     ok(state == USERINFOSTATE_ABSENT,
7132        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7133     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7134     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7135     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7136     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7137     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7138     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7139
7140     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7142
7143     /* ProductID value exists */
7144     INIT_USERINFO();
7145     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7146     ok(state == USERINFOSTATE_PRESENT,
7147        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7148     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7149     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7150     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7151     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7152     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7153     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7154
7155     RegDeleteValueA(props, "ProductID");
7156     RegDeleteValueA(props, "RegCompany");
7157     RegDeleteValueA(props, "RegOwner");
7158     RegDeleteKeyA(props, "");
7159     RegCloseKey(props);
7160     RegDeleteKeyA(userprod, "");
7161     RegCloseKey(userprod);
7162     RegDeleteKeyA(prodkey, "");
7163     RegCloseKey(prodkey);
7164 }
7165
7166 static void test_MsiOpenProduct(void)
7167 {
7168     MSIHANDLE hprod, hdb;
7169     CHAR val[MAX_PATH];
7170     CHAR path[MAX_PATH];
7171     CHAR keypath[MAX_PATH*2];
7172     CHAR prodcode[MAX_PATH];
7173     CHAR prod_squashed[MAX_PATH];
7174     HKEY prodkey, userkey, props;
7175     LPSTR usersid;
7176     DWORD size;
7177     LONG res;
7178     UINT r;
7179
7180     GetCurrentDirectoryA(MAX_PATH, path);
7181     lstrcatA(path, "\\");
7182
7183     create_test_guid(prodcode, prod_squashed);
7184     get_user_sid(&usersid);
7185
7186     hdb = create_package_db(prodcode);
7187     MsiCloseHandle(hdb);
7188
7189     /* NULL szProduct */
7190     hprod = 0xdeadbeef;
7191     r = MsiOpenProductA(NULL, &hprod);
7192     ok(r == ERROR_INVALID_PARAMETER,
7193        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7194     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7195
7196     /* empty szProduct */
7197     hprod = 0xdeadbeef;
7198     r = MsiOpenProductA("", &hprod);
7199     ok(r == ERROR_INVALID_PARAMETER,
7200        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7201     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7202
7203     /* garbage szProduct */
7204     hprod = 0xdeadbeef;
7205     r = MsiOpenProductA("garbage", &hprod);
7206     ok(r == ERROR_INVALID_PARAMETER,
7207        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7208     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7209
7210     /* guid without brackets */
7211     hprod = 0xdeadbeef;
7212     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7213     ok(r == ERROR_INVALID_PARAMETER,
7214        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7215     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7216
7217     /* guid with brackets */
7218     hprod = 0xdeadbeef;
7219     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7220     ok(r == ERROR_UNKNOWN_PRODUCT,
7221        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7222     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7223
7224     /* same length as guid, but random */
7225     hprod = 0xdeadbeef;
7226     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7227     ok(r == ERROR_INVALID_PARAMETER,
7228        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7229     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7230
7231     /* hProduct is NULL */
7232     hprod = 0xdeadbeef;
7233     r = MsiOpenProductA(prodcode, NULL);
7234     ok(r == ERROR_INVALID_PARAMETER,
7235        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7236     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7237
7238     /* MSIINSTALLCONTEXT_USERMANAGED */
7239
7240     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7241     lstrcatA(keypath, "Installer\\Managed\\");
7242     lstrcatA(keypath, usersid);
7243     lstrcatA(keypath, "\\Installer\\Products\\");
7244     lstrcatA(keypath, prod_squashed);
7245
7246     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7248
7249     /* managed product key exists */
7250     hprod = 0xdeadbeef;
7251     r = MsiOpenProductA(prodcode, &hprod);
7252     ok(r == ERROR_UNKNOWN_PRODUCT,
7253        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7254     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7255
7256     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7257     lstrcatA(keypath, "Installer\\UserData\\");
7258     lstrcatA(keypath, usersid);
7259     lstrcatA(keypath, "\\Products\\");
7260     lstrcatA(keypath, prod_squashed);
7261
7262     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7263     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7264
7265     /* user product key exists */
7266     hprod = 0xdeadbeef;
7267     r = MsiOpenProductA(prodcode, &hprod);
7268     ok(r == ERROR_UNKNOWN_PRODUCT,
7269        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7270     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7271
7272     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7274
7275     /* InstallProperties key exists */
7276     hprod = 0xdeadbeef;
7277     r = MsiOpenProductA(prodcode, &hprod);
7278     ok(r == ERROR_UNKNOWN_PRODUCT,
7279        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7280     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7281
7282     lstrcpyA(val, path);
7283     lstrcatA(val, "\\winetest.msi");
7284     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7285                          (const BYTE *)val, lstrlenA(val) + 1);
7286     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7287
7288     /* ManagedLocalPackage value exists */
7289     hprod = 0xdeadbeef;
7290     r = MsiOpenProductA(prodcode, &hprod);
7291     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7292     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7293
7294     size = MAX_PATH;
7295     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7296     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7297     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7298     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7299
7300     MsiCloseHandle(hprod);
7301
7302     RegDeleteValueA(props, "ManagedLocalPackage");
7303     RegDeleteKeyA(props, "");
7304     RegCloseKey(props);
7305     RegDeleteKeyA(userkey, "");
7306     RegCloseKey(userkey);
7307     RegDeleteKeyA(prodkey, "");
7308     RegCloseKey(prodkey);
7309
7310     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7311
7312     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7313     lstrcatA(keypath, prod_squashed);
7314
7315     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7317
7318     /* unmanaged product key exists */
7319     hprod = 0xdeadbeef;
7320     r = MsiOpenProductA(prodcode, &hprod);
7321     ok(r == ERROR_UNKNOWN_PRODUCT,
7322        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7323     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7324
7325     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7326     lstrcatA(keypath, "Installer\\UserData\\");
7327     lstrcatA(keypath, usersid);
7328     lstrcatA(keypath, "\\Products\\");
7329     lstrcatA(keypath, prod_squashed);
7330
7331     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7333
7334     /* user product key exists */
7335     hprod = 0xdeadbeef;
7336     r = MsiOpenProductA(prodcode, &hprod);
7337     ok(r == ERROR_UNKNOWN_PRODUCT,
7338        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7339     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7340
7341     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7343
7344     /* InstallProperties key exists */
7345     hprod = 0xdeadbeef;
7346     r = MsiOpenProductA(prodcode, &hprod);
7347     ok(r == ERROR_UNKNOWN_PRODUCT,
7348        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7349     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7350
7351     lstrcpyA(val, path);
7352     lstrcatA(val, "\\winetest.msi");
7353     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7354                          (const BYTE *)val, lstrlenA(val) + 1);
7355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7356
7357     /* LocalPackage value exists */
7358     hprod = 0xdeadbeef;
7359     r = MsiOpenProductA(prodcode, &hprod);
7360     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7361     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7362
7363     size = MAX_PATH;
7364     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7365     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7366     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7367     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7368
7369     MsiCloseHandle(hprod);
7370
7371     RegDeleteValueA(props, "LocalPackage");
7372     RegDeleteKeyA(props, "");
7373     RegCloseKey(props);
7374     RegDeleteKeyA(userkey, "");
7375     RegCloseKey(userkey);
7376     RegDeleteKeyA(prodkey, "");
7377     RegCloseKey(prodkey);
7378
7379     /* MSIINSTALLCONTEXT_MACHINE */
7380
7381     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7382     lstrcatA(keypath, prod_squashed);
7383
7384     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7385     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7386
7387     /* managed product key exists */
7388     hprod = 0xdeadbeef;
7389     r = MsiOpenProductA(prodcode, &hprod);
7390     ok(r == ERROR_UNKNOWN_PRODUCT,
7391        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7392     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7393
7394     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7395     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7396     lstrcatA(keypath, prod_squashed);
7397
7398     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7399     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7400
7401     /* user product key exists */
7402     hprod = 0xdeadbeef;
7403     r = MsiOpenProductA(prodcode, &hprod);
7404     ok(r == ERROR_UNKNOWN_PRODUCT,
7405        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7406     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7407
7408     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7409     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7410
7411     /* InstallProperties key exists */
7412     hprod = 0xdeadbeef;
7413     r = MsiOpenProductA(prodcode, &hprod);
7414     ok(r == ERROR_UNKNOWN_PRODUCT,
7415        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7416     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7417
7418     lstrcpyA(val, path);
7419     lstrcatA(val, "\\winetest.msi");
7420     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7421                          (const BYTE *)val, lstrlenA(val) + 1);
7422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7423
7424     /* LocalPackage value exists */
7425     hprod = 0xdeadbeef;
7426     r = MsiOpenProductA(prodcode, &hprod);
7427     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7428     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7429
7430     size = MAX_PATH;
7431     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7432     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7433     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7434     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7435
7436     MsiCloseHandle(hprod);
7437
7438     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7439                          (const BYTE *)"winetest.msi", 13);
7440     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7441
7442     /* LocalPackage has just the package name */
7443     hprod = 0xdeadbeef;
7444     r = MsiOpenProductA(prodcode, &hprod);
7445     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7446        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7447     if (r == ERROR_SUCCESS)
7448         MsiCloseHandle(hprod);
7449     else
7450         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7451
7452     lstrcpyA(val, path);
7453     lstrcatA(val, "\\winetest.msi");
7454     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7455                          (const BYTE *)val, lstrlenA(val) + 1);
7456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7457
7458     DeleteFileA(msifile);
7459
7460     /* local package does not exist */
7461     hprod = 0xdeadbeef;
7462     r = MsiOpenProductA(prodcode, &hprod);
7463     ok(r == ERROR_UNKNOWN_PRODUCT,
7464        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7465     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7466
7467     RegDeleteValueA(props, "LocalPackage");
7468     RegDeleteKeyA(props, "");
7469     RegCloseKey(props);
7470     RegDeleteKeyA(userkey, "");
7471     RegCloseKey(userkey);
7472     RegDeleteKeyA(prodkey, "");
7473     RegCloseKey(prodkey);
7474
7475     DeleteFileA(msifile);
7476 }
7477
7478 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7479 {
7480     MSIINSTALLCONTEXT context;
7481     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7482     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7483     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7484     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7485     HKEY prodkey, patches, udprod, udpatch, hpatch;
7486     DWORD size, data;
7487     LONG res;
7488     UINT r;
7489
7490     create_test_guid(prodcode, prod_squashed);
7491     create_test_guid(patch, patch_squashed);
7492
7493     /* MSIPATCHSTATE_APPLIED */
7494
7495     lstrcpyA(patchcode, "apple");
7496     lstrcpyA(targetprod, "banana");
7497     context = 0xdeadbeef;
7498     lstrcpyA(targetsid, "kiwi");
7499     size = MAX_PATH;
7500     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7501                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7502                            &context, targetsid, &size);
7503     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7504     ok(!lstrcmpA(patchcode, "apple"),
7505        "Expected patchcode to be unchanged, got %s\n", patchcode);
7506     ok(!lstrcmpA(targetprod, "banana"),
7507        "Expected targetprod to be unchanged, got %s\n", targetprod);
7508     ok(context == 0xdeadbeef,
7509        "Expected context to be unchanged, got %d\n", context);
7510     ok(!lstrcmpA(targetsid, "kiwi"),
7511        "Expected targetsid to be unchanged, got %s\n", targetsid);
7512     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7513
7514     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7515     lstrcatA(keypath, expectedsid);
7516     lstrcatA(keypath, "\\Installer\\Products\\");
7517     lstrcatA(keypath, prod_squashed);
7518
7519     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7520     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7521
7522     /* managed product key exists */
7523     lstrcpyA(patchcode, "apple");
7524     lstrcpyA(targetprod, "banana");
7525     context = 0xdeadbeef;
7526     lstrcpyA(targetsid, "kiwi");
7527     size = MAX_PATH;
7528     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7529                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7530                            &context, targetsid, &size);
7531     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7532     ok(!lstrcmpA(patchcode, "apple"),
7533        "Expected patchcode to be unchanged, got %s\n", patchcode);
7534     ok(!lstrcmpA(targetprod, "banana"),
7535        "Expected targetprod to be unchanged, got %s\n", targetprod);
7536     ok(context == 0xdeadbeef,
7537        "Expected context to be unchanged, got %d\n", context);
7538     ok(!lstrcmpA(targetsid, "kiwi"),
7539        "Expected targetsid to be unchanged, got %s\n", targetsid);
7540     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7541
7542     res = RegCreateKeyA(prodkey, "Patches", &patches);
7543     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7544
7545     /* patches key exists */
7546     lstrcpyA(patchcode, "apple");
7547     lstrcpyA(targetprod, "banana");
7548     context = 0xdeadbeef;
7549     lstrcpyA(targetsid, "kiwi");
7550     size = MAX_PATH;
7551     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7552                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7553                            &context, targetsid, &size);
7554     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7555     ok(!lstrcmpA(patchcode, "apple"),
7556        "Expected patchcode to be unchanged, got %s\n", patchcode);
7557     ok(!lstrcmpA(targetprod, "banana"),
7558        "Expected targetprod to be unchanged, got %s\n", targetprod);
7559     ok(context == 0xdeadbeef,
7560        "Expected context to be unchanged, got %d\n", context);
7561     ok(!lstrcmpA(targetsid, "kiwi"),
7562        "Expected targetsid to be unchanged, got %s\n", targetsid);
7563     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7564
7565     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7566                          (const BYTE *)patch_squashed,
7567                          lstrlenA(patch_squashed) + 1);
7568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7569
7570     /* Patches value exists, is not REG_MULTI_SZ */
7571     lstrcpyA(patchcode, "apple");
7572     lstrcpyA(targetprod, "banana");
7573     context = 0xdeadbeef;
7574     lstrcpyA(targetsid, "kiwi");
7575     size = MAX_PATH;
7576     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7577                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7578                            &context, targetsid, &size);
7579     ok(r == ERROR_BAD_CONFIGURATION,
7580        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7581     ok(!lstrcmpA(patchcode, "apple"),
7582        "Expected patchcode to be unchanged, got %s\n", patchcode);
7583     ok(!lstrcmpA(targetprod, "banana"),
7584        "Expected targetprod to be unchanged, got %s\n", targetprod);
7585     ok(context == 0xdeadbeef,
7586        "Expected context to be unchanged, got %d\n", context);
7587     ok(!lstrcmpA(targetsid, "kiwi"),
7588        "Expected targetsid to be unchanged, got %s\n", targetsid);
7589     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7590
7591     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7592                          (const BYTE *)"a\0b\0c\0\0", 7);
7593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7594
7595     /* Patches value exists, is not a squashed guid */
7596     lstrcpyA(patchcode, "apple");
7597     lstrcpyA(targetprod, "banana");
7598     context = 0xdeadbeef;
7599     lstrcpyA(targetsid, "kiwi");
7600     size = MAX_PATH;
7601     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7602                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7603                            &context, targetsid, &size);
7604     ok(r == ERROR_BAD_CONFIGURATION,
7605        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7606     ok(!lstrcmpA(patchcode, "apple"),
7607        "Expected patchcode to be unchanged, got %s\n", patchcode);
7608     ok(!lstrcmpA(targetprod, "banana"),
7609        "Expected targetprod to be unchanged, got %s\n", targetprod);
7610     ok(context == 0xdeadbeef,
7611        "Expected context to be unchanged, got %d\n", context);
7612     ok(!lstrcmpA(targetsid, "kiwi"),
7613        "Expected targetsid to be unchanged, got %s\n", targetsid);
7614     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7615
7616     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
7617     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7618                          (const BYTE *)patch_squashed,
7619                          lstrlenA(patch_squashed) + 2);
7620     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7621
7622     /* Patches value exists */
7623     lstrcpyA(patchcode, "apple");
7624     lstrcpyA(targetprod, "banana");
7625     context = 0xdeadbeef;
7626     lstrcpyA(targetsid, "kiwi");
7627     size = MAX_PATH;
7628     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7629                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7630                            &context, targetsid, &size);
7631     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7632     ok(!lstrcmpA(patchcode, "apple"),
7633        "Expected patchcode to be unchanged, got %s\n", patchcode);
7634     ok(!lstrcmpA(targetprod, "banana"),
7635        "Expected targetprod to be unchanged, got %s\n", targetprod);
7636     ok(context == 0xdeadbeef,
7637        "Expected context to be unchanged, got %d\n", context);
7638     ok(!lstrcmpA(targetsid, "kiwi"),
7639        "Expected targetsid to be unchanged, got %s\n", targetsid);
7640     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7641
7642     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7643                          (const BYTE *)"whatever", 9);
7644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7645
7646     /* patch squashed value exists */
7647     lstrcpyA(patchcode, "apple");
7648     lstrcpyA(targetprod, "banana");
7649     context = 0xdeadbeef;
7650     lstrcpyA(targetsid, "kiwi");
7651     size = MAX_PATH;
7652     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7653                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7654                            &context, targetsid, &size);
7655     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7656     ok(!lstrcmpA(patchcode, patch),
7657        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7658     ok(!lstrcmpA(targetprod, prodcode),
7659        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7660     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7661        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7662     ok(!lstrcmpA(targetsid, expectedsid),
7663        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7664     ok(size == lstrlenA(expectedsid),
7665        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7666
7667     /* increase the index */
7668     lstrcpyA(patchcode, "apple");
7669     lstrcpyA(targetprod, "banana");
7670     context = 0xdeadbeef;
7671     lstrcpyA(targetsid, "kiwi");
7672     size = MAX_PATH;
7673     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7674                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7675                            &context, targetsid, &size);
7676     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7677     ok(!lstrcmpA(patchcode, "apple"),
7678        "Expected patchcode to be unchanged, got %s\n", patchcode);
7679     ok(!lstrcmpA(targetprod, "banana"),
7680        "Expected targetprod to be unchanged, got %s\n", targetprod);
7681     ok(context == 0xdeadbeef,
7682        "Expected context to be unchanged, got %d\n", context);
7683     ok(!lstrcmpA(targetsid, "kiwi"),
7684        "Expected targetsid to be unchanged, got %s\n", targetsid);
7685     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7686
7687     /* increase again */
7688     lstrcpyA(patchcode, "apple");
7689     lstrcpyA(targetprod, "banana");
7690     context = 0xdeadbeef;
7691     lstrcpyA(targetsid, "kiwi");
7692     size = MAX_PATH;
7693     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7694                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
7695                            &context, targetsid, &size);
7696     ok(r == ERROR_INVALID_PARAMETER,
7697        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7698     ok(!lstrcmpA(patchcode, "apple"),
7699        "Expected patchcode to be unchanged, got %s\n", patchcode);
7700     ok(!lstrcmpA(targetprod, "banana"),
7701        "Expected targetprod to be unchanged, got %s\n", targetprod);
7702     ok(context == 0xdeadbeef,
7703        "Expected context to be unchanged, got %d\n", context);
7704     ok(!lstrcmpA(targetsid, "kiwi"),
7705        "Expected targetsid to be unchanged, got %s\n", targetsid);
7706     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7707
7708     /* szPatchCode is NULL */
7709     lstrcpyA(targetprod, "banana");
7710     context = 0xdeadbeef;
7711     lstrcpyA(targetsid, "kiwi");
7712     size = MAX_PATH;
7713     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7714                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
7715                            &context, targetsid, &size);
7716     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7717     ok(!lstrcmpA(targetprod, prodcode),
7718        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7719     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7720        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7721     ok(!lstrcmpA(targetsid, expectedsid),
7722        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7723     ok(size == lstrlenA(expectedsid),
7724        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7725
7726     /* szTargetProductCode is NULL */
7727     lstrcpyA(patchcode, "apple");
7728     context = 0xdeadbeef;
7729     lstrcpyA(targetsid, "kiwi");
7730     size = MAX_PATH;
7731     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7732                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
7733                            &context, targetsid, &size);
7734     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7735     ok(!lstrcmpA(patchcode, patch),
7736        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7737     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7738        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7739     ok(!lstrcmpA(targetsid, expectedsid),
7740        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7741     ok(size == lstrlenA(expectedsid),
7742        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7743
7744     /* pdwTargetProductContext is NULL */
7745     lstrcpyA(patchcode, "apple");
7746     lstrcpyA(targetprod, "banana");
7747     lstrcpyA(targetsid, "kiwi");
7748     size = MAX_PATH;
7749     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7750                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7751                            NULL, targetsid, &size);
7752     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7753     ok(!lstrcmpA(patchcode, patch),
7754        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7755     ok(!lstrcmpA(targetprod, prodcode),
7756        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7757     ok(!lstrcmpA(targetsid, expectedsid),
7758        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7759     ok(size == lstrlenA(expectedsid),
7760        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7761
7762     /* szTargetUserSid is NULL */
7763     lstrcpyA(patchcode, "apple");
7764     lstrcpyA(targetprod, "banana");
7765     context = 0xdeadbeef;
7766     size = MAX_PATH;
7767     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7768                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7769                            &context, NULL, &size);
7770     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7771     ok(!lstrcmpA(patchcode, patch),
7772        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7773     ok(!lstrcmpA(targetprod, prodcode),
7774        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7775     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7776        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7777     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7778        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
7779
7780     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
7781     lstrcpyA(patchcode, "apple");
7782     lstrcpyA(targetprod, "banana");
7783     context = 0xdeadbeef;
7784     lstrcpyA(targetsid, "kiwi");
7785     size = lstrlenA(expectedsid);
7786     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7787                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7788                            &context, targetsid, &size);
7789     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
7790     ok(!lstrcmpA(patchcode, patch),
7791        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7792     ok(!lstrcmpA(targetprod, prodcode),
7793        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7794     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7795        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7796     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
7797        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7798     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7799        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
7800
7801     /* pcchTargetUserSid has enough room for NULL terminator */
7802     lstrcpyA(patchcode, "apple");
7803     lstrcpyA(targetprod, "banana");
7804     context = 0xdeadbeef;
7805     lstrcpyA(targetsid, "kiwi");
7806     size = lstrlenA(expectedsid) + 1;
7807     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7808                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7809                            &context, targetsid, &size);
7810     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7811     ok(!lstrcmpA(patchcode, patch),
7812        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7813     ok(!lstrcmpA(targetprod, prodcode),
7814        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7815     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7816        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7817     ok(!lstrcmpA(targetsid, expectedsid),
7818        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7819     ok(size == lstrlenA(expectedsid),
7820        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7821
7822     /* both szTargetuserSid and pcchTargetUserSid are NULL */
7823     lstrcpyA(patchcode, "apple");
7824     lstrcpyA(targetprod, "banana");
7825     context = 0xdeadbeef;
7826     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7827                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7828                            &context, NULL, NULL);
7829     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7830     ok(!lstrcmpA(patchcode, patch),
7831        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7832     ok(!lstrcmpA(targetprod, prodcode),
7833        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7834     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7835        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7836
7837     /* MSIPATCHSTATE_SUPERSEDED */
7838
7839     lstrcpyA(patchcode, "apple");
7840     lstrcpyA(targetprod, "banana");
7841     context = 0xdeadbeef;
7842     lstrcpyA(targetsid, "kiwi");
7843     size = MAX_PATH;
7844     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7845                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7846                            &context, targetsid, &size);
7847     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7848     ok(!lstrcmpA(patchcode, "apple"),
7849        "Expected patchcode to be unchanged, got %s\n", patchcode);
7850     ok(!lstrcmpA(targetprod, "banana"),
7851        "Expected targetprod to be unchanged, got %s\n", targetprod);
7852     ok(context == 0xdeadbeef,
7853        "Expected context to be unchanged, got %d\n", context);
7854     ok(!lstrcmpA(targetsid, "kiwi"),
7855        "Expected targetsid to be unchanged, got %s\n", targetsid);
7856     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7857
7858     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
7859     lstrcatA(keypath, expectedsid);
7860     lstrcatA(keypath, "\\Products\\");
7861     lstrcatA(keypath, prod_squashed);
7862
7863     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
7864     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7865
7866     /* UserData product key exists */
7867     lstrcpyA(patchcode, "apple");
7868     lstrcpyA(targetprod, "banana");
7869     context = 0xdeadbeef;
7870     lstrcpyA(targetsid, "kiwi");
7871     size = MAX_PATH;
7872     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7873                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7874                            &context, targetsid, &size);
7875     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7876     ok(!lstrcmpA(patchcode, "apple"),
7877        "Expected patchcode to be unchanged, got %s\n", patchcode);
7878     ok(!lstrcmpA(targetprod, "banana"),
7879        "Expected targetprod to be unchanged, got %s\n", targetprod);
7880     ok(context == 0xdeadbeef,
7881        "Expected context to be unchanged, got %d\n", context);
7882     ok(!lstrcmpA(targetsid, "kiwi"),
7883        "Expected targetsid to be unchanged, got %s\n", targetsid);
7884     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7885
7886     res = RegCreateKeyA(udprod, "Patches", &udpatch);
7887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7888
7889     /* UserData patches key exists */
7890     lstrcpyA(patchcode, "apple");
7891     lstrcpyA(targetprod, "banana");
7892     context = 0xdeadbeef;
7893     lstrcpyA(targetsid, "kiwi");
7894     size = MAX_PATH;
7895     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7896                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7897                            &context, targetsid, &size);
7898     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7899     ok(!lstrcmpA(patchcode, "apple"),
7900        "Expected patchcode to be unchanged, got %s\n", patchcode);
7901     ok(!lstrcmpA(targetprod, "banana"),
7902        "Expected targetprod to be unchanged, got %s\n", targetprod);
7903     ok(context == 0xdeadbeef,
7904        "Expected context to be unchanged, got %d\n", context);
7905     ok(!lstrcmpA(targetsid, "kiwi"),
7906        "Expected targetsid to be unchanged, got %s\n", targetsid);
7907     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7908
7909     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
7910     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7911
7912     /* specific UserData patch key exists */
7913     lstrcpyA(patchcode, "apple");
7914     lstrcpyA(targetprod, "banana");
7915     context = 0xdeadbeef;
7916     lstrcpyA(targetsid, "kiwi");
7917     size = MAX_PATH;
7918     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7919                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7920                            &context, targetsid, &size);
7921     ok(r == ERROR_BAD_CONFIGURATION,
7922        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7923     ok(!lstrcmpA(patchcode, "apple"),
7924        "Expected patchcode to be unchanged, got %s\n", patchcode);
7925     ok(!lstrcmpA(targetprod, "banana"),
7926        "Expected targetprod to be unchanged, got %s\n", targetprod);
7927     ok(context == 0xdeadbeef,
7928        "Expected context to be unchanged, got %d\n", context);
7929     ok(!lstrcmpA(targetsid, "kiwi"),
7930        "Expected targetsid to be unchanged, got %s\n", targetsid);
7931     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7932
7933     data = MSIPATCHSTATE_SUPERSEDED;
7934     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
7935                          (const BYTE *)&data, sizeof(DWORD));
7936     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7937
7938     /* State value exists */
7939     lstrcpyA(patchcode, "apple");
7940     lstrcpyA(targetprod, "banana");
7941     context = 0xdeadbeef;
7942     lstrcpyA(targetsid, "kiwi");
7943     size = MAX_PATH;
7944     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7945                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7946                            &context, targetsid, &size);
7947     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7948     ok(!lstrcmpA(patchcode, patch),
7949        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7950     ok(!lstrcmpA(targetprod, prodcode),
7951        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7952     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7953        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7954     ok(!lstrcmpA(targetsid, expectedsid),
7955        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7956     ok(size == lstrlenA(expectedsid),
7957        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7958
7959     /* MSIPATCHSTATE_OBSOLETED */
7960
7961     lstrcpyA(patchcode, "apple");
7962     lstrcpyA(targetprod, "banana");
7963     context = 0xdeadbeef;
7964     lstrcpyA(targetsid, "kiwi");
7965     size = MAX_PATH;
7966     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7967                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
7968                            &context, targetsid, &size);
7969     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7970     ok(!lstrcmpA(patchcode, "apple"),
7971        "Expected patchcode to be unchanged, got %s\n", patchcode);
7972     ok(!lstrcmpA(targetprod, "banana"),
7973        "Expected targetprod to be unchanged, got %s\n", targetprod);
7974     ok(context == 0xdeadbeef,
7975        "Expected context to be unchanged, got %d\n", context);
7976     ok(!lstrcmpA(targetsid, "kiwi"),
7977        "Expected targetsid to be unchanged, got %s\n", targetsid);
7978     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7979
7980     data = MSIPATCHSTATE_OBSOLETED;
7981     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
7982                          (const BYTE *)&data, sizeof(DWORD));
7983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7984
7985     /* State value is obsoleted */
7986     lstrcpyA(patchcode, "apple");
7987     lstrcpyA(targetprod, "banana");
7988     context = 0xdeadbeef;
7989     lstrcpyA(targetsid, "kiwi");
7990     size = MAX_PATH;
7991     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7992                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
7993                            &context, targetsid, &size);
7994     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7995     ok(!lstrcmpA(patchcode, patch),
7996        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7997     ok(!lstrcmpA(targetprod, prodcode),
7998        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7999     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8000        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8001     ok(!lstrcmpA(targetsid, expectedsid),
8002        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8003     ok(size == lstrlenA(expectedsid),
8004        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8005
8006     /* MSIPATCHSTATE_REGISTERED */
8007     /* FIXME */
8008
8009     /* MSIPATCHSTATE_ALL */
8010
8011     /* 1st */
8012     lstrcpyA(patchcode, "apple");
8013     lstrcpyA(targetprod, "banana");
8014     context = 0xdeadbeef;
8015     lstrcpyA(targetsid, "kiwi");
8016     size = MAX_PATH;
8017     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8018                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8019                            &context, targetsid, &size);
8020     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8021     ok(!lstrcmpA(patchcode, patch),
8022        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8023     ok(!lstrcmpA(targetprod, prodcode),
8024        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8025     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8026        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8027     ok(!lstrcmpA(targetsid, expectedsid),
8028        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8029     ok(size == lstrlenA(expectedsid),
8030        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8031
8032     /* same patch in multiple places, only one is enumerated */
8033     lstrcpyA(patchcode, "apple");
8034     lstrcpyA(targetprod, "banana");
8035     context = 0xdeadbeef;
8036     lstrcpyA(targetsid, "kiwi");
8037     size = MAX_PATH;
8038     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8039                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8040                            &context, targetsid, &size);
8041     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8042     ok(!lstrcmpA(patchcode, "apple"),
8043        "Expected patchcode to be unchanged, got %s\n", patchcode);
8044     ok(!lstrcmpA(targetprod, "banana"),
8045        "Expected targetprod to be unchanged, got %s\n", targetprod);
8046     ok(context == 0xdeadbeef,
8047        "Expected context to be unchanged, got %d\n", context);
8048     ok(!lstrcmpA(targetsid, "kiwi"),
8049        "Expected targetsid to be unchanged, got %s\n", targetsid);
8050     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8051
8052     RegDeleteValueA(hpatch, "State");
8053     RegDeleteKeyA(hpatch, "");
8054     RegCloseKey(hpatch);
8055     RegDeleteKeyA(udpatch, "");
8056     RegCloseKey(udpatch);
8057     RegDeleteKeyA(udprod, "");
8058     RegCloseKey(udprod);
8059     RegDeleteValueA(patches, "Patches");
8060     RegDeleteKeyA(patches, "");
8061     RegCloseKey(patches);
8062     RegDeleteKeyA(prodkey, "");
8063     RegCloseKey(prodkey);
8064 }
8065
8066 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8067 {
8068     MSIINSTALLCONTEXT context;
8069     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8070     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8071     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8072     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8073     HKEY prodkey, patches, udprod, udpatch;
8074     HKEY userkey, hpatch;
8075     DWORD size, data;
8076     LONG res;
8077     UINT r;
8078
8079     create_test_guid(prodcode, prod_squashed);
8080     create_test_guid(patch, patch_squashed);
8081
8082     /* MSIPATCHSTATE_APPLIED */
8083
8084     lstrcpyA(patchcode, "apple");
8085     lstrcpyA(targetprod, "banana");
8086     context = 0xdeadbeef;
8087     lstrcpyA(targetsid, "kiwi");
8088     size = MAX_PATH;
8089     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8090                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8091                            &context, targetsid, &size);
8092     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8093     ok(!lstrcmpA(patchcode, "apple"),
8094        "Expected patchcode to be unchanged, got %s\n", patchcode);
8095     ok(!lstrcmpA(targetprod, "banana"),
8096        "Expected targetprod to be unchanged, got %s\n", targetprod);
8097     ok(context == 0xdeadbeef,
8098        "Expected context to be unchanged, got %d\n", context);
8099     ok(!lstrcmpA(targetsid, "kiwi"),
8100        "Expected targetsid to be unchanged, got %s\n", targetsid);
8101     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8102
8103     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8104     lstrcatA(keypath, prod_squashed);
8105
8106     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8107     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8108
8109     /* current user product key exists */
8110     lstrcpyA(patchcode, "apple");
8111     lstrcpyA(targetprod, "banana");
8112     context = 0xdeadbeef;
8113     lstrcpyA(targetsid, "kiwi");
8114     size = MAX_PATH;
8115     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8116                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8117                            &context, targetsid, &size);
8118     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8119     ok(!lstrcmpA(patchcode, "apple"),
8120        "Expected patchcode to be unchanged, got %s\n", patchcode);
8121     ok(!lstrcmpA(targetprod, "banana"),
8122        "Expected targetprod to be unchanged, got %s\n", targetprod);
8123     ok(context == 0xdeadbeef,
8124        "Expected context to be unchanged, got %d\n", context);
8125     ok(!lstrcmpA(targetsid, "kiwi"),
8126        "Expected targetsid to be unchanged, got %s\n", targetsid);
8127     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8128
8129     res = RegCreateKeyA(prodkey, "Patches", &patches);
8130     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8131
8132     /* Patches key exists */
8133     lstrcpyA(patchcode, "apple");
8134     lstrcpyA(targetprod, "banana");
8135     context = 0xdeadbeef;
8136     lstrcpyA(targetsid, "kiwi");
8137     size = MAX_PATH;
8138     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8139                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8140                            &context, targetsid, &size);
8141     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8142     ok(!lstrcmpA(patchcode, "apple"),
8143        "Expected patchcode to be unchanged, got %s\n", patchcode);
8144     ok(!lstrcmpA(targetprod, "banana"),
8145        "Expected targetprod to be unchanged, got %s\n", targetprod);
8146     ok(context == 0xdeadbeef,
8147        "Expected context to be unchanged, got %d\n", context);
8148     ok(!lstrcmpA(targetsid, "kiwi"),
8149        "Expected targetsid to be unchanged, got %s\n", targetsid);
8150     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8151
8152     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8153                          (const BYTE *)patch_squashed,
8154                          lstrlenA(patch_squashed) + 1);
8155     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8156
8157     /* Patches value exists, is not REG_MULTI_SZ */
8158     lstrcpyA(patchcode, "apple");
8159     lstrcpyA(targetprod, "banana");
8160     context = 0xdeadbeef;
8161     lstrcpyA(targetsid, "kiwi");
8162     size = MAX_PATH;
8163     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8164                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8165                            &context, targetsid, &size);
8166     ok(r == ERROR_BAD_CONFIGURATION,
8167        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8168     ok(!lstrcmpA(patchcode, "apple"),
8169        "Expected patchcode to be unchanged, got %s\n", patchcode);
8170     ok(!lstrcmpA(targetprod, "banana"),
8171        "Expected targetprod to be unchanged, got %s\n", targetprod);
8172     ok(context == 0xdeadbeef,
8173        "Expected context to be unchanged, got %d\n", context);
8174     ok(!lstrcmpA(targetsid, "kiwi"),
8175        "Expected targetsid to be unchanged, got %s\n", targetsid);
8176     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8177
8178     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8179                          (const BYTE *)"a\0b\0c\0\0", 7);
8180     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8181
8182     /* Patches value exists, is not a squashed guid */
8183     lstrcpyA(patchcode, "apple");
8184     lstrcpyA(targetprod, "banana");
8185     context = 0xdeadbeef;
8186     lstrcpyA(targetsid, "kiwi");
8187     size = MAX_PATH;
8188     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8189                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8190                            &context, targetsid, &size);
8191     ok(r == ERROR_BAD_CONFIGURATION,
8192        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8193     ok(!lstrcmpA(patchcode, "apple"),
8194        "Expected patchcode to be unchanged, got %s\n", patchcode);
8195     ok(!lstrcmpA(targetprod, "banana"),
8196        "Expected targetprod to be unchanged, got %s\n", targetprod);
8197     ok(context == 0xdeadbeef,
8198        "Expected context to be unchanged, got %d\n", context);
8199     ok(!lstrcmpA(targetsid, "kiwi"),
8200        "Expected targetsid to be unchanged, got %s\n", targetsid);
8201     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8202
8203     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8204                          (const BYTE *)patch_squashed,
8205                          lstrlenA(patch_squashed) + 1);
8206     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8207
8208     /* Patches value exists */
8209     lstrcpyA(patchcode, "apple");
8210     lstrcpyA(targetprod, "banana");
8211     context = 0xdeadbeef;
8212     lstrcpyA(targetsid, "kiwi");
8213     size = MAX_PATH;
8214     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8215                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8216                            &context, targetsid, &size);
8217     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8218     ok(!lstrcmpA(patchcode, "apple"),
8219        "Expected patchcode to be unchanged, got %s\n", patchcode);
8220     ok(!lstrcmpA(targetprod, "banana"),
8221        "Expected targetprod to be unchanged, got %s\n", targetprod);
8222     ok(context == 0xdeadbeef,
8223        "Expected context to be unchanged, got %d\n", context);
8224     ok(!lstrcmpA(targetsid, "kiwi"),
8225        "Expected targetsid to be unchanged, got %s\n", targetsid);
8226     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8227
8228     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8229                          (const BYTE *)"whatever", 9);
8230     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8231
8232     /* patch code value exists */
8233     lstrcpyA(patchcode, "apple");
8234     lstrcpyA(targetprod, "banana");
8235     context = 0xdeadbeef;
8236     lstrcpyA(targetsid, "kiwi");
8237     size = MAX_PATH;
8238     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8239                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8240                            &context, targetsid, &size);
8241     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8242     ok(!lstrcmpA(patchcode, "apple"),
8243        "Expected patchcode to be unchanged, got %s\n", patchcode);
8244     ok(!lstrcmpA(targetprod, "banana"),
8245        "Expected targetprod to be unchanged, got %s\n", targetprod);
8246     ok(context == 0xdeadbeef,
8247        "Expected context to be unchanged, got %d\n", context);
8248     ok(!lstrcmpA(targetsid, "kiwi"),
8249        "Expected targetsid to be unchanged, got %s\n", targetsid);
8250     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8251
8252     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8253     lstrcatA(keypath, expectedsid);
8254     lstrcatA(keypath, "\\Patches\\");
8255     lstrcatA(keypath, patch_squashed);
8256
8257     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
8258     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8259
8260     /* userdata patch key exists */
8261     lstrcpyA(patchcode, "apple");
8262     lstrcpyA(targetprod, "banana");
8263     context = 0xdeadbeef;
8264     lstrcpyA(targetsid, "kiwi");
8265     size = MAX_PATH;
8266     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8267                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8268                            &context, targetsid, &size);
8269     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8270     ok(!lstrcmpA(patchcode, patch),
8271        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8272     ok(!lstrcmpA(targetprod, prodcode),
8273        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8274     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8275        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8276     ok(!lstrcmpA(targetsid, expectedsid),
8277        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8278     ok(size == lstrlenA(expectedsid),
8279        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8280
8281     /* MSIPATCHSTATE_SUPERSEDED */
8282
8283     lstrcpyA(patchcode, "apple");
8284     lstrcpyA(targetprod, "banana");
8285     context = 0xdeadbeef;
8286     lstrcpyA(targetsid, "kiwi");
8287     size = MAX_PATH;
8288     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8289                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8290                            &context, targetsid, &size);
8291     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8292     ok(!lstrcmpA(patchcode, "apple"),
8293        "Expected patchcode to be unchanged, got %s\n", patchcode);
8294     ok(!lstrcmpA(targetprod, "banana"),
8295        "Expected targetprod to be unchanged, got %s\n", targetprod);
8296     ok(context == 0xdeadbeef,
8297        "Expected context to be unchanged, got %d\n", context);
8298     ok(!lstrcmpA(targetsid, "kiwi"),
8299        "Expected targetsid to be unchanged, got %s\n", targetsid);
8300     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8301
8302     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8303     lstrcatA(keypath, expectedsid);
8304     lstrcatA(keypath, "\\Products\\");
8305     lstrcatA(keypath, prod_squashed);
8306
8307     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8309
8310     /* UserData product key exists */
8311     lstrcpyA(patchcode, "apple");
8312     lstrcpyA(targetprod, "banana");
8313     context = 0xdeadbeef;
8314     lstrcpyA(targetsid, "kiwi");
8315     size = MAX_PATH;
8316     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8317                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8318                            &context, targetsid, &size);
8319     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8320     ok(!lstrcmpA(patchcode, "apple"),
8321        "Expected patchcode to be unchanged, got %s\n", patchcode);
8322     ok(!lstrcmpA(targetprod, "banana"),
8323        "Expected targetprod to be unchanged, got %s\n", targetprod);
8324     ok(context == 0xdeadbeef,
8325        "Expected context to be unchanged, got %d\n", context);
8326     ok(!lstrcmpA(targetsid, "kiwi"),
8327        "Expected targetsid to be unchanged, got %s\n", targetsid);
8328     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8329
8330     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8331     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8332
8333     /* UserData patches key exists */
8334     lstrcpyA(patchcode, "apple");
8335     lstrcpyA(targetprod, "banana");
8336     context = 0xdeadbeef;
8337     lstrcpyA(targetsid, "kiwi");
8338     size = MAX_PATH;
8339     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8340                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8341                            &context, targetsid, &size);
8342     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8343     ok(!lstrcmpA(patchcode, "apple"),
8344        "Expected patchcode to be unchanged, got %s\n", patchcode);
8345     ok(!lstrcmpA(targetprod, "banana"),
8346        "Expected targetprod to be unchanged, got %s\n", targetprod);
8347     ok(context == 0xdeadbeef,
8348        "Expected context to be unchanged, got %d\n", context);
8349     ok(!lstrcmpA(targetsid, "kiwi"),
8350        "Expected targetsid to be unchanged, got %s\n", targetsid);
8351     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8352
8353     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8355
8356     /* specific UserData patch key exists */
8357     lstrcpyA(patchcode, "apple");
8358     lstrcpyA(targetprod, "banana");
8359     context = 0xdeadbeef;
8360     lstrcpyA(targetsid, "kiwi");
8361     size = MAX_PATH;
8362     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8363                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8364                            &context, targetsid, &size);
8365     ok(r == ERROR_BAD_CONFIGURATION,
8366        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8367     ok(!lstrcmpA(patchcode, "apple"),
8368        "Expected patchcode to be unchanged, got %s\n", patchcode);
8369     ok(!lstrcmpA(targetprod, "banana"),
8370        "Expected targetprod to be unchanged, got %s\n", targetprod);
8371     ok(context == 0xdeadbeef,
8372        "Expected context to be unchanged, got %d\n", context);
8373     ok(!lstrcmpA(targetsid, "kiwi"),
8374        "Expected targetsid to be unchanged, got %s\n", targetsid);
8375     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8376
8377     data = MSIPATCHSTATE_SUPERSEDED;
8378     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8379                          (const BYTE *)&data, sizeof(DWORD));
8380     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8381
8382     /* State value exists */
8383     lstrcpyA(patchcode, "apple");
8384     lstrcpyA(targetprod, "banana");
8385     context = 0xdeadbeef;
8386     lstrcpyA(targetsid, "kiwi");
8387     size = MAX_PATH;
8388     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8389                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8390                            &context, targetsid, &size);
8391     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8392     ok(!lstrcmpA(patchcode, patch),
8393        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8394     ok(!lstrcmpA(targetprod, prodcode),
8395        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8396     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8397        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8398     ok(!lstrcmpA(targetsid, expectedsid),
8399        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8400     ok(size == lstrlenA(expectedsid),
8401        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8402
8403     /* MSIPATCHSTATE_OBSOLETED */
8404
8405     lstrcpyA(patchcode, "apple");
8406     lstrcpyA(targetprod, "banana");
8407     context = 0xdeadbeef;
8408     lstrcpyA(targetsid, "kiwi");
8409     size = MAX_PATH;
8410     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8411                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8412                            &context, targetsid, &size);
8413     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8414     ok(!lstrcmpA(patchcode, "apple"),
8415        "Expected patchcode to be unchanged, got %s\n", patchcode);
8416     ok(!lstrcmpA(targetprod, "banana"),
8417        "Expected targetprod to be unchanged, got %s\n", targetprod);
8418     ok(context == 0xdeadbeef,
8419        "Expected context to be unchanged, got %d\n", context);
8420     ok(!lstrcmpA(targetsid, "kiwi"),
8421        "Expected targetsid to be unchanged, got %s\n", targetsid);
8422     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8423
8424     data = MSIPATCHSTATE_OBSOLETED;
8425     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8426                          (const BYTE *)&data, sizeof(DWORD));
8427     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8428
8429     /* State value is obsoleted */
8430     lstrcpyA(patchcode, "apple");
8431     lstrcpyA(targetprod, "banana");
8432     context = 0xdeadbeef;
8433     lstrcpyA(targetsid, "kiwi");
8434     size = MAX_PATH;
8435     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8436                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8437                            &context, targetsid, &size);
8438     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8439     ok(!lstrcmpA(patchcode, patch),
8440        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8441     ok(!lstrcmpA(targetprod, prodcode),
8442        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8443     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8444        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8445     ok(!lstrcmpA(targetsid, expectedsid),
8446        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8447     ok(size == lstrlenA(expectedsid),
8448        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8449
8450     /* MSIPATCHSTATE_REGISTERED */
8451     /* FIXME */
8452
8453     /* MSIPATCHSTATE_ALL */
8454
8455     /* 1st */
8456     lstrcpyA(patchcode, "apple");
8457     lstrcpyA(targetprod, "banana");
8458     context = 0xdeadbeef;
8459     lstrcpyA(targetsid, "kiwi");
8460     size = MAX_PATH;
8461     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8462                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8463                            &context, targetsid, &size);
8464     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8465     ok(!lstrcmpA(patchcode, patch),
8466        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8467     ok(!lstrcmpA(targetprod, prodcode),
8468        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8469     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8470        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8471     ok(!lstrcmpA(targetsid, expectedsid),
8472        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8473     ok(size == lstrlenA(expectedsid),
8474        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8475
8476     /* same patch in multiple places, only one is enumerated */
8477     lstrcpyA(patchcode, "apple");
8478     lstrcpyA(targetprod, "banana");
8479     context = 0xdeadbeef;
8480     lstrcpyA(targetsid, "kiwi");
8481     size = MAX_PATH;
8482     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8483                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8484                            &context, targetsid, &size);
8485     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8486     ok(!lstrcmpA(patchcode, "apple"),
8487        "Expected patchcode to be unchanged, got %s\n", patchcode);
8488     ok(!lstrcmpA(targetprod, "banana"),
8489        "Expected targetprod to be unchanged, got %s\n", targetprod);
8490     ok(context == 0xdeadbeef,
8491        "Expected context to be unchanged, got %d\n", context);
8492     ok(!lstrcmpA(targetsid, "kiwi"),
8493        "Expected targetsid to be unchanged, got %s\n", targetsid);
8494     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8495
8496     RegDeleteValueA(hpatch, "State");
8497     RegDeleteKeyA(hpatch, "");
8498     RegCloseKey(hpatch);
8499     RegDeleteKeyA(udpatch, "");
8500     RegCloseKey(udpatch);
8501     RegDeleteKeyA(udprod, "");
8502     RegCloseKey(udprod);
8503     RegDeleteKeyA(userkey, "");
8504     RegCloseKey(userkey);
8505     RegDeleteValueA(patches, patch_squashed);
8506     RegDeleteValueA(patches, "Patches");
8507     RegDeleteKeyA(patches, "");
8508     RegCloseKey(patches);
8509     RegDeleteKeyA(prodkey, "");
8510     RegCloseKey(prodkey);
8511 }
8512
8513 static void test_MsiEnumPatchesEx_machine()
8514 {
8515     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8516     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8517     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8518     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8519     HKEY prodkey, patches, udprod, udpatch;
8520     HKEY hpatch;
8521     MSIINSTALLCONTEXT context;
8522     DWORD size, data;
8523     LONG res;
8524     UINT r;
8525
8526     create_test_guid(prodcode, prod_squashed);
8527     create_test_guid(patch, patch_squashed);
8528
8529     /* MSIPATCHSTATE_APPLIED */
8530
8531     lstrcpyA(patchcode, "apple");
8532     lstrcpyA(targetprod, "banana");
8533     context = 0xdeadbeef;
8534     lstrcpyA(targetsid, "kiwi");
8535     size = MAX_PATH;
8536     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8537                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8538                            &context, targetsid, &size);
8539     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8540     ok(!lstrcmpA(patchcode, "apple"),
8541        "Expected patchcode to be unchanged, got %s\n", patchcode);
8542     ok(!lstrcmpA(targetprod, "banana"),
8543        "Expected targetprod to be unchanged, got %s\n", targetprod);
8544     ok(context == 0xdeadbeef,
8545        "Expected context to be unchanged, got %d\n", context);
8546     ok(!lstrcmpA(targetsid, "kiwi"),
8547        "Expected targetsid to be unchanged, got %s\n", targetsid);
8548     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8549
8550     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8551     lstrcatA(keypath, prod_squashed);
8552
8553     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
8554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8555
8556     /* local product key exists */
8557     lstrcpyA(patchcode, "apple");
8558     lstrcpyA(targetprod, "banana");
8559     context = 0xdeadbeef;
8560     lstrcpyA(targetsid, "kiwi");
8561     size = MAX_PATH;
8562     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8563                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8564                            &context, targetsid, &size);
8565     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8566     ok(!lstrcmpA(patchcode, "apple"),
8567        "Expected patchcode to be unchanged, got %s\n", patchcode);
8568     ok(!lstrcmpA(targetprod, "banana"),
8569        "Expected targetprod to be unchanged, got %s\n", targetprod);
8570     ok(context == 0xdeadbeef,
8571        "Expected context to be unchanged, got %d\n", context);
8572     ok(!lstrcmpA(targetsid, "kiwi"),
8573        "Expected targetsid to be unchanged, got %s\n", targetsid);
8574     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8575
8576     res = RegCreateKeyA(prodkey, "Patches", &patches);
8577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8578
8579     /* Patches key exists */
8580     lstrcpyA(patchcode, "apple");
8581     lstrcpyA(targetprod, "banana");
8582     context = 0xdeadbeef;
8583     lstrcpyA(targetsid, "kiwi");
8584     size = MAX_PATH;
8585     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8586                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8587                            &context, targetsid, &size);
8588     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8589     ok(!lstrcmpA(patchcode, "apple"),
8590        "Expected patchcode to be unchanged, got %s\n", patchcode);
8591     ok(!lstrcmpA(targetprod, "banana"),
8592        "Expected targetprod to be unchanged, got %s\n", targetprod);
8593     ok(context == 0xdeadbeef,
8594        "Expected context to be unchanged, got %d\n", context);
8595     ok(!lstrcmpA(targetsid, "kiwi"),
8596        "Expected targetsid to be unchanged, got %s\n", targetsid);
8597     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8598
8599     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8600                          (const BYTE *)patch_squashed,
8601                          lstrlenA(patch_squashed) + 1);
8602     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8603
8604     /* Patches value exists, is not REG_MULTI_SZ */
8605     lstrcpyA(patchcode, "apple");
8606     lstrcpyA(targetprod, "banana");
8607     context = 0xdeadbeef;
8608     lstrcpyA(targetsid, "kiwi");
8609     size = MAX_PATH;
8610     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8611                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8612                            &context, targetsid, &size);
8613     ok(r == ERROR_BAD_CONFIGURATION,
8614        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8615     ok(!lstrcmpA(patchcode, "apple"),
8616        "Expected patchcode to be unchanged, got %s\n", patchcode);
8617     ok(!lstrcmpA(targetprod, "banana"),
8618        "Expected targetprod to be unchanged, got %s\n", targetprod);
8619     ok(context == 0xdeadbeef,
8620        "Expected context to be unchanged, got %d\n", context);
8621     ok(!lstrcmpA(targetsid, "kiwi"),
8622        "Expected targetsid to be unchanged, got %s\n", targetsid);
8623     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8624
8625     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8626                          (const BYTE *)"a\0b\0c\0\0", 7);
8627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8628
8629     /* Patches value exists, is not a squashed guid */
8630     lstrcpyA(patchcode, "apple");
8631     lstrcpyA(targetprod, "banana");
8632     context = 0xdeadbeef;
8633     lstrcpyA(targetsid, "kiwi");
8634     size = MAX_PATH;
8635     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8636                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8637                            &context, targetsid, &size);
8638     ok(r == ERROR_BAD_CONFIGURATION,
8639        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8640     ok(!lstrcmpA(patchcode, "apple"),
8641        "Expected patchcode to be unchanged, got %s\n", patchcode);
8642     ok(!lstrcmpA(targetprod, "banana"),
8643        "Expected targetprod to be unchanged, got %s\n", targetprod);
8644     ok(context == 0xdeadbeef,
8645        "Expected context to be unchanged, got %d\n", context);
8646     ok(!lstrcmpA(targetsid, "kiwi"),
8647        "Expected targetsid to be unchanged, got %s\n", targetsid);
8648     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8649
8650     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8651     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8652                          (const BYTE *)patch_squashed,
8653                          lstrlenA(patch_squashed) + 2);
8654     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8655
8656     /* Patches value exists */
8657     lstrcpyA(patchcode, "apple");
8658     lstrcpyA(targetprod, "banana");
8659     context = 0xdeadbeef;
8660     lstrcpyA(targetsid, "kiwi");
8661     size = MAX_PATH;
8662     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8663                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8664                            &context, targetsid, &size);
8665     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8666     ok(!lstrcmpA(patchcode, "apple"),
8667        "Expected patchcode to be unchanged, got %s\n", patchcode);
8668     ok(!lstrcmpA(targetprod, "banana"),
8669        "Expected targetprod to be unchanged, got %s\n", targetprod);
8670     ok(context == 0xdeadbeef,
8671        "Expected context to be unchanged, got %d\n", context);
8672     ok(!lstrcmpA(targetsid, "kiwi"),
8673        "Expected targetsid to be unchanged, got %s\n", targetsid);
8674     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8675
8676     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8677                          (const BYTE *)"whatever", 9);
8678     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8679
8680     /* patch code value exists */
8681     lstrcpyA(patchcode, "apple");
8682     lstrcpyA(targetprod, "banana");
8683     context = 0xdeadbeef;
8684     lstrcpyA(targetsid, "kiwi");
8685     size = MAX_PATH;
8686     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8687                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8688                            &context, targetsid, &size);
8689     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8690     ok(!lstrcmpA(patchcode, patch),
8691        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8692     ok(!lstrcmpA(targetprod, prodcode),
8693        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8694     ok(context == MSIINSTALLCONTEXT_MACHINE,
8695        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8696     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8697     ok(size == 0, "Expected 0, got %d\n", size);
8698
8699     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8700     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8701     lstrcatA(keypath, prod_squashed);
8702
8703     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8704     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8705
8706     /* local UserData product key exists */
8707     lstrcpyA(patchcode, "apple");
8708     lstrcpyA(targetprod, "banana");
8709     context = 0xdeadbeef;
8710     lstrcpyA(targetsid, "kiwi");
8711     size = MAX_PATH;
8712     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8713                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8714                            &context, targetsid, &size);
8715     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8716     ok(!lstrcmpA(patchcode, patch),
8717        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8718     ok(!lstrcmpA(targetprod, prodcode),
8719        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8720     ok(context == MSIINSTALLCONTEXT_MACHINE,
8721        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8722     ok(!lstrcmpA(targetsid, ""),
8723        "Expected \"\", got \"%s\"\n", targetsid);
8724     ok(size == 0, "Expected 0, got %d\n", size);
8725
8726     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8728
8729     /* local UserData Patches key exists */
8730     lstrcpyA(patchcode, "apple");
8731     lstrcpyA(targetprod, "banana");
8732     context = 0xdeadbeef;
8733     lstrcpyA(targetsid, "kiwi");
8734     size = MAX_PATH;
8735     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8736                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8737                            &context, targetsid, &size);
8738     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8739     ok(!lstrcmpA(patchcode, patch),
8740        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8741     ok(!lstrcmpA(targetprod, prodcode),
8742        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8743     ok(context == MSIINSTALLCONTEXT_MACHINE,
8744        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8745     ok(!lstrcmpA(targetsid, ""),
8746        "Expected \"\", got \"%s\"\n", targetsid);
8747     ok(size == 0, "Expected 0, got %d\n", size);
8748
8749     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8750     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8751
8752     /* local UserData Product patch key exists */
8753     lstrcpyA(patchcode, "apple");
8754     lstrcpyA(targetprod, "banana");
8755     context = 0xdeadbeef;
8756     lstrcpyA(targetsid, "kiwi");
8757     size = MAX_PATH;
8758     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8759                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8760                            &context, targetsid, &size);
8761     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8762     ok(!lstrcmpA(patchcode, "apple"),
8763        "Expected patchcode to be unchanged, got %s\n", patchcode);
8764     ok(!lstrcmpA(targetprod, "banana"),
8765        "Expected targetprod to be unchanged, got %s\n", targetprod);
8766     ok(context == 0xdeadbeef,
8767        "Expected context to be unchanged, got %d\n", context);
8768     ok(!lstrcmpA(targetsid, "kiwi"),
8769        "Expected targetsid to be unchanged, got %s\n", targetsid);
8770     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8771
8772     data = MSIPATCHSTATE_APPLIED;
8773     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8774                          (const BYTE *)&data, sizeof(DWORD));
8775     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8776
8777     /* State value exists */
8778     lstrcpyA(patchcode, "apple");
8779     lstrcpyA(targetprod, "banana");
8780     context = 0xdeadbeef;
8781     lstrcpyA(targetsid, "kiwi");
8782     size = MAX_PATH;
8783     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8784                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8785                            &context, targetsid, &size);
8786     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8787     ok(!lstrcmpA(patchcode, patch),
8788        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8789     ok(!lstrcmpA(targetprod, prodcode),
8790        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8791     ok(context == MSIINSTALLCONTEXT_MACHINE,
8792        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8793     ok(!lstrcmpA(targetsid, ""),
8794        "Expected \"\", got \"%s\"\n", targetsid);
8795     ok(size == 0, "Expected 0, got %d\n", size);
8796
8797     /* MSIPATCHSTATE_SUPERSEDED */
8798
8799     lstrcpyA(patchcode, "apple");
8800     lstrcpyA(targetprod, "banana");
8801     context = 0xdeadbeef;
8802     lstrcpyA(targetsid, "kiwi");
8803     size = MAX_PATH;
8804     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8805                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8806                            &context, targetsid, &size);
8807     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8808     ok(!lstrcmpA(patchcode, "apple"),
8809        "Expected patchcode to be unchanged, got %s\n", patchcode);
8810     ok(!lstrcmpA(targetprod, "banana"),
8811        "Expected targetprod to be unchanged, got %s\n", targetprod);
8812     ok(context == 0xdeadbeef,
8813        "Expected context to be unchanged, got %d\n", context);
8814     ok(!lstrcmpA(targetsid, "kiwi"),
8815        "Expected targetsid to be unchanged, got %s\n", targetsid);
8816     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8817
8818     data = MSIPATCHSTATE_SUPERSEDED;
8819     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8820                          (const BYTE *)&data, sizeof(DWORD));
8821     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8822
8823     /* State value is MSIPATCHSTATE_SUPERSEDED */
8824     lstrcpyA(patchcode, "apple");
8825     lstrcpyA(targetprod, "banana");
8826     context = 0xdeadbeef;
8827     lstrcpyA(targetsid, "kiwi");
8828     size = MAX_PATH;
8829     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8830                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8831                            &context, targetsid, &size);
8832     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8833     ok(!lstrcmpA(patchcode, patch),
8834        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8835     ok(!lstrcmpA(targetprod, prodcode),
8836        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8837     ok(context == MSIINSTALLCONTEXT_MACHINE,
8838        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8839     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8840     ok(size == 0, "Expected 0, got %d\n", size);
8841
8842     /* MSIPATCHSTATE_OBSOLETED */
8843
8844     lstrcpyA(patchcode, "apple");
8845     lstrcpyA(targetprod, "banana");
8846     context = 0xdeadbeef;
8847     lstrcpyA(targetsid, "kiwi");
8848     size = MAX_PATH;
8849     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8850                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8851                            &context, targetsid, &size);
8852     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8853     ok(!lstrcmpA(patchcode, "apple"),
8854        "Expected patchcode to be unchanged, got %s\n", patchcode);
8855     ok(!lstrcmpA(targetprod, "banana"),
8856        "Expected targetprod to be unchanged, got %s\n", targetprod);
8857     ok(context == 0xdeadbeef,
8858        "Expected context to be unchanged, got %d\n", context);
8859     ok(!lstrcmpA(targetsid, "kiwi"),
8860        "Expected targetsid to be unchanged, got %s\n", targetsid);
8861     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8862
8863     data = MSIPATCHSTATE_OBSOLETED;
8864     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8865                          (const BYTE *)&data, sizeof(DWORD));
8866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8867
8868     /* State value is obsoleted */
8869     lstrcpyA(patchcode, "apple");
8870     lstrcpyA(targetprod, "banana");
8871     context = 0xdeadbeef;
8872     lstrcpyA(targetsid, "kiwi");
8873     size = MAX_PATH;
8874     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8875                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8876                            &context, targetsid, &size);
8877     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8878     ok(!lstrcmpA(patchcode, patch),
8879        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8880     ok(!lstrcmpA(targetprod, prodcode),
8881        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8882     ok(context == MSIINSTALLCONTEXT_MACHINE,
8883        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8884     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8885     ok(size == 0, "Expected 0, got %d\n", size);
8886
8887     /* MSIPATCHSTATE_REGISTERED */
8888     /* FIXME */
8889
8890     /* MSIPATCHSTATE_ALL */
8891
8892     /* 1st */
8893     lstrcpyA(patchcode, "apple");
8894     lstrcpyA(targetprod, "banana");
8895     context = 0xdeadbeef;
8896     lstrcpyA(targetsid, "kiwi");
8897     size = MAX_PATH;
8898     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8899                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8900                            &context, targetsid, &size);
8901     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8902     ok(!lstrcmpA(patchcode, patch),
8903        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8904     ok(!lstrcmpA(targetprod, prodcode),
8905        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8906     ok(context == MSIINSTALLCONTEXT_MACHINE,
8907        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8908     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8909     ok(size == 0, "Expected 0, got %d\n", size);
8910
8911     /* same patch in multiple places, only one is enumerated */
8912     lstrcpyA(patchcode, "apple");
8913     lstrcpyA(targetprod, "banana");
8914     context = 0xdeadbeef;
8915     lstrcpyA(targetsid, "kiwi");
8916     size = MAX_PATH;
8917     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8918                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8919                            &context, targetsid, &size);
8920     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8921     ok(!lstrcmpA(patchcode, "apple"),
8922        "Expected patchcode to be unchanged, got %s\n", patchcode);
8923     ok(!lstrcmpA(targetprod, "banana"),
8924        "Expected targetprod to be unchanged, got %s\n", targetprod);
8925     ok(context == 0xdeadbeef,
8926        "Expected context to be unchanged, got %d\n", context);
8927     ok(!lstrcmpA(targetsid, "kiwi"),
8928        "Expected targetsid to be unchanged, got %s\n", targetsid);
8929     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8930
8931     RegDeleteValueA(patches, patch_squashed);
8932     RegDeleteValueA(patches, "Patches");
8933     RegDeleteKeyA(patches, "");
8934     RegCloseKey(patches);
8935     RegDeleteValueA(hpatch, "State");
8936     RegDeleteKeyA(hpatch, "");
8937     RegCloseKey(hpatch);
8938     RegDeleteKeyA(udpatch, "");
8939     RegCloseKey(udpatch);
8940     RegDeleteKeyA(udprod, "");
8941     RegCloseKey(udprod);
8942     RegDeleteKeyA(prodkey, "");
8943     RegCloseKey(prodkey);
8944 }
8945
8946 static void test_MsiEnumPatchesEx(void)
8947 {
8948     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8949     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8950     CHAR patchcode[MAX_PATH];
8951     MSIINSTALLCONTEXT context;
8952     LPSTR usersid;
8953     DWORD size;
8954     UINT r;
8955
8956     if (!pMsiEnumPatchesExA)
8957     {
8958         win_skip("MsiEnumPatchesExA not implemented\n");
8959         return;
8960     }
8961
8962     create_test_guid(prodcode, prod_squashed);
8963     get_user_sid(&usersid);
8964
8965     /* empty szProductCode */
8966     lstrcpyA(patchcode, "apple");
8967     lstrcpyA(targetprod, "banana");
8968     context = 0xdeadbeef;
8969     lstrcpyA(targetsid, "kiwi");
8970     size = MAX_PATH;
8971     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8972                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
8973                            targetsid, &size);
8974     ok(r == ERROR_INVALID_PARAMETER,
8975        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8976     ok(!lstrcmpA(patchcode, "apple"),
8977        "Expected patchcode to be unchanged, got %s\n", patchcode);
8978     ok(!lstrcmpA(targetprod, "banana"),
8979        "Expected targetprod to be unchanged, got %s\n", targetprod);
8980     ok(context == 0xdeadbeef,
8981        "Expected context to be unchanged, got %d\n", context);
8982     ok(!lstrcmpA(targetsid, "kiwi"),
8983        "Expected targetsid to be unchanged, got %s\n", targetsid);
8984     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8985
8986     /* garbage szProductCode */
8987     lstrcpyA(patchcode, "apple");
8988     lstrcpyA(targetprod, "banana");
8989     context = 0xdeadbeef;
8990     lstrcpyA(targetsid, "kiwi");
8991     size = MAX_PATH;
8992     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8993                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
8994                            targetsid, &size);
8995     ok(r == ERROR_INVALID_PARAMETER,
8996        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8997     ok(!lstrcmpA(patchcode, "apple"),
8998        "Expected patchcode to be unchanged, got %s\n", patchcode);
8999     ok(!lstrcmpA(targetprod, "banana"),
9000        "Expected targetprod to be unchanged, got %s\n", targetprod);
9001     ok(context == 0xdeadbeef,
9002        "Expected context to be unchanged, got %d\n", context);
9003     ok(!lstrcmpA(targetsid, "kiwi"),
9004        "Expected targetsid to be unchanged, got %s\n", targetsid);
9005     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9006
9007     /* guid without brackets */
9008     lstrcpyA(patchcode, "apple");
9009     lstrcpyA(targetprod, "banana");
9010     context = 0xdeadbeef;
9011     lstrcpyA(targetsid, "kiwi");
9012     size = MAX_PATH;
9013     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9014                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9015                            0, patchcode, targetprod, &context,
9016                            targetsid, &size);
9017     ok(r == ERROR_INVALID_PARAMETER,
9018        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9019     ok(!lstrcmpA(patchcode, "apple"),
9020        "Expected patchcode to be unchanged, got %s\n", patchcode);
9021     ok(!lstrcmpA(targetprod, "banana"),
9022        "Expected targetprod to be unchanged, got %s\n", targetprod);
9023     ok(context == 0xdeadbeef,
9024        "Expected context to be unchanged, got %d\n", context);
9025     ok(!lstrcmpA(targetsid, "kiwi"),
9026        "Expected targetsid to be unchanged, got %s\n", targetsid);
9027     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9028
9029     /* guid with brackets */
9030     lstrcpyA(patchcode, "apple");
9031     lstrcpyA(targetprod, "banana");
9032     context = 0xdeadbeef;
9033     lstrcpyA(targetsid, "kiwi");
9034     size = MAX_PATH;
9035     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9036                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9037                            0, patchcode, targetprod, &context,
9038                            targetsid, &size);
9039     ok(r == ERROR_NO_MORE_ITEMS,
9040        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9041     ok(!lstrcmpA(patchcode, "apple"),
9042        "Expected patchcode to be unchanged, got %s\n", patchcode);
9043     ok(!lstrcmpA(targetprod, "banana"),
9044        "Expected targetprod to be unchanged, got %s\n", targetprod);
9045     ok(context == 0xdeadbeef,
9046        "Expected context to be unchanged, got %d\n", context);
9047     ok(!lstrcmpA(targetsid, "kiwi"),
9048        "Expected targetsid to be unchanged, got %s\n", targetsid);
9049     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9050
9051     /* szUserSid is S-1-5-18 */
9052     lstrcpyA(patchcode, "apple");
9053     lstrcpyA(targetprod, "banana");
9054     context = 0xdeadbeef;
9055     lstrcpyA(targetsid, "kiwi");
9056     size = MAX_PATH;
9057     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9058                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9059                            0, patchcode, targetprod, &context,
9060                            targetsid, &size);
9061     ok(r == ERROR_INVALID_PARAMETER,
9062        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9063     ok(!lstrcmpA(patchcode, "apple"),
9064        "Expected patchcode to be unchanged, got %s\n", patchcode);
9065     ok(!lstrcmpA(targetprod, "banana"),
9066        "Expected targetprod to be unchanged, got %s\n", targetprod);
9067     ok(context == 0xdeadbeef,
9068        "Expected context to be unchanged, got %d\n", context);
9069     ok(!lstrcmpA(targetsid, "kiwi"),
9070        "Expected targetsid to be unchanged, got %s\n", targetsid);
9071     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9072
9073     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9074     lstrcpyA(patchcode, "apple");
9075     lstrcpyA(targetprod, "banana");
9076     context = 0xdeadbeef;
9077     lstrcpyA(targetsid, "kiwi");
9078     size = MAX_PATH;
9079     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9080                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9081                            &context, targetsid, &size);
9082     ok(r == ERROR_INVALID_PARAMETER,
9083        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9084     ok(!lstrcmpA(patchcode, "apple"),
9085        "Expected patchcode to be unchanged, got %s\n", patchcode);
9086     ok(!lstrcmpA(targetprod, "banana"),
9087        "Expected targetprod to be unchanged, got %s\n", targetprod);
9088     ok(context == 0xdeadbeef,
9089        "Expected context to be unchanged, got %d\n", context);
9090     ok(!lstrcmpA(targetsid, "kiwi"),
9091        "Expected targetsid to be unchanged, got %s\n", targetsid);
9092     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9093
9094     /* dwContext is out of bounds */
9095     lstrcpyA(patchcode, "apple");
9096     lstrcpyA(targetprod, "banana");
9097     context = 0xdeadbeef;
9098     lstrcpyA(targetsid, "kiwi");
9099     size = MAX_PATH;
9100     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9101                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9102                            &context, targetsid, &size);
9103     ok(r == ERROR_INVALID_PARAMETER,
9104        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9105     ok(!lstrcmpA(patchcode, "apple"),
9106        "Expected patchcode to be unchanged, got %s\n", patchcode);
9107     ok(!lstrcmpA(targetprod, "banana"),
9108        "Expected targetprod to be unchanged, got %s\n", targetprod);
9109     ok(context == 0xdeadbeef,
9110        "Expected context to be unchanged, got %d\n", context);
9111     ok(!lstrcmpA(targetsid, "kiwi"),
9112        "Expected targetsid to be unchanged, got %s\n", targetsid);
9113     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9114
9115     /* dwContext is out of bounds */
9116     lstrcpyA(patchcode, "apple");
9117     lstrcpyA(targetprod, "banana");
9118     context = 0xdeadbeef;
9119     lstrcpyA(targetsid, "kiwi");
9120     size = MAX_PATH;
9121     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9122                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9123                            &context, targetsid, &size);
9124     ok(r == ERROR_INVALID_PARAMETER,
9125        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9126     ok(!lstrcmpA(patchcode, "apple"),
9127        "Expected patchcode to be unchanged, got %s\n", patchcode);
9128     ok(!lstrcmpA(targetprod, "banana"),
9129        "Expected targetprod to be unchanged, got %s\n", targetprod);
9130     ok(context == 0xdeadbeef,
9131        "Expected context to be unchanged, got %d\n", context);
9132     ok(!lstrcmpA(targetsid, "kiwi"),
9133        "Expected targetsid to be unchanged, got %s\n", targetsid);
9134     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9135
9136     /* dwFilter is out of bounds */
9137     lstrcpyA(patchcode, "apple");
9138     lstrcpyA(targetprod, "banana");
9139     context = 0xdeadbeef;
9140     lstrcpyA(targetsid, "kiwi");
9141     size = MAX_PATH;
9142     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9143                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9144                            &context, targetsid, &size);
9145     ok(r == ERROR_INVALID_PARAMETER,
9146        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9147     ok(!lstrcmpA(patchcode, "apple"),
9148        "Expected patchcode to be unchanged, got %s\n", patchcode);
9149     ok(!lstrcmpA(targetprod, "banana"),
9150        "Expected targetprod to be unchanged, got %s\n", targetprod);
9151     ok(context == 0xdeadbeef,
9152        "Expected context to be unchanged, got %d\n", context);
9153     ok(!lstrcmpA(targetsid, "kiwi"),
9154        "Expected targetsid to be unchanged, got %s\n", targetsid);
9155     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9156
9157     /* dwFilter is out of bounds */
9158     lstrcpyA(patchcode, "apple");
9159     lstrcpyA(targetprod, "banana");
9160     context = 0xdeadbeef;
9161     lstrcpyA(targetsid, "kiwi");
9162     size = MAX_PATH;
9163     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9164                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9165                            &context, targetsid, &size);
9166     ok(r == ERROR_INVALID_PARAMETER,
9167        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9168     ok(!lstrcmpA(patchcode, "apple"),
9169        "Expected patchcode to be unchanged, got %s\n", patchcode);
9170     ok(!lstrcmpA(targetprod, "banana"),
9171        "Expected targetprod to be unchanged, got %s\n", targetprod);
9172     ok(context == 0xdeadbeef,
9173        "Expected context to be unchanged, got %d\n", context);
9174     ok(!lstrcmpA(targetsid, "kiwi"),
9175        "Expected targetsid to be unchanged, got %s\n", targetsid);
9176     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9177
9178     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9179     lstrcpyA(patchcode, "apple");
9180     lstrcpyA(targetprod, "banana");
9181     context = 0xdeadbeef;
9182     lstrcpyA(targetsid, "kiwi");
9183     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9184                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9185                            &context, targetsid, NULL);
9186     ok(r == ERROR_INVALID_PARAMETER,
9187        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9188     ok(!lstrcmpA(patchcode, "apple"),
9189        "Expected patchcode to be unchanged, got %s\n", patchcode);
9190     ok(!lstrcmpA(targetprod, "banana"),
9191        "Expected targetprod to be unchanged, got %s\n", targetprod);
9192     ok(context == 0xdeadbeef,
9193        "Expected context to be unchanged, got %d\n", context);
9194     ok(!lstrcmpA(targetsid, "kiwi"),
9195        "Expected targetsid to be unchanged, got %s\n", targetsid);
9196
9197     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9198     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9199     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9200     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9201     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9202     /* FIXME: Successfully test userunmanaged with a different user */
9203     test_MsiEnumPatchesEx_machine();
9204 }
9205
9206 static void test_MsiEnumPatches(void)
9207 {
9208     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9209     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9210     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9211     CHAR transforms[MAX_PATH];
9212     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9213     HKEY prodkey, patches, udprod;
9214     HKEY userkey, hpatch, udpatch;
9215     DWORD size, data;
9216     LPSTR usersid;
9217     LONG res;
9218     UINT r;
9219
9220     create_test_guid(prodcode, prod_squashed);
9221     create_test_guid(patchcode, patch_squashed);
9222     get_user_sid(&usersid);
9223
9224     /* NULL szProduct */
9225     size = MAX_PATH;
9226     lstrcpyA(patch, "apple");
9227     lstrcpyA(transforms, "banana");
9228     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9229     ok(r == ERROR_INVALID_PARAMETER,
9230        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9231     ok(!lstrcmpA(patch, "apple"),
9232        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9233     ok(!lstrcmpA(transforms, "banana"),
9234        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9235     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9236
9237     /* empty szProduct */
9238     size = MAX_PATH;
9239     lstrcpyA(patch, "apple");
9240     lstrcpyA(transforms, "banana");
9241     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9242     ok(r == ERROR_INVALID_PARAMETER,
9243        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9244     ok(!lstrcmpA(patch, "apple"),
9245        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9246     ok(!lstrcmpA(transforms, "banana"),
9247        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9248     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9249
9250     /* garbage szProduct */
9251     size = MAX_PATH;
9252     lstrcpyA(patch, "apple");
9253     lstrcpyA(transforms, "banana");
9254     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9255     ok(r == ERROR_INVALID_PARAMETER,
9256        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9257     ok(!lstrcmpA(patch, "apple"),
9258        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9259     ok(!lstrcmpA(transforms, "banana"),
9260        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9261     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9262
9263     /* guid without brackets */
9264     size = MAX_PATH;
9265     lstrcpyA(patch, "apple");
9266     lstrcpyA(transforms, "banana");
9267     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9268                         transforms, &size);
9269     ok(r == ERROR_INVALID_PARAMETER,
9270        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9271     ok(!lstrcmpA(patch, "apple"),
9272        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9273     ok(!lstrcmpA(transforms, "banana"),
9274        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9275     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9276
9277     /* guid with brackets */
9278     size = MAX_PATH;
9279     lstrcpyA(patch, "apple");
9280     lstrcpyA(transforms, "banana");
9281     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9282                         transforms, &size);
9283     ok(r == ERROR_UNKNOWN_PRODUCT,
9284        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9285     ok(!lstrcmpA(patch, "apple"),
9286        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9287     ok(!lstrcmpA(transforms, "banana"),
9288        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9289     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9290
9291     /* same length as guid, but random */
9292     size = MAX_PATH;
9293     lstrcpyA(patch, "apple");
9294     lstrcpyA(transforms, "banana");
9295     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9296                         transforms, &size);
9297     ok(r == ERROR_INVALID_PARAMETER,
9298        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9299     ok(!lstrcmpA(patch, "apple"),
9300        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9301     ok(!lstrcmpA(transforms, "banana"),
9302        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9303     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9304
9305     /* MSIINSTALLCONTEXT_USERMANAGED */
9306
9307     size = MAX_PATH;
9308     lstrcpyA(patch, "apple");
9309     lstrcpyA(transforms, "banana");
9310     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9311     ok(r == ERROR_UNKNOWN_PRODUCT,
9312        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9313     ok(!lstrcmpA(patch, "apple"),
9314        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9315     ok(!lstrcmpA(transforms, "banana"),
9316        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9317     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9318
9319     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9320     lstrcatA(keypath, usersid);
9321     lstrcatA(keypath, "\\Installer\\Products\\");
9322     lstrcatA(keypath, prod_squashed);
9323
9324     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9326
9327     /* managed product key exists */
9328     size = MAX_PATH;
9329     lstrcpyA(patch, "apple");
9330     lstrcpyA(transforms, "banana");
9331     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9332     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9333     ok(!lstrcmpA(patch, "apple"),
9334        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9335     ok(!lstrcmpA(transforms, "banana"),
9336        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9337     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9338
9339     res = RegCreateKeyA(prodkey, "Patches", &patches);
9340     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9341
9342     /* patches key exists */
9343     size = MAX_PATH;
9344     lstrcpyA(patch, "apple");
9345     lstrcpyA(transforms, "banana");
9346     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9347     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9348     ok(!lstrcmpA(patch, "apple"),
9349        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9350     ok(!lstrcmpA(transforms, "banana"),
9351        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9352     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9353
9354     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9355                          (const BYTE *)patch_squashed,
9356                          lstrlenA(patch_squashed) + 1);
9357     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9358
9359     /* Patches value exists, is not REG_MULTI_SZ */
9360     size = MAX_PATH;
9361     lstrcpyA(patch, "apple");
9362     lstrcpyA(transforms, "banana");
9363     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9364     ok(r == ERROR_BAD_CONFIGURATION,
9365        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9366     ok(!lstrcmpA(patch, "apple"),
9367        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9368     ok(!lstrcmpA(transforms, "banana"),
9369        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9370     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9371
9372     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9373                          (const BYTE *)"a\0b\0c\0\0", 7);
9374     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9375
9376     /* Patches value exists, is not a squashed guid */
9377     size = MAX_PATH;
9378     lstrcpyA(patch, "apple");
9379     lstrcpyA(transforms, "banana");
9380     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9381     ok(r == ERROR_BAD_CONFIGURATION,
9382        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9383     ok(!lstrcmpA(patch, "apple"),
9384        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9385     ok(!lstrcmpA(transforms, "banana"),
9386        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9387     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9388
9389     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9390     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9391                          (const BYTE *)patch_squashed,
9392                          lstrlenA(patch_squashed) + 2);
9393     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9394
9395     /* Patches value exists */
9396     size = MAX_PATH;
9397     lstrcpyA(patch, "apple");
9398     lstrcpyA(transforms, "banana");
9399     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9400     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9401     ok(!lstrcmpA(patch, "apple"),
9402        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9403     ok(!lstrcmpA(transforms, "banana"),
9404        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9405     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9406
9407     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9408                          (const BYTE *)"whatever", 9);
9409     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9410
9411     /* patch squashed value exists */
9412     size = MAX_PATH;
9413     lstrcpyA(patch, "apple");
9414     lstrcpyA(transforms, "banana");
9415     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9416     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9417     ok(!lstrcmpA(patch, patchcode),
9418        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9419     ok(!lstrcmpA(transforms, "whatever"),
9420        "Expected \"whatever\", got \"%s\"\n", transforms);
9421     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9422
9423     /* lpPatchBuf is NULL */
9424     size = MAX_PATH;
9425     lstrcpyA(transforms, "banana");
9426     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9427     ok(r == ERROR_INVALID_PARAMETER,
9428        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9429     ok(!lstrcmpA(transforms, "banana"),
9430        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9431     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9432
9433     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9434     size = MAX_PATH;
9435     lstrcpyA(patch, "apple");
9436     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9437     ok(r == ERROR_INVALID_PARAMETER,
9438        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9439     ok(!lstrcmpA(patch, "apple"),
9440        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9441     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9442
9443     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9444     lstrcpyA(patch, "apple");
9445     lstrcpyA(transforms, "banana");
9446     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
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(!lstrcmpA(transforms, "banana"),
9452        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9453
9454     /* pcchTransformsBuf is too small */
9455     size = 6;
9456     lstrcpyA(patch, "apple");
9457     lstrcpyA(transforms, "banana");
9458     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9459     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9460     ok(!lstrcmpA(patch, patchcode),
9461        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9462     ok(!lstrcmpA(transforms, "whate"),
9463        "Expected \"whate\", got \"%s\"\n", transforms);
9464     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
9465
9466     /* increase the index */
9467     size = MAX_PATH;
9468     lstrcpyA(patch, "apple");
9469     lstrcpyA(transforms, "banana");
9470     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9471     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9472     ok(!lstrcmpA(patch, "apple"),
9473        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9474     ok(!lstrcmpA(transforms, "banana"),
9475        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9476     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9477
9478     /* increase again */
9479     size = MAX_PATH;
9480     lstrcpyA(patch, "apple");
9481     lstrcpyA(transforms, "banana");
9482     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9483     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9484     ok(!lstrcmpA(patch, "apple"),
9485        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9486     ok(!lstrcmpA(transforms, "banana"),
9487        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9488     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9489
9490     RegDeleteValueA(patches, "Patches");
9491     RegDeleteKeyA(patches, "");
9492     RegCloseKey(patches);
9493     RegDeleteKeyA(prodkey, "");
9494     RegCloseKey(prodkey);
9495
9496     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9497
9498     size = MAX_PATH;
9499     lstrcpyA(patch, "apple");
9500     lstrcpyA(transforms, "banana");
9501     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9502     ok(r == ERROR_UNKNOWN_PRODUCT,
9503        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9504     ok(!lstrcmpA(patch, "apple"),
9505        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9506     ok(!lstrcmpA(transforms, "banana"),
9507        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9508     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9509
9510     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9511     lstrcatA(keypath, prod_squashed);
9512
9513     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9514     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9515
9516     /* current user product key exists */
9517     size = MAX_PATH;
9518     lstrcpyA(patch, "apple");
9519     lstrcpyA(transforms, "banana");
9520     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9521     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9522     ok(!lstrcmpA(patch, "apple"),
9523        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9524     ok(!lstrcmpA(transforms, "banana"),
9525        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9526     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9527
9528     res = RegCreateKeyA(prodkey, "Patches", &patches);
9529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9530
9531     /* Patches key exists */
9532     size = MAX_PATH;
9533     lstrcpyA(patch, "apple");
9534     lstrcpyA(transforms, "banana");
9535     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9536     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9537     ok(!lstrcmpA(patch, "apple"),
9538        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9539     ok(!lstrcmpA(transforms, "banana"),
9540        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9541     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9542
9543     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9544                          (const BYTE *)patch_squashed,
9545                          lstrlenA(patch_squashed) + 1);
9546     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9547
9548     /* Patches value exists, is not REG_MULTI_SZ */
9549     size = MAX_PATH;
9550     lstrcpyA(patch, "apple");
9551     lstrcpyA(transforms, "banana");
9552     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9553     ok(r == ERROR_BAD_CONFIGURATION,
9554        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9555     ok(!lstrcmpA(patch, "apple"),
9556        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9557     ok(!lstrcmpA(transforms, "banana"),
9558        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9559     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9560
9561     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9562                          (const BYTE *)"a\0b\0c\0\0", 7);
9563     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9564
9565     /* Patches value exists, is not a squashed guid */
9566     size = MAX_PATH;
9567     lstrcpyA(patch, "apple");
9568     lstrcpyA(transforms, "banana");
9569     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9570     ok(r == ERROR_BAD_CONFIGURATION,
9571        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9572     ok(!lstrcmpA(patch, "apple"),
9573        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9574     ok(!lstrcmpA(transforms, "banana"),
9575        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9576     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9577
9578     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9579     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9580                          (const BYTE *)patch_squashed,
9581                          lstrlenA(patch_squashed) + 2);
9582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9583
9584     /* Patches value exists */
9585     size = MAX_PATH;
9586     lstrcpyA(patch, "apple");
9587     lstrcpyA(transforms, "banana");
9588     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9589     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9590     ok(!lstrcmpA(patch, "apple"),
9591        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9592     ok(!lstrcmpA(transforms, "banana"),
9593        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9594     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9595
9596     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9597                          (const BYTE *)"whatever", 9);
9598     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9599
9600     /* patch code value exists */
9601     size = MAX_PATH;
9602     lstrcpyA(patch, "apple");
9603     lstrcpyA(transforms, "banana");
9604     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9605     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9606     ok(!lstrcmpA(patch, "apple"),
9607        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9608     ok(!lstrcmpA(transforms, "banana"),
9609        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9610     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9611
9612     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9613     lstrcatA(keypath, usersid);
9614     lstrcatA(keypath, "\\Patches\\");
9615     lstrcatA(keypath, patch_squashed);
9616
9617     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
9618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9619
9620     /* userdata patch key exists */
9621     size = MAX_PATH;
9622     lstrcpyA(patch, "apple");
9623     lstrcpyA(transforms, "banana");
9624     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9625     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9626     ok(!lstrcmpA(patch, patchcode),
9627        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9628     ok(!lstrcmpA(transforms, "whatever"),
9629        "Expected \"whatever\", got \"%s\"\n", transforms);
9630     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9631
9632     RegDeleteKeyA(userkey, "");
9633     RegCloseKey(userkey);
9634     RegDeleteValueA(patches, patch_squashed);
9635     RegDeleteValueA(patches, "Patches");
9636     RegDeleteKeyA(patches, "");
9637     RegCloseKey(patches);
9638     RegDeleteKeyA(prodkey, "");
9639     RegCloseKey(prodkey);
9640
9641     /* MSIINSTALLCONTEXT_MACHINE */
9642
9643     size = MAX_PATH;
9644     lstrcpyA(patch, "apple");
9645     lstrcpyA(transforms, "banana");
9646     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9647     ok(r == ERROR_UNKNOWN_PRODUCT,
9648        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9649     ok(!lstrcmpA(patch, "apple"),
9650        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9651     ok(!lstrcmpA(transforms, "banana"),
9652        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9653     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9654
9655     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9656     lstrcatA(keypath, prod_squashed);
9657
9658     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9659     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9660
9661     /* local product key exists */
9662     size = MAX_PATH;
9663     lstrcpyA(patch, "apple");
9664     lstrcpyA(transforms, "banana");
9665     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9666     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9667     ok(!lstrcmpA(patch, "apple"),
9668        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9669     ok(!lstrcmpA(transforms, "banana"),
9670        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9671     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9672
9673     res = RegCreateKeyA(prodkey, "Patches", &patches);
9674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9675
9676     /* Patches key exists */
9677     size = MAX_PATH;
9678     lstrcpyA(patch, "apple");
9679     lstrcpyA(transforms, "banana");
9680     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9681     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9682     ok(!lstrcmpA(patch, "apple"),
9683        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9684     ok(!lstrcmpA(transforms, "banana"),
9685        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9686     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9687
9688     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9689                          (const BYTE *)patch_squashed,
9690                          lstrlenA(patch_squashed) + 1);
9691     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9692
9693     /* Patches value exists, is not REG_MULTI_SZ */
9694     size = MAX_PATH;
9695     lstrcpyA(patch, "apple");
9696     lstrcpyA(transforms, "banana");
9697     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9698     ok(r == ERROR_BAD_CONFIGURATION,
9699        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9700     ok(!lstrcmpA(patch, "apple"),
9701        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9702     ok(!lstrcmpA(transforms, "banana"),
9703        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9704     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9705
9706     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9707                          (const BYTE *)"a\0b\0c\0\0", 7);
9708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9709
9710     /* Patches value exists, is not a squashed guid */
9711     size = MAX_PATH;
9712     lstrcpyA(patch, "apple");
9713     lstrcpyA(transforms, "banana");
9714     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9715     ok(r == ERROR_BAD_CONFIGURATION,
9716        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9717     ok(!lstrcmpA(patch, "apple"),
9718        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9719     ok(!lstrcmpA(transforms, "banana"),
9720        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9721     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9722
9723     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9724     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9725                          (const BYTE *)patch_squashed,
9726                          lstrlenA(patch_squashed) + 2);
9727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9728
9729     /* Patches value exists */
9730     size = MAX_PATH;
9731     lstrcpyA(patch, "apple");
9732     lstrcpyA(transforms, "banana");
9733     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9734     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9735     ok(!lstrcmpA(patch, "apple"),
9736        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9737     ok(!lstrcmpA(transforms, "banana"),
9738        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9739     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9740
9741     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9742                          (const BYTE *)"whatever", 9);
9743     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9744
9745     /* patch code value exists */
9746     size = MAX_PATH;
9747     lstrcpyA(patch, "apple");
9748     lstrcpyA(transforms, "banana");
9749     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9750     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9751     ok(!lstrcmpA(patch, patchcode),
9752        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9753     ok(!lstrcmpA(transforms, "whatever"),
9754        "Expected \"whatever\", got \"%s\"\n", transforms);
9755     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9756
9757     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9758     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9759     lstrcatA(keypath, prod_squashed);
9760
9761     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9762     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9763
9764     /* local UserData product key exists */
9765     size = MAX_PATH;
9766     lstrcpyA(patch, "apple");
9767     lstrcpyA(transforms, "banana");
9768     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9769     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9770     ok(!lstrcmpA(patch, patchcode),
9771        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9772     ok(!lstrcmpA(transforms, "whatever"),
9773        "Expected \"whatever\", got \"%s\"\n", transforms);
9774     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9775
9776     res = RegCreateKeyA(udprod, "Patches", &udpatch);
9777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9778
9779     /* local UserData Patches key exists */
9780     size = MAX_PATH;
9781     lstrcpyA(patch, "apple");
9782     lstrcpyA(transforms, "banana");
9783     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9784     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9785     ok(!lstrcmpA(patch, patchcode),
9786        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9787     ok(!lstrcmpA(transforms, "whatever"),
9788        "Expected \"whatever\", got \"%s\"\n", transforms);
9789     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9790
9791     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
9792     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9793
9794     /* local UserData Product patch key exists */
9795     size = MAX_PATH;
9796     lstrcpyA(patch, "apple");
9797     lstrcpyA(transforms, "banana");
9798     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9799     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9800     ok(!lstrcmpA(patch, "apple"),
9801        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9802     ok(!lstrcmpA(transforms, "banana"),
9803        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9804     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9805
9806     data = MSIPATCHSTATE_APPLIED;
9807     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9808                          (const BYTE *)&data, sizeof(DWORD));
9809     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9810
9811     /* State value exists */
9812     size = MAX_PATH;
9813     lstrcpyA(patch, "apple");
9814     lstrcpyA(transforms, "banana");
9815     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9816     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9817     ok(!lstrcmpA(patch, patchcode),
9818        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9819     ok(!lstrcmpA(transforms, "whatever"),
9820        "Expected \"whatever\", got \"%s\"\n", transforms);
9821     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9822
9823     /* now duplicate some of the tests for the W version */
9824
9825     /* pcchTransformsBuf is too small */
9826     size = 6;
9827     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
9828     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9829     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9830     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9831     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9832     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9833     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
9834     ok(!lstrcmpA(patch, patchcode),
9835        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9836     ok(!lstrcmpA(transforms, "whate"),
9837        "Expected \"whate\", got \"%s\"\n", transforms);
9838     ok(size == 8, "Expected 8, got %d\n", size);
9839
9840     /* patch code value exists */
9841     size = MAX_PATH;
9842     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9843     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9844     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9845     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9846     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9847     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
9848     ok(!lstrcmpA(patch, patchcode),
9849        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9850     ok(!lstrcmpA(transforms, "whatever"),
9851        "Expected \"whatever\", got \"%s\"\n", transforms);
9852     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9853
9854     RegDeleteValueA(patches, patch_squashed);
9855     RegDeleteValueA(patches, "Patches");
9856     RegDeleteKeyA(patches, "");
9857     RegCloseKey(patches);
9858     RegDeleteValueA(hpatch, "State");
9859     RegDeleteKeyA(hpatch, "");
9860     RegCloseKey(hpatch);
9861     RegDeleteKeyA(udpatch, "");
9862     RegCloseKey(udpatch);
9863     RegDeleteKeyA(udprod, "");
9864     RegCloseKey(udprod);
9865     RegDeleteKeyA(prodkey, "");
9866     RegCloseKey(prodkey);
9867 }
9868
9869 static void test_MsiGetPatchInfoEx(void)
9870 {
9871     CHAR keypath[MAX_PATH], val[MAX_PATH];
9872     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9873     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9874     HKEY prodkey, patches, udprod, props;
9875     HKEY hpatch, udpatch, prodpatches;
9876     LPSTR usersid;
9877     DWORD size;
9878     LONG res;
9879     UINT r;
9880
9881     if (!pMsiGetPatchInfoExA)
9882     {
9883         win_skip("MsiGetPatchInfoEx not implemented\n");
9884         return;
9885     }
9886
9887     create_test_guid(prodcode, prod_squashed);
9888     create_test_guid(patchcode, patch_squashed);
9889     get_user_sid(&usersid);
9890
9891     /* NULL szPatchCode */
9892     lstrcpyA(val, "apple");
9893     size = MAX_PATH;
9894     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9895                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9896     ok(r == ERROR_INVALID_PARAMETER,
9897        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9898     ok(!lstrcmpA(val, "apple"),
9899        "Expected val to be unchanged, got \"%s\"\n", val);
9900     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9901
9902     /* empty szPatchCode */
9903     size = MAX_PATH;
9904     lstrcpyA(val, "apple");
9905     r = pMsiGetPatchInfoExA("", 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     /* garbage szPatchCode */
9914     size = MAX_PATH;
9915     lstrcpyA(val, "apple");
9916     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
9917                             MSIINSTALLCONTEXT_USERMANAGED,
9918                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9919     ok(r == ERROR_INVALID_PARAMETER,
9920        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9921     ok(!lstrcmpA(val, "apple"),
9922        "Expected val to be unchanged, got \"%s\"\n", val);
9923     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9924
9925     /* guid without brackets */
9926     size = MAX_PATH;
9927     lstrcpyA(val, "apple");
9928     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
9929                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9930                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9931     ok(r == ERROR_INVALID_PARAMETER,
9932        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9933     ok(!lstrcmpA(val, "apple"),
9934        "Expected val to be unchanged, got \"%s\"\n", val);
9935     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9936
9937     /* guid with brackets */
9938     size = MAX_PATH;
9939     lstrcpyA(val, "apple");
9940     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
9941                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9942                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9943     ok(r == ERROR_UNKNOWN_PRODUCT,
9944        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9945     ok(!lstrcmpA(val, "apple"),
9946        "Expected val to be unchanged, got \"%s\"\n", val);
9947     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9948
9949     /* same length as guid, but random */
9950     size = MAX_PATH;
9951     lstrcpyA(val, "apple");
9952     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
9953                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9954                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9955     ok(r == ERROR_INVALID_PARAMETER,
9956        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9957     ok(!lstrcmpA(val, "apple"),
9958        "Expected val to be unchanged, got \"%s\"\n", val);
9959     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9960
9961     /* NULL szProductCode */
9962     lstrcpyA(val, "apple");
9963     size = MAX_PATH;
9964     r = pMsiGetPatchInfoExA(patchcode, NULL, 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     /* empty szProductCode */
9973     size = MAX_PATH;
9974     lstrcpyA(val, "apple");
9975     r = pMsiGetPatchInfoExA(patchcode, "", 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     /* garbage szProductCode */
9984     size = MAX_PATH;
9985     lstrcpyA(val, "apple");
9986     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
9987                             MSIINSTALLCONTEXT_USERMANAGED,
9988                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9989     ok(r == ERROR_INVALID_PARAMETER,
9990        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9991     ok(!lstrcmpA(val, "apple"),
9992        "Expected val to be unchanged, got \"%s\"\n", val);
9993     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9994
9995     /* guid without brackets */
9996     size = MAX_PATH;
9997     lstrcpyA(val, "apple");
9998     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
9999                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10000                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10001     ok(r == ERROR_INVALID_PARAMETER,
10002        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10003     ok(!lstrcmpA(val, "apple"),
10004        "Expected val to be unchanged, got \"%s\"\n", val);
10005     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10006
10007     /* guid with brackets */
10008     size = MAX_PATH;
10009     lstrcpyA(val, "apple");
10010     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10011                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10012                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10013     ok(r == ERROR_UNKNOWN_PRODUCT,
10014        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10015     ok(!lstrcmpA(val, "apple"),
10016        "Expected val to be unchanged, got \"%s\"\n", val);
10017     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10018
10019     /* same length as guid, but random */
10020     size = MAX_PATH;
10021     lstrcpyA(val, "apple");
10022     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10023                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10024                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10025     ok(r == ERROR_INVALID_PARAMETER,
10026        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10027     ok(!lstrcmpA(val, "apple"),
10028        "Expected val to be unchanged, got \"%s\"\n", val);
10029     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10030
10031     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10032     size = MAX_PATH;
10033     lstrcpyA(val, "apple");
10034     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10035                             MSIINSTALLCONTEXT_USERMANAGED,
10036                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10037     ok(r == ERROR_INVALID_PARAMETER,
10038        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10039     ok(!lstrcmpA(val, "apple"),
10040        "Expected val to be unchanged, got \"%s\"\n", val);
10041     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10042
10043     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10044     size = MAX_PATH;
10045     lstrcpyA(val, "apple");
10046     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10047                             MSIINSTALLCONTEXT_USERUNMANAGED,
10048                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10049     ok(r == ERROR_INVALID_PARAMETER,
10050        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10051     ok(!lstrcmpA(val, "apple"),
10052        "Expected val to be unchanged, got \"%s\"\n", val);
10053     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10054
10055     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10056     size = MAX_PATH;
10057     lstrcpyA(val, "apple");
10058     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10059                             MSIINSTALLCONTEXT_MACHINE,
10060                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10061     ok(r == ERROR_INVALID_PARAMETER,
10062        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10063     ok(!lstrcmpA(val, "apple"),
10064        "Expected val to be unchanged, got \"%s\"\n", val);
10065     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10066
10067     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10068     size = MAX_PATH;
10069     lstrcpyA(val, "apple");
10070     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10071                             MSIINSTALLCONTEXT_MACHINE,
10072                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10073     ok(r == ERROR_INVALID_PARAMETER,
10074        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10075     ok(!lstrcmpA(val, "apple"),
10076        "Expected val to be unchanged, got \"%s\"\n", val);
10077     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10078
10079     /* dwContext is out of range */
10080     size = MAX_PATH;
10081     lstrcpyA(val, "apple");
10082     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10083                             MSIINSTALLCONTEXT_NONE,
10084                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10085     ok(r == ERROR_INVALID_PARAMETER,
10086        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10087     ok(!lstrcmpA(val, "apple"),
10088        "Expected val to be unchanged, got \"%s\"\n", val);
10089     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10090
10091     /* dwContext is out of range */
10092     size = MAX_PATH;
10093     lstrcpyA(val, "apple");
10094     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10095                             MSIINSTALLCONTEXT_ALL,
10096                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10097     ok(r == ERROR_INVALID_PARAMETER,
10098        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10099     ok(!lstrcmpA(val, "apple"),
10100        "Expected val to be unchanged, got \"%s\"\n", val);
10101     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10102
10103     /* dwContext is invalid */
10104     size = MAX_PATH;
10105     lstrcpyA(val, "apple");
10106     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
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     /* MSIINSTALLCONTEXT_USERMANAGED */
10115
10116     size = MAX_PATH;
10117     lstrcpyA(val, "apple");
10118     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10119                             MSIINSTALLCONTEXT_USERMANAGED,
10120                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10121     ok(r == ERROR_UNKNOWN_PRODUCT,
10122        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10123     ok(!lstrcmpA(val, "apple"),
10124        "Expected val to be unchanged, got \"%s\"\n", val);
10125     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10126
10127     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10128     lstrcatA(keypath, usersid);
10129     lstrcatA(keypath, "\\Products\\");
10130     lstrcatA(keypath, prod_squashed);
10131
10132     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10133     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10134
10135     /* local UserData product key exists */
10136     size = MAX_PATH;
10137     lstrcpyA(val, "apple");
10138     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10139                             MSIINSTALLCONTEXT_USERMANAGED,
10140                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10141     ok(r == ERROR_UNKNOWN_PRODUCT,
10142        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10143     ok(!lstrcmpA(val, "apple"),
10144        "Expected val to be unchanged, got \"%s\"\n", val);
10145     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10146
10147     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10148     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10149
10150     /* InstallProperties key exists */
10151     size = MAX_PATH;
10152     lstrcpyA(val, "apple");
10153     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10154                             MSIINSTALLCONTEXT_USERMANAGED,
10155                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10156     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10157     ok(!lstrcmpA(val, "apple"),
10158        "Expected val to be unchanged, got \"%s\"\n", val);
10159     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10160
10161     res = RegCreateKeyA(udprod, "Patches", &patches);
10162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10163
10164     /* Patches key exists */
10165     size = MAX_PATH;
10166     lstrcpyA(val, "apple");
10167     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10168                             MSIINSTALLCONTEXT_USERMANAGED,
10169                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10170     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10171     ok(!lstrcmpA(val, "apple"),
10172        "Expected val to be unchanged, got \"%s\"\n", val);
10173     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10174
10175     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10176     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10177
10178     /* Patches key exists */
10179     size = MAX_PATH;
10180     lstrcpyA(val, "apple");
10181     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10182                             MSIINSTALLCONTEXT_USERMANAGED,
10183                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10184     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10185     ok(!lstrcmpA(val, "apple"),
10186        "Expected val to be unchanged, got \"%s\"\n", val);
10187     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10188
10189     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10190     lstrcatA(keypath, usersid);
10191     lstrcatA(keypath, "\\Installer\\Products\\");
10192     lstrcatA(keypath, prod_squashed);
10193
10194     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10196
10197     /* managed product key exists */
10198     size = MAX_PATH;
10199     lstrcpyA(val, "apple");
10200     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10201                             MSIINSTALLCONTEXT_USERMANAGED,
10202                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10203     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10204     ok(!lstrcmpA(val, "apple"),
10205        "Expected val to be unchanged, got \"%s\"\n", val);
10206     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10207
10208     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10209     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10210
10211     /* Patches key exists */
10212     size = MAX_PATH;
10213     lstrcpyA(val, "apple");
10214     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10215                             MSIINSTALLCONTEXT_USERMANAGED,
10216                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10217     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10218     ok(!lstrcmpA(val, "apple"),
10219        "Expected val to be unchanged, got \"%s\"\n", val);
10220     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10221
10222     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10223                          (const BYTE *)"transforms", 11);
10224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10225
10226     /* specific patch value exists */
10227     size = MAX_PATH;
10228     lstrcpyA(val, "apple");
10229     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10230                             MSIINSTALLCONTEXT_USERMANAGED,
10231                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10232     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10233     ok(!lstrcmpA(val, "apple"),
10234        "Expected val to be unchanged, got \"%s\"\n", val);
10235     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10236
10237     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10238     lstrcatA(keypath, usersid);
10239     lstrcatA(keypath, "\\Patches\\");
10240     lstrcatA(keypath, patch_squashed);
10241
10242     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10243     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10244
10245     /* UserData Patches key exists */
10246     size = MAX_PATH;
10247     lstrcpyA(val, "apple");
10248     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10249                             MSIINSTALLCONTEXT_USERMANAGED,
10250                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10252     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10253     ok(size == 0, "Expected 0, got %d\n", size);
10254
10255     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10256                          (const BYTE *)"pack", 5);
10257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10258
10259     /* ManagedLocalPatch value exists */
10260     size = MAX_PATH;
10261     lstrcpyA(val, "apple");
10262     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10263                             MSIINSTALLCONTEXT_USERMANAGED,
10264                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10265     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10266     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10267     ok(size == 4, "Expected 4, got %d\n", size);
10268
10269     size = MAX_PATH;
10270     lstrcpyA(val, "apple");
10271     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10272                             MSIINSTALLCONTEXT_USERMANAGED,
10273                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10274     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10275     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10276     ok(size == 10, "Expected 10, got %d\n", size);
10277
10278     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10279                          (const BYTE *)"mydate", 7);
10280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10281
10282     /* Installed value exists */
10283     size = MAX_PATH;
10284     lstrcpyA(val, "apple");
10285     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10286                             MSIINSTALLCONTEXT_USERMANAGED,
10287                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10288     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10289     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10290     ok(size == 6, "Expected 6, got %d\n", size);
10291
10292     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10293                          (const BYTE *)"yes", 4);
10294     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10295
10296     /* Uninstallable value exists */
10297     size = MAX_PATH;
10298     lstrcpyA(val, "apple");
10299     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10300                             MSIINSTALLCONTEXT_USERMANAGED,
10301                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10303     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10304     ok(size == 3, "Expected 3, got %d\n", size);
10305
10306     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10307                          (const BYTE *)"good", 5);
10308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10309
10310     /* State value exists */
10311     size = MAX_PATH;
10312     lstrcpyA(val, "apple");
10313     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10314                             MSIINSTALLCONTEXT_USERMANAGED,
10315                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10316     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10317     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10318     ok(size == 4, "Expected 4, got %d\n", size);
10319
10320     size = 1;
10321     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10322                          (const BYTE *)&size, sizeof(DWORD));
10323     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10324
10325     /* State value exists */
10326     size = MAX_PATH;
10327     lstrcpyA(val, "apple");
10328     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10329                             MSIINSTALLCONTEXT_USERMANAGED,
10330                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10331     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10332     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10333     ok(size == 1, "Expected 1, got %d\n", size);
10334
10335     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10336                          (const BYTE *)"display", 8);
10337     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10338
10339     /* DisplayName value exists */
10340     size = MAX_PATH;
10341     lstrcpyA(val, "apple");
10342     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10343                             MSIINSTALLCONTEXT_USERMANAGED,
10344                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10345     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10346     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10347     ok(size == 7, "Expected 7, got %d\n", size);
10348
10349     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10350                          (const BYTE *)"moreinfo", 9);
10351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10352
10353     /* MoreInfoURL value exists */
10354     size = MAX_PATH;
10355     lstrcpyA(val, "apple");
10356     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10357                             MSIINSTALLCONTEXT_USERMANAGED,
10358                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10359     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10360     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10361     ok(size == 8, "Expected 8, got %d\n", size);
10362
10363     /* szProperty is invalid */
10364     size = MAX_PATH;
10365     lstrcpyA(val, "apple");
10366     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10367                             MSIINSTALLCONTEXT_USERMANAGED,
10368                             "IDontExist", val, &size);
10369     ok(r == ERROR_UNKNOWN_PROPERTY,
10370        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10371     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10372     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10373
10374     /* lpValue is NULL, while pcchValue is non-NULL */
10375     size = MAX_PATH;
10376     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10377                             MSIINSTALLCONTEXT_USERMANAGED,
10378                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10379     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10380     ok(size == 16, "Expected 16, got %d\n", size);
10381
10382     /* pcchValue is NULL, while lpValue is non-NULL */
10383     lstrcpyA(val, "apple");
10384     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10385                             MSIINSTALLCONTEXT_USERMANAGED,
10386                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10387     ok(r == ERROR_INVALID_PARAMETER,
10388        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10389     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10390
10391     /* both lpValue and pcchValue are NULL */
10392     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10393                             MSIINSTALLCONTEXT_USERMANAGED,
10394                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10395     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10396
10397     /* pcchValue doesn't have enough room for NULL terminator */
10398     size = 8;
10399     lstrcpyA(val, "apple");
10400     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10401                             MSIINSTALLCONTEXT_USERMANAGED,
10402                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10403     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10404     ok(!lstrcmpA(val, "moreinf"),
10405        "Expected \"moreinf\", got \"%s\"\n", val);
10406     ok(size == 16, "Expected 16, got %d\n", size);
10407
10408     /* pcchValue has exactly enough room for NULL terminator */
10409     size = 9;
10410     lstrcpyA(val, "apple");
10411     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10412                             MSIINSTALLCONTEXT_USERMANAGED,
10413                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10414     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10415     ok(!lstrcmpA(val, "moreinfo"),
10416        "Expected \"moreinfo\", got \"%s\"\n", val);
10417     ok(size == 8, "Expected 8, got %d\n", size);
10418
10419     /* pcchValue is too small, lpValue is NULL */
10420     size = 0;
10421     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10422                             MSIINSTALLCONTEXT_USERMANAGED,
10423                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10425     ok(size == 16, "Expected 16, got %d\n", size);
10426
10427     RegDeleteValueA(prodpatches, patch_squashed);
10428     RegDeleteKeyA(prodpatches, "");
10429     RegCloseKey(prodpatches);
10430     RegDeleteKeyA(prodkey, "");
10431     RegCloseKey(prodkey);
10432
10433     /* UserData is sufficient for all properties
10434      * except INSTALLPROPERTY_TRANSFORMS
10435      */
10436     size = MAX_PATH;
10437     lstrcpyA(val, "apple");
10438     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10439                             MSIINSTALLCONTEXT_USERMANAGED,
10440                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10442     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10443     ok(size == 4, "Expected 4, got %d\n", size);
10444
10445     /* UserData is sufficient for all properties
10446      * except INSTALLPROPERTY_TRANSFORMS
10447      */
10448     size = MAX_PATH;
10449     lstrcpyA(val, "apple");
10450     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10451                             MSIINSTALLCONTEXT_USERMANAGED,
10452                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10453     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10454     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10455     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10456
10457     RegDeleteValueA(hpatch, "MoreInfoURL");
10458     RegDeleteValueA(hpatch, "Display");
10459     RegDeleteValueA(hpatch, "State");
10460     RegDeleteValueA(hpatch, "Uninstallable");
10461     RegDeleteValueA(hpatch, "Installed");
10462     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10463     RegDeleteKeyA(udpatch, "");
10464     RegCloseKey(udpatch);
10465     RegDeleteKeyA(hpatch, "");
10466     RegCloseKey(hpatch);
10467     RegDeleteKeyA(patches, "");
10468     RegCloseKey(patches);
10469     RegDeleteKeyA(props, "");
10470     RegCloseKey(props);
10471     RegDeleteKeyA(udprod, "");
10472     RegCloseKey(udprod);
10473
10474     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10475
10476     size = MAX_PATH;
10477     lstrcpyA(val, "apple");
10478     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10479                             MSIINSTALLCONTEXT_USERUNMANAGED,
10480                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10481     ok(r == ERROR_UNKNOWN_PRODUCT,
10482        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10483     ok(!lstrcmpA(val, "apple"),
10484        "Expected val to be unchanged, got \"%s\"\n", val);
10485     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10486
10487     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10488     lstrcatA(keypath, usersid);
10489     lstrcatA(keypath, "\\Products\\");
10490     lstrcatA(keypath, prod_squashed);
10491
10492     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10493     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10494
10495     /* local UserData product key exists */
10496     size = MAX_PATH;
10497     lstrcpyA(val, "apple");
10498     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10499                             MSIINSTALLCONTEXT_USERUNMANAGED,
10500                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10501     ok(r == ERROR_UNKNOWN_PRODUCT,
10502        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10503     ok(!lstrcmpA(val, "apple"),
10504        "Expected val to be unchanged, got \"%s\"\n", val);
10505     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10506
10507     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10508     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10509
10510     /* InstallProperties key exists */
10511     size = MAX_PATH;
10512     lstrcpyA(val, "apple");
10513     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10514                             MSIINSTALLCONTEXT_USERUNMANAGED,
10515                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10516     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10517     ok(!lstrcmpA(val, "apple"),
10518        "Expected val to be unchanged, got \"%s\"\n", val);
10519     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10520
10521     res = RegCreateKeyA(udprod, "Patches", &patches);
10522     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10523
10524     /* Patches key exists */
10525     size = MAX_PATH;
10526     lstrcpyA(val, "apple");
10527     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10528                             MSIINSTALLCONTEXT_USERUNMANAGED,
10529                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10530     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10531     ok(!lstrcmpA(val, "apple"),
10532        "Expected val to be unchanged, got \"%s\"\n", val);
10533     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10534
10535     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10536     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10537
10538     /* Patches key exists */
10539     size = MAX_PATH;
10540     lstrcpyA(val, "apple");
10541     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10542                             MSIINSTALLCONTEXT_USERUNMANAGED,
10543                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10544     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10545     ok(!lstrcmpA(val, "apple"),
10546        "Expected val to be unchanged, got \"%s\"\n", val);
10547     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10548
10549     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10550     lstrcatA(keypath, prod_squashed);
10551
10552     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10553     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10554
10555     /* current user product key exists */
10556     size = MAX_PATH;
10557     lstrcpyA(val, "apple");
10558     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10559                             MSIINSTALLCONTEXT_USERUNMANAGED,
10560                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10561     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10562     ok(!lstrcmpA(val, "apple"),
10563        "Expected val to be unchanged, got \"%s\"\n", val);
10564     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10565
10566     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10567     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10568
10569     /* Patches key exists */
10570     size = MAX_PATH;
10571     lstrcpyA(val, "apple");
10572     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10573                             MSIINSTALLCONTEXT_USERUNMANAGED,
10574                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10575     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10576     ok(!lstrcmpA(val, "apple"),
10577        "Expected val to be unchanged, got \"%s\"\n", val);
10578     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10579
10580     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10581                          (const BYTE *)"transforms", 11);
10582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10583
10584     /* specific patch value exists */
10585     size = MAX_PATH;
10586     lstrcpyA(val, "apple");
10587     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10588                             MSIINSTALLCONTEXT_USERUNMANAGED,
10589                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10590     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10591     ok(!lstrcmpA(val, "apple"),
10592        "Expected val to be unchanged, got \"%s\"\n", val);
10593     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10594
10595     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10596     lstrcatA(keypath, usersid);
10597     lstrcatA(keypath, "\\Patches\\");
10598     lstrcatA(keypath, patch_squashed);
10599
10600     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10602
10603     /* UserData Patches key exists */
10604     size = MAX_PATH;
10605     lstrcpyA(val, "apple");
10606     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10607                             MSIINSTALLCONTEXT_USERUNMANAGED,
10608                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10609     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10610     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10611     ok(size == 0, "Expected 0, got %d\n", size);
10612
10613     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10614                          (const BYTE *)"pack", 5);
10615     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10616
10617     /* LocalPatch value exists */
10618     size = MAX_PATH;
10619     lstrcpyA(val, "apple");
10620     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10621                             MSIINSTALLCONTEXT_USERUNMANAGED,
10622                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10623     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10624     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10625     ok(size == 4, "Expected 4, got %d\n", size);
10626
10627     size = MAX_PATH;
10628     lstrcpyA(val, "apple");
10629     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10630                             MSIINSTALLCONTEXT_USERUNMANAGED,
10631                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10632     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10633     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10634     ok(size == 10, "Expected 10, got %d\n", size);
10635
10636     RegDeleteValueA(prodpatches, patch_squashed);
10637     RegDeleteKeyA(prodpatches, "");
10638     RegCloseKey(prodpatches);
10639     RegDeleteKeyA(prodkey, "");
10640     RegCloseKey(prodkey);
10641
10642     /* UserData is sufficient for all properties
10643      * except INSTALLPROPERTY_TRANSFORMS
10644      */
10645     size = MAX_PATH;
10646     lstrcpyA(val, "apple");
10647     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10648                             MSIINSTALLCONTEXT_USERUNMANAGED,
10649                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10650     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10651     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10652     ok(size == 4, "Expected 4, got %d\n", size);
10653
10654     /* UserData is sufficient for all properties
10655      * except INSTALLPROPERTY_TRANSFORMS
10656      */
10657     size = MAX_PATH;
10658     lstrcpyA(val, "apple");
10659     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10660                             MSIINSTALLCONTEXT_USERUNMANAGED,
10661                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10662     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10663     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10664     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10665
10666     RegDeleteValueA(udpatch, "LocalPackage");
10667     RegDeleteKeyA(udpatch, "");
10668     RegCloseKey(udpatch);
10669     RegDeleteKeyA(hpatch, "");
10670     RegCloseKey(hpatch);
10671     RegDeleteKeyA(patches, "");
10672     RegCloseKey(patches);
10673     RegDeleteKeyA(props, "");
10674     RegCloseKey(props);
10675     RegDeleteKeyA(udprod, "");
10676     RegCloseKey(udprod);
10677
10678     /* MSIINSTALLCONTEXT_MACHINE */
10679
10680     size = MAX_PATH;
10681     lstrcpyA(val, "apple");
10682     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10683                             MSIINSTALLCONTEXT_MACHINE,
10684                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10685     ok(r == ERROR_UNKNOWN_PRODUCT,
10686        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10687     ok(!lstrcmpA(val, "apple"),
10688        "Expected val to be unchanged, got \"%s\"\n", val);
10689     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10690
10691     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10692     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10693     lstrcatA(keypath, prod_squashed);
10694
10695     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10696     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10697
10698     /* local UserData product key exists */
10699     size = MAX_PATH;
10700     lstrcpyA(val, "apple");
10701     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10702                             MSIINSTALLCONTEXT_MACHINE,
10703                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10704     ok(r == ERROR_UNKNOWN_PRODUCT,
10705        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10706     ok(!lstrcmpA(val, "apple"),
10707        "Expected val to be unchanged, got \"%s\"\n", val);
10708     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10709
10710     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10711     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10712
10713     /* InstallProperties key exists */
10714     size = MAX_PATH;
10715     lstrcpyA(val, "apple");
10716     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10717                             MSIINSTALLCONTEXT_MACHINE,
10718                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10719     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10720     ok(!lstrcmpA(val, "apple"),
10721        "Expected val to be unchanged, got \"%s\"\n", val);
10722     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10723
10724     res = RegCreateKeyA(udprod, "Patches", &patches);
10725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10726
10727     /* Patches key exists */
10728     size = MAX_PATH;
10729     lstrcpyA(val, "apple");
10730     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10731                             MSIINSTALLCONTEXT_MACHINE,
10732                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10733     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10734     ok(!lstrcmpA(val, "apple"),
10735        "Expected val to be unchanged, got \"%s\"\n", val);
10736     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10737
10738     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10739     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10740
10741     /* Patches key exists */
10742     size = MAX_PATH;
10743     lstrcpyA(val, "apple");
10744     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10745                             MSIINSTALLCONTEXT_MACHINE,
10746                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10747     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10748     ok(!lstrcmpA(val, "apple"),
10749        "Expected val to be unchanged, got \"%s\"\n", val);
10750     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10751
10752     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10753     lstrcatA(keypath, prod_squashed);
10754
10755     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10756     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10757
10758     /* local product key exists */
10759     size = MAX_PATH;
10760     lstrcpyA(val, "apple");
10761     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10762                             MSIINSTALLCONTEXT_MACHINE,
10763                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10764     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10765     ok(!lstrcmpA(val, "apple"),
10766        "Expected val to be unchanged, got \"%s\"\n", val);
10767     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10768
10769     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10770     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10771
10772     /* Patches key exists */
10773     size = MAX_PATH;
10774     lstrcpyA(val, "apple");
10775     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10776                             MSIINSTALLCONTEXT_MACHINE,
10777                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10778     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10779     ok(!lstrcmpA(val, "apple"),
10780        "Expected val to be unchanged, got \"%s\"\n", val);
10781     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10782
10783     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10784                          (const BYTE *)"transforms", 11);
10785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10786
10787     /* specific patch value exists */
10788     size = MAX_PATH;
10789     lstrcpyA(val, "apple");
10790     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10791                             MSIINSTALLCONTEXT_MACHINE,
10792                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10793     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10794     ok(!lstrcmpA(val, "apple"),
10795        "Expected val to be unchanged, got \"%s\"\n", val);
10796     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10797
10798     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10799     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
10800     lstrcatA(keypath, patch_squashed);
10801
10802     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10803     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10804
10805     /* UserData Patches key exists */
10806     size = MAX_PATH;
10807     lstrcpyA(val, "apple");
10808     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10809                             MSIINSTALLCONTEXT_MACHINE,
10810                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10811     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10812     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10813     ok(size == 0, "Expected 0, got %d\n", size);
10814
10815     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10816                          (const BYTE *)"pack", 5);
10817     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10818
10819     /* LocalPatch value exists */
10820     size = MAX_PATH;
10821     lstrcpyA(val, "apple");
10822     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10823                             MSIINSTALLCONTEXT_MACHINE,
10824                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10825     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10826     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10827     ok(size == 4, "Expected 4, got %d\n", size);
10828
10829     size = MAX_PATH;
10830     lstrcpyA(val, "apple");
10831     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10832                             MSIINSTALLCONTEXT_MACHINE,
10833                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10834     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10835     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10836     ok(size == 10, "Expected 10, got %d\n", size);
10837
10838     RegDeleteValueA(prodpatches, patch_squashed);
10839     RegDeleteKeyA(prodpatches, "");
10840     RegCloseKey(prodpatches);
10841     RegDeleteKeyA(prodkey, "");
10842     RegCloseKey(prodkey);
10843
10844     /* UserData is sufficient for all properties
10845      * except INSTALLPROPERTY_TRANSFORMS
10846      */
10847     size = MAX_PATH;
10848     lstrcpyA(val, "apple");
10849     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10850                             MSIINSTALLCONTEXT_MACHINE,
10851                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10852     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10853     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10854     ok(size == 4, "Expected 4, got %d\n", size);
10855
10856     /* UserData is sufficient for all properties
10857      * except INSTALLPROPERTY_TRANSFORMS
10858      */
10859     size = MAX_PATH;
10860     lstrcpyA(val, "apple");
10861     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10862                             MSIINSTALLCONTEXT_MACHINE,
10863                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10864     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10865     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10866     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10867
10868     RegDeleteValueA(udpatch, "LocalPackage");
10869     RegDeleteKeyA(udpatch, "");
10870     RegCloseKey(udpatch);
10871     RegDeleteKeyA(hpatch, "");
10872     RegCloseKey(hpatch);
10873     RegDeleteKeyA(patches, "");
10874     RegCloseKey(patches);
10875     RegDeleteKeyA(props, "");
10876     RegCloseKey(props);
10877     RegDeleteKeyA(udprod, "");
10878     RegCloseKey(udprod);
10879 }
10880
10881 static void test_MsiEnumProducts(void)
10882 {
10883     UINT r;
10884     int found1, found2, found3;
10885     DWORD index;
10886     char product1[39], product2[39], product3[39], guid[39];
10887     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
10888     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
10889     char *usersid;
10890     HKEY key1, key2, key3;
10891
10892     create_test_guid(product1, product_squashed1);
10893     create_test_guid(product2, product_squashed2);
10894     create_test_guid(product3, product_squashed3);
10895     get_user_sid(&usersid);
10896
10897     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
10898     strcat(keypath1, product_squashed1);
10899
10900     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath1, &key1);
10901     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10902
10903     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10904     strcat(keypath2, usersid);
10905     strcat(keypath2, "\\Installer\\Products\\");
10906     strcat(keypath2, product_squashed2);
10907
10908     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath2, &key2);
10909     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10910
10911     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
10912     strcat(keypath3, product_squashed3);
10913
10914     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
10915     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10916
10917     index = 0;
10918     r = MsiEnumProductsA(index, NULL);
10919     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
10920
10921     index = 2;
10922     r = MsiEnumProductsA(index, guid);
10923     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
10924
10925     index = 0;
10926     r = MsiEnumProductsA(index, guid);
10927     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
10928
10929     found1 = found2 = found3 = 0;
10930     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
10931     {
10932         if (!strcmp(product1, guid)) found1 = 1;
10933         if (!strcmp(product2, guid)) found2 = 1;
10934         if (!strcmp(product3, guid)) found3 = 1;
10935         index++;
10936     }
10937     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
10938     ok(found1, "product1 not found\n");
10939     ok(found2, "product2 not found\n");
10940     ok(found3, "product3 not found\n");
10941
10942     RegDeleteKeyA(key1, "");
10943     RegDeleteKeyA(key2, "");
10944     RegDeleteKeyA(key3, "");
10945     RegCloseKey(key1);
10946     RegCloseKey(key2);
10947     RegCloseKey(key3);
10948     LocalFree(usersid);
10949 }
10950
10951 START_TEST(msi)
10952 {
10953     init_functionpointers();
10954
10955     test_usefeature();
10956     test_null();
10957     test_getcomponentpath();
10958     test_MsiGetFileHash();
10959
10960     if (!pConvertSidToStringSidA)
10961         win_skip("ConvertSidToStringSidA not implemented\n");
10962     else
10963     {
10964         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
10965         test_MsiQueryProductState();
10966         test_MsiQueryFeatureState();
10967         test_MsiQueryComponentState();
10968         test_MsiGetComponentPath();
10969         test_MsiGetProductCode();
10970         test_MsiEnumClients();
10971         test_MsiGetProductInfo();
10972         test_MsiGetProductInfoEx();
10973         test_MsiGetUserInfo();
10974         test_MsiOpenProduct();
10975         test_MsiEnumPatchesEx();
10976         test_MsiEnumPatches();
10977         test_MsiGetPatchInfoEx();
10978         test_MsiEnumProducts();
10979     }
10980
10981     test_MsiGetFileVersion();
10982 }