wnaspi32: Make winaspi.dll into a stand-alone 16-bit module.
[wine] / dlls / msi / tests / msi.c
1 /*
2  * tests for Microsoft Installer functionality
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_MSI 300
22
23 #include <stdio.h>
24 #include <windows.h>
25 #include <msi.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <sddl.h>
29
30 #include "wine/test.h"
31
32 static const char msifile[] = "winetest.msi";
33
34 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
35
36 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
37     (LPCSTR, LPCSTR, LPSTR, DWORD*);
38 static UINT (WINAPI *pMsiGetFileHashA)
39     (LPCSTR, DWORD, PMSIFILEHASHINFO);
40 static UINT (WINAPI *pMsiGetProductInfoExA)
41     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
42 static UINT (WINAPI *pMsiOpenPackageExA)
43     (LPCSTR, DWORD, MSIHANDLE*);
44 static UINT (WINAPI *pMsiOpenPackageExW)
45     (LPCWSTR, DWORD, MSIHANDLE*);
46 static UINT (WINAPI *pMsiEnumPatchesExA)
47     (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
48     MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
49 static UINT (WINAPI *pMsiQueryComponentStateA)
50     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
51 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
52     (LPCSTR, LPCSTR ,DWORD, DWORD);
53 static UINT (WINAPI *pMsiGetPatchInfoExA)
54     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
55
56 static void init_functionpointers(void)
57 {
58     HMODULE hmsi = GetModuleHandleA("msi.dll");
59     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
60
61 #define GET_PROC(dll, func) \
62     p ## func = (void *)GetProcAddress(dll, #func); \
63     if(!p ## func) \
64       trace("GetProcAddress(%s) failed\n", #func);
65
66     GET_PROC(hmsi, MsiGetComponentPathA)
67     GET_PROC(hmsi, MsiGetFileHashA)
68     GET_PROC(hmsi, MsiGetProductInfoExA)
69     GET_PROC(hmsi, MsiOpenPackageExA)
70     GET_PROC(hmsi, MsiOpenPackageExW)
71     GET_PROC(hmsi, MsiEnumPatchesExA)
72     GET_PROC(hmsi, MsiQueryComponentStateA)
73     GET_PROC(hmsi, MsiUseFeatureExA)
74     GET_PROC(hmsi, MsiGetPatchInfoExA)
75
76     GET_PROC(hadvapi32, ConvertSidToStringSidA)
77
78 #undef GET_PROC
79 }
80
81 static UINT run_query(MSIHANDLE hdb, const char *query)
82 {
83     MSIHANDLE hview = 0;
84     UINT r;
85
86     r = MsiDatabaseOpenView(hdb, query, &hview);
87     if (r != ERROR_SUCCESS)
88         return r;
89
90     r = MsiViewExecute(hview, 0);
91     if (r == ERROR_SUCCESS)
92         r = MsiViewClose(hview);
93     MsiCloseHandle(hview);
94     return r;
95 }
96
97 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
98 {
99     UINT res;
100     MSIHANDLE suminfo;
101
102     /* build summary info */
103     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
104     ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
105
106     res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
107                                     "Installation Database");
108     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
109
110     res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
111                                     "Installation Database");
112     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
113
114     res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
115                                     "Wine Hackers");
116     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
117
118     res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
119                                     ";1033");
120     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
121
122     res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
123                                     "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
124     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
125
126     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
127     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
128
129     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
130     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
131
132     res = MsiSummaryInfoPersist(suminfo);
133     ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
134
135     res = MsiCloseHandle(suminfo);
136     ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
137
138     return res;
139 }
140
141 static MSIHANDLE create_package_db(LPSTR prodcode)
142 {
143     MSIHANDLE hdb = 0;
144     CHAR query[MAX_PATH];
145     UINT res;
146
147     DeleteFile(msifile);
148
149     /* create an empty database */
150     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
151     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
152     if (res != ERROR_SUCCESS)
153         return hdb;
154
155     res = MsiDatabaseCommit(hdb);
156     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
157
158     set_summary_info(hdb, prodcode);
159
160     res = run_query(hdb,
161             "CREATE TABLE `Directory` ( "
162             "`Directory` CHAR(255) NOT NULL, "
163             "`Directory_Parent` CHAR(255), "
164             "`DefaultDir` CHAR(255) NOT NULL "
165             "PRIMARY KEY `Directory`)");
166     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
167
168     res = run_query(hdb,
169             "CREATE TABLE `Property` ( "
170             "`Property` CHAR(72) NOT NULL, "
171             "`Value` CHAR(255) "
172             "PRIMARY KEY `Property`)");
173     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
174
175     sprintf(query, "INSERT INTO `Property` "
176             "(`Property`, `Value`) "
177             "VALUES( 'ProductCode', '%s' )", prodcode);
178     res = run_query(hdb, query);
179     ok(res == ERROR_SUCCESS , "Failed\n");
180
181     res = MsiDatabaseCommit(hdb);
182     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
183
184     return hdb;
185 }
186
187 static void test_usefeature(void)
188 {
189     INSTALLSTATE r;
190
191     if (!pMsiUseFeatureExA)
192     {
193         skip("MsiUseFeatureExA not implemented\n");
194         return;
195     }
196
197     r = MsiQueryFeatureState(NULL,NULL);
198     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
199
200     r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
201     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
202
203     r = pMsiUseFeatureExA(NULL,NULL,0,0);
204     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
205
206     r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
207     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
208
209     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
210                          NULL, -2, 0 );
211     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
212
213     r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}", 
214                          "WORDVIEWFiles", -2, 0 );
215     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
216
217     r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}", 
218                          "WORDVIEWFiles", -2, 0 );
219     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
220
221     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
222                          "WORDVIEWFiles", -2, 1 );
223     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
224 }
225
226 static void test_null(void)
227 {
228     MSIHANDLE hpkg;
229     UINT r;
230     HKEY hkey;
231     DWORD dwType, cbData;
232     LPBYTE lpData = NULL;
233     INSTALLSTATE state;
234
235     r = pMsiOpenPackageExW(NULL, 0, &hpkg);
236     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
237
238     state = MsiQueryProductStateW(NULL);
239     ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
240
241     r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
242     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
243
244     r = MsiConfigureFeatureW(NULL, NULL, 0);
245     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
246
247     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
248     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
249
250     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", 0);
251     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
252
253     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", INSTALLSTATE_DEFAULT);
254     ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
255
256     /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
257      * necessary registry values */
258
259     /* empty product string */
260     r = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", &hkey);
261     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
262
263     r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
264     ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
265     if ( r == ERROR_SUCCESS )
266     {
267         lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
268         if (!lpData)
269             skip("Out of memory\n");
270         else
271         {
272             r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
273             ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
274         }
275     }
276
277     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
278     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
279
280     r = MsiGetProductInfoA("", "", NULL, NULL);
281     ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
282
283     if (lpData)
284     {
285         r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
286         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
287
288         HeapFree(GetProcessHeap(), 0, lpData);
289     }
290     else
291     {
292         r = RegDeleteValueA(hkey, NULL);
293         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
294     }
295
296     r = RegCloseKey(hkey);
297     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
298
299     /* empty attribute */
300     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", &hkey);
301     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
302
303     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
304     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
305
306     r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
307     ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
308
309     r = RegCloseKey(hkey);
310     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
311
312     r = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}");
313     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
314 }
315
316 static void test_getcomponentpath(void)
317 {
318     INSTALLSTATE r;
319     char buffer[0x100];
320     DWORD sz;
321
322     if(!pMsiGetComponentPathA)
323         return;
324
325     r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
326     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
327
328     r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
329     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
330
331     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
332     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
333
334     sz = sizeof buffer;
335     buffer[0]=0;
336     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
337     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
338
339     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
340         "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
341     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
342
343     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
344         "{00000000-0000-0000-0000-00000000}", buffer, &sz );
345     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
346
347     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
348         "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
349     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
350
351     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
352                             "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
353     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
354 }
355
356 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
357 {
358     HANDLE file;
359     DWORD written;
360
361     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
362     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
363     WriteFile(file, data, strlen(data), &written, NULL);
364
365     if (size)
366     {
367         SetFilePointer(file, size, NULL, FILE_BEGIN);
368         SetEndOfFile(file);
369     }
370
371     CloseHandle(file);
372 }
373
374 #define HASHSIZE sizeof(MSIFILEHASHINFO)
375
376 static const struct
377 {
378     LPCSTR data;
379     DWORD size;
380     MSIFILEHASHINFO hash;
381 } hash_data[] =
382 {
383     { "abc", 0,
384       { HASHSIZE,
385         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
386       },
387     },
388
389     { "C:\\Program Files\\msitest\\caesar\n", 0,
390       { HASHSIZE,
391         { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
392       },
393     },
394
395     { "C:\\Program Files\\msitest\\caesar\n", 500,
396       { HASHSIZE,
397         { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
398       },
399     },
400 };
401
402 static void test_MsiGetFileHash(void)
403 {
404     const char name[] = "msitest.bin";
405     UINT r;
406     MSIFILEHASHINFO hash;
407     DWORD i;
408
409     if (!pMsiGetFileHashA)
410     {
411         skip("MsiGetFileHash not implemented\n");
412         return;
413     }
414
415     hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
416
417     /* szFilePath is NULL */
418     r = pMsiGetFileHashA(NULL, 0, &hash);
419     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
420
421     /* szFilePath is empty */
422     r = pMsiGetFileHashA("", 0, &hash);
423     ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
424        "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
425
426     /* szFilePath is nonexistent */
427     r = pMsiGetFileHashA(name, 0, &hash);
428     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
429
430     /* dwOptions is non-zero */
431     r = pMsiGetFileHashA(name, 1, &hash);
432     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
433
434     /* pHash.dwFileHashInfoSize is not correct */
435     hash.dwFileHashInfoSize = 0;
436     r = pMsiGetFileHashA(name, 0, &hash);
437     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
438
439     /* pHash is NULL */
440     r = pMsiGetFileHashA(name, 0, NULL);
441     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
442
443     for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
444     {
445         int ret;
446
447         create_file(name, hash_data[i].data, hash_data[i].size);
448
449         memset(&hash, 0, sizeof(MSIFILEHASHINFO));
450         hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
451
452         r = pMsiGetFileHashA(name, 0, &hash);
453         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
454
455         ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
456         ok(ret == 0 ||
457            broken(ret != 0), /* win95 */
458            "Hash incorrect\n");
459
460         DeleteFile(name);
461     }
462 }
463
464 /* copied from dlls/msi/registry.c */
465 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
466 {
467     DWORD i,n=1;
468     GUID guid;
469
470     if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
471         return FALSE;
472
473     for(i=0; i<8; i++)
474         out[7-i] = in[n++];
475     n++;
476     for(i=0; i<4; i++)
477         out[11-i] = in[n++];
478     n++;
479     for(i=0; i<4; i++)
480         out[15-i] = in[n++];
481     n++;
482     for(i=0; i<2; i++)
483     {
484         out[17+i*2] = in[n++];
485         out[16+i*2] = in[n++];
486     }
487     n++;
488     for( ; i<8; i++)
489     {
490         out[17+i*2] = in[n++];
491         out[16+i*2] = in[n++];
492     }
493     out[32]=0;
494     return TRUE;
495 }
496
497 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
498 {
499     WCHAR guidW[MAX_PATH];
500     WCHAR squashedW[MAX_PATH];
501     GUID guid;
502     HRESULT hr;
503     int size;
504
505     hr = CoCreateGuid(&guid);
506     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
507
508     size = StringFromGUID2(&guid, guidW, MAX_PATH);
509     ok(size == 39, "Expected 39, got %d\n", hr);
510
511     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
512     squash_guid(guidW, squashedW);
513     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
514 }
515
516 static void get_user_sid(LPSTR *usersid)
517 {
518     HANDLE token;
519     BYTE buf[1024];
520     DWORD size;
521     PTOKEN_USER user;
522
523     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
524     size = sizeof(buf);
525     GetTokenInformation(token, TokenUser, buf, size, &size);
526     user = (PTOKEN_USER)buf;
527     pConvertSidToStringSidA(user->User.Sid, usersid);
528     CloseHandle(token);
529 }
530
531 static void test_MsiQueryProductState(void)
532 {
533     CHAR prodcode[MAX_PATH];
534     CHAR prod_squashed[MAX_PATH];
535     CHAR keypath[MAX_PATH*2];
536     LPSTR usersid;
537     INSTALLSTATE state;
538     LONG res;
539     HKEY userkey, localkey, props;
540     HKEY prodkey;
541     DWORD data;
542
543     create_test_guid(prodcode, prod_squashed);
544     get_user_sid(&usersid);
545
546     /* NULL prodcode */
547     state = MsiQueryProductStateA(NULL);
548     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
549
550     /* empty prodcode */
551     state = MsiQueryProductStateA("");
552     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
553
554     /* garbage prodcode */
555     state = MsiQueryProductStateA("garbage");
556     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
557
558     /* guid without brackets */
559     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
560     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
561
562     /* guid with brackets */
563     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
564     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
565
566     /* same length as guid, but random */
567     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
568     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
569
570     /* MSIINSTALLCONTEXT_USERUNMANAGED */
571
572     state = MsiQueryProductStateA(prodcode);
573     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
574
575     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
576     lstrcatA(keypath, prod_squashed);
577
578     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
580
581     /* user product key exists */
582     state = MsiQueryProductStateA(prodcode);
583     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
584
585     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
586     lstrcatA(keypath, prodcode);
587
588     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
590
591     /* local uninstall key exists */
592     state = MsiQueryProductStateA(prodcode);
593     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
594
595     data = 1;
596     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
597     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
598
599     /* WindowsInstaller value exists */
600     state = MsiQueryProductStateA(prodcode);
601     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
602
603     RegDeleteValueA(localkey, "WindowsInstaller");
604     RegDeleteKeyA(localkey, "");
605
606     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
607     lstrcatA(keypath, usersid);
608     lstrcatA(keypath, "\\Products\\");
609     lstrcatA(keypath, prod_squashed);
610
611     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
612     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
613
614     /* local product key exists */
615     state = MsiQueryProductStateA(prodcode);
616     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
617
618     res = RegCreateKeyA(localkey, "InstallProperties", &props);
619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
620
621     /* install properties key exists */
622     state = MsiQueryProductStateA(prodcode);
623     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
624
625     data = 1;
626     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
628
629     /* WindowsInstaller value exists */
630     state = MsiQueryProductStateA(prodcode);
631     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
632
633     data = 2;
634     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
635     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
636
637     /* WindowsInstaller value is not 1 */
638     state = MsiQueryProductStateA(prodcode);
639     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
640
641     RegDeleteKeyA(userkey, "");
642
643     /* user product key does not exist */
644     state = MsiQueryProductStateA(prodcode);
645     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
646
647     RegDeleteValueA(props, "WindowsInstaller");
648     RegDeleteKeyA(props, "");
649     RegCloseKey(props);
650     RegDeleteKeyA(localkey, "");
651     RegCloseKey(localkey);
652     RegDeleteKeyA(userkey, "");
653     RegCloseKey(userkey);
654
655     /* MSIINSTALLCONTEXT_USERMANAGED */
656
657     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
658     lstrcatA(keypath, usersid);
659     lstrcatA(keypath, "\\Installer\\Products\\");
660     lstrcatA(keypath, prod_squashed);
661
662     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
663     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
664
665     state = MsiQueryProductStateA(prodcode);
666     ok(state == INSTALLSTATE_ADVERTISED,
667        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
668
669     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
670     lstrcatA(keypath, usersid);
671     lstrcatA(keypath, "\\Products\\");
672     lstrcatA(keypath, prod_squashed);
673
674     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
675     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
676
677     state = MsiQueryProductStateA(prodcode);
678     ok(state == INSTALLSTATE_ADVERTISED,
679        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
680
681     res = RegCreateKeyA(localkey, "InstallProperties", &props);
682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
683
684     state = MsiQueryProductStateA(prodcode);
685     ok(state == INSTALLSTATE_ADVERTISED,
686        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
687
688     data = 1;
689     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
690     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
691
692     /* WindowsInstaller value exists */
693     state = MsiQueryProductStateA(prodcode);
694     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
695
696     RegDeleteValueA(props, "WindowsInstaller");
697     RegDeleteKeyA(props, "");
698     RegCloseKey(props);
699     RegDeleteKeyA(localkey, "");
700     RegCloseKey(localkey);
701     RegDeleteKeyA(prodkey, "");
702     RegCloseKey(prodkey);
703
704     /* MSIINSTALLCONTEXT_MACHINE */
705
706     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
707     lstrcatA(keypath, prod_squashed);
708
709     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
711
712     state = MsiQueryProductStateA(prodcode);
713     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
714
715     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
716     lstrcatA(keypath, "S-1-5-18\\Products\\");
717     lstrcatA(keypath, prod_squashed);
718
719     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
721
722     state = MsiQueryProductStateA(prodcode);
723     ok(state == INSTALLSTATE_ADVERTISED,
724        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
725
726     res = RegCreateKeyA(localkey, "InstallProperties", &props);
727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
728
729     state = MsiQueryProductStateA(prodcode);
730     ok(state == INSTALLSTATE_ADVERTISED,
731        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
732
733     data = 1;
734     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
735     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
736
737     /* WindowsInstaller value exists */
738     state = MsiQueryProductStateA(prodcode);
739     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
740
741     RegDeleteValueA(props, "WindowsInstaller");
742     RegDeleteKeyA(props, "");
743     RegCloseKey(props);
744     RegDeleteKeyA(localkey, "");
745     RegCloseKey(localkey);
746     RegDeleteKeyA(prodkey, "");
747     RegCloseKey(prodkey);
748
749     LocalFree(usersid);
750 }
751
752 static const char table_enc85[] =
753 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
754 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
755 "yz{}~";
756
757 /*
758  *  Encodes a base85 guid given a GUID pointer
759  *  Caller should provide a 21 character buffer for the encoded string.
760  *
761  *  returns TRUE if successful, FALSE if not
762  */
763 static BOOL encode_base85_guid( GUID *guid, LPWSTR str )
764 {
765     unsigned int x, *p, i;
766
767     p = (unsigned int*) guid;
768     for( i=0; i<4; i++ )
769     {
770         x = p[i];
771         *str++ = table_enc85[x%85];
772         x = x/85;
773         *str++ = table_enc85[x%85];
774         x = x/85;
775         *str++ = table_enc85[x%85];
776         x = x/85;
777         *str++ = table_enc85[x%85];
778         x = x/85;
779         *str++ = table_enc85[x%85];
780     }
781     *str = 0;
782
783     return TRUE;
784 }
785
786 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
787 {
788     WCHAR guidW[MAX_PATH];
789     WCHAR base85W[MAX_PATH];
790     WCHAR squashedW[MAX_PATH];
791     GUID guid;
792     HRESULT hr;
793     int size;
794
795     hr = CoCreateGuid(&guid);
796     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
797
798     size = StringFromGUID2(&guid, guidW, MAX_PATH);
799     ok(size == 39, "Expected 39, got %d\n", hr);
800
801     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
802     encode_base85_guid(&guid, base85W);
803     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
804     squash_guid(guidW, squashedW);
805     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
806 }
807
808 static void test_MsiQueryFeatureState(void)
809 {
810     HKEY userkey, localkey, compkey;
811     CHAR prodcode[MAX_PATH];
812     CHAR prod_squashed[MAX_PATH];
813     CHAR component[MAX_PATH];
814     CHAR comp_base85[MAX_PATH];
815     CHAR comp_squashed[MAX_PATH];
816     CHAR keypath[MAX_PATH*2];
817     INSTALLSTATE state;
818     LPSTR usersid;
819     LONG res;
820
821     create_test_guid(prodcode, prod_squashed);
822     compose_base85_guid(component, comp_base85, comp_squashed);
823     get_user_sid(&usersid);
824
825     /* NULL prodcode */
826     state = MsiQueryFeatureStateA(NULL, "feature");
827     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
828
829     /* empty prodcode */
830     state = MsiQueryFeatureStateA("", "feature");
831     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
832
833     /* garbage prodcode */
834     state = MsiQueryFeatureStateA("garbage", "feature");
835     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
836
837     /* guid without brackets */
838     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
839     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
840
841     /* guid with brackets */
842     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
843     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
844
845     /* same length as guid, but random */
846     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
847     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
848
849     /* NULL szFeature */
850     state = MsiQueryFeatureStateA(prodcode, NULL);
851     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
852
853     /* empty szFeature */
854     state = MsiQueryFeatureStateA(prodcode, "");
855     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
856
857     /* feature key does not exist yet */
858     state = MsiQueryFeatureStateA(prodcode, "feature");
859     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
860
861     /* MSIINSTALLCONTEXT_USERUNMANAGED */
862
863     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
864     lstrcatA(keypath, prod_squashed);
865
866     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
867     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
868
869     /* feature key exists */
870     state = MsiQueryFeatureStateA(prodcode, "feature");
871     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
872
873     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
874     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
875
876     /* feature value exists */
877     state = MsiQueryFeatureStateA(prodcode, "feature");
878     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
879
880     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
881     lstrcatA(keypath, usersid);
882     lstrcatA(keypath, "\\Products\\");
883     lstrcatA(keypath, prod_squashed);
884     lstrcatA(keypath, "\\Features");
885
886     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
888
889     /* userdata features key exists */
890     state = MsiQueryFeatureStateA(prodcode, "feature");
891     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
892
893     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
894     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
895
896     state = MsiQueryFeatureStateA(prodcode, "feature");
897     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
898
899     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
900     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
901
902     state = MsiQueryFeatureStateA(prodcode, "feature");
903     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
904
905     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
907
908     state = MsiQueryFeatureStateA(prodcode, "feature");
909     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
910
911     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
913
914     state = MsiQueryFeatureStateA(prodcode, "feature");
915     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
916
917     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
918     lstrcatA(keypath, usersid);
919     lstrcatA(keypath, "\\Components\\");
920     lstrcatA(keypath, comp_squashed);
921
922     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
924
925     state = MsiQueryFeatureStateA(prodcode, "feature");
926     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
927
928     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
930
931     state = MsiQueryFeatureStateA(prodcode, "feature");
932     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
933
934     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
936
937     /* INSTALLSTATE_LOCAL */
938     state = MsiQueryFeatureStateA(prodcode, "feature");
939     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
940
941     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
943
944     /* INSTALLSTATE_SOURCE */
945     state = MsiQueryFeatureStateA(prodcode, "feature");
946     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
947
948     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
949     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
950
951     /* bad INSTALLSTATE_SOURCE */
952     state = MsiQueryFeatureStateA(prodcode, "feature");
953     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
954
955     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
957
958     /* INSTALLSTATE_SOURCE */
959     state = MsiQueryFeatureStateA(prodcode, "feature");
960     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
961
962     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
964
965     /* bad INSTALLSTATE_SOURCE */
966     state = MsiQueryFeatureStateA(prodcode, "feature");
967     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
968
969     RegDeleteValueA(compkey, prod_squashed);
970     RegDeleteKeyA(compkey, "");
971     RegDeleteValueA(localkey, "feature");
972     RegDeleteValueA(userkey, "feature");
973     RegDeleteKeyA(userkey, "");
974     RegCloseKey(compkey);
975     RegCloseKey(localkey);
976     RegCloseKey(userkey);
977
978     /* MSIINSTALLCONTEXT_USERMANAGED */
979
980     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
981     lstrcatA(keypath, usersid);
982     lstrcatA(keypath, "\\Installer\\Features\\");
983     lstrcatA(keypath, prod_squashed);
984
985     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
987
988     /* feature key exists */
989     state = MsiQueryFeatureStateA(prodcode, "feature");
990     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
991
992     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
993     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
994
995     /* feature value exists */
996     state = MsiQueryFeatureStateA(prodcode, "feature");
997     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
998
999     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1000     lstrcatA(keypath, usersid);
1001     lstrcatA(keypath, "\\Products\\");
1002     lstrcatA(keypath, prod_squashed);
1003     lstrcatA(keypath, "\\Features");
1004
1005     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1006     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1007
1008     /* userdata features key exists */
1009     state = MsiQueryFeatureStateA(prodcode, "feature");
1010     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1011
1012     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1014
1015     state = MsiQueryFeatureStateA(prodcode, "feature");
1016     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1017
1018     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1020
1021     state = MsiQueryFeatureStateA(prodcode, "feature");
1022     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1023
1024     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1026
1027     state = MsiQueryFeatureStateA(prodcode, "feature");
1028     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1029
1030     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
1031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1032
1033     state = MsiQueryFeatureStateA(prodcode, "feature");
1034     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1035
1036     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1037     lstrcatA(keypath, usersid);
1038     lstrcatA(keypath, "\\Components\\");
1039     lstrcatA(keypath, comp_squashed);
1040
1041     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1042     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1043
1044     state = MsiQueryFeatureStateA(prodcode, "feature");
1045     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1046
1047     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1049
1050     state = MsiQueryFeatureStateA(prodcode, "feature");
1051     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1052
1053     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
1054     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1055
1056     state = MsiQueryFeatureStateA(prodcode, "feature");
1057     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1058
1059     RegDeleteValueA(compkey, prod_squashed);
1060     RegDeleteKeyA(compkey, "");
1061     RegDeleteValueA(localkey, "feature");
1062     RegDeleteValueA(userkey, "feature");
1063     RegDeleteKeyA(userkey, "");
1064     RegCloseKey(compkey);
1065     RegCloseKey(localkey);
1066     RegCloseKey(userkey);
1067
1068     /* MSIINSTALLCONTEXT_MACHINE */
1069
1070     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1071     lstrcatA(keypath, prod_squashed);
1072
1073     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
1074     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1075
1076     /* feature key exists */
1077     state = MsiQueryFeatureStateA(prodcode, "feature");
1078     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1079
1080     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1081     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1082
1083     /* feature value exists */
1084     state = MsiQueryFeatureStateA(prodcode, "feature");
1085     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1086
1087     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1088     lstrcatA(keypath, "S-1-5-18\\Products\\");
1089     lstrcatA(keypath, prod_squashed);
1090     lstrcatA(keypath, "\\Features");
1091
1092     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1094
1095     /* userdata features key exists */
1096     state = MsiQueryFeatureStateA(prodcode, "feature");
1097     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1098
1099     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1101
1102     state = MsiQueryFeatureStateA(prodcode, "feature");
1103     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1104
1105     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1107
1108     state = MsiQueryFeatureStateA(prodcode, "feature");
1109     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1110
1111     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1113
1114     state = MsiQueryFeatureStateA(prodcode, "feature");
1115     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1116
1117     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
1118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1119
1120     state = MsiQueryFeatureStateA(prodcode, "feature");
1121     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1122
1123     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1124     lstrcatA(keypath, "S-1-5-18\\Components\\");
1125     lstrcatA(keypath, comp_squashed);
1126
1127     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1129
1130     state = MsiQueryFeatureStateA(prodcode, "feature");
1131     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1132
1133     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1135
1136     state = MsiQueryFeatureStateA(prodcode, "feature");
1137     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1138
1139     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
1140     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1141
1142     state = MsiQueryFeatureStateA(prodcode, "feature");
1143     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1144
1145     RegDeleteValueA(compkey, prod_squashed);
1146     RegDeleteKeyA(compkey, "");
1147     RegDeleteValueA(localkey, "feature");
1148     RegDeleteValueA(userkey, "feature");
1149     RegDeleteKeyA(userkey, "");
1150     RegCloseKey(compkey);
1151     RegCloseKey(localkey);
1152     RegCloseKey(userkey);
1153 }
1154
1155 static void test_MsiQueryComponentState(void)
1156 {
1157     HKEY compkey, prodkey;
1158     CHAR prodcode[MAX_PATH];
1159     CHAR prod_squashed[MAX_PATH];
1160     CHAR component[MAX_PATH];
1161     CHAR comp_base85[MAX_PATH];
1162     CHAR comp_squashed[MAX_PATH];
1163     CHAR keypath[MAX_PATH];
1164     INSTALLSTATE state;
1165     LPSTR usersid;
1166     LONG res;
1167     UINT r;
1168
1169     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1170
1171     if (!pMsiQueryComponentStateA)
1172     {
1173         skip("MsiQueryComponentStateA not implemented\n");
1174         return;
1175     }
1176
1177     create_test_guid(prodcode, prod_squashed);
1178     compose_base85_guid(component, comp_base85, comp_squashed);
1179     get_user_sid(&usersid);
1180
1181     /* NULL szProductCode */
1182     state = MAGIC_ERROR;
1183     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1184     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1185     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1186
1187     /* empty szProductCode */
1188     state = MAGIC_ERROR;
1189     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1190     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1191     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1192
1193     /* random szProductCode */
1194     state = MAGIC_ERROR;
1195     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1196     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1197     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1198
1199     /* GUID-length szProductCode */
1200     state = MAGIC_ERROR;
1201     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1202     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1203     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1204
1205     /* GUID-length with brackets */
1206     state = MAGIC_ERROR;
1207     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1208     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1209     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1210
1211     /* actual GUID */
1212     state = MAGIC_ERROR;
1213     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1214     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1215     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1216
1217     state = MAGIC_ERROR;
1218     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1219     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1220     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1221
1222     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1223     lstrcatA(keypath, prod_squashed);
1224
1225     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1227
1228     state = MAGIC_ERROR;
1229     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1230     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1231     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1232
1233     RegDeleteKeyA(prodkey, "");
1234     RegCloseKey(prodkey);
1235
1236     /* create local system product key */
1237     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1238     lstrcatA(keypath, prod_squashed);
1239     lstrcatA(keypath, "\\InstallProperties");
1240
1241     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1242     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1243
1244     /* local system product key exists */
1245     state = MAGIC_ERROR;
1246     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1247     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1248     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1249
1250     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1251     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1252
1253     /* LocalPackage value exists */
1254     state = MAGIC_ERROR;
1255     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1256     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1257     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1258
1259     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1260     lstrcatA(keypath, comp_squashed);
1261
1262     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1263     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1264
1265     /* component key exists */
1266     state = MAGIC_ERROR;
1267     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1268     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1269     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1270
1271     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1273
1274     /* component\product exists */
1275     state = MAGIC_ERROR;
1276     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1278     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1279        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1280
1281     /* NULL component, product exists */
1282     state = MAGIC_ERROR;
1283     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1284     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1285     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1286
1287     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1289
1290     /* INSTALLSTATE_LOCAL */
1291     state = MAGIC_ERROR;
1292     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1293     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1294     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1295
1296     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1297     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1298
1299     /* INSTALLSTATE_SOURCE */
1300     state = MAGIC_ERROR;
1301     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1303     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1304
1305     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1306     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1307
1308     /* bad INSTALLSTATE_SOURCE */
1309     state = MAGIC_ERROR;
1310     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1311     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1312     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1313
1314     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1315     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1316
1317     /* INSTALLSTATE_SOURCE */
1318     state = MAGIC_ERROR;
1319     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1320     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1321     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1322
1323     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1325
1326     /* bad INSTALLSTATE_SOURCE */
1327     state = MAGIC_ERROR;
1328     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1329     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1330     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1331
1332     RegDeleteValueA(prodkey, "LocalPackage");
1333     RegDeleteKeyA(prodkey, "");
1334     RegDeleteValueA(compkey, prod_squashed);
1335     RegDeleteKeyA(prodkey, "");
1336     RegCloseKey(prodkey);
1337     RegCloseKey(compkey);
1338
1339     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1340
1341     state = MAGIC_ERROR;
1342     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1343     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1344     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1345
1346     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1347     lstrcatA(keypath, prod_squashed);
1348
1349     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1351
1352     state = MAGIC_ERROR;
1353     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1354     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1355     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1356
1357     RegDeleteKeyA(prodkey, "");
1358     RegCloseKey(prodkey);
1359
1360     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1361     lstrcatA(keypath, usersid);
1362     lstrcatA(keypath, "\\Products\\");
1363     lstrcatA(keypath, prod_squashed);
1364     lstrcatA(keypath, "\\InstallProperties");
1365
1366     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1368
1369     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1371
1372     RegCloseKey(prodkey);
1373
1374     state = MAGIC_ERROR;
1375     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1376     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1377     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1378
1379     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1380     lstrcatA(keypath, usersid);
1381     lstrcatA(keypath, "\\Components\\");
1382     lstrcatA(keypath, comp_squashed);
1383
1384     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1385     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1386
1387     /* component key exists */
1388     state = MAGIC_ERROR;
1389     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1390     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1391     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1392
1393     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1395
1396     /* component\product exists */
1397     state = MAGIC_ERROR;
1398     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1399     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1400     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1401        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1402
1403     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1404     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1405
1406     state = MAGIC_ERROR;
1407     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1408     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1409     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1410
1411     /* MSIINSTALLCONTEXT_USERMANAGED */
1412
1413     state = MAGIC_ERROR;
1414     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1415     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1416     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1417
1418     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1419     lstrcatA(keypath, prod_squashed);
1420
1421     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1423
1424     state = MAGIC_ERROR;
1425     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1426     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1427     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1428
1429     RegDeleteKeyA(prodkey, "");
1430     RegCloseKey(prodkey);
1431
1432     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1433     lstrcatA(keypath, usersid);
1434     lstrcatA(keypath, "\\Installer\\Products\\");
1435     lstrcatA(keypath, prod_squashed);
1436
1437     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1439
1440     state = MAGIC_ERROR;
1441     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1442     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1443     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1444
1445     RegDeleteKeyA(prodkey, "");
1446     RegCloseKey(prodkey);
1447
1448     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1449     lstrcatA(keypath, usersid);
1450     lstrcatA(keypath, "\\Products\\");
1451     lstrcatA(keypath, prod_squashed);
1452     lstrcatA(keypath, "\\InstallProperties");
1453
1454     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1455     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1456
1457     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1459
1460     state = MAGIC_ERROR;
1461     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1463     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1464
1465     RegDeleteValueA(prodkey, "LocalPackage");
1466     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1467     RegDeleteKeyA(prodkey, "");
1468     RegDeleteValueA(compkey, prod_squashed);
1469     RegDeleteKeyA(compkey, "");
1470     RegCloseKey(prodkey);
1471     RegCloseKey(compkey);
1472 }
1473
1474 static void test_MsiGetComponentPath(void)
1475 {
1476     HKEY compkey, prodkey, installprop;
1477     CHAR prodcode[MAX_PATH];
1478     CHAR prod_squashed[MAX_PATH];
1479     CHAR component[MAX_PATH];
1480     CHAR comp_base85[MAX_PATH];
1481     CHAR comp_squashed[MAX_PATH];
1482     CHAR keypath[MAX_PATH];
1483     CHAR path[MAX_PATH];
1484     INSTALLSTATE state;
1485     LPSTR usersid;
1486     DWORD size, val;
1487     LONG res;
1488
1489     create_test_guid(prodcode, prod_squashed);
1490     compose_base85_guid(component, comp_base85, comp_squashed);
1491     get_user_sid(&usersid);
1492
1493     /* NULL szProduct */
1494     size = MAX_PATH;
1495     state = MsiGetComponentPathA(NULL, component, path, &size);
1496     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1497     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1498
1499     /* NULL szComponent */
1500     size = MAX_PATH;
1501     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1502     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1503     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1504
1505     /* NULL lpPathBuf */
1506     size = MAX_PATH;
1507     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1508     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1509     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1510
1511     /* NULL pcchBuf */
1512     size = MAX_PATH;
1513     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1514     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1515     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1516
1517     /* all params valid */
1518     size = MAX_PATH;
1519     state = MsiGetComponentPathA(prodcode, component, path, &size);
1520     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1521     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1522
1523     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1524     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1525     lstrcatA(keypath, comp_squashed);
1526
1527     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1528     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1529
1530     /* local system component key exists */
1531     size = MAX_PATH;
1532     state = MsiGetComponentPathA(prodcode, component, path, &size);
1533     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1534     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1535
1536     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1537     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1538
1539     /* product value exists */
1540     size = MAX_PATH;
1541     state = MsiGetComponentPathA(prodcode, component, path, &size);
1542     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1543     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1544     ok(size == 10, "Expected 10, got %d\n", size);
1545
1546     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1547     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1548     lstrcatA(keypath, prod_squashed);
1549     lstrcatA(keypath, "\\InstallProperties");
1550
1551     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1552     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1553
1554     val = 1;
1555     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1557
1558     /* install properties key exists */
1559     size = MAX_PATH;
1560     state = MsiGetComponentPathA(prodcode, component, path, &size);
1561     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1562     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1563     ok(size == 10, "Expected 10, got %d\n", size);
1564
1565     create_file("C:\\imapath", "C:\\imapath", 11);
1566
1567     /* file exists */
1568     size = MAX_PATH;
1569     state = MsiGetComponentPathA(prodcode, component, path, &size);
1570     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1571     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1572     ok(size == 10, "Expected 10, got %d\n", size);
1573
1574     RegDeleteValueA(compkey, prod_squashed);
1575     RegDeleteKeyA(compkey, "");
1576     RegDeleteValueA(installprop, "WindowsInstaller");
1577     RegDeleteKeyA(installprop, "");
1578     RegCloseKey(compkey);
1579     RegCloseKey(installprop);
1580     DeleteFileA("C:\\imapath");
1581
1582     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1583     lstrcatA(keypath, "Installer\\UserData\\");
1584     lstrcatA(keypath, usersid);
1585     lstrcatA(keypath, "\\Components\\");
1586     lstrcatA(keypath, comp_squashed);
1587
1588     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1590
1591     /* user managed component key exists */
1592     size = MAX_PATH;
1593     state = MsiGetComponentPathA(prodcode, component, path, &size);
1594     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1595     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1596
1597     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1598     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1599
1600     /* product value exists */
1601     size = MAX_PATH;
1602     state = MsiGetComponentPathA(prodcode, component, path, &size);
1603     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1604     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1605     ok(size == 10, "Expected 10, got %d\n", size);
1606
1607     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1608     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1609     lstrcatA(keypath, prod_squashed);
1610     lstrcatA(keypath, "\\InstallProperties");
1611
1612     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1614
1615     val = 1;
1616     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1617     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1618
1619     /* install properties key exists */
1620     size = MAX_PATH;
1621     state = MsiGetComponentPathA(prodcode, component, path, &size);
1622     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1623     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1624     ok(size == 10, "Expected 10, got %d\n", size);
1625
1626     create_file("C:\\imapath", "C:\\imapath", 11);
1627
1628     /* file exists */
1629     size = MAX_PATH;
1630     state = MsiGetComponentPathA(prodcode, component, path, &size);
1631     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1632     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1633     ok(size == 10, "Expected 10, got %d\n", size);
1634
1635     RegDeleteValueA(compkey, prod_squashed);
1636     RegDeleteKeyA(compkey, "");
1637     RegDeleteValueA(installprop, "WindowsInstaller");
1638     RegDeleteKeyA(installprop, "");
1639     RegCloseKey(compkey);
1640     RegCloseKey(installprop);
1641     DeleteFileA("C:\\imapath");
1642
1643     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1644     lstrcatA(keypath, "Installer\\Managed\\");
1645     lstrcatA(keypath, usersid);
1646     lstrcatA(keypath, "\\Installer\\Products\\");
1647     lstrcatA(keypath, prod_squashed);
1648
1649     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1651
1652     /* user managed product key exists */
1653     size = MAX_PATH;
1654     state = MsiGetComponentPathA(prodcode, component, path, &size);
1655     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1656     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1657
1658     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1659     lstrcatA(keypath, "Installer\\UserData\\");
1660     lstrcatA(keypath, usersid);
1661     lstrcatA(keypath, "\\Components\\");
1662     lstrcatA(keypath, comp_squashed);
1663
1664     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1665     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1666
1667     /* user managed component key exists */
1668     size = MAX_PATH;
1669     state = MsiGetComponentPathA(prodcode, component, path, &size);
1670     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1671     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1672
1673     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1675
1676     /* product value exists */
1677     size = MAX_PATH;
1678     state = MsiGetComponentPathA(prodcode, component, path, &size);
1679     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1680     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1681     ok(size == 10, "Expected 10, got %d\n", size);
1682
1683     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1684     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1685     lstrcatA(keypath, prod_squashed);
1686     lstrcatA(keypath, "\\InstallProperties");
1687
1688     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1690
1691     val = 1;
1692     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1694
1695     /* install properties key exists */
1696     size = MAX_PATH;
1697     state = MsiGetComponentPathA(prodcode, component, path, &size);
1698     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1699     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1700     ok(size == 10, "Expected 10, got %d\n", size);
1701
1702     create_file("C:\\imapath", "C:\\imapath", 11);
1703
1704     /* file exists */
1705     size = MAX_PATH;
1706     state = MsiGetComponentPathA(prodcode, component, path, &size);
1707     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1708     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1709     ok(size == 10, "Expected 10, got %d\n", size);
1710
1711     RegDeleteValueA(compkey, prod_squashed);
1712     RegDeleteKeyA(prodkey, "");
1713     RegDeleteKeyA(compkey, "");
1714     RegDeleteValueA(installprop, "WindowsInstaller");
1715     RegDeleteKeyA(installprop, "");
1716     RegCloseKey(prodkey);
1717     RegCloseKey(compkey);
1718     RegCloseKey(installprop);
1719     DeleteFileA("C:\\imapath");
1720
1721     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1722     lstrcatA(keypath, prod_squashed);
1723
1724     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1726
1727     /* user unmanaged product key exists */
1728     size = MAX_PATH;
1729     state = MsiGetComponentPathA(prodcode, component, path, &size);
1730     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1731     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1732
1733     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1734     lstrcatA(keypath, "Installer\\UserData\\");
1735     lstrcatA(keypath, usersid);
1736     lstrcatA(keypath, "\\Components\\");
1737     lstrcatA(keypath, comp_squashed);
1738
1739     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1741
1742     /* user unmanaged component key exists */
1743     size = MAX_PATH;
1744     state = MsiGetComponentPathA(prodcode, component, path, &size);
1745     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1746     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1747
1748     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1749     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1750
1751     /* product value exists */
1752     size = MAX_PATH;
1753     state = MsiGetComponentPathA(prodcode, component, path, &size);
1754     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1755     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1756     ok(size == 10, "Expected 10, got %d\n", size);
1757
1758     create_file("C:\\imapath", "C:\\imapath", 11);
1759
1760     /* file exists */
1761     size = MAX_PATH;
1762     state = MsiGetComponentPathA(prodcode, component, path, &size);
1763     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1764     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1765     ok(size == 10, "Expected 10, got %d\n", size);
1766
1767     RegDeleteValueA(compkey, prod_squashed);
1768     RegDeleteKeyA(prodkey, "");
1769     RegDeleteKeyA(compkey, "");
1770     RegCloseKey(prodkey);
1771     RegCloseKey(compkey);
1772     DeleteFileA("C:\\imapath");
1773
1774     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1775     lstrcatA(keypath, prod_squashed);
1776
1777     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1779
1780     /* local classes product key exists */
1781     size = MAX_PATH;
1782     state = MsiGetComponentPathA(prodcode, component, path, &size);
1783     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1784     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1785
1786     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1787     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1788     lstrcatA(keypath, comp_squashed);
1789
1790     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1792
1793     /* local user component key exists */
1794     size = MAX_PATH;
1795     state = MsiGetComponentPathA(prodcode, component, path, &size);
1796     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1797     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1798
1799     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1800     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1801
1802     /* product value exists */
1803     size = MAX_PATH;
1804     state = MsiGetComponentPathA(prodcode, component, path, &size);
1805     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1806     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1807     ok(size == 10, "Expected 10, got %d\n", size);
1808
1809     create_file("C:\\imapath", "C:\\imapath", 11);
1810
1811     /* file exists */
1812     size = MAX_PATH;
1813     state = MsiGetComponentPathA(prodcode, component, path, &size);
1814     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1815     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1816     ok(size == 10, "Expected 10, got %d\n", size);
1817
1818     RegDeleteValueA(compkey, prod_squashed);
1819     RegDeleteKeyA(prodkey, "");
1820     RegDeleteKeyA(compkey, "");
1821     RegCloseKey(prodkey);
1822     RegCloseKey(compkey);
1823     DeleteFileA("C:\\imapath");
1824 }
1825
1826 static void test_MsiGetProductCode(void)
1827 {
1828     HKEY compkey, prodkey;
1829     CHAR prodcode[MAX_PATH];
1830     CHAR prod_squashed[MAX_PATH];
1831     CHAR prodcode2[MAX_PATH];
1832     CHAR prod2_squashed[MAX_PATH];
1833     CHAR component[MAX_PATH];
1834     CHAR comp_base85[MAX_PATH];
1835     CHAR comp_squashed[MAX_PATH];
1836     CHAR keypath[MAX_PATH];
1837     CHAR product[MAX_PATH];
1838     LPSTR usersid;
1839     LONG res;
1840     UINT r;
1841
1842     create_test_guid(prodcode, prod_squashed);
1843     create_test_guid(prodcode2, prod2_squashed);
1844     compose_base85_guid(component, comp_base85, comp_squashed);
1845     get_user_sid(&usersid);
1846
1847     /* szComponent is NULL */
1848     lstrcpyA(product, "prod");
1849     r = MsiGetProductCodeA(NULL, product);
1850     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1851     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1852
1853     /* szComponent is empty */
1854     lstrcpyA(product, "prod");
1855     r = MsiGetProductCodeA("", product);
1856     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1857     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1858
1859     /* garbage szComponent */
1860     lstrcpyA(product, "prod");
1861     r = MsiGetProductCodeA("garbage", product);
1862     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1863     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1864
1865     /* guid without brackets */
1866     lstrcpyA(product, "prod");
1867     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
1868     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1869     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1870
1871     /* guid with brackets */
1872     lstrcpyA(product, "prod");
1873     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
1874     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1875     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1876
1877     /* same length as guid, but random */
1878     lstrcpyA(product, "prod");
1879     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
1880     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1881     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1882
1883     /* all params correct, szComponent not published */
1884     lstrcpyA(product, "prod");
1885     r = MsiGetProductCodeA(component, product);
1886     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1887     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1888
1889     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1890     lstrcatA(keypath, "Installer\\UserData\\");
1891     lstrcatA(keypath, usersid);
1892     lstrcatA(keypath, "\\Components\\");
1893     lstrcatA(keypath, comp_squashed);
1894
1895     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1896     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1897
1898     /* user unmanaged component key exists */
1899     lstrcpyA(product, "prod");
1900     r = MsiGetProductCodeA(component, product);
1901     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1902     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1903
1904     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1906
1907     /* product value exists */
1908     lstrcpyA(product, "prod");
1909     r = MsiGetProductCodeA(component, product);
1910     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1911     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1912
1913     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1915
1916     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1917     lstrcatA(keypath, "Installer\\Managed\\");
1918     lstrcatA(keypath, usersid);
1919     lstrcatA(keypath, "\\Installer\\Products\\");
1920     lstrcatA(keypath, prod_squashed);
1921
1922     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1924
1925     /* user managed product key of first product exists */
1926     lstrcpyA(product, "prod");
1927     r = MsiGetProductCodeA(component, product);
1928     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1929     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1930
1931     RegDeleteKeyA(prodkey, "");
1932     RegCloseKey(prodkey);
1933
1934     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1935     lstrcatA(keypath, prod_squashed);
1936
1937     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1938     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1939
1940     /* user unmanaged product key exists */
1941     lstrcpyA(product, "prod");
1942     r = MsiGetProductCodeA(component, product);
1943     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1944     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1945
1946     RegDeleteKeyA(prodkey, "");
1947     RegCloseKey(prodkey);
1948
1949     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1950     lstrcatA(keypath, prod_squashed);
1951
1952     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1953     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1954
1955     /* local classes product key exists */
1956     lstrcpyA(product, "prod");
1957     r = MsiGetProductCodeA(component, product);
1958     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1959     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1960
1961     RegDeleteKeyA(prodkey, "");
1962     RegCloseKey(prodkey);
1963
1964     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1965     lstrcatA(keypath, "Installer\\Managed\\");
1966     lstrcatA(keypath, usersid);
1967     lstrcatA(keypath, "\\Installer\\Products\\");
1968     lstrcatA(keypath, prod2_squashed);
1969
1970     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1972
1973     /* user managed product key of second product exists */
1974     lstrcpyA(product, "prod");
1975     r = MsiGetProductCodeA(component, product);
1976     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1977     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
1978
1979     RegDeleteKeyA(prodkey, "");
1980     RegCloseKey(prodkey);
1981     RegDeleteValueA(compkey, prod_squashed);
1982     RegDeleteValueA(compkey, prod2_squashed);
1983     RegDeleteKeyA(compkey, "");
1984     RegCloseKey(compkey);
1985
1986     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1987     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1988     lstrcatA(keypath, comp_squashed);
1989
1990     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1992
1993     /* local user component key exists */
1994     lstrcpyA(product, "prod");
1995     r = MsiGetProductCodeA(component, product);
1996     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1997     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1998
1999     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2001
2002     /* product value exists */
2003     lstrcpyA(product, "prod");
2004     r = MsiGetProductCodeA(component, product);
2005     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2006     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2007
2008     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2010
2011     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2012     lstrcatA(keypath, "Installer\\Managed\\");
2013     lstrcatA(keypath, usersid);
2014     lstrcatA(keypath, "\\Installer\\Products\\");
2015     lstrcatA(keypath, prod_squashed);
2016
2017     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2019
2020     /* user managed product key of first product exists */
2021     lstrcpyA(product, "prod");
2022     r = MsiGetProductCodeA(component, product);
2023     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2024     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2025
2026     RegDeleteKeyA(prodkey, "");
2027     RegCloseKey(prodkey);
2028
2029     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2030     lstrcatA(keypath, prod_squashed);
2031
2032     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2033     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2034
2035     /* user unmanaged product key exists */
2036     lstrcpyA(product, "prod");
2037     r = MsiGetProductCodeA(component, product);
2038     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2039     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2040
2041     RegDeleteKeyA(prodkey, "");
2042     RegCloseKey(prodkey);
2043
2044     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2045     lstrcatA(keypath, prod_squashed);
2046
2047     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2049
2050     /* local classes product key exists */
2051     lstrcpyA(product, "prod");
2052     r = MsiGetProductCodeA(component, product);
2053     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2054     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2055
2056     RegDeleteKeyA(prodkey, "");
2057     RegCloseKey(prodkey);
2058
2059     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2060     lstrcatA(keypath, "Installer\\Managed\\");
2061     lstrcatA(keypath, usersid);
2062     lstrcatA(keypath, "\\Installer\\Products\\");
2063     lstrcatA(keypath, prod2_squashed);
2064
2065     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2067
2068     /* user managed product key of second product exists */
2069     lstrcpyA(product, "prod");
2070     r = MsiGetProductCodeA(component, product);
2071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2072     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2073
2074     RegDeleteKeyA(prodkey, "");
2075     RegCloseKey(prodkey);
2076     RegDeleteValueA(compkey, prod_squashed);
2077     RegDeleteValueA(compkey, prod2_squashed);
2078     RegDeleteKeyA(compkey, "");
2079     RegCloseKey(compkey);
2080 }
2081
2082 static void test_MsiEnumClients(void)
2083 {
2084     HKEY compkey;
2085     CHAR prodcode[MAX_PATH];
2086     CHAR prod_squashed[MAX_PATH];
2087     CHAR prodcode2[MAX_PATH];
2088     CHAR prod2_squashed[MAX_PATH];
2089     CHAR component[MAX_PATH];
2090     CHAR comp_base85[MAX_PATH];
2091     CHAR comp_squashed[MAX_PATH];
2092     CHAR product[MAX_PATH];
2093     CHAR keypath[MAX_PATH];
2094     LPSTR usersid;
2095     LONG res;
2096     UINT r;
2097
2098     create_test_guid(prodcode, prod_squashed);
2099     create_test_guid(prodcode2, prod2_squashed);
2100     compose_base85_guid(component, comp_base85, comp_squashed);
2101     get_user_sid(&usersid);
2102
2103     /* NULL szComponent */
2104     product[0] = '\0';
2105     r = MsiEnumClientsA(NULL, 0, product);
2106     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2107     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2108
2109     /* empty szComponent */
2110     product[0] = '\0';
2111     r = MsiEnumClientsA("", 0, product);
2112     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2113     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2114
2115     /* NULL lpProductBuf */
2116     r = MsiEnumClientsA(component, 0, NULL);
2117     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2118
2119     /* all params correct, component missing */
2120     product[0] = '\0';
2121     r = MsiEnumClientsA(component, 0, product);
2122     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2123     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2124
2125     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2126     lstrcatA(keypath, "Installer\\UserData\\");
2127     lstrcatA(keypath, usersid);
2128     lstrcatA(keypath, "\\Components\\");
2129     lstrcatA(keypath, comp_squashed);
2130
2131     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2133
2134     /* user unmanaged component key exists */
2135     product[0] = '\0';
2136     r = MsiEnumClientsA(component, 0, product);
2137     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2138     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2139
2140     /* index > 0, no products exist */
2141     product[0] = '\0';
2142     r = MsiEnumClientsA(component, 1, product);
2143     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2144     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2145
2146     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2148
2149     /* product value exists */
2150     r = MsiEnumClientsA(component, 0, product);
2151     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2152     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2153
2154     /* try index 0 again */
2155     product[0] = '\0';
2156     r = MsiEnumClientsA(component, 0, product);
2157     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2158     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2159
2160     /* try index 1, second product value does not exist */
2161     product[0] = '\0';
2162     r = MsiEnumClientsA(component, 1, product);
2163     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2164     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2165
2166     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2167     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2168
2169     /* try index 1, second product value does exist */
2170     product[0] = '\0';
2171     r = MsiEnumClientsA(component, 1, product);
2172     todo_wine
2173     {
2174         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2175         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2176     }
2177
2178     /* start the enumeration over */
2179     product[0] = '\0';
2180     r = MsiEnumClientsA(component, 0, product);
2181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2182     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2183        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2184
2185     /* correctly query second product */
2186     product[0] = '\0';
2187     r = MsiEnumClientsA(component, 1, product);
2188     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2189     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2190        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2191
2192     RegDeleteValueA(compkey, prod_squashed);
2193     RegDeleteValueA(compkey, prod2_squashed);
2194     RegDeleteKeyA(compkey, "");
2195     RegCloseKey(compkey);
2196
2197     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2198     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2199     lstrcatA(keypath, comp_squashed);
2200
2201     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2203
2204     /* user local component key exists */
2205     product[0] = '\0';
2206     r = MsiEnumClientsA(component, 0, product);
2207     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2208     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2209
2210     /* index > 0, no products exist */
2211     product[0] = '\0';
2212     r = MsiEnumClientsA(component, 1, product);
2213     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2214     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2215
2216     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2218
2219     /* product value exists */
2220     product[0] = '\0';
2221     r = MsiEnumClientsA(component, 0, product);
2222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2223     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2224
2225     /* try index 0 again */
2226     product[0] = '\0';
2227     r = MsiEnumClientsA(component, 0, product);
2228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2229
2230     /* try index 1, second product value does not exist */
2231     product[0] = '\0';
2232     r = MsiEnumClientsA(component, 1, product);
2233     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2234     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2235
2236     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2238
2239     /* try index 1, second product value does exist */
2240     product[0] = '\0';
2241     r = MsiEnumClientsA(component, 1, product);
2242     todo_wine
2243     {
2244         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2245         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2246     }
2247
2248     /* start the enumeration over */
2249     product[0] = '\0';
2250     r = MsiEnumClientsA(component, 0, product);
2251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2252     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2253        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2254
2255     /* correctly query second product */
2256     product[0] = '\0';
2257     r = MsiEnumClientsA(component, 1, product);
2258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2259     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2260        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2261
2262     RegDeleteValueA(compkey, prod_squashed);
2263     RegDeleteValueA(compkey, prod2_squashed);
2264     RegDeleteKeyA(compkey, "");
2265     RegCloseKey(compkey);
2266 }
2267
2268 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2269                              LPSTR *langcheck, LPDWORD langchecksz)
2270 {
2271     LPSTR version;
2272     VS_FIXEDFILEINFO *ffi;
2273     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2274     USHORT *lang;
2275
2276     version = HeapAlloc(GetProcessHeap(), 0, size);
2277     GetFileVersionInfoA(path, 0, size, version);
2278
2279     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2280     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2281     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2282             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2283             LOWORD(ffi->dwFileVersionLS));
2284     *verchecksz = lstrlenA(*vercheck);
2285
2286     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2287     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2288     sprintf(*langcheck, "%d", *lang);
2289     *langchecksz = lstrlenA(*langcheck);
2290
2291     HeapFree(GetProcessHeap(), 0, version);
2292 }
2293
2294 static void test_MsiGetFileVersion(void)
2295 {
2296     UINT r;
2297     DWORD versz, langsz;
2298     char version[MAX_PATH];
2299     char lang[MAX_PATH];
2300     char path[MAX_PATH];
2301     LPSTR vercheck, langcheck;
2302     DWORD verchecksz, langchecksz;
2303
2304     /* NULL szFilePath */
2305     versz = MAX_PATH;
2306     langsz = MAX_PATH;
2307     lstrcpyA(version, "version");
2308     lstrcpyA(lang, "lang");
2309     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2310     ok(r == ERROR_INVALID_PARAMETER,
2311        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2312     ok(!lstrcmpA(version, "version"),
2313        "Expected version to be unchanged, got %s\n", version);
2314     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2315     ok(!lstrcmpA(lang, "lang"),
2316        "Expected lang to be unchanged, got %s\n", lang);
2317     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2318
2319     /* empty szFilePath */
2320     versz = MAX_PATH;
2321     langsz = MAX_PATH;
2322     lstrcpyA(version, "version");
2323     lstrcpyA(lang, "lang");
2324     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2325     ok(r == ERROR_FILE_NOT_FOUND,
2326        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2327     ok(!lstrcmpA(version, "version"),
2328        "Expected version to be unchanged, got %s\n", version);
2329     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2330     ok(!lstrcmpA(lang, "lang"),
2331        "Expected lang to be unchanged, got %s\n", lang);
2332     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2333
2334     /* nonexistent szFilePath */
2335     versz = MAX_PATH;
2336     langsz = MAX_PATH;
2337     lstrcpyA(version, "version");
2338     lstrcpyA(lang, "lang");
2339     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2340     ok(r == ERROR_FILE_NOT_FOUND,
2341        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2342     ok(!lstrcmpA(version, "version"),
2343        "Expected version to be unchanged, got %s\n", version);
2344     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2345     ok(!lstrcmpA(lang, "lang"),
2346        "Expected lang to be unchanged, got %s\n", lang);
2347     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2348
2349     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2350     versz = MAX_PATH;
2351     langsz = MAX_PATH;
2352     lstrcpyA(version, "version");
2353     lstrcpyA(lang, "lang");
2354     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2355     ok(r == ERROR_INVALID_PARAMETER,
2356        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2357     ok(!lstrcmpA(version, "version"),
2358        "Expected version to be unchanged, got %s\n", version);
2359     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2360     ok(!lstrcmpA(lang, "lang"),
2361        "Expected lang to be unchanged, got %s\n", lang);
2362     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2363
2364     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2365     versz = MAX_PATH;
2366     langsz = MAX_PATH;
2367     lstrcpyA(version, "version");
2368     lstrcpyA(lang, "lang");
2369     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2370     ok(r == ERROR_INVALID_PARAMETER,
2371        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2372     ok(!lstrcmpA(version, "version"),
2373        "Expected version to be unchanged, got %s\n", version);
2374     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2375     ok(!lstrcmpA(lang, "lang"),
2376        "Expected lang to be unchanged, got %s\n", lang);
2377     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2378
2379     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2380     versz = 0;
2381     langsz = MAX_PATH;
2382     lstrcpyA(version, "version");
2383     lstrcpyA(lang, "lang");
2384     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2385     ok(r == ERROR_FILE_NOT_FOUND,
2386        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2387     ok(!lstrcmpA(version, "version"),
2388        "Expected version to be unchanged, got %s\n", version);
2389     ok(versz == 0, "Expected 0, got %d\n", versz);
2390     ok(!lstrcmpA(lang, "lang"),
2391        "Expected lang to be unchanged, got %s\n", lang);
2392     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2393
2394     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2395     versz = MAX_PATH;
2396     langsz = 0;
2397     lstrcpyA(version, "version");
2398     lstrcpyA(lang, "lang");
2399     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2400     ok(r == ERROR_FILE_NOT_FOUND,
2401        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2402     ok(!lstrcmpA(version, "version"),
2403        "Expected version to be unchanged, got %s\n", version);
2404     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2405     ok(!lstrcmpA(lang, "lang"),
2406        "Expected lang to be unchanged, got %s\n", lang);
2407     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2408
2409     /* nonexistent szFilePath, rest NULL */
2410     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2411     ok(r == ERROR_FILE_NOT_FOUND,
2412        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2413
2414     create_file("ver.txt", "ver.txt", 20);
2415
2416     /* file exists, no version information */
2417     versz = MAX_PATH;
2418     langsz = MAX_PATH;
2419     lstrcpyA(version, "version");
2420     lstrcpyA(lang, "lang");
2421     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2422     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2423     ok(!lstrcmpA(version, "version"),
2424        "Expected version to be unchanged, got %s\n", version);
2425     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2426     ok(!lstrcmpA(lang, "lang"),
2427        "Expected lang to be unchanged, got %s\n", lang);
2428     ok(r == ERROR_FILE_INVALID,
2429        "Expected ERROR_FILE_INVALID, got %d\n", r);
2430
2431     DeleteFileA("ver.txt");
2432
2433     /* relative path, has version information */
2434     versz = MAX_PATH;
2435     langsz = MAX_PATH;
2436     lstrcpyA(version, "version");
2437     lstrcpyA(lang, "lang");
2438     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2439     todo_wine
2440     {
2441         ok(r == ERROR_FILE_NOT_FOUND,
2442            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2443         ok(!lstrcmpA(version, "version"),
2444            "Expected version to be unchanged, got %s\n", version);
2445         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2446         ok(!lstrcmpA(lang, "lang"),
2447            "Expected lang to be unchanged, got %s\n", lang);
2448         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2449     }
2450
2451     GetSystemDirectoryA(path, MAX_PATH);
2452     lstrcatA(path, "\\kernel32.dll");
2453
2454     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2455
2456     /* absolute path, has version information */
2457     versz = MAX_PATH;
2458     langsz = MAX_PATH;
2459     lstrcpyA(version, "version");
2460     lstrcpyA(lang, "lang");
2461     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2463     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2464     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2465     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2466     ok(!lstrcmpA(version, vercheck),
2467         "Expected %s, got %s\n", vercheck, version);
2468
2469     /* only check version */
2470     versz = MAX_PATH;
2471     lstrcpyA(version, "version");
2472     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2473     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2474     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2475     ok(!lstrcmpA(version, vercheck),
2476        "Expected %s, got %s\n", vercheck, version);
2477
2478     /* only check language */
2479     langsz = MAX_PATH;
2480     lstrcpyA(lang, "lang");
2481     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2483     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2484     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2485
2486     /* check neither version nor language */
2487     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2488     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2489
2490     /* get pcchVersionBuf */
2491     versz = MAX_PATH;
2492     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2494     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2495
2496     /* get pcchLangBuf */
2497     langsz = MAX_PATH;
2498     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2499     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2500     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2501
2502     /* pcchVersionBuf not big enough */
2503     versz = 5;
2504     lstrcpyA(version, "version");
2505     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2506     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2507     ok(!strncmp(version, vercheck, 4),
2508        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2509     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2510
2511     /* pcchLangBuf not big enough */
2512     langsz = 3;
2513     lstrcpyA(lang, "lang");
2514     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2515     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2516     ok(!strncmp(lang, langcheck, 2),
2517        "Expected first character of %s, got %s\n", langcheck, lang);
2518     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2519
2520     HeapFree(GetProcessHeap(), 0, vercheck);
2521     HeapFree(GetProcessHeap(), 0, langcheck);
2522 }
2523
2524 static void test_MsiGetProductInfo(void)
2525 {
2526     UINT r;
2527     LONG res;
2528     HKEY propkey, source;
2529     HKEY prodkey, localkey;
2530     CHAR prodcode[MAX_PATH];
2531     CHAR prod_squashed[MAX_PATH];
2532     CHAR packcode[MAX_PATH];
2533     CHAR pack_squashed[MAX_PATH];
2534     CHAR buf[MAX_PATH];
2535     CHAR keypath[MAX_PATH];
2536     LPSTR usersid;
2537     DWORD sz, val = 42;
2538
2539     create_test_guid(prodcode, prod_squashed);
2540     create_test_guid(packcode, pack_squashed);
2541     get_user_sid(&usersid);
2542
2543     /* NULL szProduct */
2544     sz = MAX_PATH;
2545     lstrcpyA(buf, "apple");
2546     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2547     ok(r == ERROR_INVALID_PARAMETER,
2548        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2549     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2550     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2551
2552     /* empty szProduct */
2553     sz = MAX_PATH;
2554     lstrcpyA(buf, "apple");
2555     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2556     ok(r == ERROR_INVALID_PARAMETER,
2557        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2558     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2559     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2560
2561     /* garbage szProduct */
2562     sz = MAX_PATH;
2563     lstrcpyA(buf, "apple");
2564     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2565     ok(r == ERROR_INVALID_PARAMETER,
2566        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2567     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2568     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2569
2570     /* guid without brackets */
2571     sz = MAX_PATH;
2572     lstrcpyA(buf, "apple");
2573     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2574                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2575     ok(r == ERROR_INVALID_PARAMETER,
2576        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2577     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2578     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2579
2580     /* guid with brackets */
2581     sz = MAX_PATH;
2582     lstrcpyA(buf, "apple");
2583     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2584                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2585     ok(r == ERROR_UNKNOWN_PRODUCT,
2586        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2587     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2588     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2589
2590     /* same length as guid, but random */
2591     sz = MAX_PATH;
2592     lstrcpyA(buf, "apple");
2593     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2594                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2595     ok(r == ERROR_INVALID_PARAMETER,
2596        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2597     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2598     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2599
2600     /* not installed, NULL szAttribute */
2601     sz = MAX_PATH;
2602     lstrcpyA(buf, "apple");
2603     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2604     ok(r == ERROR_INVALID_PARAMETER,
2605        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2606     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2607     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2608
2609     /* not installed, NULL lpValueBuf */
2610     sz = MAX_PATH;
2611     lstrcpyA(buf, "apple");
2612     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2613     ok(r == ERROR_UNKNOWN_PRODUCT,
2614        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2615     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2616     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2617
2618     /* not installed, NULL pcchValueBuf */
2619     sz = MAX_PATH;
2620     lstrcpyA(buf, "apple");
2621     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2622     ok(r == ERROR_INVALID_PARAMETER,
2623        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2624     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2625     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2626
2627     /* created guid cannot possibly be an installed product code */
2628     sz = MAX_PATH;
2629     lstrcpyA(buf, "apple");
2630     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2631     ok(r == ERROR_UNKNOWN_PRODUCT,
2632        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2633     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2634     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2635
2636     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2637     lstrcatA(keypath, usersid);
2638     lstrcatA(keypath, "\\Installer\\Products\\");
2639     lstrcatA(keypath, prod_squashed);
2640
2641     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2643
2644     /* managed product code exists */
2645     sz = MAX_PATH;
2646     lstrcpyA(buf, "apple");
2647     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2648     ok(r == ERROR_UNKNOWN_PROPERTY,
2649        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2650     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2651     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2652
2653     RegDeleteKeyA(prodkey, "");
2654     RegCloseKey(prodkey);
2655
2656     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2657     lstrcatA(keypath, usersid);
2658     lstrcatA(keypath, "\\Products\\");
2659     lstrcatA(keypath, prod_squashed);
2660
2661     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2662     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2663
2664     /* local user product code exists */
2665     sz = MAX_PATH;
2666     lstrcpyA(buf, "apple");
2667     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2668     ok(r == ERROR_UNKNOWN_PRODUCT,
2669        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2670     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2671     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2672
2673     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2674     lstrcatA(keypath, usersid);
2675     lstrcatA(keypath, "\\Installer\\Products\\");
2676     lstrcatA(keypath, prod_squashed);
2677
2678     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2680
2681     /* both local and managed product code exist */
2682     sz = MAX_PATH;
2683     lstrcpyA(buf, "apple");
2684     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2685     ok(r == ERROR_UNKNOWN_PROPERTY,
2686        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2687     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2688     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2689
2690     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2691     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2692
2693     /* InstallProperties key exists */
2694     sz = MAX_PATH;
2695     lstrcpyA(buf, "apple");
2696     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2697     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2698     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2699     ok(sz == 0, "Expected 0, got %d\n", sz);
2700
2701     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2703
2704     /* HelpLink value exists */
2705     sz = MAX_PATH;
2706     lstrcpyA(buf, "apple");
2707     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2708     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2709     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2710     ok(sz == 4, "Expected 4, got %d\n", sz);
2711
2712     /* pcchBuf is NULL */
2713     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
2714     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2715
2716     /* lpValueBuf is NULL */
2717     sz = MAX_PATH;
2718     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2719     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2720     ok(sz == 4, "Expected 4, got %d\n", sz);
2721
2722     /* lpValueBuf is NULL, pcchValueBuf is too small */
2723     sz = 2;
2724     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2726     ok(sz == 4, "Expected 4, got %d\n", sz);
2727
2728     /* lpValueBuf is NULL, pcchValueBuf is too small */
2729     sz = 2;
2730     lstrcpyA(buf, "apple");
2731     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2732     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
2733     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2734     ok(sz == 4, "Expected 4, got %d\n", sz);
2735
2736     /* lpValueBuf is NULL, pcchValueBuf is exactly 4 */
2737     sz = 4;
2738     lstrcpyA(buf, "apple");
2739     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2740     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2741     ok(!lstrcmpA(buf, "apple"),
2742        "Expected buf to remain unchanged, got \"%s\"\n", buf);
2743     ok(sz == 4, "Expected 4, got %d\n", sz);
2744
2745     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
2746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2747
2748     /* random property not supported by MSI, value exists */
2749     sz = MAX_PATH;
2750     lstrcpyA(buf, "apple");
2751     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
2752     ok(r == ERROR_UNKNOWN_PROPERTY,
2753        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2754     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2755     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2756
2757     RegDeleteValueA(propkey, "IMadeThis");
2758     RegDeleteValueA(propkey, "HelpLink");
2759     RegDeleteKeyA(propkey, "");
2760     RegDeleteKeyA(localkey, "");
2761     RegDeleteKeyA(prodkey, "");
2762     RegCloseKey(propkey);
2763     RegCloseKey(localkey);
2764     RegCloseKey(prodkey);
2765
2766     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2767     lstrcatA(keypath, prod_squashed);
2768
2769     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2770     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2771
2772     /* user product key exists */
2773     sz = MAX_PATH;
2774     lstrcpyA(buf, "apple");
2775     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2776     ok(r == ERROR_UNKNOWN_PROPERTY,
2777        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2778     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2779     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2780
2781     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2782     lstrcatA(keypath, usersid);
2783     lstrcatA(keypath, "\\Products\\");
2784     lstrcatA(keypath, prod_squashed);
2785
2786     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2788
2789     /* local user product key exists */
2790     sz = MAX_PATH;
2791     lstrcpyA(buf, "apple");
2792     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2793     ok(r == ERROR_UNKNOWN_PROPERTY,
2794        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2795     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2796     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2797
2798     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2799     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2800
2801     /* InstallProperties key exists */
2802     sz = MAX_PATH;
2803     lstrcpyA(buf, "apple");
2804     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2805     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2806     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2807     ok(sz == 0, "Expected 0, got %d\n", sz);
2808
2809     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2810     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2811
2812     /* HelpLink value exists */
2813     sz = MAX_PATH;
2814     lstrcpyA(buf, "apple");
2815     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2816     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2817     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2818     ok(sz == 4, "Expected 4, got %d\n", sz);
2819
2820     RegDeleteValueA(propkey, "HelpLink");
2821     RegDeleteKeyA(propkey, "");
2822     RegDeleteKeyA(localkey, "");
2823     RegDeleteKeyA(prodkey, "");
2824     RegCloseKey(propkey);
2825     RegCloseKey(localkey);
2826     RegCloseKey(prodkey);
2827
2828     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2829     lstrcatA(keypath, prod_squashed);
2830
2831     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2832     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2833
2834     /* classes product key exists */
2835     sz = MAX_PATH;
2836     lstrcpyA(buf, "apple");
2837     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2838     ok(r == ERROR_UNKNOWN_PROPERTY,
2839        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2840     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2841     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2842
2843     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2844     lstrcatA(keypath, usersid);
2845     lstrcatA(keypath, "\\Products\\");
2846     lstrcatA(keypath, prod_squashed);
2847
2848     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2849     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2850
2851     /* local user product key exists */
2852     sz = MAX_PATH;
2853     lstrcpyA(buf, "apple");
2854     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2855     ok(r == ERROR_UNKNOWN_PROPERTY,
2856        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2857     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2858     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2859
2860     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2861     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2862
2863     /* InstallProperties key exists */
2864     sz = MAX_PATH;
2865     lstrcpyA(buf, "apple");
2866     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2867     ok(r == ERROR_UNKNOWN_PROPERTY,
2868        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2869     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2870     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2871
2872     RegDeleteKeyA(propkey, "");
2873     RegDeleteKeyA(localkey, "");
2874     RegCloseKey(propkey);
2875     RegCloseKey(localkey);
2876
2877     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2878     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
2879     lstrcatA(keypath, prod_squashed);
2880
2881     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2882     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2883
2884     /* Local System product key exists */
2885     sz = MAX_PATH;
2886     lstrcpyA(buf, "apple");
2887     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2888     ok(r == ERROR_UNKNOWN_PROPERTY,
2889         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2890     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2891     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2892
2893     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2894     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2895
2896     /* InstallProperties key exists */
2897     sz = MAX_PATH;
2898     lstrcpyA(buf, "apple");
2899     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2900     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2901     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2902     ok(sz == 0, "Expected 0, got %d\n", sz);
2903
2904     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2906
2907     /* HelpLink value exists */
2908     sz = MAX_PATH;
2909     lstrcpyA(buf, "apple");
2910     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2911     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2912     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2913     ok(sz == 4, "Expected 4, got %d\n", sz);
2914
2915     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
2916                          (const BYTE *)&val, sizeof(DWORD));
2917     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2918
2919     /* HelpLink type is REG_DWORD */
2920     sz = MAX_PATH;
2921     lstrcpyA(buf, "apple");
2922     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2923     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2924     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2925     ok(sz == 2, "Expected 2, got %d\n", sz);
2926
2927     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
2928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2929
2930     /* DisplayName value exists */
2931     sz = MAX_PATH;
2932     lstrcpyA(buf, "apple");
2933     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2934     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2935     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
2936     ok(sz == 4, "Expected 4, got %d\n", sz);
2937
2938     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
2939                          (const BYTE *)&val, sizeof(DWORD));
2940     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2941
2942     /* DisplayName type is REG_DWORD */
2943     sz = MAX_PATH;
2944     lstrcpyA(buf, "apple");
2945     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2946     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2947     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2948     ok(sz == 2, "Expected 2, got %d\n", sz);
2949
2950     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
2951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2952
2953     /* DisplayVersion value exists */
2954     sz = MAX_PATH;
2955     lstrcpyA(buf, "apple");
2956     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2957     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2958     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
2959     ok(sz == 5, "Expected 5, got %d\n", sz);
2960
2961     res = RegSetValueExA(propkey, "DisplayVersion", 0,
2962                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2964
2965     /* DisplayVersion type is REG_DWORD */
2966     sz = MAX_PATH;
2967     lstrcpyA(buf, "apple");
2968     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2969     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2970     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2971     ok(sz == 2, "Expected 2, got %d\n", sz);
2972
2973     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
2974     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2975
2976     /* HelpTelephone value exists */
2977     sz = MAX_PATH;
2978     lstrcpyA(buf, "apple");
2979     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2980     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2981     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
2982     ok(sz == 4, "Expected 4, got %d\n", sz);
2983
2984     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
2985                          (const BYTE *)&val, sizeof(DWORD));
2986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2987
2988     /* HelpTelephone type is REG_DWORD */
2989     sz = MAX_PATH;
2990     lstrcpyA(buf, "apple");
2991     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2992     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2993     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2994     ok(sz == 2, "Expected 2, got %d\n", sz);
2995
2996     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
2997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2998
2999     /* InstallLocation value exists */
3000     sz = MAX_PATH;
3001     lstrcpyA(buf, "apple");
3002     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3004     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3005     ok(sz == 3, "Expected 3, got %d\n", sz);
3006
3007     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3008                          (const BYTE *)&val, sizeof(DWORD));
3009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3010
3011     /* InstallLocation type is REG_DWORD */
3012     sz = MAX_PATH;
3013     lstrcpyA(buf, "apple");
3014     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3016     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3017     ok(sz == 2, "Expected 2, got %d\n", sz);
3018
3019     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3020     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3021
3022     /* InstallSource value exists */
3023     sz = MAX_PATH;
3024     lstrcpyA(buf, "apple");
3025     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3027     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3028     ok(sz == 6, "Expected 6, got %d\n", sz);
3029
3030     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3031                          (const BYTE *)&val, sizeof(DWORD));
3032     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3033
3034     /* InstallSource type is REG_DWORD */
3035     sz = MAX_PATH;
3036     lstrcpyA(buf, "apple");
3037     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3038     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3039     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3040     ok(sz == 2, "Expected 2, got %d\n", sz);
3041
3042     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3044
3045     /* InstallDate value exists */
3046     sz = MAX_PATH;
3047     lstrcpyA(buf, "apple");
3048     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3049     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3050     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3051     ok(sz == 4, "Expected 4, got %d\n", sz);
3052
3053     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3054                          (const BYTE *)&val, sizeof(DWORD));
3055     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3056
3057     /* InstallDate type is REG_DWORD */
3058     sz = MAX_PATH;
3059     lstrcpyA(buf, "apple");
3060     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3062     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3063     ok(sz == 2, "Expected 2, got %d\n", sz);
3064
3065     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3067
3068     /* Publisher value exists */
3069     sz = MAX_PATH;
3070     lstrcpyA(buf, "apple");
3071     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3073     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3074     ok(sz == 3, "Expected 3, got %d\n", sz);
3075
3076     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3077                          (const BYTE *)&val, sizeof(DWORD));
3078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3079
3080     /* Publisher type is REG_DWORD */
3081     sz = MAX_PATH;
3082     lstrcpyA(buf, "apple");
3083     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3084     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3085     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3086     ok(sz == 2, "Expected 2, got %d\n", sz);
3087
3088     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3089     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3090
3091     /* LocalPackage value exists */
3092     sz = MAX_PATH;
3093     lstrcpyA(buf, "apple");
3094     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3095     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3096     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3097     ok(sz == 4, "Expected 4, got %d\n", sz);
3098
3099     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3100                          (const BYTE *)&val, sizeof(DWORD));
3101     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3102
3103     /* LocalPackage type is REG_DWORD */
3104     sz = MAX_PATH;
3105     lstrcpyA(buf, "apple");
3106     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3107     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3108     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3109     ok(sz == 2, "Expected 2, got %d\n", sz);
3110
3111     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3113
3114     /* UrlInfoAbout value exists */
3115     sz = MAX_PATH;
3116     lstrcpyA(buf, "apple");
3117     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3118     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3119     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3120     ok(sz == 5, "Expected 5, got %d\n", sz);
3121
3122     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3123                          (const BYTE *)&val, sizeof(DWORD));
3124     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3125
3126     /* UrlInfoAbout type is REG_DWORD */
3127     sz = MAX_PATH;
3128     lstrcpyA(buf, "apple");
3129     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3130     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3131     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3132     ok(sz == 2, "Expected 2, got %d\n", sz);
3133
3134     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3136
3137     /* UrlUpdateInfo value exists */
3138     sz = MAX_PATH;
3139     lstrcpyA(buf, "apple");
3140     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3142     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3143     ok(sz == 4, "Expected 4, got %d\n", sz);
3144
3145     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3146                          (const BYTE *)&val, sizeof(DWORD));
3147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3148
3149     /* UrlUpdateInfo type is REG_DWORD */
3150     sz = MAX_PATH;
3151     lstrcpyA(buf, "apple");
3152     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3153     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3154     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3155     ok(sz == 2, "Expected 2, got %d\n", sz);
3156
3157     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3159
3160     /* VersionMinor value exists */
3161     sz = MAX_PATH;
3162     lstrcpyA(buf, "apple");
3163     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3165     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3166     ok(sz == 1, "Expected 1, got %d\n", sz);
3167
3168     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3169                          (const BYTE *)&val, sizeof(DWORD));
3170     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3171
3172     /* VersionMinor type is REG_DWORD */
3173     sz = MAX_PATH;
3174     lstrcpyA(buf, "apple");
3175     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3177     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3178     ok(sz == 2, "Expected 2, got %d\n", sz);
3179
3180     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3181     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3182
3183     /* VersionMajor value exists */
3184     sz = MAX_PATH;
3185     lstrcpyA(buf, "apple");
3186     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3187     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3188     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3189     ok(sz == 1, "Expected 1, got %d\n", sz);
3190
3191     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3192                          (const BYTE *)&val, sizeof(DWORD));
3193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3194
3195     /* VersionMajor type is REG_DWORD */
3196     sz = MAX_PATH;
3197     lstrcpyA(buf, "apple");
3198     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3199     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3200     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3201     ok(sz == 2, "Expected 2, got %d\n", sz);
3202
3203     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3205
3206     /* ProductID value exists */
3207     sz = MAX_PATH;
3208     lstrcpyA(buf, "apple");
3209     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3211     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3212     ok(sz == 2, "Expected 2, got %d\n", sz);
3213
3214     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3215                          (const BYTE *)&val, sizeof(DWORD));
3216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3217
3218     /* ProductID type is REG_DWORD */
3219     sz = MAX_PATH;
3220     lstrcpyA(buf, "apple");
3221     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3223     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3224     ok(sz == 2, "Expected 2, got %d\n", sz);
3225
3226     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3228
3229     /* RegCompany value exists */
3230     sz = MAX_PATH;
3231     lstrcpyA(buf, "apple");
3232     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3234     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3235     ok(sz == 4, "Expected 4, got %d\n", sz);
3236
3237     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3238                          (const BYTE *)&val, sizeof(DWORD));
3239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3240
3241     /* RegCompany type is REG_DWORD */
3242     sz = MAX_PATH;
3243     lstrcpyA(buf, "apple");
3244     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3246     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3247     ok(sz == 2, "Expected 2, got %d\n", sz);
3248
3249     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3251
3252     /* RegOwner value exists */
3253     sz = MAX_PATH;
3254     lstrcpyA(buf, "apple");
3255     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3257     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3258     ok(sz == 3, "Expected 3, got %d\n", sz);
3259
3260     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3261                          (const BYTE *)&val, sizeof(DWORD));
3262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3263
3264     /* RegOwner type is REG_DWORD */
3265     sz = MAX_PATH;
3266     lstrcpyA(buf, "apple");
3267     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3268     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3269     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3270     ok(sz == 2, "Expected 2, got %d\n", sz);
3271
3272     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3274
3275     /* InstanceType value exists */
3276     sz = MAX_PATH;
3277     lstrcpyA(buf, "apple");
3278     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3280     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3281     ok(sz == 0, "Expected 0, got %d\n", sz);
3282
3283     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3284                          (const BYTE *)&val, sizeof(DWORD));
3285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3286
3287     /* InstanceType type is REG_DWORD */
3288     sz = MAX_PATH;
3289     lstrcpyA(buf, "apple");
3290     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3291     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3292     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3293     ok(sz == 0, "Expected 0, got %d\n", sz);
3294
3295     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3297
3298     /* InstanceType value exists */
3299     sz = MAX_PATH;
3300     lstrcpyA(buf, "apple");
3301     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3303     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3304     ok(sz == 4, "Expected 4, got %d\n", sz);
3305
3306     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3307                          (const BYTE *)&val, sizeof(DWORD));
3308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3309
3310     /* InstanceType type is REG_DWORD */
3311     sz = MAX_PATH;
3312     lstrcpyA(buf, "apple");
3313     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3315     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3316     ok(sz == 2, "Expected 2, got %d\n", sz);
3317
3318     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3320
3321     /* Transforms value exists */
3322     sz = MAX_PATH;
3323     lstrcpyA(buf, "apple");
3324     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3326     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3327     ok(sz == 0, "Expected 0, got %d\n", sz);
3328
3329     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3330                          (const BYTE *)&val, sizeof(DWORD));
3331     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3332
3333     /* Transforms type is REG_DWORD */
3334     sz = MAX_PATH;
3335     lstrcpyA(buf, "apple");
3336     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3338     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3339     ok(sz == 0, "Expected 0, got %d\n", sz);
3340
3341     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3343
3344     /* Transforms value exists */
3345     sz = MAX_PATH;
3346     lstrcpyA(buf, "apple");
3347     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3349     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3350     ok(sz == 6, "Expected 6, got %d\n", sz);
3351
3352     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3353                          (const BYTE *)&val, sizeof(DWORD));
3354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3355
3356     /* Transforms type is REG_DWORD */
3357     sz = MAX_PATH;
3358     lstrcpyA(buf, "apple");
3359     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3360     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3361     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3362     ok(sz == 2, "Expected 2, got %d\n", sz);
3363
3364     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3366
3367     /* Language value exists */
3368     sz = MAX_PATH;
3369     lstrcpyA(buf, "apple");
3370     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3372     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3373     ok(sz == 0, "Expected 0, got %d\n", sz);
3374
3375     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3376                          (const BYTE *)&val, sizeof(DWORD));
3377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3378
3379     /* Language type is REG_DWORD */
3380     sz = MAX_PATH;
3381     lstrcpyA(buf, "apple");
3382     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3384     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3385     ok(sz == 0, "Expected 0, got %d\n", sz);
3386
3387     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3389
3390     /* Language value exists */
3391     sz = MAX_PATH;
3392     lstrcpyA(buf, "apple");
3393     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3394     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3395     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3396     ok(sz == 4, "Expected 4, got %d\n", sz);
3397
3398     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3399                          (const BYTE *)&val, sizeof(DWORD));
3400     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3401
3402     /* Language type is REG_DWORD */
3403     sz = MAX_PATH;
3404     lstrcpyA(buf, "apple");
3405     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3406     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3407     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3408     ok(sz == 2, "Expected 2, got %d\n", sz);
3409
3410     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3412
3413     /* ProductName value exists */
3414     sz = MAX_PATH;
3415     lstrcpyA(buf, "apple");
3416     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3417     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3418     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3419     ok(sz == 0, "Expected 0, got %d\n", sz);
3420
3421     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3422                          (const BYTE *)&val, sizeof(DWORD));
3423     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3424
3425     /* ProductName type is REG_DWORD */
3426     sz = MAX_PATH;
3427     lstrcpyA(buf, "apple");
3428     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3429     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3430     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3431     ok(sz == 0, "Expected 0, got %d\n", sz);
3432
3433     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3435
3436     /* ProductName value exists */
3437     sz = MAX_PATH;
3438     lstrcpyA(buf, "apple");
3439     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3441     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3442     ok(sz == 4, "Expected 4, got %d\n", sz);
3443
3444     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3445                          (const BYTE *)&val, sizeof(DWORD));
3446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3447
3448     /* ProductName type is REG_DWORD */
3449     sz = MAX_PATH;
3450     lstrcpyA(buf, "apple");
3451     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3452     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3453     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3454     ok(sz == 2, "Expected 2, got %d\n", sz);
3455
3456     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3457     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3458
3459     /* Assignment value exists */
3460     sz = MAX_PATH;
3461     lstrcpyA(buf, "apple");
3462     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3464     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3465     ok(sz == 0, "Expected 0, got %d\n", sz);
3466
3467     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3468                          (const BYTE *)&val, sizeof(DWORD));
3469     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3470
3471     /* Assignment type is REG_DWORD */
3472     sz = MAX_PATH;
3473     lstrcpyA(buf, "apple");
3474     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3475     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3476     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3477     ok(sz == 0, "Expected 0, got %d\n", sz);
3478
3479     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3481
3482     /* Assignment value exists */
3483     sz = MAX_PATH;
3484     lstrcpyA(buf, "apple");
3485     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3486     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3487     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3488     ok(sz == 2, "Expected 2, got %d\n", sz);
3489
3490     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3491                          (const BYTE *)&val, sizeof(DWORD));
3492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3493
3494     /* Assignment type is REG_DWORD */
3495     sz = MAX_PATH;
3496     lstrcpyA(buf, "apple");
3497     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3498     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3499     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3500     ok(sz == 2, "Expected 2, got %d\n", sz);
3501
3502     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3504
3505     /* PackageCode value exists */
3506     sz = MAX_PATH;
3507     lstrcpyA(buf, "apple");
3508     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3510     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3511     ok(sz == 0, "Expected 0, got %d\n", sz);
3512
3513     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3514                          (const BYTE *)&val, sizeof(DWORD));
3515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3516
3517     /* PackageCode type is REG_DWORD */
3518     sz = MAX_PATH;
3519     lstrcpyA(buf, "apple");
3520     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3522     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3523     ok(sz == 0, "Expected 0, got %d\n", sz);
3524
3525     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3527
3528     /* PackageCode value exists */
3529     sz = MAX_PATH;
3530     lstrcpyA(buf, "apple");
3531     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3532     ok(r == ERROR_BAD_CONFIGURATION,
3533        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3534     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3535     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3536
3537     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3538                          (const BYTE *)&val, sizeof(DWORD));
3539     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3540
3541     /* PackageCode type is REG_DWORD */
3542     sz = MAX_PATH;
3543     lstrcpyA(buf, "apple");
3544     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3545     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3546     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3547     ok(sz == 2, "Expected 2, got %d\n", sz);
3548
3549     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3551
3552     /* PackageCode value exists */
3553     sz = MAX_PATH;
3554     lstrcpyA(buf, "apple");
3555     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3556     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3557     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3558     ok(sz == 38, "Expected 38, got %d\n", sz);
3559
3560     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3562
3563     /* Version value exists */
3564     sz = MAX_PATH;
3565     lstrcpyA(buf, "apple");
3566     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3567     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3568     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3569     ok(sz == 0, "Expected 0, got %d\n", sz);
3570
3571     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3572                          (const BYTE *)&val, sizeof(DWORD));
3573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3574
3575     /* Version type is REG_DWORD */
3576     sz = MAX_PATH;
3577     lstrcpyA(buf, "apple");
3578     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3579     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3580     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3581     ok(sz == 0, "Expected 0, got %d\n", sz);
3582
3583     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3584     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3585
3586     /* Version value exists */
3587     sz = MAX_PATH;
3588     lstrcpyA(buf, "apple");
3589     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3590     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3591     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3592     ok(sz == 3, "Expected 3, got %d\n", sz);
3593
3594     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3595                          (const BYTE *)&val, sizeof(DWORD));
3596     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3597
3598     /* Version type is REG_DWORD */
3599     sz = MAX_PATH;
3600     lstrcpyA(buf, "apple");
3601     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3602     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3603     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3604     ok(sz == 2, "Expected 2, got %d\n", sz);
3605
3606     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3608
3609     /* ProductIcon value exists */
3610     sz = MAX_PATH;
3611     lstrcpyA(buf, "apple");
3612     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3613     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3614     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3615     ok(sz == 0, "Expected 0, got %d\n", sz);
3616
3617     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3618                          (const BYTE *)&val, sizeof(DWORD));
3619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3620
3621     /* ProductIcon type is REG_DWORD */
3622     sz = MAX_PATH;
3623     lstrcpyA(buf, "apple");
3624     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3625     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3626     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3627     ok(sz == 0, "Expected 0, got %d\n", sz);
3628
3629     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3631
3632     /* ProductIcon value exists */
3633     sz = MAX_PATH;
3634     lstrcpyA(buf, "apple");
3635     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3636     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3637     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3638     ok(sz == 3, "Expected 3, got %d\n", sz);
3639
3640     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3641                          (const BYTE *)&val, sizeof(DWORD));
3642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3643
3644     /* ProductIcon type is REG_DWORD */
3645     sz = MAX_PATH;
3646     lstrcpyA(buf, "apple");
3647     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3648     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3649     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3650     ok(sz == 2, "Expected 2, got %d\n", sz);
3651
3652     /* SourceList key does not exist */
3653     sz = MAX_PATH;
3654     lstrcpyA(buf, "apple");
3655     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3656     ok(r == ERROR_UNKNOWN_PRODUCT,
3657        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3658     ok(!lstrcmpA(buf, "apple"),
3659        "Expected buf to be unchanged, got \"%s\"\n", buf);
3660     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
3661
3662     res = RegCreateKeyA(prodkey, "SourceList", &source);
3663     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3664
3665     /* SourceList key exists, but PackageName val does not exist */
3666     sz = MAX_PATH;
3667     lstrcpyA(buf, "apple");
3668     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3669     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3670     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3671     ok(sz == 0, "Expected 0, got %d\n", sz);
3672
3673     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3675
3676     /* PackageName val exists */
3677     sz = MAX_PATH;
3678     lstrcpyA(buf, "apple");
3679     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3680     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3681     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
3682     ok(sz == 8, "Expected 8, got %d\n", sz);
3683
3684     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
3685                          (const BYTE *)&val, sizeof(DWORD));
3686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3687
3688     /* PackageName type is REG_DWORD */
3689     sz = MAX_PATH;
3690     lstrcpyA(buf, "apple");
3691     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3692     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3693     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3694     ok(sz == 2, "Expected 2, got %d\n", sz);
3695
3696     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3697     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3698
3699     /* Authorized value exists */
3700     sz = MAX_PATH;
3701     lstrcpyA(buf, "apple");
3702     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3703     if (r != ERROR_UNKNOWN_PROPERTY)
3704     {
3705         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3706         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3707         ok(sz == 0, "Expected 0, got %d\n", sz);
3708     }
3709
3710     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
3711                          (const BYTE *)&val, sizeof(DWORD));
3712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3713
3714     /* AuthorizedLUAApp type is REG_DWORD */
3715     sz = MAX_PATH;
3716     lstrcpyA(buf, "apple");
3717     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3718     if (r != ERROR_UNKNOWN_PROPERTY)
3719     {
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
3725     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3727
3728     /* Authorized value exists */
3729     sz = MAX_PATH;
3730     lstrcpyA(buf, "apple");
3731     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3732     if (r != ERROR_UNKNOWN_PROPERTY)
3733     {
3734         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3735         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
3736         ok(sz == 4, "Expected 4, got %d\n", sz);
3737     }
3738
3739     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
3740                          (const BYTE *)&val, sizeof(DWORD));
3741     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3742
3743     /* AuthorizedLUAApp type is REG_DWORD */
3744     sz = MAX_PATH;
3745     lstrcpyA(buf, "apple");
3746     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3747     if (r != ERROR_UNKNOWN_PROPERTY)
3748     {
3749         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3750         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3751         ok(sz == 2, "Expected 2, got %d\n", sz);
3752     }
3753
3754     RegDeleteValueA(propkey, "HelpLink");
3755     RegDeleteValueA(propkey, "DisplayName");
3756     RegDeleteValueA(propkey, "DisplayVersion");
3757     RegDeleteValueA(propkey, "HelpTelephone");
3758     RegDeleteValueA(propkey, "InstallLocation");
3759     RegDeleteValueA(propkey, "InstallSource");
3760     RegDeleteValueA(propkey, "InstallDate");
3761     RegDeleteValueA(propkey, "Publisher");
3762     RegDeleteValueA(propkey, "LocalPackage");
3763     RegDeleteValueA(propkey, "UrlInfoAbout");
3764     RegDeleteValueA(propkey, "UrlUpdateInfo");
3765     RegDeleteValueA(propkey, "VersionMinor");
3766     RegDeleteValueA(propkey, "VersionMajor");
3767     RegDeleteValueA(propkey, "ProductID");
3768     RegDeleteValueA(propkey, "RegCompany");
3769     RegDeleteValueA(propkey, "RegOwner");
3770     RegDeleteValueA(propkey, "InstanceType");
3771     RegDeleteValueA(propkey, "Transforms");
3772     RegDeleteValueA(propkey, "Language");
3773     RegDeleteValueA(propkey, "ProductName");
3774     RegDeleteValueA(propkey, "Assignment");
3775     RegDeleteValueA(propkey, "PackageCode");
3776     RegDeleteValueA(propkey, "Version");
3777     RegDeleteValueA(propkey, "ProductIcon");
3778     RegDeleteValueA(propkey, "AuthorizedLUAApp");
3779     RegDeleteKeyA(propkey, "");
3780     RegDeleteKeyA(localkey, "");
3781     RegDeleteValueA(prodkey, "InstanceType");
3782     RegDeleteValueA(prodkey, "Transforms");
3783     RegDeleteValueA(prodkey, "Language");
3784     RegDeleteValueA(prodkey, "ProductName");
3785     RegDeleteValueA(prodkey, "Assignment");
3786     RegDeleteValueA(prodkey, "PackageCode");
3787     RegDeleteValueA(prodkey, "Version");
3788     RegDeleteValueA(prodkey, "ProductIcon");
3789     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
3790     RegDeleteValueA(source, "PackageName");
3791     RegDeleteKeyA(source, "");
3792     RegDeleteKeyA(prodkey, "");
3793     RegCloseKey(propkey);
3794     RegCloseKey(localkey);
3795     RegCloseKey(source);
3796     RegCloseKey(prodkey);
3797 }
3798
3799 static void test_MsiGetProductInfoEx(void)
3800 {
3801     UINT r;
3802     LONG res;
3803     HKEY propkey, userkey;
3804     HKEY prodkey, localkey;
3805     CHAR prodcode[MAX_PATH];
3806     CHAR prod_squashed[MAX_PATH];
3807     CHAR packcode[MAX_PATH];
3808     CHAR pack_squashed[MAX_PATH];
3809     CHAR buf[MAX_PATH];
3810     CHAR keypath[MAX_PATH];
3811     LPSTR usersid;
3812     DWORD sz;
3813
3814     if (!pMsiGetProductInfoExA)
3815     {
3816         skip("MsiGetProductInfoExA is not available\n");
3817         return;
3818     }
3819
3820     create_test_guid(prodcode, prod_squashed);
3821     create_test_guid(packcode, pack_squashed);
3822     get_user_sid(&usersid);
3823
3824     /* NULL szProductCode */
3825     sz = MAX_PATH;
3826     lstrcpyA(buf, "apple");
3827     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3828                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3829     ok(r == ERROR_INVALID_PARAMETER,
3830        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3831     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3832     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3833
3834     /* empty szProductCode */
3835     sz = MAX_PATH;
3836     lstrcpyA(buf, "apple");
3837     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3838                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3839     ok(r == ERROR_INVALID_PARAMETER,
3840        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3841     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3842     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3843
3844     /* garbage szProductCode */
3845     sz = MAX_PATH;
3846     lstrcpyA(buf, "apple");
3847     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3848                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3849     ok(r == ERROR_INVALID_PARAMETER,
3850        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3851     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3852     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3853
3854     /* guid without brackets */
3855     sz = MAX_PATH;
3856     lstrcpyA(buf, "apple");
3857     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
3858                               MSIINSTALLCONTEXT_USERUNMANAGED,
3859                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3860     ok(r == ERROR_INVALID_PARAMETER,
3861        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3862     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3863     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3864
3865     /* guid with brackets */
3866     sz = MAX_PATH;
3867     lstrcpyA(buf, "apple");
3868     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
3869                               MSIINSTALLCONTEXT_USERUNMANAGED,
3870                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3871     ok(r == ERROR_UNKNOWN_PRODUCT,
3872        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3873     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3874     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3875
3876     /* szValue is non-NULL while pcchValue is NULL */
3877     lstrcpyA(buf, "apple");
3878     r = pMsiGetProductInfoExA(prodcode, usersid,
3879                               MSIINSTALLCONTEXT_USERUNMANAGED,
3880                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
3881     ok(r == ERROR_INVALID_PARAMETER,
3882        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3883     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3884
3885     /* dwContext is out of range */
3886     sz = MAX_PATH;
3887     lstrcpyA(buf, "apple");
3888     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
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     /* szProperty is NULL */
3896     sz = MAX_PATH;
3897     lstrcpyA(buf, "apple");
3898     r = pMsiGetProductInfoExA(prodcode, usersid,
3899                               MSIINSTALLCONTEXT_USERUNMANAGED,
3900                               NULL, buf, &sz);
3901     ok(r == ERROR_INVALID_PARAMETER,
3902        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3903     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3904     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3905
3906     /* szProperty is empty */
3907     sz = MAX_PATH;
3908     lstrcpyA(buf, "apple");
3909     r = pMsiGetProductInfoExA(prodcode, usersid,
3910                               MSIINSTALLCONTEXT_USERUNMANAGED,
3911                               "", buf, &sz);
3912     ok(r == ERROR_INVALID_PARAMETER,
3913        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3914     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3915     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3916
3917     /* szProperty is not a valid property */
3918     sz = MAX_PATH;
3919     lstrcpyA(buf, "apple");
3920     r = pMsiGetProductInfoExA(prodcode, usersid,
3921                               MSIINSTALLCONTEXT_USERUNMANAGED,
3922                               "notvalid", buf, &sz);
3923     ok(r == ERROR_UNKNOWN_PRODUCT,
3924        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3925     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3926     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3927
3928     /* same length as guid, but random */
3929     sz = MAX_PATH;
3930     lstrcpyA(buf, "apple");
3931     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
3932                               MSIINSTALLCONTEXT_USERUNMANAGED,
3933                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3934     ok(r == ERROR_INVALID_PARAMETER,
3935        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3936     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3937     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3938
3939     /* MSIINSTALLCONTEXT_USERUNMANAGED */
3940
3941     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3942     lstrcatA(keypath, usersid);
3943     lstrcatA(keypath, "\\Products\\");
3944     lstrcatA(keypath, prod_squashed);
3945
3946     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
3947     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3948
3949     /* local user product key exists */
3950     sz = MAX_PATH;
3951     lstrcpyA(buf, "apple");
3952     r = pMsiGetProductInfoExA(prodcode, usersid,
3953                               MSIINSTALLCONTEXT_USERUNMANAGED,
3954                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3955     ok(r == ERROR_UNKNOWN_PRODUCT,
3956        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3957     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3958     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3959
3960     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
3961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3962
3963     /* InstallProperties key exists */
3964     sz = MAX_PATH;
3965     lstrcpyA(buf, "apple");
3966     r = pMsiGetProductInfoExA(prodcode, usersid,
3967                               MSIINSTALLCONTEXT_USERUNMANAGED,
3968                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3969     ok(r == ERROR_UNKNOWN_PRODUCT,
3970        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3971     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3972     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3973
3974     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3975     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3976
3977     /* LocalPackage value exists */
3978     sz = MAX_PATH;
3979     lstrcpyA(buf, "apple");
3980     r = pMsiGetProductInfoExA(prodcode, usersid,
3981                               MSIINSTALLCONTEXT_USERUNMANAGED,
3982                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3984     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
3985     ok(sz == 1, "Expected 1, got %d\n", sz);
3986
3987     RegDeleteValueA(propkey, "LocalPackage");
3988
3989     /* LocalPackage value must exist */
3990     sz = MAX_PATH;
3991     lstrcpyA(buf, "apple");
3992     r = pMsiGetProductInfoExA(prodcode, usersid,
3993                               MSIINSTALLCONTEXT_USERUNMANAGED,
3994                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3995     ok(r == ERROR_UNKNOWN_PRODUCT,
3996        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3997     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3998     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3999
4000     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4001     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4002
4003     /* LocalPackage exists, but HelpLink does not exist */
4004     sz = MAX_PATH;
4005     lstrcpyA(buf, "apple");
4006     r = pMsiGetProductInfoExA(prodcode, usersid,
4007                               MSIINSTALLCONTEXT_USERUNMANAGED,
4008                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4009     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4010     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4011     ok(sz == 0, "Expected 0, got %d\n", sz);
4012
4013     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4014     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4015
4016     /* HelpLink value exists */
4017     sz = MAX_PATH;
4018     lstrcpyA(buf, "apple");
4019     r = pMsiGetProductInfoExA(prodcode, usersid,
4020                               MSIINSTALLCONTEXT_USERUNMANAGED,
4021                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4022     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4023     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4024     ok(sz == 4, "Expected 4, got %d\n", sz);
4025
4026     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4027     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4028
4029     /* HelpTelephone value exists */
4030     sz = MAX_PATH;
4031     lstrcpyA(buf, "apple");
4032     r = pMsiGetProductInfoExA(prodcode, usersid,
4033                               MSIINSTALLCONTEXT_USERUNMANAGED,
4034                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4035     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4036     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4037     ok(sz == 5, "Expected 5, got %d\n", sz);
4038
4039     /* szValue and pcchValue are NULL */
4040     r = pMsiGetProductInfoExA(prodcode, usersid,
4041                               MSIINSTALLCONTEXT_USERUNMANAGED,
4042                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4044
4045     /* pcchValue is exactly 5 */
4046     sz = 5;
4047     lstrcpyA(buf, "apple");
4048     r = pMsiGetProductInfoExA(prodcode, usersid,
4049                               MSIINSTALLCONTEXT_USERUNMANAGED,
4050                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4051     ok(r == ERROR_MORE_DATA,
4052        "Expected ERROR_MORE_DATA, got %d\n", r);
4053     ok(sz == 10, "Expected 10, got %d\n", sz);
4054
4055     /* szValue is NULL, pcchValue is exactly 5 */
4056     sz = 5;
4057     r = pMsiGetProductInfoExA(prodcode, usersid,
4058                               MSIINSTALLCONTEXT_USERUNMANAGED,
4059                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4060     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4061     ok(sz == 10, "Expected 10, got %d\n", sz);
4062
4063     /* szValue is NULL, pcchValue is MAX_PATH */
4064     sz = MAX_PATH;
4065     r = pMsiGetProductInfoExA(prodcode, usersid,
4066                               MSIINSTALLCONTEXT_USERUNMANAGED,
4067                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4068     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4069     ok(sz == 10, "Expected 10, got %d\n", sz);
4070
4071     /* pcchValue is exactly 0 */
4072     sz = 0;
4073     lstrcpyA(buf, "apple");
4074     r = pMsiGetProductInfoExA(prodcode, usersid,
4075                               MSIINSTALLCONTEXT_USERUNMANAGED,
4076                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4077     ok(r == ERROR_MORE_DATA,
4078        "Expected ERROR_MORE_DATA, got %d\n", r);
4079     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4080     ok(sz == 10, "Expected 10, got %d\n", sz);
4081
4082     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4084
4085     /* szProperty is not a valid property */
4086     sz = MAX_PATH;
4087     lstrcpyA(buf, "apple");
4088     r = pMsiGetProductInfoExA(prodcode, usersid,
4089                               MSIINSTALLCONTEXT_USERUNMANAGED,
4090                               "notvalid", buf, &sz);
4091     ok(r == ERROR_UNKNOWN_PROPERTY,
4092        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4093     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4094     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4095
4096     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4097     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4098
4099     /* InstallDate value exists */
4100     sz = MAX_PATH;
4101     lstrcpyA(buf, "apple");
4102     r = pMsiGetProductInfoExA(prodcode, usersid,
4103                               MSIINSTALLCONTEXT_USERUNMANAGED,
4104                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4105     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4106     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4107     ok(sz == 4, "Expected 4, got %d\n", sz);
4108
4109     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4110     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4111
4112     /* DisplayName value exists */
4113     sz = MAX_PATH;
4114     lstrcpyA(buf, "apple");
4115     r = pMsiGetProductInfoExA(prodcode, usersid,
4116                               MSIINSTALLCONTEXT_USERUNMANAGED,
4117                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4118     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4119     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4120     ok(sz == 4, "Expected 4, got %d\n", sz);
4121
4122     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4124
4125     /* InstallLocation value exists */
4126     sz = MAX_PATH;
4127     lstrcpyA(buf, "apple");
4128     r = pMsiGetProductInfoExA(prodcode, usersid,
4129                               MSIINSTALLCONTEXT_USERUNMANAGED,
4130                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4131     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4132     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4133     ok(sz == 3, "Expected 3, got %d\n", sz);
4134
4135     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4136     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4137
4138     /* InstallSource value exists */
4139     sz = MAX_PATH;
4140     lstrcpyA(buf, "apple");
4141     r = pMsiGetProductInfoExA(prodcode, usersid,
4142                               MSIINSTALLCONTEXT_USERUNMANAGED,
4143                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4144     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4145     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4146     ok(sz == 6, "Expected 6, got %d\n", sz);
4147
4148     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4149     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4150
4151     /* LocalPackage value exists */
4152     sz = MAX_PATH;
4153     lstrcpyA(buf, "apple");
4154     r = pMsiGetProductInfoExA(prodcode, usersid,
4155                               MSIINSTALLCONTEXT_USERUNMANAGED,
4156                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4157     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4158     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4159     ok(sz == 5, "Expected 5, got %d\n", sz);
4160
4161     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4163
4164     /* Publisher value exists */
4165     sz = MAX_PATH;
4166     lstrcpyA(buf, "apple");
4167     r = pMsiGetProductInfoExA(prodcode, usersid,
4168                               MSIINSTALLCONTEXT_USERUNMANAGED,
4169                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4170     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4171     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4172     ok(sz == 3, "Expected 3, got %d\n", sz);
4173
4174     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4175     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4176
4177     /* URLInfoAbout value exists */
4178     sz = MAX_PATH;
4179     lstrcpyA(buf, "apple");
4180     r = pMsiGetProductInfoExA(prodcode, usersid,
4181                               MSIINSTALLCONTEXT_USERUNMANAGED,
4182                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4183     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4184     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4185     ok(sz == 5, "Expected 5, got %d\n", sz);
4186
4187     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4189
4190     /* URLUpdateInfo value exists */
4191     sz = MAX_PATH;
4192     lstrcpyA(buf, "apple");
4193     r = pMsiGetProductInfoExA(prodcode, usersid,
4194                               MSIINSTALLCONTEXT_USERUNMANAGED,
4195                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4196     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4197     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4198     ok(sz == 6, "Expected 6, got %d\n", sz);
4199
4200     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4201     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4202
4203     /* VersionMinor value exists */
4204     sz = MAX_PATH;
4205     lstrcpyA(buf, "apple");
4206     r = pMsiGetProductInfoExA(prodcode, usersid,
4207                               MSIINSTALLCONTEXT_USERUNMANAGED,
4208                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4209     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4210     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4211     ok(sz == 1, "Expected 1, got %d\n", sz);
4212
4213     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4214     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4215
4216     /* VersionMajor value exists */
4217     sz = MAX_PATH;
4218     lstrcpyA(buf, "apple");
4219     r = pMsiGetProductInfoExA(prodcode, usersid,
4220                               MSIINSTALLCONTEXT_USERUNMANAGED,
4221                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4223     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4224     ok(sz == 1, "Expected 1, got %d\n", sz);
4225
4226     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4228
4229     /* DisplayVersion value exists */
4230     sz = MAX_PATH;
4231     lstrcpyA(buf, "apple");
4232     r = pMsiGetProductInfoExA(prodcode, usersid,
4233                               MSIINSTALLCONTEXT_USERUNMANAGED,
4234                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4235     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4236     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4237     ok(sz == 5, "Expected 5, got %d\n", sz);
4238
4239     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4240     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4241
4242     /* ProductID value exists */
4243     sz = MAX_PATH;
4244     lstrcpyA(buf, "apple");
4245     r = pMsiGetProductInfoExA(prodcode, usersid,
4246                               MSIINSTALLCONTEXT_USERUNMANAGED,
4247                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4248     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4249     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4250     ok(sz == 2, "Expected 2, got %d\n", sz);
4251
4252     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4253     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4254
4255     /* RegCompany value exists */
4256     sz = MAX_PATH;
4257     lstrcpyA(buf, "apple");
4258     r = pMsiGetProductInfoExA(prodcode, usersid,
4259                               MSIINSTALLCONTEXT_USERUNMANAGED,
4260                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4261     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4262     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4263     ok(sz == 4, "Expected 4, got %d\n", sz);
4264
4265     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4267
4268     /* RegOwner value exists */
4269     sz = MAX_PATH;
4270     lstrcpyA(buf, "apple");
4271     r = pMsiGetProductInfoExA(prodcode, usersid,
4272                               MSIINSTALLCONTEXT_USERUNMANAGED,
4273                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4274     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4275     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4276     ok(sz == 5, "Expected 5, got %d\n", sz);
4277
4278     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4279     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4280
4281     /* Transforms value exists */
4282     sz = MAX_PATH;
4283     lstrcpyA(buf, "apple");
4284     r = pMsiGetProductInfoExA(prodcode, usersid,
4285                               MSIINSTALLCONTEXT_USERUNMANAGED,
4286                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4287     ok(r == ERROR_UNKNOWN_PRODUCT,
4288        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4289     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4290     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4291
4292     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4294
4295     /* Language value exists */
4296     sz = MAX_PATH;
4297     lstrcpyA(buf, "apple");
4298     r = pMsiGetProductInfoExA(prodcode, usersid,
4299                               MSIINSTALLCONTEXT_USERUNMANAGED,
4300                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4301     ok(r == ERROR_UNKNOWN_PRODUCT,
4302        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4303     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4304     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4305
4306     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4308
4309     /* ProductName value exists */
4310     sz = MAX_PATH;
4311     lstrcpyA(buf, "apple");
4312     r = pMsiGetProductInfoExA(prodcode, usersid,
4313                               MSIINSTALLCONTEXT_USERUNMANAGED,
4314                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4315     ok(r == ERROR_UNKNOWN_PRODUCT,
4316        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4317     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4318     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4319
4320     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4321     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4322
4323     /* FIXME */
4324
4325     /* AssignmentType value exists */
4326     sz = MAX_PATH;
4327     lstrcpyA(buf, "apple");
4328     r = pMsiGetProductInfoExA(prodcode, usersid,
4329                               MSIINSTALLCONTEXT_USERUNMANAGED,
4330                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4331     ok(r == ERROR_UNKNOWN_PRODUCT,
4332        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4333     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4334     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4335
4336     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4337     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4338
4339     /* PackageCode value exists */
4340     sz = MAX_PATH;
4341     lstrcpyA(buf, "apple");
4342     r = pMsiGetProductInfoExA(prodcode, usersid,
4343                               MSIINSTALLCONTEXT_USERUNMANAGED,
4344                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4345     ok(r == ERROR_UNKNOWN_PRODUCT,
4346        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4347     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4348     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4349
4350     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4352
4353     /* Version value exists */
4354     sz = MAX_PATH;
4355     lstrcpyA(buf, "apple");
4356     r = pMsiGetProductInfoExA(prodcode, usersid,
4357                               MSIINSTALLCONTEXT_USERUNMANAGED,
4358                               INSTALLPROPERTY_VERSION, buf, &sz);
4359     ok(r == ERROR_UNKNOWN_PRODUCT,
4360        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4361     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4362     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4363
4364     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4366
4367     /* ProductIcon value exists */
4368     sz = MAX_PATH;
4369     lstrcpyA(buf, "apple");
4370     r = pMsiGetProductInfoExA(prodcode, usersid,
4371                               MSIINSTALLCONTEXT_USERUNMANAGED,
4372                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4373     ok(r == ERROR_UNKNOWN_PRODUCT,
4374        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4375     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4376     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4377
4378     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4380
4381     /* PackageName value exists */
4382     sz = MAX_PATH;
4383     lstrcpyA(buf, "apple");
4384     r = pMsiGetProductInfoExA(prodcode, usersid,
4385                               MSIINSTALLCONTEXT_USERUNMANAGED,
4386                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4387     ok(r == ERROR_UNKNOWN_PRODUCT,
4388        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4389     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4390     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4391
4392     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4393     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4394
4395     /* AuthorizedLUAApp value exists */
4396     sz = MAX_PATH;
4397     lstrcpyA(buf, "apple");
4398     r = pMsiGetProductInfoExA(prodcode, usersid,
4399                               MSIINSTALLCONTEXT_USERUNMANAGED,
4400                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4401     ok(r == ERROR_UNKNOWN_PRODUCT,
4402        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4403     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4404     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4405
4406     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4407     RegDeleteValueA(propkey, "PackageName");
4408     RegDeleteValueA(propkey, "ProductIcon");
4409     RegDeleteValueA(propkey, "Version");
4410     RegDeleteValueA(propkey, "PackageCode");
4411     RegDeleteValueA(propkey, "AssignmentType");
4412     RegDeleteValueA(propkey, "ProductName");
4413     RegDeleteValueA(propkey, "Language");
4414     RegDeleteValueA(propkey, "Transforms");
4415     RegDeleteValueA(propkey, "RegOwner");
4416     RegDeleteValueA(propkey, "RegCompany");
4417     RegDeleteValueA(propkey, "ProductID");
4418     RegDeleteValueA(propkey, "DisplayVersion");
4419     RegDeleteValueA(propkey, "VersionMajor");
4420     RegDeleteValueA(propkey, "VersionMinor");
4421     RegDeleteValueA(propkey, "URLUpdateInfo");
4422     RegDeleteValueA(propkey, "URLInfoAbout");
4423     RegDeleteValueA(propkey, "Publisher");
4424     RegDeleteValueA(propkey, "LocalPackage");
4425     RegDeleteValueA(propkey, "InstallSource");
4426     RegDeleteValueA(propkey, "InstallLocation");
4427     RegDeleteValueA(propkey, "DisplayName");
4428     RegDeleteValueA(propkey, "InstallDate");
4429     RegDeleteValueA(propkey, "HelpTelephone");
4430     RegDeleteValueA(propkey, "HelpLink");
4431     RegDeleteValueA(propkey, "LocalPackage");
4432     RegDeleteKeyA(propkey, "");
4433     RegCloseKey(propkey);
4434     RegDeleteKeyA(localkey, "");
4435     RegCloseKey(localkey);
4436
4437     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4438     lstrcatA(keypath, usersid);
4439     lstrcatA(keypath, "\\Installer\\Products\\");
4440     lstrcatA(keypath, prod_squashed);
4441
4442     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
4443     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4444
4445     /* user product key exists */
4446     sz = MAX_PATH;
4447     lstrcpyA(buf, "apple");
4448     r = pMsiGetProductInfoExA(prodcode, usersid,
4449                               MSIINSTALLCONTEXT_USERUNMANAGED,
4450                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4451     ok(r == ERROR_UNKNOWN_PRODUCT,
4452        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4453     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4454     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4455
4456     RegDeleteKeyA(userkey, "");
4457     RegCloseKey(userkey);
4458
4459     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4460     lstrcatA(keypath, prod_squashed);
4461
4462     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4463     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4464
4465     sz = MAX_PATH;
4466     lstrcpyA(buf, "apple");
4467     r = pMsiGetProductInfoExA(prodcode, usersid,
4468                               MSIINSTALLCONTEXT_USERUNMANAGED,
4469                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4470     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4471     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4472     ok(sz == 1, "Expected 1, got %d\n", sz);
4473
4474     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4475     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4476
4477     /* HelpLink value exists */
4478     sz = MAX_PATH;
4479     lstrcpyA(buf, "apple");
4480     r = pMsiGetProductInfoExA(prodcode, usersid,
4481                               MSIINSTALLCONTEXT_USERUNMANAGED,
4482                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4483     ok(r == ERROR_UNKNOWN_PROPERTY,
4484        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4485     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4486     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4487
4488     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4489     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4490
4491     /* HelpTelephone value exists */
4492     sz = MAX_PATH;
4493     lstrcpyA(buf, "apple");
4494     r = pMsiGetProductInfoExA(prodcode, usersid,
4495                               MSIINSTALLCONTEXT_USERUNMANAGED,
4496                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4497     ok(r == ERROR_UNKNOWN_PROPERTY,
4498        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4499     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4500     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4501
4502     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4504
4505     /* InstallDate value exists */
4506     sz = MAX_PATH;
4507     lstrcpyA(buf, "apple");
4508     r = pMsiGetProductInfoExA(prodcode, usersid,
4509                               MSIINSTALLCONTEXT_USERUNMANAGED,
4510                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4511     ok(r == ERROR_UNKNOWN_PROPERTY,
4512        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4513     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4514     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4515
4516     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4517     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4518
4519     /* DisplayName value exists */
4520     sz = MAX_PATH;
4521     lstrcpyA(buf, "apple");
4522     r = pMsiGetProductInfoExA(prodcode, usersid,
4523                               MSIINSTALLCONTEXT_USERUNMANAGED,
4524                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4525     ok(r == ERROR_UNKNOWN_PROPERTY,
4526        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4527     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4528     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4529
4530     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4531     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4532
4533     /* InstallLocation value exists */
4534     sz = MAX_PATH;
4535     lstrcpyA(buf, "apple");
4536     r = pMsiGetProductInfoExA(prodcode, usersid,
4537                               MSIINSTALLCONTEXT_USERUNMANAGED,
4538                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4539     ok(r == ERROR_UNKNOWN_PROPERTY,
4540        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4541     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4542     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4543
4544     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4545     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4546
4547     /* InstallSource value exists */
4548     sz = MAX_PATH;
4549     lstrcpyA(buf, "apple");
4550     r = pMsiGetProductInfoExA(prodcode, usersid,
4551                               MSIINSTALLCONTEXT_USERUNMANAGED,
4552                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4553     ok(r == ERROR_UNKNOWN_PROPERTY,
4554        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4555     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4556     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4557
4558     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4559     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4560
4561     /* LocalPackage value exists */
4562     sz = MAX_PATH;
4563     lstrcpyA(buf, "apple");
4564     r = pMsiGetProductInfoExA(prodcode, usersid,
4565                               MSIINSTALLCONTEXT_USERUNMANAGED,
4566                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4567     ok(r == ERROR_UNKNOWN_PROPERTY,
4568        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4569     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4570     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4571
4572     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4574
4575     /* Publisher value exists */
4576     sz = MAX_PATH;
4577     lstrcpyA(buf, "apple");
4578     r = pMsiGetProductInfoExA(prodcode, usersid,
4579                               MSIINSTALLCONTEXT_USERUNMANAGED,
4580                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4581     ok(r == ERROR_UNKNOWN_PROPERTY,
4582        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4583     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4584     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4585
4586     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4587     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4588
4589     /* URLInfoAbout value exists */
4590     sz = MAX_PATH;
4591     lstrcpyA(buf, "apple");
4592     r = pMsiGetProductInfoExA(prodcode, usersid,
4593                               MSIINSTALLCONTEXT_USERUNMANAGED,
4594                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4595     ok(r == ERROR_UNKNOWN_PROPERTY,
4596        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4597     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4598     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4599
4600     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4602
4603     /* URLUpdateInfo value exists */
4604     sz = MAX_PATH;
4605     lstrcpyA(buf, "apple");
4606     r = pMsiGetProductInfoExA(prodcode, usersid,
4607                               MSIINSTALLCONTEXT_USERUNMANAGED,
4608                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4609     ok(r == ERROR_UNKNOWN_PROPERTY,
4610        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4611     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4612     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4613
4614     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4615     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4616
4617     /* VersionMinor value exists */
4618     sz = MAX_PATH;
4619     lstrcpyA(buf, "apple");
4620     r = pMsiGetProductInfoExA(prodcode, usersid,
4621                               MSIINSTALLCONTEXT_USERUNMANAGED,
4622                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4623     ok(r == ERROR_UNKNOWN_PROPERTY,
4624        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4625     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4626     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4627
4628     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4629     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4630
4631     /* VersionMajor value exists */
4632     sz = MAX_PATH;
4633     lstrcpyA(buf, "apple");
4634     r = pMsiGetProductInfoExA(prodcode, usersid,
4635                               MSIINSTALLCONTEXT_USERUNMANAGED,
4636                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4637     ok(r == ERROR_UNKNOWN_PROPERTY,
4638        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4639     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4640     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4641
4642     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4643     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4644
4645     /* DisplayVersion value exists */
4646     sz = MAX_PATH;
4647     lstrcpyA(buf, "apple");
4648     r = pMsiGetProductInfoExA(prodcode, usersid,
4649                               MSIINSTALLCONTEXT_USERUNMANAGED,
4650                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4651     ok(r == ERROR_UNKNOWN_PROPERTY,
4652        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4653     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4654     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4655
4656     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4657     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4658
4659     /* ProductID value exists */
4660     sz = MAX_PATH;
4661     lstrcpyA(buf, "apple");
4662     r = pMsiGetProductInfoExA(prodcode, usersid,
4663                               MSIINSTALLCONTEXT_USERUNMANAGED,
4664                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4665     ok(r == ERROR_UNKNOWN_PROPERTY,
4666        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4667     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4668     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4669
4670     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4671     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4672
4673     /* RegCompany value exists */
4674     sz = MAX_PATH;
4675     lstrcpyA(buf, "apple");
4676     r = pMsiGetProductInfoExA(prodcode, usersid,
4677                               MSIINSTALLCONTEXT_USERUNMANAGED,
4678                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4679     ok(r == ERROR_UNKNOWN_PROPERTY,
4680        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4681     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4682     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4683
4684     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4685     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4686
4687     /* RegOwner value exists */
4688     sz = MAX_PATH;
4689     lstrcpyA(buf, "apple");
4690     r = pMsiGetProductInfoExA(prodcode, usersid,
4691                               MSIINSTALLCONTEXT_USERUNMANAGED,
4692                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4693     ok(r == ERROR_UNKNOWN_PROPERTY,
4694        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4695     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4696     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4697
4698     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4700
4701     /* Transforms value exists */
4702     sz = MAX_PATH;
4703     lstrcpyA(buf, "apple");
4704     r = pMsiGetProductInfoExA(prodcode, usersid,
4705                               MSIINSTALLCONTEXT_USERUNMANAGED,
4706                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4707     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4708     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
4709     ok(sz == 5, "Expected 5, got %d\n", sz);
4710
4711     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4713
4714     /* Language value exists */
4715     sz = MAX_PATH;
4716     lstrcpyA(buf, "apple");
4717     r = pMsiGetProductInfoExA(prodcode, usersid,
4718                               MSIINSTALLCONTEXT_USERUNMANAGED,
4719                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4720     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4721     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4722     ok(sz == 4, "Expected 4, got %d\n", sz);
4723
4724     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4726
4727     /* ProductName value exists */
4728     sz = MAX_PATH;
4729     lstrcpyA(buf, "apple");
4730     r = pMsiGetProductInfoExA(prodcode, usersid,
4731                               MSIINSTALLCONTEXT_USERUNMANAGED,
4732                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4733     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4734     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4735     ok(sz == 4, "Expected 4, got %d\n", sz);
4736
4737     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4738     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4739
4740     /* FIXME */
4741
4742     /* AssignmentType value exists */
4743     sz = MAX_PATH;
4744     lstrcpyA(buf, "apple");
4745     r = pMsiGetProductInfoExA(prodcode, usersid,
4746                               MSIINSTALLCONTEXT_USERUNMANAGED,
4747                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4748     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4749     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4750     ok(sz == 0, "Expected 0, got %d\n", sz);
4751
4752     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4754
4755     /* FIXME */
4756
4757     /* PackageCode value exists */
4758     sz = MAX_PATH;
4759     lstrcpyA(buf, "apple");
4760     r = pMsiGetProductInfoExA(prodcode, usersid,
4761                               MSIINSTALLCONTEXT_USERUNMANAGED,
4762                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4763     todo_wine
4764     {
4765         ok(r == ERROR_BAD_CONFIGURATION,
4766            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4767         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4768         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4769     }
4770
4771     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4772     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4773
4774     /* Version value exists */
4775     sz = MAX_PATH;
4776     lstrcpyA(buf, "apple");
4777     r = pMsiGetProductInfoExA(prodcode, usersid,
4778                               MSIINSTALLCONTEXT_USERUNMANAGED,
4779                               INSTALLPROPERTY_VERSION, buf, &sz);
4780     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4781     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4782     ok(sz == 3, "Expected 3, got %d\n", sz);
4783
4784     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4786
4787     /* ProductIcon value exists */
4788     sz = MAX_PATH;
4789     lstrcpyA(buf, "apple");
4790     r = pMsiGetProductInfoExA(prodcode, usersid,
4791                               MSIINSTALLCONTEXT_USERUNMANAGED,
4792                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4793     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4794     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
4795     ok(sz == 4, "Expected 4, got %d\n", sz);
4796
4797     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4798     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4799
4800     /* PackageName value exists */
4801     sz = MAX_PATH;
4802     lstrcpyA(buf, "apple");
4803     r = pMsiGetProductInfoExA(prodcode, usersid,
4804                               MSIINSTALLCONTEXT_USERUNMANAGED,
4805                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4806     todo_wine
4807     {
4808         ok(r == ERROR_UNKNOWN_PRODUCT,
4809            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4810         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4811         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4812     }
4813
4814     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4815     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4816
4817     /* AuthorizedLUAApp value exists */
4818     sz = MAX_PATH;
4819     lstrcpyA(buf, "apple");
4820     r = pMsiGetProductInfoExA(prodcode, usersid,
4821                               MSIINSTALLCONTEXT_USERUNMANAGED,
4822                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4823     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4824     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4825     ok(sz == 4, "Expected 4, got %d\n", sz);
4826
4827     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4828     RegDeleteValueA(prodkey, "PackageName");
4829     RegDeleteValueA(prodkey, "ProductIcon");
4830     RegDeleteValueA(prodkey, "Version");
4831     RegDeleteValueA(prodkey, "PackageCode");
4832     RegDeleteValueA(prodkey, "AssignmentType");
4833     RegDeleteValueA(prodkey, "ProductName");
4834     RegDeleteValueA(prodkey, "Language");
4835     RegDeleteValueA(prodkey, "Transforms");
4836     RegDeleteValueA(prodkey, "RegOwner");
4837     RegDeleteValueA(prodkey, "RegCompany");
4838     RegDeleteValueA(prodkey, "ProductID");
4839     RegDeleteValueA(prodkey, "DisplayVersion");
4840     RegDeleteValueA(prodkey, "VersionMajor");
4841     RegDeleteValueA(prodkey, "VersionMinor");
4842     RegDeleteValueA(prodkey, "URLUpdateInfo");
4843     RegDeleteValueA(prodkey, "URLInfoAbout");
4844     RegDeleteValueA(prodkey, "Publisher");
4845     RegDeleteValueA(prodkey, "LocalPackage");
4846     RegDeleteValueA(prodkey, "InstallSource");
4847     RegDeleteValueA(prodkey, "InstallLocation");
4848     RegDeleteValueA(prodkey, "DisplayName");
4849     RegDeleteValueA(prodkey, "InstallDate");
4850     RegDeleteValueA(prodkey, "HelpTelephone");
4851     RegDeleteValueA(prodkey, "HelpLink");
4852     RegDeleteValueA(prodkey, "LocalPackage");
4853     RegDeleteKeyA(prodkey, "");
4854     RegCloseKey(prodkey);
4855
4856     /* MSIINSTALLCONTEXT_USERMANAGED */
4857
4858     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4859     lstrcatA(keypath, usersid);
4860     lstrcatA(keypath, "\\Products\\");
4861     lstrcatA(keypath, prod_squashed);
4862
4863     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4864     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4865
4866     /* local user product key exists */
4867     sz = MAX_PATH;
4868     lstrcpyA(buf, "apple");
4869     r = pMsiGetProductInfoExA(prodcode, usersid,
4870                               MSIINSTALLCONTEXT_USERMANAGED,
4871                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4872     ok(r == ERROR_UNKNOWN_PRODUCT,
4873        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4874     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4875     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4876
4877     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4878     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4879
4880     /* InstallProperties key exists */
4881     sz = MAX_PATH;
4882     lstrcpyA(buf, "apple");
4883     r = pMsiGetProductInfoExA(prodcode, usersid,
4884                               MSIINSTALLCONTEXT_USERMANAGED,
4885                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4886     ok(r == ERROR_UNKNOWN_PRODUCT,
4887        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4888     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4889     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4890
4891     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4892     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4893
4894     /* ManagedLocalPackage value exists */
4895     sz = MAX_PATH;
4896     lstrcpyA(buf, "apple");
4897     r = pMsiGetProductInfoExA(prodcode, usersid,
4898                               MSIINSTALLCONTEXT_USERMANAGED,
4899                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4900     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4901     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4902     ok(sz == 1, "Expected 1, got %d\n", sz);
4903
4904     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4906
4907     /* HelpLink value exists */
4908     sz = MAX_PATH;
4909     lstrcpyA(buf, "apple");
4910     r = pMsiGetProductInfoExA(prodcode, usersid,
4911                               MSIINSTALLCONTEXT_USERMANAGED,
4912                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4913     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4914     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4915     ok(sz == 4, "Expected 4, got %d\n", sz);
4916
4917     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4918     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4919
4920     /* HelpTelephone value exists */
4921     sz = MAX_PATH;
4922     lstrcpyA(buf, "apple");
4923     r = pMsiGetProductInfoExA(prodcode, usersid,
4924                               MSIINSTALLCONTEXT_USERMANAGED,
4925                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4926     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4927     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4928     ok(sz == 5, "Expected 5, got %d\n", sz);
4929
4930     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4931     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4932
4933     /* InstallDate value exists */
4934     sz = MAX_PATH;
4935     lstrcpyA(buf, "apple");
4936     r = pMsiGetProductInfoExA(prodcode, usersid,
4937                               MSIINSTALLCONTEXT_USERMANAGED,
4938                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4939     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4940     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4941     ok(sz == 4, "Expected 4, got %d\n", sz);
4942
4943     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4945
4946     /* DisplayName value exists */
4947     sz = MAX_PATH;
4948     lstrcpyA(buf, "apple");
4949     r = pMsiGetProductInfoExA(prodcode, usersid,
4950                               MSIINSTALLCONTEXT_USERMANAGED,
4951                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4953     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4954     ok(sz == 4, "Expected 4, got %d\n", sz);
4955
4956     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4958
4959     /* InstallLocation value exists */
4960     sz = MAX_PATH;
4961     lstrcpyA(buf, "apple");
4962     r = pMsiGetProductInfoExA(prodcode, usersid,
4963                               MSIINSTALLCONTEXT_USERMANAGED,
4964                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4965     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4966     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4967     ok(sz == 3, "Expected 3, got %d\n", sz);
4968
4969     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4970     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4971
4972     /* InstallSource value exists */
4973     sz = MAX_PATH;
4974     lstrcpyA(buf, "apple");
4975     r = pMsiGetProductInfoExA(prodcode, usersid,
4976                               MSIINSTALLCONTEXT_USERMANAGED,
4977                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4978     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4979     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4980     ok(sz == 6, "Expected 6, got %d\n", sz);
4981
4982     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4984
4985     /* LocalPackage value exists */
4986     sz = MAX_PATH;
4987     lstrcpyA(buf, "apple");
4988     r = pMsiGetProductInfoExA(prodcode, usersid,
4989                               MSIINSTALLCONTEXT_USERMANAGED,
4990                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4991     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4992     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4993     ok(sz == 5, "Expected 5, got %d\n", sz);
4994
4995     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4997
4998     /* Publisher value exists */
4999     sz = MAX_PATH;
5000     lstrcpyA(buf, "apple");
5001     r = pMsiGetProductInfoExA(prodcode, usersid,
5002                               MSIINSTALLCONTEXT_USERMANAGED,
5003                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5004     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5005     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5006     ok(sz == 3, "Expected 3, got %d\n", sz);
5007
5008     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5010
5011     /* URLInfoAbout value exists */
5012     sz = MAX_PATH;
5013     lstrcpyA(buf, "apple");
5014     r = pMsiGetProductInfoExA(prodcode, usersid,
5015                               MSIINSTALLCONTEXT_USERMANAGED,
5016                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5017     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5018     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5019     ok(sz == 5, "Expected 5, got %d\n", sz);
5020
5021     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5022     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5023
5024     /* URLUpdateInfo value exists */
5025     sz = MAX_PATH;
5026     lstrcpyA(buf, "apple");
5027     r = pMsiGetProductInfoExA(prodcode, usersid,
5028                               MSIINSTALLCONTEXT_USERMANAGED,
5029                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5030     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5031     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5032     ok(sz == 6, "Expected 6, got %d\n", sz);
5033
5034     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5035     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5036
5037     /* VersionMinor value exists */
5038     sz = MAX_PATH;
5039     lstrcpyA(buf, "apple");
5040     r = pMsiGetProductInfoExA(prodcode, usersid,
5041                               MSIINSTALLCONTEXT_USERMANAGED,
5042                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5044     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5045     ok(sz == 1, "Expected 1, got %d\n", sz);
5046
5047     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5049
5050     /* VersionMajor value exists */
5051     sz = MAX_PATH;
5052     lstrcpyA(buf, "apple");
5053     r = pMsiGetProductInfoExA(prodcode, usersid,
5054                               MSIINSTALLCONTEXT_USERMANAGED,
5055                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5056     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5057     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5058     ok(sz == 1, "Expected 1, got %d\n", sz);
5059
5060     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5062
5063     /* DisplayVersion value exists */
5064     sz = MAX_PATH;
5065     lstrcpyA(buf, "apple");
5066     r = pMsiGetProductInfoExA(prodcode, usersid,
5067                               MSIINSTALLCONTEXT_USERMANAGED,
5068                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5069     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5070     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5071     ok(sz == 5, "Expected 5, got %d\n", sz);
5072
5073     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5074     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5075
5076     /* ProductID value exists */
5077     sz = MAX_PATH;
5078     lstrcpyA(buf, "apple");
5079     r = pMsiGetProductInfoExA(prodcode, usersid,
5080                               MSIINSTALLCONTEXT_USERMANAGED,
5081                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5082     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5083     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5084     ok(sz == 2, "Expected 2, got %d\n", sz);
5085
5086     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5088
5089     /* RegCompany value exists */
5090     sz = MAX_PATH;
5091     lstrcpyA(buf, "apple");
5092     r = pMsiGetProductInfoExA(prodcode, usersid,
5093                               MSIINSTALLCONTEXT_USERMANAGED,
5094                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5095     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5096     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5097     ok(sz == 4, "Expected 4, got %d\n", sz);
5098
5099     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5101
5102     /* RegOwner value exists */
5103     sz = MAX_PATH;
5104     lstrcpyA(buf, "apple");
5105     r = pMsiGetProductInfoExA(prodcode, usersid,
5106                               MSIINSTALLCONTEXT_USERMANAGED,
5107                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5108     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5109     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5110     ok(sz == 5, "Expected 5, got %d\n", sz);
5111
5112     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5113     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5114
5115     /* Transforms value exists */
5116     sz = MAX_PATH;
5117     lstrcpyA(buf, "apple");
5118     r = pMsiGetProductInfoExA(prodcode, usersid,
5119                               MSIINSTALLCONTEXT_USERMANAGED,
5120                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5121     ok(r == ERROR_UNKNOWN_PRODUCT,
5122        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5123     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5124     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5125
5126     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5127     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5128
5129     /* Language value exists */
5130     sz = MAX_PATH;
5131     lstrcpyA(buf, "apple");
5132     r = pMsiGetProductInfoExA(prodcode, usersid,
5133                               MSIINSTALLCONTEXT_USERMANAGED,
5134                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5135     ok(r == ERROR_UNKNOWN_PRODUCT,
5136        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5137     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5138     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5139
5140     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5142
5143     /* ProductName value exists */
5144     sz = MAX_PATH;
5145     lstrcpyA(buf, "apple");
5146     r = pMsiGetProductInfoExA(prodcode, usersid,
5147                               MSIINSTALLCONTEXT_USERMANAGED,
5148                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5149     ok(r == ERROR_UNKNOWN_PRODUCT,
5150        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5151     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5152     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5153
5154     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5155     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5156
5157     /* FIXME */
5158
5159     /* AssignmentType value exists */
5160     sz = MAX_PATH;
5161     lstrcpyA(buf, "apple");
5162     r = pMsiGetProductInfoExA(prodcode, usersid,
5163                               MSIINSTALLCONTEXT_USERMANAGED,
5164                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5165     ok(r == ERROR_UNKNOWN_PRODUCT,
5166        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5167     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5168     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5169
5170     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5171     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5172
5173     /* PackageCode value exists */
5174     sz = MAX_PATH;
5175     lstrcpyA(buf, "apple");
5176     r = pMsiGetProductInfoExA(prodcode, usersid,
5177                               MSIINSTALLCONTEXT_USERMANAGED,
5178                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5179     ok(r == ERROR_UNKNOWN_PRODUCT,
5180        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5181     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5182     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5183
5184     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5185     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5186
5187     /* Version value exists */
5188     sz = MAX_PATH;
5189     lstrcpyA(buf, "apple");
5190     r = pMsiGetProductInfoExA(prodcode, usersid,
5191                               MSIINSTALLCONTEXT_USERMANAGED,
5192                               INSTALLPROPERTY_VERSION, buf, &sz);
5193     ok(r == ERROR_UNKNOWN_PRODUCT,
5194        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5195     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5196     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5197
5198     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5199     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5200
5201     /* ProductIcon value exists */
5202     sz = MAX_PATH;
5203     lstrcpyA(buf, "apple");
5204     r = pMsiGetProductInfoExA(prodcode, usersid,
5205                               MSIINSTALLCONTEXT_USERMANAGED,
5206                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5207     ok(r == ERROR_UNKNOWN_PRODUCT,
5208        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5209     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5210     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5211
5212     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5213     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5214
5215     /* PackageName value exists */
5216     sz = MAX_PATH;
5217     lstrcpyA(buf, "apple");
5218     r = pMsiGetProductInfoExA(prodcode, usersid,
5219                               MSIINSTALLCONTEXT_USERMANAGED,
5220                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5221     ok(r == ERROR_UNKNOWN_PRODUCT,
5222        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5223     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5224     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5225
5226     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5228
5229     /* AuthorizedLUAApp value exists */
5230     sz = MAX_PATH;
5231     lstrcpyA(buf, "apple");
5232     r = pMsiGetProductInfoExA(prodcode, usersid,
5233                               MSIINSTALLCONTEXT_USERMANAGED,
5234                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5235     ok(r == ERROR_UNKNOWN_PRODUCT,
5236        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5237     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5238     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5239
5240     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5241     RegDeleteValueA(propkey, "PackageName");
5242     RegDeleteValueA(propkey, "ProductIcon");
5243     RegDeleteValueA(propkey, "Version");
5244     RegDeleteValueA(propkey, "PackageCode");
5245     RegDeleteValueA(propkey, "AssignmentType");
5246     RegDeleteValueA(propkey, "ProductName");
5247     RegDeleteValueA(propkey, "Language");
5248     RegDeleteValueA(propkey, "Transforms");
5249     RegDeleteValueA(propkey, "RegOwner");
5250     RegDeleteValueA(propkey, "RegCompany");
5251     RegDeleteValueA(propkey, "ProductID");
5252     RegDeleteValueA(propkey, "DisplayVersion");
5253     RegDeleteValueA(propkey, "VersionMajor");
5254     RegDeleteValueA(propkey, "VersionMinor");
5255     RegDeleteValueA(propkey, "URLUpdateInfo");
5256     RegDeleteValueA(propkey, "URLInfoAbout");
5257     RegDeleteValueA(propkey, "Publisher");
5258     RegDeleteValueA(propkey, "LocalPackage");
5259     RegDeleteValueA(propkey, "InstallSource");
5260     RegDeleteValueA(propkey, "InstallLocation");
5261     RegDeleteValueA(propkey, "DisplayName");
5262     RegDeleteValueA(propkey, "InstallDate");
5263     RegDeleteValueA(propkey, "HelpTelephone");
5264     RegDeleteValueA(propkey, "HelpLink");
5265     RegDeleteValueA(propkey, "ManagedLocalPackage");
5266     RegDeleteKeyA(propkey, "");
5267     RegCloseKey(propkey);
5268     RegDeleteKeyA(localkey, "");
5269     RegCloseKey(localkey);
5270
5271     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5272     lstrcatA(keypath, usersid);
5273     lstrcatA(keypath, "\\Installer\\Products\\");
5274     lstrcatA(keypath, prod_squashed);
5275
5276     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5277     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5278
5279     /* user product key exists */
5280     sz = MAX_PATH;
5281     lstrcpyA(buf, "apple");
5282     r = pMsiGetProductInfoExA(prodcode, usersid,
5283                               MSIINSTALLCONTEXT_USERMANAGED,
5284                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5285     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5286     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5287     ok(sz == 1, "Expected 1, got %d\n", sz);
5288
5289     RegDeleteKeyA(userkey, "");
5290     RegCloseKey(userkey);
5291
5292     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5293     lstrcatA(keypath, prod_squashed);
5294
5295     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5297
5298     /* current user product key exists */
5299     sz = MAX_PATH;
5300     lstrcpyA(buf, "apple");
5301     r = pMsiGetProductInfoExA(prodcode, usersid,
5302                               MSIINSTALLCONTEXT_USERMANAGED,
5303                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5304     ok(r == ERROR_UNKNOWN_PRODUCT,
5305        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5306     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5307     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5308
5309     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5311
5312     /* HelpLink value exists, user product key does not exist */
5313     sz = MAX_PATH;
5314     lstrcpyA(buf, "apple");
5315     r = pMsiGetProductInfoExA(prodcode, usersid,
5316                               MSIINSTALLCONTEXT_USERMANAGED,
5317                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5318     ok(r == ERROR_UNKNOWN_PRODUCT,
5319        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5320     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5321     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5322
5323     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5324     lstrcatA(keypath, usersid);
5325     lstrcatA(keypath, "\\Installer\\Products\\");
5326     lstrcatA(keypath, prod_squashed);
5327
5328     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5330
5331     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5333
5334     /* HelpLink value exists, user product key does exist */
5335     sz = MAX_PATH;
5336     lstrcpyA(buf, "apple");
5337     r = pMsiGetProductInfoExA(prodcode, usersid,
5338                               MSIINSTALLCONTEXT_USERMANAGED,
5339                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5340     ok(r == ERROR_UNKNOWN_PROPERTY,
5341        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5342     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5343     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5344
5345     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5347
5348     /* HelpTelephone value exists */
5349     sz = MAX_PATH;
5350     lstrcpyA(buf, "apple");
5351     r = pMsiGetProductInfoExA(prodcode, usersid,
5352                               MSIINSTALLCONTEXT_USERMANAGED,
5353                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5354     ok(r == ERROR_UNKNOWN_PROPERTY,
5355        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5356     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5357     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5358
5359     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5361
5362     /* InstallDate value exists */
5363     sz = MAX_PATH;
5364     lstrcpyA(buf, "apple");
5365     r = pMsiGetProductInfoExA(prodcode, usersid,
5366                               MSIINSTALLCONTEXT_USERMANAGED,
5367                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5368     ok(r == ERROR_UNKNOWN_PROPERTY,
5369        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5370     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5371     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5372
5373     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5374     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5375
5376     /* DisplayName value exists */
5377     sz = MAX_PATH;
5378     lstrcpyA(buf, "apple");
5379     r = pMsiGetProductInfoExA(prodcode, usersid,
5380                               MSIINSTALLCONTEXT_USERMANAGED,
5381                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5382     ok(r == ERROR_UNKNOWN_PROPERTY,
5383        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5384     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5385     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5386
5387     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5389
5390     /* InstallLocation value exists */
5391     sz = MAX_PATH;
5392     lstrcpyA(buf, "apple");
5393     r = pMsiGetProductInfoExA(prodcode, usersid,
5394                               MSIINSTALLCONTEXT_USERMANAGED,
5395                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5396     ok(r == ERROR_UNKNOWN_PROPERTY,
5397        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5398     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5399     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5400
5401     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5403
5404     /* InstallSource value exists */
5405     sz = MAX_PATH;
5406     lstrcpyA(buf, "apple");
5407     r = pMsiGetProductInfoExA(prodcode, usersid,
5408                               MSIINSTALLCONTEXT_USERMANAGED,
5409                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5410     ok(r == ERROR_UNKNOWN_PROPERTY,
5411        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5412     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5413     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5414
5415     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5417
5418     /* LocalPackage value exists */
5419     sz = MAX_PATH;
5420     lstrcpyA(buf, "apple");
5421     r = pMsiGetProductInfoExA(prodcode, usersid,
5422                               MSIINSTALLCONTEXT_USERMANAGED,
5423                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5424     ok(r == ERROR_UNKNOWN_PROPERTY,
5425        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5426     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5427     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5428
5429     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5431
5432     /* Publisher value exists */
5433     sz = MAX_PATH;
5434     lstrcpyA(buf, "apple");
5435     r = pMsiGetProductInfoExA(prodcode, usersid,
5436                               MSIINSTALLCONTEXT_USERMANAGED,
5437                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5438     ok(r == ERROR_UNKNOWN_PROPERTY,
5439        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5440     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5441     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5442
5443     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5445
5446     /* URLInfoAbout value exists */
5447     sz = MAX_PATH;
5448     lstrcpyA(buf, "apple");
5449     r = pMsiGetProductInfoExA(prodcode, usersid,
5450                               MSIINSTALLCONTEXT_USERMANAGED,
5451                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5452     ok(r == ERROR_UNKNOWN_PROPERTY,
5453        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5454     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5455     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5456
5457     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5459
5460     /* URLUpdateInfo value exists */
5461     sz = MAX_PATH;
5462     lstrcpyA(buf, "apple");
5463     r = pMsiGetProductInfoExA(prodcode, usersid,
5464                               MSIINSTALLCONTEXT_USERMANAGED,
5465                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5466     ok(r == ERROR_UNKNOWN_PROPERTY,
5467        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5468     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5469     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5470
5471     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5472     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5473
5474     /* VersionMinor value exists */
5475     sz = MAX_PATH;
5476     lstrcpyA(buf, "apple");
5477     r = pMsiGetProductInfoExA(prodcode, usersid,
5478                               MSIINSTALLCONTEXT_USERMANAGED,
5479                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5480     ok(r == ERROR_UNKNOWN_PROPERTY,
5481        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5482     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5483     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5484
5485     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5486     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5487
5488     /* VersionMajor value exists */
5489     sz = MAX_PATH;
5490     lstrcpyA(buf, "apple");
5491     r = pMsiGetProductInfoExA(prodcode, usersid,
5492                               MSIINSTALLCONTEXT_USERMANAGED,
5493                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5494     ok(r == ERROR_UNKNOWN_PROPERTY,
5495        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5496     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5497     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5498
5499     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5500     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5501
5502     /* DisplayVersion value exists */
5503     sz = MAX_PATH;
5504     lstrcpyA(buf, "apple");
5505     r = pMsiGetProductInfoExA(prodcode, usersid,
5506                               MSIINSTALLCONTEXT_USERMANAGED,
5507                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5508     ok(r == ERROR_UNKNOWN_PROPERTY,
5509        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5510     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5511     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5512
5513     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5514     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5515
5516     /* ProductID value exists */
5517     sz = MAX_PATH;
5518     lstrcpyA(buf, "apple");
5519     r = pMsiGetProductInfoExA(prodcode, usersid,
5520                               MSIINSTALLCONTEXT_USERMANAGED,
5521                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5522     ok(r == ERROR_UNKNOWN_PROPERTY,
5523        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5524     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5525     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5526
5527     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5528     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5529
5530     /* RegCompany value exists */
5531     sz = MAX_PATH;
5532     lstrcpyA(buf, "apple");
5533     r = pMsiGetProductInfoExA(prodcode, usersid,
5534                               MSIINSTALLCONTEXT_USERMANAGED,
5535                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5536     ok(r == ERROR_UNKNOWN_PROPERTY,
5537        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5538     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5539     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5540
5541     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5543
5544     /* RegOwner value exists */
5545     sz = MAX_PATH;
5546     lstrcpyA(buf, "apple");
5547     r = pMsiGetProductInfoExA(prodcode, usersid,
5548                               MSIINSTALLCONTEXT_USERMANAGED,
5549                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5550     ok(r == ERROR_UNKNOWN_PROPERTY,
5551        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5552     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5553     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5554
5555     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5557
5558     /* Transforms value exists */
5559     sz = MAX_PATH;
5560     lstrcpyA(buf, "apple");
5561     r = pMsiGetProductInfoExA(prodcode, usersid,
5562                               MSIINSTALLCONTEXT_USERMANAGED,
5563                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5564     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5565     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5566     ok(sz == 5, "Expected 5, got %d\n", sz);
5567
5568     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5569     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5570
5571     /* Language value exists */
5572     sz = MAX_PATH;
5573     lstrcpyA(buf, "apple");
5574     r = pMsiGetProductInfoExA(prodcode, usersid,
5575                               MSIINSTALLCONTEXT_USERMANAGED,
5576                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5577     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5578     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5579     ok(sz == 4, "Expected 4, got %d\n", sz);
5580
5581     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5583
5584     /* ProductName value exists */
5585     sz = MAX_PATH;
5586     lstrcpyA(buf, "apple");
5587     r = pMsiGetProductInfoExA(prodcode, usersid,
5588                               MSIINSTALLCONTEXT_USERMANAGED,
5589                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5590     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5591     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5592     ok(sz == 4, "Expected 4, got %d\n", sz);
5593
5594     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5595     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5596
5597     /* FIXME */
5598
5599     /* AssignmentType value exists */
5600     sz = MAX_PATH;
5601     lstrcpyA(buf, "apple");
5602     r = pMsiGetProductInfoExA(prodcode, usersid,
5603                               MSIINSTALLCONTEXT_USERMANAGED,
5604                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5605     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5606     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5607     ok(sz == 0, "Expected 0, got %d\n", sz);
5608
5609     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5611
5612     /* FIXME */
5613
5614     /* PackageCode value exists */
5615     sz = MAX_PATH;
5616     lstrcpyA(buf, "apple");
5617     r = pMsiGetProductInfoExA(prodcode, usersid,
5618                               MSIINSTALLCONTEXT_USERMANAGED,
5619                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5620     todo_wine
5621     {
5622         ok(r == ERROR_BAD_CONFIGURATION,
5623            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5624         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5625         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5626     }
5627
5628     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5629     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5630
5631     /* Version value exists */
5632     sz = MAX_PATH;
5633     lstrcpyA(buf, "apple");
5634     r = pMsiGetProductInfoExA(prodcode, usersid,
5635                               MSIINSTALLCONTEXT_USERMANAGED,
5636                               INSTALLPROPERTY_VERSION, buf, &sz);
5637     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5638     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5639     ok(sz == 3, "Expected 3, got %d\n", sz);
5640
5641     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5643
5644     /* ProductIcon value exists */
5645     sz = MAX_PATH;
5646     lstrcpyA(buf, "apple");
5647     r = pMsiGetProductInfoExA(prodcode, usersid,
5648                               MSIINSTALLCONTEXT_USERMANAGED,
5649                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5650     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5651     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5652     ok(sz == 4, "Expected 4, got %d\n", sz);
5653
5654     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5655     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5656
5657     /* PackageName value exists */
5658     sz = MAX_PATH;
5659     lstrcpyA(buf, "apple");
5660     r = pMsiGetProductInfoExA(prodcode, usersid,
5661                               MSIINSTALLCONTEXT_USERMANAGED,
5662                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5663     todo_wine
5664     {
5665         ok(r == ERROR_UNKNOWN_PRODUCT,
5666            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5667         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5668         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5669     }
5670
5671     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5672     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5673
5674     /* AuthorizedLUAApp value exists */
5675     sz = MAX_PATH;
5676     lstrcpyA(buf, "apple");
5677     r = pMsiGetProductInfoExA(prodcode, usersid,
5678                               MSIINSTALLCONTEXT_USERMANAGED,
5679                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5680     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5681     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5682     ok(sz == 4, "Expected 4, got %d\n", sz);
5683
5684     RegDeleteValueA(userkey, "AuthorizedLUAApp");
5685     RegDeleteValueA(userkey, "PackageName");
5686     RegDeleteValueA(userkey, "ProductIcon");
5687     RegDeleteValueA(userkey, "Version");
5688     RegDeleteValueA(userkey, "PackageCode");
5689     RegDeleteValueA(userkey, "AssignmentType");
5690     RegDeleteValueA(userkey, "ProductName");
5691     RegDeleteValueA(userkey, "Language");
5692     RegDeleteValueA(userkey, "Transforms");
5693     RegDeleteValueA(userkey, "RegOwner");
5694     RegDeleteValueA(userkey, "RegCompany");
5695     RegDeleteValueA(userkey, "ProductID");
5696     RegDeleteValueA(userkey, "DisplayVersion");
5697     RegDeleteValueA(userkey, "VersionMajor");
5698     RegDeleteValueA(userkey, "VersionMinor");
5699     RegDeleteValueA(userkey, "URLUpdateInfo");
5700     RegDeleteValueA(userkey, "URLInfoAbout");
5701     RegDeleteValueA(userkey, "Publisher");
5702     RegDeleteValueA(userkey, "LocalPackage");
5703     RegDeleteValueA(userkey, "InstallSource");
5704     RegDeleteValueA(userkey, "InstallLocation");
5705     RegDeleteValueA(userkey, "DisplayName");
5706     RegDeleteValueA(userkey, "InstallDate");
5707     RegDeleteValueA(userkey, "HelpTelephone");
5708     RegDeleteValueA(userkey, "HelpLink");
5709     RegDeleteKeyA(userkey, "");
5710     RegCloseKey(userkey);
5711     RegDeleteKeyA(prodkey, "");
5712     RegCloseKey(prodkey);
5713
5714     /* MSIINSTALLCONTEXT_MACHINE */
5715
5716     /* szUserSid is non-NULL */
5717     sz = MAX_PATH;
5718     lstrcpyA(buf, "apple");
5719     r = pMsiGetProductInfoExA(prodcode, usersid,
5720                               MSIINSTALLCONTEXT_MACHINE,
5721                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5722     ok(r == ERROR_INVALID_PARAMETER,
5723        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5724     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5725     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5726
5727     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
5728     lstrcatA(keypath, prod_squashed);
5729
5730     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5731     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5732
5733     /* local system product key exists */
5734     sz = MAX_PATH;
5735     lstrcpyA(buf, "apple");
5736     r = pMsiGetProductInfoExA(prodcode, NULL,
5737                               MSIINSTALLCONTEXT_MACHINE,
5738                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5739     ok(r == ERROR_UNKNOWN_PRODUCT,
5740        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5741     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5742     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5743
5744     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5745     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5746
5747     /* InstallProperties key exists */
5748     sz = MAX_PATH;
5749     lstrcpyA(buf, "apple");
5750     r = pMsiGetProductInfoExA(prodcode, NULL,
5751                               MSIINSTALLCONTEXT_MACHINE,
5752                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5753     ok(r == ERROR_UNKNOWN_PRODUCT,
5754        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5755     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5756     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5757
5758     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5759     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5760
5761     /* LocalPackage value exists */
5762     sz = MAX_PATH;
5763     lstrcpyA(buf, "apple");
5764     r = pMsiGetProductInfoExA(prodcode, NULL,
5765                               MSIINSTALLCONTEXT_MACHINE,
5766                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5767     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5768     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5769     ok(sz == 1, "Expected 1, got %d\n", sz);
5770
5771     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5772     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5773
5774     /* HelpLink value exists */
5775     sz = MAX_PATH;
5776     lstrcpyA(buf, "apple");
5777     r = pMsiGetProductInfoExA(prodcode, NULL,
5778                               MSIINSTALLCONTEXT_MACHINE,
5779                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5780     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5781     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5782     ok(sz == 4, "Expected 4, got %d\n", sz);
5783
5784     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5786
5787     /* HelpTelephone value exists */
5788     sz = MAX_PATH;
5789     lstrcpyA(buf, "apple");
5790     r = pMsiGetProductInfoExA(prodcode, NULL,
5791                               MSIINSTALLCONTEXT_MACHINE,
5792                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5793     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5794     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5795     ok(sz == 5, "Expected 5, got %d\n", sz);
5796
5797     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5798     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5799
5800     /* InstallDate value exists */
5801     sz = MAX_PATH;
5802     lstrcpyA(buf, "apple");
5803     r = pMsiGetProductInfoExA(prodcode, NULL,
5804                               MSIINSTALLCONTEXT_MACHINE,
5805                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5806     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5807     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5808     ok(sz == 4, "Expected 4, got %d\n", sz);
5809
5810     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5811     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5812
5813     /* DisplayName value exists */
5814     sz = MAX_PATH;
5815     lstrcpyA(buf, "apple");
5816     r = pMsiGetProductInfoExA(prodcode, NULL,
5817                               MSIINSTALLCONTEXT_MACHINE,
5818                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5819     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5820     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5821     ok(sz == 4, "Expected 4, got %d\n", sz);
5822
5823     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5824     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5825
5826     /* InstallLocation value exists */
5827     sz = MAX_PATH;
5828     lstrcpyA(buf, "apple");
5829     r = pMsiGetProductInfoExA(prodcode, NULL,
5830                               MSIINSTALLCONTEXT_MACHINE,
5831                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5832     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5833     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5834     ok(sz == 3, "Expected 3, got %d\n", sz);
5835
5836     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5837     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5838
5839     /* InstallSource value exists */
5840     sz = MAX_PATH;
5841     lstrcpyA(buf, "apple");
5842     r = pMsiGetProductInfoExA(prodcode, NULL,
5843                               MSIINSTALLCONTEXT_MACHINE,
5844                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5845     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5846     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5847     ok(sz == 6, "Expected 6, got %d\n", sz);
5848
5849     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5850     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5851
5852     /* LocalPackage value exists */
5853     sz = MAX_PATH;
5854     lstrcpyA(buf, "apple");
5855     r = pMsiGetProductInfoExA(prodcode, NULL,
5856                               MSIINSTALLCONTEXT_MACHINE,
5857                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5858     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5859     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5860     ok(sz == 5, "Expected 5, got %d\n", sz);
5861
5862     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5863     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5864
5865     /* Publisher value exists */
5866     sz = MAX_PATH;
5867     lstrcpyA(buf, "apple");
5868     r = pMsiGetProductInfoExA(prodcode, NULL,
5869                               MSIINSTALLCONTEXT_MACHINE,
5870                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5871     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5872     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5873     ok(sz == 3, "Expected 3, got %d\n", sz);
5874
5875     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5876     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5877
5878     /* URLInfoAbout value exists */
5879     sz = MAX_PATH;
5880     lstrcpyA(buf, "apple");
5881     r = pMsiGetProductInfoExA(prodcode, NULL,
5882                               MSIINSTALLCONTEXT_MACHINE,
5883                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5884     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5885     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5886     ok(sz == 5, "Expected 5, got %d\n", sz);
5887
5888     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5889     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5890
5891     /* URLUpdateInfo value exists */
5892     sz = MAX_PATH;
5893     lstrcpyA(buf, "apple");
5894     r = pMsiGetProductInfoExA(prodcode, NULL,
5895                               MSIINSTALLCONTEXT_MACHINE,
5896                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5897     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5898     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5899     ok(sz == 6, "Expected 6, got %d\n", sz);
5900
5901     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5902     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5903
5904     /* VersionMinor value exists */
5905     sz = MAX_PATH;
5906     lstrcpyA(buf, "apple");
5907     r = pMsiGetProductInfoExA(prodcode, NULL,
5908                               MSIINSTALLCONTEXT_MACHINE,
5909                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5910     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5911     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5912     ok(sz == 1, "Expected 1, got %d\n", sz);
5913
5914     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5915     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5916
5917     /* VersionMajor value exists */
5918     sz = MAX_PATH;
5919     lstrcpyA(buf, "apple");
5920     r = pMsiGetProductInfoExA(prodcode, NULL,
5921                               MSIINSTALLCONTEXT_MACHINE,
5922                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5923     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5924     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5925     ok(sz == 1, "Expected 1, got %d\n", sz);
5926
5927     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5929
5930     /* DisplayVersion value exists */
5931     sz = MAX_PATH;
5932     lstrcpyA(buf, "apple");
5933     r = pMsiGetProductInfoExA(prodcode, NULL,
5934                               MSIINSTALLCONTEXT_MACHINE,
5935                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5936     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5937     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5938     ok(sz == 5, "Expected 5, got %d\n", sz);
5939
5940     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5941     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5942
5943     /* ProductID value exists */
5944     sz = MAX_PATH;
5945     lstrcpyA(buf, "apple");
5946     r = pMsiGetProductInfoExA(prodcode, NULL,
5947                               MSIINSTALLCONTEXT_MACHINE,
5948                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5949     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5950     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5951     ok(sz == 2, "Expected 2, got %d\n", sz);
5952
5953     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5954     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5955
5956     /* RegCompany value exists */
5957     sz = MAX_PATH;
5958     lstrcpyA(buf, "apple");
5959     r = pMsiGetProductInfoExA(prodcode, NULL,
5960                               MSIINSTALLCONTEXT_MACHINE,
5961                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5962     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5963     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5964     ok(sz == 4, "Expected 4, got %d\n", sz);
5965
5966     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5967     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5968
5969     /* RegOwner value exists */
5970     sz = MAX_PATH;
5971     lstrcpyA(buf, "apple");
5972     r = pMsiGetProductInfoExA(prodcode, NULL,
5973                               MSIINSTALLCONTEXT_MACHINE,
5974                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5975     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5976     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5977     ok(sz == 5, "Expected 5, got %d\n", sz);
5978
5979     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5980     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5981
5982     /* Transforms value exists */
5983     sz = MAX_PATH;
5984     lstrcpyA(buf, "apple");
5985     r = pMsiGetProductInfoExA(prodcode, NULL,
5986                               MSIINSTALLCONTEXT_MACHINE,
5987                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5988     ok(r == ERROR_UNKNOWN_PRODUCT,
5989        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5990     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5991     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5992
5993     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5994     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5995
5996     /* Language value exists */
5997     sz = MAX_PATH;
5998     lstrcpyA(buf, "apple");
5999     r = pMsiGetProductInfoExA(prodcode, NULL,
6000                               MSIINSTALLCONTEXT_MACHINE,
6001                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6002     ok(r == ERROR_UNKNOWN_PRODUCT,
6003        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6004     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6005     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6006
6007     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6009
6010     /* ProductName value exists */
6011     sz = MAX_PATH;
6012     lstrcpyA(buf, "apple");
6013     r = pMsiGetProductInfoExA(prodcode, NULL,
6014                               MSIINSTALLCONTEXT_MACHINE,
6015                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6016     ok(r == ERROR_UNKNOWN_PRODUCT,
6017        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6018     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6019     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6020
6021     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6022     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6023
6024     /* FIXME */
6025
6026     /* AssignmentType value exists */
6027     sz = MAX_PATH;
6028     lstrcpyA(buf, "apple");
6029     r = pMsiGetProductInfoExA(prodcode, NULL,
6030                               MSIINSTALLCONTEXT_MACHINE,
6031                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6032     ok(r == ERROR_UNKNOWN_PRODUCT,
6033        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6034     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6035     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6036
6037     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6038     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6039
6040     /* PackageCode value exists */
6041     sz = MAX_PATH;
6042     lstrcpyA(buf, "apple");
6043     r = pMsiGetProductInfoExA(prodcode, NULL,
6044                               MSIINSTALLCONTEXT_MACHINE,
6045                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6046     ok(r == ERROR_UNKNOWN_PRODUCT,
6047        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6048     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6049     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6050
6051     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6052     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6053
6054     /* Version value exists */
6055     sz = MAX_PATH;
6056     lstrcpyA(buf, "apple");
6057     r = pMsiGetProductInfoExA(prodcode, NULL,
6058                               MSIINSTALLCONTEXT_MACHINE,
6059                               INSTALLPROPERTY_VERSION, buf, &sz);
6060     ok(r == ERROR_UNKNOWN_PRODUCT,
6061        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6062     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6063     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6064
6065     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6067
6068     /* ProductIcon value exists */
6069     sz = MAX_PATH;
6070     lstrcpyA(buf, "apple");
6071     r = pMsiGetProductInfoExA(prodcode, NULL,
6072                               MSIINSTALLCONTEXT_MACHINE,
6073                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6074     ok(r == ERROR_UNKNOWN_PRODUCT,
6075        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6076     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6077     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6078
6079     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6081
6082     /* PackageName value exists */
6083     sz = MAX_PATH;
6084     lstrcpyA(buf, "apple");
6085     r = pMsiGetProductInfoExA(prodcode, NULL,
6086                               MSIINSTALLCONTEXT_MACHINE,
6087                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6088     ok(r == ERROR_UNKNOWN_PRODUCT,
6089        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6090     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6091     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6092
6093     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6094     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6095
6096     /* AuthorizedLUAApp value exists */
6097     sz = MAX_PATH;
6098     lstrcpyA(buf, "apple");
6099     r = pMsiGetProductInfoExA(prodcode, NULL,
6100                               MSIINSTALLCONTEXT_MACHINE,
6101                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6102     ok(r == ERROR_UNKNOWN_PRODUCT,
6103        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6104     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6105     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6106
6107     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6108     RegDeleteValueA(propkey, "PackageName");
6109     RegDeleteValueA(propkey, "ProductIcon");
6110     RegDeleteValueA(propkey, "Version");
6111     RegDeleteValueA(propkey, "PackageCode");
6112     RegDeleteValueA(propkey, "AssignmentType");
6113     RegDeleteValueA(propkey, "ProductName");
6114     RegDeleteValueA(propkey, "Language");
6115     RegDeleteValueA(propkey, "Transforms");
6116     RegDeleteValueA(propkey, "RegOwner");
6117     RegDeleteValueA(propkey, "RegCompany");
6118     RegDeleteValueA(propkey, "ProductID");
6119     RegDeleteValueA(propkey, "DisplayVersion");
6120     RegDeleteValueA(propkey, "VersionMajor");
6121     RegDeleteValueA(propkey, "VersionMinor");
6122     RegDeleteValueA(propkey, "URLUpdateInfo");
6123     RegDeleteValueA(propkey, "URLInfoAbout");
6124     RegDeleteValueA(propkey, "Publisher");
6125     RegDeleteValueA(propkey, "LocalPackage");
6126     RegDeleteValueA(propkey, "InstallSource");
6127     RegDeleteValueA(propkey, "InstallLocation");
6128     RegDeleteValueA(propkey, "DisplayName");
6129     RegDeleteValueA(propkey, "InstallDate");
6130     RegDeleteValueA(propkey, "HelpTelephone");
6131     RegDeleteValueA(propkey, "HelpLink");
6132     RegDeleteValueA(propkey, "LocalPackage");
6133     RegDeleteKeyA(propkey, "");
6134     RegCloseKey(propkey);
6135     RegDeleteKeyA(localkey, "");
6136     RegCloseKey(localkey);
6137
6138     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6139     lstrcatA(keypath, prod_squashed);
6140
6141     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6142     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6143
6144     /* local classes product key exists */
6145     sz = MAX_PATH;
6146     lstrcpyA(buf, "apple");
6147     r = pMsiGetProductInfoExA(prodcode, NULL,
6148                               MSIINSTALLCONTEXT_MACHINE,
6149                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6150     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6151     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6152     ok(sz == 1, "Expected 1, got %d\n", sz);
6153
6154     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6155     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6156
6157     /* HelpLink value exists */
6158     sz = MAX_PATH;
6159     lstrcpyA(buf, "apple");
6160     r = pMsiGetProductInfoExA(prodcode, NULL,
6161                               MSIINSTALLCONTEXT_MACHINE,
6162                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6163     ok(r == ERROR_UNKNOWN_PROPERTY,
6164        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6165     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6166     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6167
6168     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6170
6171     /* HelpTelephone value exists */
6172     sz = MAX_PATH;
6173     lstrcpyA(buf, "apple");
6174     r = pMsiGetProductInfoExA(prodcode, NULL,
6175                               MSIINSTALLCONTEXT_MACHINE,
6176                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6177     ok(r == ERROR_UNKNOWN_PROPERTY,
6178        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6179     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6180     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6181
6182     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6183     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6184
6185     /* InstallDate value exists */
6186     sz = MAX_PATH;
6187     lstrcpyA(buf, "apple");
6188     r = pMsiGetProductInfoExA(prodcode, NULL,
6189                               MSIINSTALLCONTEXT_MACHINE,
6190                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6191     ok(r == ERROR_UNKNOWN_PROPERTY,
6192        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6193     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6194     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6195
6196     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6198
6199     /* DisplayName value exists */
6200     sz = MAX_PATH;
6201     lstrcpyA(buf, "apple");
6202     r = pMsiGetProductInfoExA(prodcode, NULL,
6203                               MSIINSTALLCONTEXT_MACHINE,
6204                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6205     ok(r == ERROR_UNKNOWN_PROPERTY,
6206        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6207     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6208     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6209
6210     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6212
6213     /* InstallLocation value exists */
6214     sz = MAX_PATH;
6215     lstrcpyA(buf, "apple");
6216     r = pMsiGetProductInfoExA(prodcode, NULL,
6217                               MSIINSTALLCONTEXT_MACHINE,
6218                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6219     ok(r == ERROR_UNKNOWN_PROPERTY,
6220        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6221     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6222     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6223
6224     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6225     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6226
6227     /* InstallSource value exists */
6228     sz = MAX_PATH;
6229     lstrcpyA(buf, "apple");
6230     r = pMsiGetProductInfoExA(prodcode, NULL,
6231                               MSIINSTALLCONTEXT_MACHINE,
6232                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6233     ok(r == ERROR_UNKNOWN_PROPERTY,
6234        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6235     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6236     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6237
6238     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6240
6241     /* LocalPackage value exists */
6242     sz = MAX_PATH;
6243     lstrcpyA(buf, "apple");
6244     r = pMsiGetProductInfoExA(prodcode, NULL,
6245                               MSIINSTALLCONTEXT_MACHINE,
6246                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6247     ok(r == ERROR_UNKNOWN_PROPERTY,
6248        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6249     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6250     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6251
6252     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6253     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6254
6255     /* Publisher value exists */
6256     sz = MAX_PATH;
6257     lstrcpyA(buf, "apple");
6258     r = pMsiGetProductInfoExA(prodcode, NULL,
6259                               MSIINSTALLCONTEXT_MACHINE,
6260                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6261     ok(r == ERROR_UNKNOWN_PROPERTY,
6262        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6263     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6264     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6265
6266     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6267     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6268
6269     /* URLInfoAbout value exists */
6270     sz = MAX_PATH;
6271     lstrcpyA(buf, "apple");
6272     r = pMsiGetProductInfoExA(prodcode, NULL,
6273                               MSIINSTALLCONTEXT_MACHINE,
6274                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6275     ok(r == ERROR_UNKNOWN_PROPERTY,
6276        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6277     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6278     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6279
6280     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6281     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6282
6283     /* URLUpdateInfo value exists */
6284     sz = MAX_PATH;
6285     lstrcpyA(buf, "apple");
6286     r = pMsiGetProductInfoExA(prodcode, NULL,
6287                               MSIINSTALLCONTEXT_MACHINE,
6288                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6289     ok(r == ERROR_UNKNOWN_PROPERTY,
6290        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6291     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6292     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6293
6294     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6295     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6296
6297     /* VersionMinor value exists */
6298     sz = MAX_PATH;
6299     lstrcpyA(buf, "apple");
6300     r = pMsiGetProductInfoExA(prodcode, NULL,
6301                               MSIINSTALLCONTEXT_MACHINE,
6302                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6303     ok(r == ERROR_UNKNOWN_PROPERTY,
6304        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6305     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6306     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6307
6308     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6309     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6310
6311     /* VersionMajor value exists */
6312     sz = MAX_PATH;
6313     lstrcpyA(buf, "apple");
6314     r = pMsiGetProductInfoExA(prodcode, NULL,
6315                               MSIINSTALLCONTEXT_MACHINE,
6316                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6317     ok(r == ERROR_UNKNOWN_PROPERTY,
6318        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6319     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6320     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6321
6322     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6323     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6324
6325     /* DisplayVersion value exists */
6326     sz = MAX_PATH;
6327     lstrcpyA(buf, "apple");
6328     r = pMsiGetProductInfoExA(prodcode, NULL,
6329                               MSIINSTALLCONTEXT_MACHINE,
6330                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6331     ok(r == ERROR_UNKNOWN_PROPERTY,
6332        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6333     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6334     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6335
6336     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6337     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6338
6339     /* ProductID value exists */
6340     sz = MAX_PATH;
6341     lstrcpyA(buf, "apple");
6342     r = pMsiGetProductInfoExA(prodcode, NULL,
6343                               MSIINSTALLCONTEXT_MACHINE,
6344                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6345     ok(r == ERROR_UNKNOWN_PROPERTY,
6346        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6347     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6348     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6349
6350     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6352
6353     /* RegCompany value exists */
6354     sz = MAX_PATH;
6355     lstrcpyA(buf, "apple");
6356     r = pMsiGetProductInfoExA(prodcode, NULL,
6357                               MSIINSTALLCONTEXT_MACHINE,
6358                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6359     ok(r == ERROR_UNKNOWN_PROPERTY,
6360        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6361     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6362     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6363
6364     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6366
6367     /* RegOwner value exists */
6368     sz = MAX_PATH;
6369     lstrcpyA(buf, "apple");
6370     r = pMsiGetProductInfoExA(prodcode, NULL,
6371                               MSIINSTALLCONTEXT_MACHINE,
6372                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6373     ok(r == ERROR_UNKNOWN_PROPERTY,
6374        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6375     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6376     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6377
6378     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6380
6381     /* Transforms value exists */
6382     sz = MAX_PATH;
6383     lstrcpyA(buf, "apple");
6384     r = pMsiGetProductInfoExA(prodcode, NULL,
6385                               MSIINSTALLCONTEXT_MACHINE,
6386                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6387     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6388     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6389     ok(sz == 5, "Expected 5, got %d\n", sz);
6390
6391     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6392     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6393
6394     /* Language value exists */
6395     sz = MAX_PATH;
6396     lstrcpyA(buf, "apple");
6397     r = pMsiGetProductInfoExA(prodcode, NULL,
6398                               MSIINSTALLCONTEXT_MACHINE,
6399                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6401     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6402     ok(sz == 4, "Expected 4, got %d\n", sz);
6403
6404     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6405     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6406
6407     /* ProductName value exists */
6408     sz = MAX_PATH;
6409     lstrcpyA(buf, "apple");
6410     r = pMsiGetProductInfoExA(prodcode, NULL,
6411                               MSIINSTALLCONTEXT_MACHINE,
6412                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6413     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6414     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6415     ok(sz == 4, "Expected 4, got %d\n", sz);
6416
6417     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6418     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6419
6420     /* FIXME */
6421
6422     /* AssignmentType value exists */
6423     sz = MAX_PATH;
6424     lstrcpyA(buf, "apple");
6425     r = pMsiGetProductInfoExA(prodcode, NULL,
6426                               MSIINSTALLCONTEXT_MACHINE,
6427                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6428     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6429     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6430     ok(sz == 0, "Expected 0, got %d\n", sz);
6431
6432     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6434
6435     /* FIXME */
6436
6437     /* PackageCode value exists */
6438     sz = MAX_PATH;
6439     lstrcpyA(buf, "apple");
6440     r = pMsiGetProductInfoExA(prodcode, NULL,
6441                               MSIINSTALLCONTEXT_MACHINE,
6442                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6443     todo_wine
6444     {
6445         ok(r == ERROR_BAD_CONFIGURATION,
6446            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6447         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6448         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6449     }
6450
6451     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6452     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6453
6454     /* Version value exists */
6455     sz = MAX_PATH;
6456     lstrcpyA(buf, "apple");
6457     r = pMsiGetProductInfoExA(prodcode, NULL,
6458                               MSIINSTALLCONTEXT_MACHINE,
6459                               INSTALLPROPERTY_VERSION, buf, &sz);
6460     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6461     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6462     ok(sz == 3, "Expected 3, got %d\n", sz);
6463
6464     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6465     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6466
6467     /* ProductIcon value exists */
6468     sz = MAX_PATH;
6469     lstrcpyA(buf, "apple");
6470     r = pMsiGetProductInfoExA(prodcode, NULL,
6471                               MSIINSTALLCONTEXT_MACHINE,
6472                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6473     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6474     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6475     ok(sz == 4, "Expected 4, got %d\n", sz);
6476
6477     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6478     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6479
6480     /* PackageName value exists */
6481     sz = MAX_PATH;
6482     lstrcpyA(buf, "apple");
6483     r = pMsiGetProductInfoExA(prodcode, NULL,
6484                               MSIINSTALLCONTEXT_MACHINE,
6485                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6486     todo_wine
6487     {
6488         ok(r == ERROR_UNKNOWN_PRODUCT,
6489            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6490         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6491         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6492     }
6493
6494     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6495     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6496
6497     /* AuthorizedLUAApp value exists */
6498     sz = MAX_PATH;
6499     lstrcpyA(buf, "apple");
6500     r = pMsiGetProductInfoExA(prodcode, NULL,
6501                               MSIINSTALLCONTEXT_MACHINE,
6502                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6503     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6504     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6505     ok(sz == 4, "Expected 4, got %d\n", sz);
6506
6507     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6508     RegDeleteValueA(prodkey, "PackageName");
6509     RegDeleteValueA(prodkey, "ProductIcon");
6510     RegDeleteValueA(prodkey, "Version");
6511     RegDeleteValueA(prodkey, "PackageCode");
6512     RegDeleteValueA(prodkey, "AssignmentType");
6513     RegDeleteValueA(prodkey, "ProductName");
6514     RegDeleteValueA(prodkey, "Language");
6515     RegDeleteValueA(prodkey, "Transforms");
6516     RegDeleteValueA(prodkey, "RegOwner");
6517     RegDeleteValueA(prodkey, "RegCompany");
6518     RegDeleteValueA(prodkey, "ProductID");
6519     RegDeleteValueA(prodkey, "DisplayVersion");
6520     RegDeleteValueA(prodkey, "VersionMajor");
6521     RegDeleteValueA(prodkey, "VersionMinor");
6522     RegDeleteValueA(prodkey, "URLUpdateInfo");
6523     RegDeleteValueA(prodkey, "URLInfoAbout");
6524     RegDeleteValueA(prodkey, "Publisher");
6525     RegDeleteValueA(prodkey, "LocalPackage");
6526     RegDeleteValueA(prodkey, "InstallSource");
6527     RegDeleteValueA(prodkey, "InstallLocation");
6528     RegDeleteValueA(prodkey, "DisplayName");
6529     RegDeleteValueA(prodkey, "InstallDate");
6530     RegDeleteValueA(prodkey, "HelpTelephone");
6531     RegDeleteValueA(prodkey, "HelpLink");
6532     RegDeleteKeyA(prodkey, "");
6533     RegCloseKey(prodkey);
6534 }
6535
6536 #define INIT_USERINFO() \
6537     lstrcpyA(user, "apple"); \
6538     lstrcpyA(org, "orange"); \
6539     lstrcpyA(serial, "banana"); \
6540     usersz = orgsz = serialsz = MAX_PATH;
6541
6542 static void test_MsiGetUserInfo(void)
6543 {
6544     USERINFOSTATE state;
6545     CHAR user[MAX_PATH];
6546     CHAR org[MAX_PATH];
6547     CHAR serial[MAX_PATH];
6548     DWORD usersz, orgsz, serialsz;
6549     CHAR keypath[MAX_PATH * 2];
6550     CHAR prodcode[MAX_PATH];
6551     CHAR prod_squashed[MAX_PATH];
6552     HKEY prodkey, userprod, props;
6553     LPSTR usersid;
6554     LONG res;
6555
6556     create_test_guid(prodcode, prod_squashed);
6557     get_user_sid(&usersid);
6558
6559     /* NULL szProduct */
6560     INIT_USERINFO();
6561     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6562     ok(state == USERINFOSTATE_INVALIDARG,
6563        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6564     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6565     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6566     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6567     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6568     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6569     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6570
6571     /* empty szProductCode */
6572     INIT_USERINFO();
6573     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6574     ok(state == USERINFOSTATE_INVALIDARG,
6575        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6576     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6577     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6578     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6579     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6580     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6581     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6582
6583     /* garbage szProductCode */
6584     INIT_USERINFO();
6585     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6586     ok(state == USERINFOSTATE_INVALIDARG,
6587        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6588     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6589     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6590     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6591     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6592     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6593     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6594
6595     /* guid without brackets */
6596     INIT_USERINFO();
6597     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6598                             user, &usersz, org, &orgsz, serial, &serialsz);
6599     ok(state == USERINFOSTATE_INVALIDARG,
6600        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6601     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6602     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6603     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6604     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6605     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6606     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6607
6608     /* guid with brackets */
6609     INIT_USERINFO();
6610     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6611                             user, &usersz, org, &orgsz, serial, &serialsz);
6612     ok(state == USERINFOSTATE_UNKNOWN,
6613        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6614     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6615     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6616     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6617     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6618     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6619     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6620
6621     /* NULL lpUserNameBuf */
6622     INIT_USERINFO();
6623     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6624     ok(state == USERINFOSTATE_UNKNOWN,
6625        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6626     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6627     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6628     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6629     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6630     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6631
6632     /* NULL pcchUserNameBuf */
6633     INIT_USERINFO();
6634     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6635     ok(state == USERINFOSTATE_INVALIDARG,
6636        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6637     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6638     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6639     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6640     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6641     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6642
6643     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6644     INIT_USERINFO();
6645     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6646     ok(state == USERINFOSTATE_UNKNOWN,
6647        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6648     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6649     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6650     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6651     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6652
6653     /* NULL lpOrgNameBuf */
6654     INIT_USERINFO();
6655     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6656     ok(state == USERINFOSTATE_UNKNOWN,
6657        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6658     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6659     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6660     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6661     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6662     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6663
6664     /* NULL pcchOrgNameBuf */
6665     INIT_USERINFO();
6666     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
6667     ok(state == USERINFOSTATE_INVALIDARG,
6668        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6669     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6670     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6671     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6672     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6673     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6674
6675     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
6676     INIT_USERINFO();
6677     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
6678     ok(state == USERINFOSTATE_UNKNOWN,
6679        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6680     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6681     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6682     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6683     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6684
6685     /* NULL lpSerialBuf */
6686     INIT_USERINFO();
6687     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
6688     ok(state == USERINFOSTATE_UNKNOWN,
6689        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6690     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6691     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6692     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6693     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6694     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6695
6696     /* NULL pcchSerialBuf */
6697     INIT_USERINFO();
6698     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
6699     ok(state == USERINFOSTATE_INVALIDARG,
6700        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6701     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6702     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6703     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6704     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6705     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6706
6707     /* both lpSerialBuf and pcchSerialBuf NULL */
6708     INIT_USERINFO();
6709     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
6710     ok(state == USERINFOSTATE_UNKNOWN,
6711        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6712     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6713     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6714     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6715     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6716
6717     /* MSIINSTALLCONTEXT_USERMANAGED */
6718
6719     /* create local system product key */
6720     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6721     lstrcatA(keypath, usersid);
6722     lstrcatA(keypath, "\\Installer\\Products\\");
6723     lstrcatA(keypath, prod_squashed);
6724
6725     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6727
6728     /* managed product key exists */
6729     INIT_USERINFO();
6730     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6731     ok(state == USERINFOSTATE_ABSENT,
6732        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6733     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6734     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6735     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6736     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6737     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6738     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6739
6740     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6741     lstrcatA(keypath, "Installer\\UserData\\");
6742     lstrcatA(keypath, usersid);
6743     lstrcatA(keypath, "\\Products\\");
6744     lstrcatA(keypath, prod_squashed);
6745
6746     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6748
6749     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6750     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6751
6752     /* InstallProperties key exists */
6753     INIT_USERINFO();
6754     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6755     ok(state == USERINFOSTATE_ABSENT,
6756        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6757     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6758     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6759     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6760     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6761     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6762     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6763
6764     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6765     INIT_USERINFO();
6766     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6767     ok(state == USERINFOSTATE_ABSENT,
6768        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6769     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6770     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6771     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6772     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6773
6774     /* RegOwner, RegCompany don't exist, out params are NULL */
6775     INIT_USERINFO();
6776     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6777     ok(state == USERINFOSTATE_ABSENT,
6778        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6779     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6780     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6781
6782     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6783     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6784
6785     /* RegOwner value exists */
6786     INIT_USERINFO();
6787     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6788     ok(state == USERINFOSTATE_ABSENT,
6789        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6790     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6791     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6792     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6793     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6794     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6795     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6796
6797     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6798     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6799
6800     /* RegCompany value exists */
6801     INIT_USERINFO();
6802     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6803     ok(state == USERINFOSTATE_ABSENT,
6804        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6805     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6806     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6807     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6808     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6809     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6810     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6811
6812     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6813     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6814
6815     /* ProductID value exists */
6816     INIT_USERINFO();
6817     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6818     ok(state == USERINFOSTATE_PRESENT,
6819        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6820     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6821     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6822     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6823     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6824     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6825     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6826
6827     /* pcchUserNameBuf is too small */
6828     INIT_USERINFO();
6829     usersz = 0;
6830     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6831     ok(state == USERINFOSTATE_MOREDATA,
6832        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6833     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6834     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6835     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6836     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6837     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6838     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6839
6840     /* pcchUserNameBuf has no room for NULL terminator */
6841     INIT_USERINFO();
6842     usersz = 5;
6843     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6844     ok(state == USERINFOSTATE_MOREDATA,
6845        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6846     todo_wine
6847     {
6848         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6849     }
6850     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6851     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6852     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6853     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6854     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6855
6856     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
6857     INIT_USERINFO();
6858     usersz = 0;
6859     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6860     ok(state == USERINFOSTATE_PRESENT,
6861        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6862     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6863     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6864     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6865     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6866     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6867     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6868
6869     RegDeleteValueA(props, "ProductID");
6870     RegDeleteValueA(props, "RegCompany");
6871     RegDeleteValueA(props, "RegOwner");
6872     RegDeleteKeyA(props, "");
6873     RegCloseKey(props);
6874     RegDeleteKeyA(userprod, "");
6875     RegCloseKey(userprod);
6876     RegDeleteKeyA(prodkey, "");
6877     RegCloseKey(prodkey);
6878
6879     /* MSIINSTALLCONTEXT_USERUNMANAGED */
6880
6881     /* create local system product key */
6882     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6883     lstrcatA(keypath, prod_squashed);
6884
6885     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6887
6888     /* product key exists */
6889     INIT_USERINFO();
6890     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6891     ok(state == USERINFOSTATE_ABSENT,
6892        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6893     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6894     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6895     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6896     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6897     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6898     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6899
6900     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6901     lstrcatA(keypath, "Installer\\UserData\\");
6902     lstrcatA(keypath, usersid);
6903     lstrcatA(keypath, "\\Products\\");
6904     lstrcatA(keypath, prod_squashed);
6905
6906     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6907     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6908
6909     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6910     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6911
6912     /* InstallProperties key exists */
6913     INIT_USERINFO();
6914     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6915     ok(state == USERINFOSTATE_ABSENT,
6916        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6917     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6918     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6919     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6920     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6921     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6922     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6923
6924     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6925     INIT_USERINFO();
6926     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6927     ok(state == USERINFOSTATE_ABSENT,
6928        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6929     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6930     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6931     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6932     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6933
6934     /* RegOwner, RegCompany don't exist, out params are NULL */
6935     INIT_USERINFO();
6936     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6937     ok(state == USERINFOSTATE_ABSENT,
6938        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6939     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6940     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6941
6942     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6943     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6944
6945     /* RegOwner value exists */
6946     INIT_USERINFO();
6947     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6948     ok(state == USERINFOSTATE_ABSENT,
6949        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6950     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6951     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6952     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6953     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6954     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6955     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6956
6957     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6958     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6959
6960     /* RegCompany value exists */
6961     INIT_USERINFO();
6962     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6963     ok(state == USERINFOSTATE_ABSENT,
6964        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6965     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6966     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6967     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6968     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6969     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6970     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6971
6972     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6973     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6974
6975     /* ProductID value exists */
6976     INIT_USERINFO();
6977     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6978     ok(state == USERINFOSTATE_PRESENT,
6979        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6980     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6981     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6982     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6983     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6984     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6985     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6986
6987     RegDeleteValueA(props, "ProductID");
6988     RegDeleteValueA(props, "RegCompany");
6989     RegDeleteValueA(props, "RegOwner");
6990     RegDeleteKeyA(props, "");
6991     RegCloseKey(props);
6992     RegDeleteKeyA(userprod, "");
6993     RegCloseKey(userprod);
6994     RegDeleteKeyA(prodkey, "");
6995     RegCloseKey(prodkey);
6996
6997     /* MSIINSTALLCONTEXT_MACHINE */
6998
6999     /* create local system product key */
7000     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7001     lstrcatA(keypath, prod_squashed);
7002
7003     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7005
7006     /* product key exists */
7007     INIT_USERINFO();
7008     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7009     ok(state == USERINFOSTATE_ABSENT,
7010        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7011     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7012     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7013     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7014     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7015     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7016     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7017
7018     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7019     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7020     lstrcatA(keypath, "\\Products\\");
7021     lstrcatA(keypath, prod_squashed);
7022
7023     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
7024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7025
7026     res = RegCreateKeyA(userprod, "InstallProperties", &props);
7027     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7028
7029     /* InstallProperties key exists */
7030     INIT_USERINFO();
7031     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7032     ok(state == USERINFOSTATE_ABSENT,
7033        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7034     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7035     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7036     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7037     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7038     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7039     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7040
7041     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7042     INIT_USERINFO();
7043     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7044     ok(state == USERINFOSTATE_ABSENT,
7045        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7046     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7047     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7048     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7049     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7050
7051     /* RegOwner, RegCompany don't exist, out params are NULL */
7052     INIT_USERINFO();
7053     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7054     ok(state == USERINFOSTATE_ABSENT,
7055        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7056     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7057     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7058
7059     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7061
7062     /* RegOwner value exists */
7063     INIT_USERINFO();
7064     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7065     ok(state == USERINFOSTATE_ABSENT,
7066        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7067     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7068     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7069     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7070     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7071     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7072     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7073
7074     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7076
7077     /* RegCompany value exists */
7078     INIT_USERINFO();
7079     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7080     ok(state == USERINFOSTATE_ABSENT,
7081        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7082     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7083     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7084     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7085     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7086     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7087     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7088
7089     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7090     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7091
7092     /* ProductID value exists */
7093     INIT_USERINFO();
7094     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7095     ok(state == USERINFOSTATE_PRESENT,
7096        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7097     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7098     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7099     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7100     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7101     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7102     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7103
7104     RegDeleteValueA(props, "ProductID");
7105     RegDeleteValueA(props, "RegCompany");
7106     RegDeleteValueA(props, "RegOwner");
7107     RegDeleteKeyA(props, "");
7108     RegCloseKey(props);
7109     RegDeleteKeyA(userprod, "");
7110     RegCloseKey(userprod);
7111     RegDeleteKeyA(prodkey, "");
7112     RegCloseKey(prodkey);
7113 }
7114
7115 static void test_MsiOpenProduct(void)
7116 {
7117     MSIHANDLE hprod, hdb;
7118     CHAR val[MAX_PATH];
7119     CHAR path[MAX_PATH];
7120     CHAR keypath[MAX_PATH*2];
7121     CHAR prodcode[MAX_PATH];
7122     CHAR prod_squashed[MAX_PATH];
7123     HKEY prodkey, userkey, props;
7124     LPSTR usersid;
7125     DWORD size;
7126     LONG res;
7127     UINT r;
7128
7129     GetCurrentDirectoryA(MAX_PATH, path);
7130     lstrcatA(path, "\\");
7131
7132     create_test_guid(prodcode, prod_squashed);
7133     get_user_sid(&usersid);
7134
7135     hdb = create_package_db(prodcode);
7136     MsiCloseHandle(hdb);
7137
7138     /* NULL szProduct */
7139     hprod = 0xdeadbeef;
7140     r = MsiOpenProductA(NULL, &hprod);
7141     ok(r == ERROR_INVALID_PARAMETER,
7142        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7143     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7144
7145     /* empty szProduct */
7146     hprod = 0xdeadbeef;
7147     r = MsiOpenProductA("", &hprod);
7148     ok(r == ERROR_INVALID_PARAMETER,
7149        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7150     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7151
7152     /* garbage szProduct */
7153     hprod = 0xdeadbeef;
7154     r = MsiOpenProductA("garbage", &hprod);
7155     ok(r == ERROR_INVALID_PARAMETER,
7156        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7157     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7158
7159     /* guid without brackets */
7160     hprod = 0xdeadbeef;
7161     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7162     ok(r == ERROR_INVALID_PARAMETER,
7163        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7164     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7165
7166     /* guid with brackets */
7167     hprod = 0xdeadbeef;
7168     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7169     ok(r == ERROR_UNKNOWN_PRODUCT,
7170        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7171     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7172
7173     /* same length as guid, but random */
7174     hprod = 0xdeadbeef;
7175     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7176     ok(r == ERROR_INVALID_PARAMETER,
7177        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7178     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7179
7180     /* hProduct is NULL */
7181     hprod = 0xdeadbeef;
7182     r = MsiOpenProductA(prodcode, NULL);
7183     ok(r == ERROR_INVALID_PARAMETER,
7184        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7185     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7186
7187     /* MSIINSTALLCONTEXT_USERMANAGED */
7188
7189     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7190     lstrcatA(keypath, "Installer\\Managed\\");
7191     lstrcatA(keypath, usersid);
7192     lstrcatA(keypath, "\\Installer\\Products\\");
7193     lstrcatA(keypath, prod_squashed);
7194
7195     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7197
7198     /* managed product key exists */
7199     hprod = 0xdeadbeef;
7200     r = MsiOpenProductA(prodcode, &hprod);
7201     ok(r == ERROR_UNKNOWN_PRODUCT,
7202        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7203     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7204
7205     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7206     lstrcatA(keypath, "Installer\\UserData\\");
7207     lstrcatA(keypath, usersid);
7208     lstrcatA(keypath, "\\Products\\");
7209     lstrcatA(keypath, prod_squashed);
7210
7211     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7213
7214     /* user product key exists */
7215     hprod = 0xdeadbeef;
7216     r = MsiOpenProductA(prodcode, &hprod);
7217     ok(r == ERROR_UNKNOWN_PRODUCT,
7218        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7219     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7220
7221     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7222     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7223
7224     /* InstallProperties key exists */
7225     hprod = 0xdeadbeef;
7226     r = MsiOpenProductA(prodcode, &hprod);
7227     ok(r == ERROR_UNKNOWN_PRODUCT,
7228        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7229     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7230
7231     lstrcpyA(val, path);
7232     lstrcatA(val, "\\winetest.msi");
7233     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7234                          (const BYTE *)val, lstrlenA(val) + 1);
7235     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7236
7237     /* ManagedLocalPackage value exists */
7238     hprod = 0xdeadbeef;
7239     r = MsiOpenProductA(prodcode, &hprod);
7240     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7241     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7242
7243     size = MAX_PATH;
7244     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7246     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7247     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7248
7249     MsiCloseHandle(hprod);
7250
7251     RegDeleteValueA(props, "ManagedLocalPackage");
7252     RegDeleteKeyA(props, "");
7253     RegCloseKey(props);
7254     RegDeleteKeyA(userkey, "");
7255     RegCloseKey(userkey);
7256     RegDeleteKeyA(prodkey, "");
7257     RegCloseKey(prodkey);
7258
7259     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7260
7261     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7262     lstrcatA(keypath, prod_squashed);
7263
7264     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7266
7267     /* unmanaged product key exists */
7268     hprod = 0xdeadbeef;
7269     r = MsiOpenProductA(prodcode, &hprod);
7270     ok(r == ERROR_UNKNOWN_PRODUCT,
7271        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7272     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7273
7274     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7275     lstrcatA(keypath, "Installer\\UserData\\");
7276     lstrcatA(keypath, usersid);
7277     lstrcatA(keypath, "\\Products\\");
7278     lstrcatA(keypath, prod_squashed);
7279
7280     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7281     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7282
7283     /* user product key exists */
7284     hprod = 0xdeadbeef;
7285     r = MsiOpenProductA(prodcode, &hprod);
7286     ok(r == ERROR_UNKNOWN_PRODUCT,
7287        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7288     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7289
7290     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7292
7293     /* InstallProperties key exists */
7294     hprod = 0xdeadbeef;
7295     r = MsiOpenProductA(prodcode, &hprod);
7296     ok(r == ERROR_UNKNOWN_PRODUCT,
7297        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7298     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7299
7300     lstrcpyA(val, path);
7301     lstrcatA(val, "\\winetest.msi");
7302     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7303                          (const BYTE *)val, lstrlenA(val) + 1);
7304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7305
7306     /* LocalPackage value exists */
7307     hprod = 0xdeadbeef;
7308     r = MsiOpenProductA(prodcode, &hprod);
7309     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7310     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7311
7312     size = MAX_PATH;
7313     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7315     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7316     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7317
7318     MsiCloseHandle(hprod);
7319
7320     RegDeleteValueA(props, "LocalPackage");
7321     RegDeleteKeyA(props, "");
7322     RegCloseKey(props);
7323     RegDeleteKeyA(userkey, "");
7324     RegCloseKey(userkey);
7325     RegDeleteKeyA(prodkey, "");
7326     RegCloseKey(prodkey);
7327
7328     /* MSIINSTALLCONTEXT_MACHINE */
7329
7330     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7331     lstrcatA(keypath, prod_squashed);
7332
7333     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7334     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7335
7336     /* managed product key exists */
7337     hprod = 0xdeadbeef;
7338     r = MsiOpenProductA(prodcode, &hprod);
7339     ok(r == ERROR_UNKNOWN_PRODUCT,
7340        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7341     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7342
7343     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7344     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7345     lstrcatA(keypath, prod_squashed);
7346
7347     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7349
7350     /* user product key exists */
7351     hprod = 0xdeadbeef;
7352     r = MsiOpenProductA(prodcode, &hprod);
7353     ok(r == ERROR_UNKNOWN_PRODUCT,
7354        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7355     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7356
7357     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7358     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7359
7360     /* InstallProperties key exists */
7361     hprod = 0xdeadbeef;
7362     r = MsiOpenProductA(prodcode, &hprod);
7363     ok(r == ERROR_UNKNOWN_PRODUCT,
7364        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7365     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7366
7367     lstrcpyA(val, path);
7368     lstrcatA(val, "\\winetest.msi");
7369     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7370                          (const BYTE *)val, lstrlenA(val) + 1);
7371     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7372
7373     /* LocalPackage value exists */
7374     hprod = 0xdeadbeef;
7375     r = MsiOpenProductA(prodcode, &hprod);
7376     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7377     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7378
7379     size = MAX_PATH;
7380     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7381     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7382     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7383     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7384
7385     MsiCloseHandle(hprod);
7386
7387     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7388                          (const BYTE *)"winetest.msi", 13);
7389     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7390
7391     /* LocalPackage has just the package name */
7392     hprod = 0xdeadbeef;
7393     r = MsiOpenProductA(prodcode, &hprod);
7394     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7395        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7396     if (r == ERROR_SUCCESS)
7397         MsiCloseHandle(hprod);
7398     else
7399         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7400
7401     lstrcpyA(val, path);
7402     lstrcatA(val, "\\winetest.msi");
7403     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7404                          (const BYTE *)val, lstrlenA(val) + 1);
7405     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7406
7407     DeleteFileA(msifile);
7408
7409     /* local package does not exist */
7410     hprod = 0xdeadbeef;
7411     r = MsiOpenProductA(prodcode, &hprod);
7412     ok(r == ERROR_UNKNOWN_PRODUCT,
7413        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7414     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7415
7416     RegDeleteValueA(props, "LocalPackage");
7417     RegDeleteKeyA(props, "");
7418     RegCloseKey(props);
7419     RegDeleteKeyA(userkey, "");
7420     RegCloseKey(userkey);
7421     RegDeleteKeyA(prodkey, "");
7422     RegCloseKey(prodkey);
7423
7424     DeleteFileA(msifile);
7425 }
7426
7427 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7428 {
7429     MSIINSTALLCONTEXT context;
7430     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7431     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7432     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7433     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7434     HKEY prodkey, patches, udprod, udpatch, hpatch;
7435     DWORD size, data;
7436     LONG res;
7437     UINT r;
7438
7439     create_test_guid(prodcode, prod_squashed);
7440     create_test_guid(patch, patch_squashed);
7441
7442     /* MSIPATCHSTATE_APPLIED */
7443
7444     lstrcpyA(patchcode, "apple");
7445     lstrcpyA(targetprod, "banana");
7446     context = 0xdeadbeef;
7447     lstrcpyA(targetsid, "kiwi");
7448     size = MAX_PATH;
7449     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7450                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7451                            &context, targetsid, &size);
7452     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7453     ok(!lstrcmpA(patchcode, "apple"),
7454        "Expected patchcode to be unchanged, got %s\n", patchcode);
7455     ok(!lstrcmpA(targetprod, "banana"),
7456        "Expected targetprod to be unchanged, got %s\n", targetprod);
7457     ok(context == 0xdeadbeef,
7458        "Expected context to be unchanged, got %d\n", context);
7459     ok(!lstrcmpA(targetsid, "kiwi"),
7460        "Expected targetsid to be unchanged, got %s\n", targetsid);
7461     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7462
7463     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7464     lstrcatA(keypath, expectedsid);
7465     lstrcatA(keypath, "\\Installer\\Products\\");
7466     lstrcatA(keypath, prod_squashed);
7467
7468     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7469     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7470
7471     /* managed product key exists */
7472     lstrcpyA(patchcode, "apple");
7473     lstrcpyA(targetprod, "banana");
7474     context = 0xdeadbeef;
7475     lstrcpyA(targetsid, "kiwi");
7476     size = MAX_PATH;
7477     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7478                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7479                            &context, targetsid, &size);
7480     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7481     ok(!lstrcmpA(patchcode, "apple"),
7482        "Expected patchcode to be unchanged, got %s\n", patchcode);
7483     ok(!lstrcmpA(targetprod, "banana"),
7484        "Expected targetprod to be unchanged, got %s\n", targetprod);
7485     ok(context == 0xdeadbeef,
7486        "Expected context to be unchanged, got %d\n", context);
7487     ok(!lstrcmpA(targetsid, "kiwi"),
7488        "Expected targetsid to be unchanged, got %s\n", targetsid);
7489     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7490
7491     res = RegCreateKeyA(prodkey, "Patches", &patches);
7492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7493
7494     /* patches key exists */
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     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7515                          (const BYTE *)patch_squashed,
7516                          lstrlenA(patch_squashed) + 1);
7517     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7518
7519     /* Patches value exists, is not REG_MULTI_SZ */
7520     lstrcpyA(patchcode, "apple");
7521     lstrcpyA(targetprod, "banana");
7522     context = 0xdeadbeef;
7523     lstrcpyA(targetsid, "kiwi");
7524     size = MAX_PATH;
7525     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7526                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7527                            &context, targetsid, &size);
7528     ok(r == ERROR_BAD_CONFIGURATION,
7529        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7530     ok(!lstrcmpA(patchcode, "apple"),
7531        "Expected patchcode to be unchanged, got %s\n", patchcode);
7532     ok(!lstrcmpA(targetprod, "banana"),
7533        "Expected targetprod to be unchanged, got %s\n", targetprod);
7534     ok(context == 0xdeadbeef,
7535        "Expected context to be unchanged, got %d\n", context);
7536     ok(!lstrcmpA(targetsid, "kiwi"),
7537        "Expected targetsid to be unchanged, got %s\n", targetsid);
7538     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7539
7540     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7541                          (const BYTE *)"a\0b\0c\0\0", 7);
7542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7543
7544     /* Patches value exists, is not a squashed guid */
7545     lstrcpyA(patchcode, "apple");
7546     lstrcpyA(targetprod, "banana");
7547     context = 0xdeadbeef;
7548     lstrcpyA(targetsid, "kiwi");
7549     size = MAX_PATH;
7550     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7551                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7552                            &context, targetsid, &size);
7553     ok(r == ERROR_BAD_CONFIGURATION,
7554        "Expected ERROR_BAD_CONFIGURATION, 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     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
7566     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7567                          (const BYTE *)patch_squashed,
7568                          lstrlenA(patch_squashed) + 2);
7569     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7570
7571     /* Patches value exists */
7572     lstrcpyA(patchcode, "apple");
7573     lstrcpyA(targetprod, "banana");
7574     context = 0xdeadbeef;
7575     lstrcpyA(targetsid, "kiwi");
7576     size = MAX_PATH;
7577     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7578                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7579                            &context, targetsid, &size);
7580     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, 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, patch_squashed, 0, REG_SZ,
7592                          (const BYTE *)"whatever", 9);
7593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7594
7595     /* patch squashed value exists */
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_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7605     ok(!lstrcmpA(patchcode, patch),
7606        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7607     ok(!lstrcmpA(targetprod, prodcode),
7608        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7609     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7610        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7611     ok(!lstrcmpA(targetsid, expectedsid),
7612        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7613     ok(size == lstrlenA(expectedsid),
7614        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7615
7616     /* increase the index */
7617     lstrcpyA(patchcode, "apple");
7618     lstrcpyA(targetprod, "banana");
7619     context = 0xdeadbeef;
7620     lstrcpyA(targetsid, "kiwi");
7621     size = MAX_PATH;
7622     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7623                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7624                            &context, targetsid, &size);
7625     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7626     ok(!lstrcmpA(patchcode, "apple"),
7627        "Expected patchcode to be unchanged, got %s\n", patchcode);
7628     ok(!lstrcmpA(targetprod, "banana"),
7629        "Expected targetprod to be unchanged, got %s\n", targetprod);
7630     ok(context == 0xdeadbeef,
7631        "Expected context to be unchanged, got %d\n", context);
7632     ok(!lstrcmpA(targetsid, "kiwi"),
7633        "Expected targetsid to be unchanged, got %s\n", targetsid);
7634     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7635
7636     /* increase again */
7637     lstrcpyA(patchcode, "apple");
7638     lstrcpyA(targetprod, "banana");
7639     context = 0xdeadbeef;
7640     lstrcpyA(targetsid, "kiwi");
7641     size = MAX_PATH;
7642     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7643                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
7644                            &context, targetsid, &size);
7645     ok(r == ERROR_INVALID_PARAMETER,
7646        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7647     ok(!lstrcmpA(patchcode, "apple"),
7648        "Expected patchcode to be unchanged, got %s\n", patchcode);
7649     ok(!lstrcmpA(targetprod, "banana"),
7650        "Expected targetprod to be unchanged, got %s\n", targetprod);
7651     ok(context == 0xdeadbeef,
7652        "Expected context to be unchanged, got %d\n", context);
7653     ok(!lstrcmpA(targetsid, "kiwi"),
7654        "Expected targetsid to be unchanged, got %s\n", targetsid);
7655     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7656
7657     /* szPatchCode is NULL */
7658     lstrcpyA(targetprod, "banana");
7659     context = 0xdeadbeef;
7660     lstrcpyA(targetsid, "kiwi");
7661     size = MAX_PATH;
7662     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7663                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
7664                            &context, targetsid, &size);
7665     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7666     ok(!lstrcmpA(targetprod, prodcode),
7667        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7668     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7669        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7670     ok(!lstrcmpA(targetsid, expectedsid),
7671        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7672     ok(size == lstrlenA(expectedsid),
7673        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7674
7675     /* szTargetProductCode is NULL */
7676     lstrcpyA(patchcode, "apple");
7677     context = 0xdeadbeef;
7678     lstrcpyA(targetsid, "kiwi");
7679     size = MAX_PATH;
7680     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7681                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
7682                            &context, targetsid, &size);
7683     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7684     ok(!lstrcmpA(patchcode, patch),
7685        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7686     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7687        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7688     ok(!lstrcmpA(targetsid, expectedsid),
7689        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7690     ok(size == lstrlenA(expectedsid),
7691        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7692
7693     /* pdwTargetProductContext is NULL */
7694     lstrcpyA(patchcode, "apple");
7695     lstrcpyA(targetprod, "banana");
7696     lstrcpyA(targetsid, "kiwi");
7697     size = MAX_PATH;
7698     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7699                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7700                            NULL, targetsid, &size);
7701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7702     ok(!lstrcmpA(patchcode, patch),
7703        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7704     ok(!lstrcmpA(targetprod, prodcode),
7705        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7706     ok(!lstrcmpA(targetsid, expectedsid),
7707        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7708     ok(size == lstrlenA(expectedsid),
7709        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7710
7711     /* szTargetUserSid is NULL */
7712     lstrcpyA(patchcode, "apple");
7713     lstrcpyA(targetprod, "banana");
7714     context = 0xdeadbeef;
7715     size = MAX_PATH;
7716     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7717                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7718                            &context, NULL, &size);
7719     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7720     ok(!lstrcmpA(patchcode, patch),
7721        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7722     ok(!lstrcmpA(targetprod, prodcode),
7723        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7724     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7725        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7726     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7727        "Expected %d, got %d\n", lstrlenA(expectedsid) * sizeof(WCHAR), size);
7728
7729     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
7730     lstrcpyA(patchcode, "apple");
7731     lstrcpyA(targetprod, "banana");
7732     context = 0xdeadbeef;
7733     lstrcpyA(targetsid, "kiwi");
7734     size = lstrlenA(expectedsid);
7735     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7736                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7737                            &context, targetsid, &size);
7738     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
7739     ok(!lstrcmpA(patchcode, patch),
7740        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7741     ok(!lstrcmpA(targetprod, prodcode),
7742        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7743     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7744        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7745     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
7746        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7747     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7748        "Expected %d, got %d\n", lstrlenA(expectedsid) * sizeof(WCHAR), size);
7749
7750     /* pcchTargetUserSid has enough room for NULL terminator */
7751     lstrcpyA(patchcode, "apple");
7752     lstrcpyA(targetprod, "banana");
7753     context = 0xdeadbeef;
7754     lstrcpyA(targetsid, "kiwi");
7755     size = lstrlenA(expectedsid) + 1;
7756     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7757                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7758                            &context, targetsid, &size);
7759     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7760     ok(!lstrcmpA(patchcode, patch),
7761        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7762     ok(!lstrcmpA(targetprod, prodcode),
7763        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7764     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7765        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7766     ok(!lstrcmpA(targetsid, expectedsid),
7767        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7768     ok(size == lstrlenA(expectedsid),
7769        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7770
7771     /* both szTargetuserSid and pcchTargetUserSid are NULL */
7772     lstrcpyA(patchcode, "apple");
7773     lstrcpyA(targetprod, "banana");
7774     context = 0xdeadbeef;
7775     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7776                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7777                            &context, NULL, NULL);
7778     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7779     ok(!lstrcmpA(patchcode, patch),
7780        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7781     ok(!lstrcmpA(targetprod, prodcode),
7782        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7783     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7784        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7785
7786     /* MSIPATCHSTATE_SUPERSEDED */
7787
7788     lstrcpyA(patchcode, "apple");
7789     lstrcpyA(targetprod, "banana");
7790     context = 0xdeadbeef;
7791     lstrcpyA(targetsid, "kiwi");
7792     size = MAX_PATH;
7793     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7794                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7795                            &context, targetsid, &size);
7796     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7797     ok(!lstrcmpA(patchcode, "apple"),
7798        "Expected patchcode to be unchanged, got %s\n", patchcode);
7799     ok(!lstrcmpA(targetprod, "banana"),
7800        "Expected targetprod to be unchanged, got %s\n", targetprod);
7801     ok(context == 0xdeadbeef,
7802        "Expected context to be unchanged, got %d\n", context);
7803     ok(!lstrcmpA(targetsid, "kiwi"),
7804        "Expected targetsid to be unchanged, got %s\n", targetsid);
7805     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7806
7807     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
7808     lstrcatA(keypath, expectedsid);
7809     lstrcatA(keypath, "\\Products\\");
7810     lstrcatA(keypath, prod_squashed);
7811
7812     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
7813     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7814
7815     /* UserData product key exists */
7816     lstrcpyA(patchcode, "apple");
7817     lstrcpyA(targetprod, "banana");
7818     context = 0xdeadbeef;
7819     lstrcpyA(targetsid, "kiwi");
7820     size = MAX_PATH;
7821     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7822                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7823                            &context, targetsid, &size);
7824     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7825     ok(!lstrcmpA(patchcode, "apple"),
7826        "Expected patchcode to be unchanged, got %s\n", patchcode);
7827     ok(!lstrcmpA(targetprod, "banana"),
7828        "Expected targetprod to be unchanged, got %s\n", targetprod);
7829     ok(context == 0xdeadbeef,
7830        "Expected context to be unchanged, got %d\n", context);
7831     ok(!lstrcmpA(targetsid, "kiwi"),
7832        "Expected targetsid to be unchanged, got %s\n", targetsid);
7833     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7834
7835     res = RegCreateKeyA(udprod, "Patches", &udpatch);
7836     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7837
7838     /* UserData patches key exists */
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     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
7859     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7860
7861     /* specific UserData patch key exists */
7862     lstrcpyA(patchcode, "apple");
7863     lstrcpyA(targetprod, "banana");
7864     context = 0xdeadbeef;
7865     lstrcpyA(targetsid, "kiwi");
7866     size = MAX_PATH;
7867     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7868                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7869                            &context, targetsid, &size);
7870     ok(r == ERROR_BAD_CONFIGURATION,
7871        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7872     ok(!lstrcmpA(patchcode, "apple"),
7873        "Expected patchcode to be unchanged, got %s\n", patchcode);
7874     ok(!lstrcmpA(targetprod, "banana"),
7875        "Expected targetprod to be unchanged, got %s\n", targetprod);
7876     ok(context == 0xdeadbeef,
7877        "Expected context to be unchanged, got %d\n", context);
7878     ok(!lstrcmpA(targetsid, "kiwi"),
7879        "Expected targetsid to be unchanged, got %s\n", targetsid);
7880     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7881
7882     data = MSIPATCHSTATE_SUPERSEDED;
7883     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
7884                          (const BYTE *)&data, sizeof(DWORD));
7885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7886
7887     /* State value exists */
7888     lstrcpyA(patchcode, "apple");
7889     lstrcpyA(targetprod, "banana");
7890     context = 0xdeadbeef;
7891     lstrcpyA(targetsid, "kiwi");
7892     size = MAX_PATH;
7893     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7894                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7895                            &context, targetsid, &size);
7896     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7897     ok(!lstrcmpA(patchcode, patch),
7898        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7899     ok(!lstrcmpA(targetprod, prodcode),
7900        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7901     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7902        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7903     ok(!lstrcmpA(targetsid, expectedsid),
7904        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7905     ok(size == lstrlenA(expectedsid),
7906        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7907
7908     /* MSIPATCHSTATE_OBSOLETED */
7909
7910     lstrcpyA(patchcode, "apple");
7911     lstrcpyA(targetprod, "banana");
7912     context = 0xdeadbeef;
7913     lstrcpyA(targetsid, "kiwi");
7914     size = MAX_PATH;
7915     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7916                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
7917                            &context, targetsid, &size);
7918     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7919     ok(!lstrcmpA(patchcode, "apple"),
7920        "Expected patchcode to be unchanged, got %s\n", patchcode);
7921     ok(!lstrcmpA(targetprod, "banana"),
7922        "Expected targetprod to be unchanged, got %s\n", targetprod);
7923     ok(context == 0xdeadbeef,
7924        "Expected context to be unchanged, got %d\n", context);
7925     ok(!lstrcmpA(targetsid, "kiwi"),
7926        "Expected targetsid to be unchanged, got %s\n", targetsid);
7927     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7928
7929     data = MSIPATCHSTATE_OBSOLETED;
7930     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
7931                          (const BYTE *)&data, sizeof(DWORD));
7932     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7933
7934     /* State value is obsoleted */
7935     lstrcpyA(patchcode, "apple");
7936     lstrcpyA(targetprod, "banana");
7937     context = 0xdeadbeef;
7938     lstrcpyA(targetsid, "kiwi");
7939     size = MAX_PATH;
7940     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7941                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
7942                            &context, targetsid, &size);
7943     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7944     ok(!lstrcmpA(patchcode, patch),
7945        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7946     ok(!lstrcmpA(targetprod, prodcode),
7947        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7948     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7949        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7950     ok(!lstrcmpA(targetsid, expectedsid),
7951        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7952     ok(size == lstrlenA(expectedsid),
7953        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7954
7955     /* MSIPATCHSTATE_REGISTERED */
7956     /* FIXME */
7957
7958     /* MSIPATCHSTATE_ALL */
7959
7960     /* 1st */
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_ALL, 0, patchcode, targetprod,
7968                            &context, targetsid, &size);
7969     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7970     ok(!lstrcmpA(patchcode, patch),
7971        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7972     ok(!lstrcmpA(targetprod, prodcode),
7973        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7974     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7975        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7976     ok(!lstrcmpA(targetsid, expectedsid),
7977        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7978     ok(size == lstrlenA(expectedsid),
7979        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7980
7981     /* same patch in multiple places, only one is enumerated */
7982     lstrcpyA(patchcode, "apple");
7983     lstrcpyA(targetprod, "banana");
7984     context = 0xdeadbeef;
7985     lstrcpyA(targetsid, "kiwi");
7986     size = MAX_PATH;
7987     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7988                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
7989                            &context, targetsid, &size);
7990     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7991     ok(!lstrcmpA(patchcode, "apple"),
7992        "Expected patchcode to be unchanged, got %s\n", patchcode);
7993     ok(!lstrcmpA(targetprod, "banana"),
7994        "Expected targetprod to be unchanged, got %s\n", targetprod);
7995     ok(context == 0xdeadbeef,
7996        "Expected context to be unchanged, got %d\n", context);
7997     ok(!lstrcmpA(targetsid, "kiwi"),
7998        "Expected targetsid to be unchanged, got %s\n", targetsid);
7999     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8000
8001     RegDeleteValueA(hpatch, "State");
8002     RegDeleteKeyA(hpatch, "");
8003     RegCloseKey(hpatch);
8004     RegDeleteKeyA(udpatch, "");
8005     RegCloseKey(udpatch);
8006     RegDeleteKeyA(udprod, "");
8007     RegCloseKey(udprod);
8008     RegDeleteValueA(patches, "Patches");
8009     RegDeleteKeyA(patches, "");
8010     RegCloseKey(patches);
8011     RegDeleteKeyA(prodkey, "");
8012     RegCloseKey(prodkey);
8013 }
8014
8015 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8016 {
8017     MSIINSTALLCONTEXT context;
8018     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8019     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8020     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8021     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8022     HKEY prodkey, patches, udprod, udpatch;
8023     HKEY userkey, hpatch;
8024     DWORD size, data;
8025     LONG res;
8026     UINT r;
8027
8028     create_test_guid(prodcode, prod_squashed);
8029     create_test_guid(patch, patch_squashed);
8030
8031     /* MSIPATCHSTATE_APPLIED */
8032
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_USERUNMANAGED,
8039                            MSIPATCHSTATE_APPLIED, 0, 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     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8053     lstrcatA(keypath, prod_squashed);
8054
8055     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8056     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8057
8058     /* current user product key exists */
8059     lstrcpyA(patchcode, "apple");
8060     lstrcpyA(targetprod, "banana");
8061     context = 0xdeadbeef;
8062     lstrcpyA(targetsid, "kiwi");
8063     size = MAX_PATH;
8064     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8065                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8066                            &context, targetsid, &size);
8067     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8068     ok(!lstrcmpA(patchcode, "apple"),
8069        "Expected patchcode to be unchanged, got %s\n", patchcode);
8070     ok(!lstrcmpA(targetprod, "banana"),
8071        "Expected targetprod to be unchanged, got %s\n", targetprod);
8072     ok(context == 0xdeadbeef,
8073        "Expected context to be unchanged, got %d\n", context);
8074     ok(!lstrcmpA(targetsid, "kiwi"),
8075        "Expected targetsid to be unchanged, got %s\n", targetsid);
8076     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8077
8078     res = RegCreateKeyA(prodkey, "Patches", &patches);
8079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8080
8081     /* Patches key exists */
8082     lstrcpyA(patchcode, "apple");
8083     lstrcpyA(targetprod, "banana");
8084     context = 0xdeadbeef;
8085     lstrcpyA(targetsid, "kiwi");
8086     size = MAX_PATH;
8087     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8088                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8089                            &context, targetsid, &size);
8090     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8091     ok(!lstrcmpA(patchcode, "apple"),
8092        "Expected patchcode to be unchanged, got %s\n", patchcode);
8093     ok(!lstrcmpA(targetprod, "banana"),
8094        "Expected targetprod to be unchanged, got %s\n", targetprod);
8095     ok(context == 0xdeadbeef,
8096        "Expected context to be unchanged, got %d\n", context);
8097     ok(!lstrcmpA(targetsid, "kiwi"),
8098        "Expected targetsid to be unchanged, got %s\n", targetsid);
8099     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8100
8101     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8102                          (const BYTE *)patch_squashed,
8103                          lstrlenA(patch_squashed) + 1);
8104     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8105
8106     /* Patches value exists, is not REG_MULTI_SZ */
8107     lstrcpyA(patchcode, "apple");
8108     lstrcpyA(targetprod, "banana");
8109     context = 0xdeadbeef;
8110     lstrcpyA(targetsid, "kiwi");
8111     size = MAX_PATH;
8112     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8113                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8114                            &context, targetsid, &size);
8115     ok(r == ERROR_BAD_CONFIGURATION,
8116        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8117     ok(!lstrcmpA(patchcode, "apple"),
8118        "Expected patchcode to be unchanged, got %s\n", patchcode);
8119     ok(!lstrcmpA(targetprod, "banana"),
8120        "Expected targetprod to be unchanged, got %s\n", targetprod);
8121     ok(context == 0xdeadbeef,
8122        "Expected context to be unchanged, got %d\n", context);
8123     ok(!lstrcmpA(targetsid, "kiwi"),
8124        "Expected targetsid to be unchanged, got %s\n", targetsid);
8125     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8126
8127     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8128                          (const BYTE *)"a\0b\0c\0\0", 7);
8129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8130
8131     /* Patches value exists, is not a squashed guid */
8132     lstrcpyA(patchcode, "apple");
8133     lstrcpyA(targetprod, "banana");
8134     context = 0xdeadbeef;
8135     lstrcpyA(targetsid, "kiwi");
8136     size = MAX_PATH;
8137     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8138                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8139                            &context, targetsid, &size);
8140     ok(r == ERROR_BAD_CONFIGURATION,
8141        "Expected ERROR_BAD_CONFIGURATION, 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_MULTI_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 */
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_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8167     ok(!lstrcmpA(patchcode, "apple"),
8168        "Expected patchcode to be unchanged, got %s\n", patchcode);
8169     ok(!lstrcmpA(targetprod, "banana"),
8170        "Expected targetprod to be unchanged, got %s\n", targetprod);
8171     ok(context == 0xdeadbeef,
8172        "Expected context to be unchanged, got %d\n", context);
8173     ok(!lstrcmpA(targetsid, "kiwi"),
8174        "Expected targetsid to be unchanged, got %s\n", targetsid);
8175     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8176
8177     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8178                          (const BYTE *)"whatever", 9);
8179     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8180
8181     /* patch code value exists */
8182     lstrcpyA(patchcode, "apple");
8183     lstrcpyA(targetprod, "banana");
8184     context = 0xdeadbeef;
8185     lstrcpyA(targetsid, "kiwi");
8186     size = MAX_PATH;
8187     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8188                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8189                            &context, targetsid, &size);
8190     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8191     ok(!lstrcmpA(patchcode, "apple"),
8192        "Expected patchcode to be unchanged, got %s\n", patchcode);
8193     ok(!lstrcmpA(targetprod, "banana"),
8194        "Expected targetprod to be unchanged, got %s\n", targetprod);
8195     ok(context == 0xdeadbeef,
8196        "Expected context to be unchanged, got %d\n", context);
8197     ok(!lstrcmpA(targetsid, "kiwi"),
8198        "Expected targetsid to be unchanged, got %s\n", targetsid);
8199     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8200
8201     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8202     lstrcatA(keypath, expectedsid);
8203     lstrcatA(keypath, "\\Patches\\");
8204     lstrcatA(keypath, patch_squashed);
8205
8206     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
8207     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8208
8209     /* userdata patch key exists */
8210     lstrcpyA(patchcode, "apple");
8211     lstrcpyA(targetprod, "banana");
8212     context = 0xdeadbeef;
8213     lstrcpyA(targetsid, "kiwi");
8214     size = MAX_PATH;
8215     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8216                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8217                            &context, targetsid, &size);
8218     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8219     ok(!lstrcmpA(patchcode, patch),
8220        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8221     ok(!lstrcmpA(targetprod, prodcode),
8222        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8223     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8224        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8225     ok(!lstrcmpA(targetsid, expectedsid),
8226        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8227     ok(size == lstrlenA(expectedsid),
8228        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8229
8230     /* MSIPATCHSTATE_SUPERSEDED */
8231
8232     lstrcpyA(patchcode, "apple");
8233     lstrcpyA(targetprod, "banana");
8234     context = 0xdeadbeef;
8235     lstrcpyA(targetsid, "kiwi");
8236     size = MAX_PATH;
8237     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8238                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8239                            &context, targetsid, &size);
8240     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8241     ok(!lstrcmpA(patchcode, "apple"),
8242        "Expected patchcode to be unchanged, got %s\n", patchcode);
8243     ok(!lstrcmpA(targetprod, "banana"),
8244        "Expected targetprod to be unchanged, got %s\n", targetprod);
8245     ok(context == 0xdeadbeef,
8246        "Expected context to be unchanged, got %d\n", context);
8247     ok(!lstrcmpA(targetsid, "kiwi"),
8248        "Expected targetsid to be unchanged, got %s\n", targetsid);
8249     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8250
8251     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8252     lstrcatA(keypath, expectedsid);
8253     lstrcatA(keypath, "\\Products\\");
8254     lstrcatA(keypath, prod_squashed);
8255
8256     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8258
8259     /* UserData product key exists */
8260     lstrcpyA(patchcode, "apple");
8261     lstrcpyA(targetprod, "banana");
8262     context = 0xdeadbeef;
8263     lstrcpyA(targetsid, "kiwi");
8264     size = MAX_PATH;
8265     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8266                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8267                            &context, targetsid, &size);
8268     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8269     ok(!lstrcmpA(patchcode, "apple"),
8270        "Expected patchcode to be unchanged, got %s\n", patchcode);
8271     ok(!lstrcmpA(targetprod, "banana"),
8272        "Expected targetprod to be unchanged, got %s\n", targetprod);
8273     ok(context == 0xdeadbeef,
8274        "Expected context to be unchanged, got %d\n", context);
8275     ok(!lstrcmpA(targetsid, "kiwi"),
8276        "Expected targetsid to be unchanged, got %s\n", targetsid);
8277     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8278
8279     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8281
8282     /* UserData patches key exists */
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     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8304
8305     /* specific UserData patch key exists */
8306     lstrcpyA(patchcode, "apple");
8307     lstrcpyA(targetprod, "banana");
8308     context = 0xdeadbeef;
8309     lstrcpyA(targetsid, "kiwi");
8310     size = MAX_PATH;
8311     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8312                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8313                            &context, targetsid, &size);
8314     ok(r == ERROR_BAD_CONFIGURATION,
8315        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8316     ok(!lstrcmpA(patchcode, "apple"),
8317        "Expected patchcode to be unchanged, got %s\n", patchcode);
8318     ok(!lstrcmpA(targetprod, "banana"),
8319        "Expected targetprod to be unchanged, got %s\n", targetprod);
8320     ok(context == 0xdeadbeef,
8321        "Expected context to be unchanged, got %d\n", context);
8322     ok(!lstrcmpA(targetsid, "kiwi"),
8323        "Expected targetsid to be unchanged, got %s\n", targetsid);
8324     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8325
8326     data = MSIPATCHSTATE_SUPERSEDED;
8327     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8328                          (const BYTE *)&data, sizeof(DWORD));
8329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8330
8331     /* State value exists */
8332     lstrcpyA(patchcode, "apple");
8333     lstrcpyA(targetprod, "banana");
8334     context = 0xdeadbeef;
8335     lstrcpyA(targetsid, "kiwi");
8336     size = MAX_PATH;
8337     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8338                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8339                            &context, targetsid, &size);
8340     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8341     ok(!lstrcmpA(patchcode, patch),
8342        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8343     ok(!lstrcmpA(targetprod, prodcode),
8344        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8345     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8346        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8347     ok(!lstrcmpA(targetsid, expectedsid),
8348        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8349     ok(size == lstrlenA(expectedsid),
8350        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8351
8352     /* MSIPATCHSTATE_OBSOLETED */
8353
8354     lstrcpyA(patchcode, "apple");
8355     lstrcpyA(targetprod, "banana");
8356     context = 0xdeadbeef;
8357     lstrcpyA(targetsid, "kiwi");
8358     size = MAX_PATH;
8359     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8360                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8361                            &context, targetsid, &size);
8362     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8363     ok(!lstrcmpA(patchcode, "apple"),
8364        "Expected patchcode to be unchanged, got %s\n", patchcode);
8365     ok(!lstrcmpA(targetprod, "banana"),
8366        "Expected targetprod to be unchanged, got %s\n", targetprod);
8367     ok(context == 0xdeadbeef,
8368        "Expected context to be unchanged, got %d\n", context);
8369     ok(!lstrcmpA(targetsid, "kiwi"),
8370        "Expected targetsid to be unchanged, got %s\n", targetsid);
8371     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8372
8373     data = MSIPATCHSTATE_OBSOLETED;
8374     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8375                          (const BYTE *)&data, sizeof(DWORD));
8376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8377
8378     /* State value is obsoleted */
8379     lstrcpyA(patchcode, "apple");
8380     lstrcpyA(targetprod, "banana");
8381     context = 0xdeadbeef;
8382     lstrcpyA(targetsid, "kiwi");
8383     size = MAX_PATH;
8384     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8385                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8386                            &context, targetsid, &size);
8387     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8388     ok(!lstrcmpA(patchcode, patch),
8389        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8390     ok(!lstrcmpA(targetprod, prodcode),
8391        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8392     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8393        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8394     ok(!lstrcmpA(targetsid, expectedsid),
8395        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8396     ok(size == lstrlenA(expectedsid),
8397        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8398
8399     /* MSIPATCHSTATE_REGISTERED */
8400     /* FIXME */
8401
8402     /* MSIPATCHSTATE_ALL */
8403
8404     /* 1st */
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_ALL, 0, patchcode, targetprod,
8412                            &context, targetsid, &size);
8413     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8414     ok(!lstrcmpA(patchcode, patch),
8415        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8416     ok(!lstrcmpA(targetprod, prodcode),
8417        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8418     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8419        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8420     ok(!lstrcmpA(targetsid, expectedsid),
8421        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8422     ok(size == lstrlenA(expectedsid),
8423        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8424
8425     /* same patch in multiple places, only one is enumerated */
8426     lstrcpyA(patchcode, "apple");
8427     lstrcpyA(targetprod, "banana");
8428     context = 0xdeadbeef;
8429     lstrcpyA(targetsid, "kiwi");
8430     size = MAX_PATH;
8431     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8432                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8433                            &context, targetsid, &size);
8434     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8435     ok(!lstrcmpA(patchcode, "apple"),
8436        "Expected patchcode to be unchanged, got %s\n", patchcode);
8437     ok(!lstrcmpA(targetprod, "banana"),
8438        "Expected targetprod to be unchanged, got %s\n", targetprod);
8439     ok(context == 0xdeadbeef,
8440        "Expected context to be unchanged, got %d\n", context);
8441     ok(!lstrcmpA(targetsid, "kiwi"),
8442        "Expected targetsid to be unchanged, got %s\n", targetsid);
8443     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8444
8445     RegDeleteValueA(hpatch, "State");
8446     RegDeleteKeyA(hpatch, "");
8447     RegCloseKey(hpatch);
8448     RegDeleteKeyA(udpatch, "");
8449     RegCloseKey(udpatch);
8450     RegDeleteKeyA(udprod, "");
8451     RegCloseKey(udprod);
8452     RegDeleteKeyA(userkey, "");
8453     RegCloseKey(userkey);
8454     RegDeleteValueA(patches, patch_squashed);
8455     RegDeleteValueA(patches, "Patches");
8456     RegDeleteKeyA(patches, "");
8457     RegCloseKey(patches);
8458     RegDeleteKeyA(prodkey, "");
8459     RegCloseKey(prodkey);
8460 }
8461
8462 static void test_MsiEnumPatchesEx_machine()
8463 {
8464     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8465     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8466     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8467     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8468     HKEY prodkey, patches, udprod, udpatch;
8469     HKEY hpatch;
8470     MSIINSTALLCONTEXT context;
8471     DWORD size, data;
8472     LONG res;
8473     UINT r;
8474
8475     create_test_guid(prodcode, prod_squashed);
8476     create_test_guid(patch, patch_squashed);
8477
8478     /* MSIPATCHSTATE_APPLIED */
8479
8480     lstrcpyA(patchcode, "apple");
8481     lstrcpyA(targetprod, "banana");
8482     context = 0xdeadbeef;
8483     lstrcpyA(targetsid, "kiwi");
8484     size = MAX_PATH;
8485     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8486                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8487                            &context, targetsid, &size);
8488     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8489     ok(!lstrcmpA(patchcode, "apple"),
8490        "Expected patchcode to be unchanged, got %s\n", patchcode);
8491     ok(!lstrcmpA(targetprod, "banana"),
8492        "Expected targetprod to be unchanged, got %s\n", targetprod);
8493     ok(context == 0xdeadbeef,
8494        "Expected context to be unchanged, got %d\n", context);
8495     ok(!lstrcmpA(targetsid, "kiwi"),
8496        "Expected targetsid to be unchanged, got %s\n", targetsid);
8497     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8498
8499     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8500     lstrcatA(keypath, prod_squashed);
8501
8502     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
8503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8504
8505     /* local product key exists */
8506     lstrcpyA(patchcode, "apple");
8507     lstrcpyA(targetprod, "banana");
8508     context = 0xdeadbeef;
8509     lstrcpyA(targetsid, "kiwi");
8510     size = MAX_PATH;
8511     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8512                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8513                            &context, targetsid, &size);
8514     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8515     ok(!lstrcmpA(patchcode, "apple"),
8516        "Expected patchcode to be unchanged, got %s\n", patchcode);
8517     ok(!lstrcmpA(targetprod, "banana"),
8518        "Expected targetprod to be unchanged, got %s\n", targetprod);
8519     ok(context == 0xdeadbeef,
8520        "Expected context to be unchanged, got %d\n", context);
8521     ok(!lstrcmpA(targetsid, "kiwi"),
8522        "Expected targetsid to be unchanged, got %s\n", targetsid);
8523     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8524
8525     res = RegCreateKeyA(prodkey, "Patches", &patches);
8526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8527
8528     /* Patches key exists */
8529     lstrcpyA(patchcode, "apple");
8530     lstrcpyA(targetprod, "banana");
8531     context = 0xdeadbeef;
8532     lstrcpyA(targetsid, "kiwi");
8533     size = MAX_PATH;
8534     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8535                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8536                            &context, targetsid, &size);
8537     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8538     ok(!lstrcmpA(patchcode, "apple"),
8539        "Expected patchcode to be unchanged, got %s\n", patchcode);
8540     ok(!lstrcmpA(targetprod, "banana"),
8541        "Expected targetprod to be unchanged, got %s\n", targetprod);
8542     ok(context == 0xdeadbeef,
8543        "Expected context to be unchanged, got %d\n", context);
8544     ok(!lstrcmpA(targetsid, "kiwi"),
8545        "Expected targetsid to be unchanged, got %s\n", targetsid);
8546     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8547
8548     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8549                          (const BYTE *)patch_squashed,
8550                          lstrlenA(patch_squashed) + 1);
8551     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8552
8553     /* Patches value exists, is not REG_MULTI_SZ */
8554     lstrcpyA(patchcode, "apple");
8555     lstrcpyA(targetprod, "banana");
8556     context = 0xdeadbeef;
8557     lstrcpyA(targetsid, "kiwi");
8558     size = MAX_PATH;
8559     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8560                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8561                            &context, targetsid, &size);
8562     ok(r == ERROR_BAD_CONFIGURATION,
8563        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8564     ok(!lstrcmpA(patchcode, "apple"),
8565        "Expected patchcode to be unchanged, got %s\n", patchcode);
8566     ok(!lstrcmpA(targetprod, "banana"),
8567        "Expected targetprod to be unchanged, got %s\n", targetprod);
8568     ok(context == 0xdeadbeef,
8569        "Expected context to be unchanged, got %d\n", context);
8570     ok(!lstrcmpA(targetsid, "kiwi"),
8571        "Expected targetsid to be unchanged, got %s\n", targetsid);
8572     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8573
8574     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8575                          (const BYTE *)"a\0b\0c\0\0", 7);
8576     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8577
8578     /* Patches value exists, is not a squashed guid */
8579     lstrcpyA(patchcode, "apple");
8580     lstrcpyA(targetprod, "banana");
8581     context = 0xdeadbeef;
8582     lstrcpyA(targetsid, "kiwi");
8583     size = MAX_PATH;
8584     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8585                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8586                            &context, targetsid, &size);
8587     ok(r == ERROR_BAD_CONFIGURATION,
8588        "Expected ERROR_BAD_CONFIGURATION, 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     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8600     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8601                          (const BYTE *)patch_squashed,
8602                          lstrlenA(patch_squashed) + 2);
8603     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8604
8605     /* Patches value exists */
8606     lstrcpyA(patchcode, "apple");
8607     lstrcpyA(targetprod, "banana");
8608     context = 0xdeadbeef;
8609     lstrcpyA(targetsid, "kiwi");
8610     size = MAX_PATH;
8611     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8612                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8613                            &context, targetsid, &size);
8614     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, 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, patch_squashed, 0, REG_SZ,
8626                          (const BYTE *)"whatever", 9);
8627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8628
8629     /* patch code value exists */
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_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8639     ok(!lstrcmpA(patchcode, patch),
8640        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8641     ok(!lstrcmpA(targetprod, prodcode),
8642        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8643     ok(context == MSIINSTALLCONTEXT_MACHINE,
8644        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8645     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8646     ok(size == 0, "Expected 0, got %d\n", size);
8647
8648     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8649     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8650     lstrcatA(keypath, prod_squashed);
8651
8652     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8654
8655     /* local UserData product key exists */
8656     lstrcpyA(patchcode, "apple");
8657     lstrcpyA(targetprod, "banana");
8658     context = 0xdeadbeef;
8659     lstrcpyA(targetsid, "kiwi");
8660     size = MAX_PATH;
8661     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8662                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8663                            &context, targetsid, &size);
8664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8665     ok(!lstrcmpA(patchcode, patch),
8666        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8667     ok(!lstrcmpA(targetprod, prodcode),
8668        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8669     ok(context == MSIINSTALLCONTEXT_MACHINE,
8670        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8671     ok(!lstrcmpA(targetsid, ""),
8672        "Expected \"\", got \"%s\"\n", targetsid);
8673     ok(size == 0, "Expected 0, got %d\n", size);
8674
8675     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8676     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8677
8678     /* local UserData Patches key exists */
8679     lstrcpyA(patchcode, "apple");
8680     lstrcpyA(targetprod, "banana");
8681     context = 0xdeadbeef;
8682     lstrcpyA(targetsid, "kiwi");
8683     size = MAX_PATH;
8684     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8685                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8686                            &context, targetsid, &size);
8687     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8688     ok(!lstrcmpA(patchcode, patch),
8689        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8690     ok(!lstrcmpA(targetprod, prodcode),
8691        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8692     ok(context == MSIINSTALLCONTEXT_MACHINE,
8693        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8694     ok(!lstrcmpA(targetsid, ""),
8695        "Expected \"\", got \"%s\"\n", targetsid);
8696     ok(size == 0, "Expected 0, got %d\n", size);
8697
8698     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8700
8701     /* local UserData Product patch key exists */
8702     lstrcpyA(patchcode, "apple");
8703     lstrcpyA(targetprod, "banana");
8704     context = 0xdeadbeef;
8705     lstrcpyA(targetsid, "kiwi");
8706     size = MAX_PATH;
8707     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8708                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8709                            &context, targetsid, &size);
8710     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8711     ok(!lstrcmpA(patchcode, "apple"),
8712        "Expected patchcode to be unchanged, got %s\n", patchcode);
8713     ok(!lstrcmpA(targetprod, "banana"),
8714        "Expected targetprod to be unchanged, got %s\n", targetprod);
8715     ok(context == 0xdeadbeef,
8716        "Expected context to be unchanged, got %d\n", context);
8717     ok(!lstrcmpA(targetsid, "kiwi"),
8718        "Expected targetsid to be unchanged, got %s\n", targetsid);
8719     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8720
8721     data = MSIPATCHSTATE_APPLIED;
8722     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8723                          (const BYTE *)&data, sizeof(DWORD));
8724     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8725
8726     /* State value exists */
8727     lstrcpyA(patchcode, "apple");
8728     lstrcpyA(targetprod, "banana");
8729     context = 0xdeadbeef;
8730     lstrcpyA(targetsid, "kiwi");
8731     size = MAX_PATH;
8732     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8733                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8734                            &context, targetsid, &size);
8735     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8736     ok(!lstrcmpA(patchcode, patch),
8737        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8738     ok(!lstrcmpA(targetprod, prodcode),
8739        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8740     ok(context == MSIINSTALLCONTEXT_MACHINE,
8741        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8742     ok(!lstrcmpA(targetsid, ""),
8743        "Expected \"\", got \"%s\"\n", targetsid);
8744     ok(size == 0, "Expected 0, got %d\n", size);
8745
8746     /* MSIPATCHSTATE_SUPERSEDED */
8747
8748     lstrcpyA(patchcode, "apple");
8749     lstrcpyA(targetprod, "banana");
8750     context = 0xdeadbeef;
8751     lstrcpyA(targetsid, "kiwi");
8752     size = MAX_PATH;
8753     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8754                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8755                            &context, targetsid, &size);
8756     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8757     ok(!lstrcmpA(patchcode, "apple"),
8758        "Expected patchcode to be unchanged, got %s\n", patchcode);
8759     ok(!lstrcmpA(targetprod, "banana"),
8760        "Expected targetprod to be unchanged, got %s\n", targetprod);
8761     ok(context == 0xdeadbeef,
8762        "Expected context to be unchanged, got %d\n", context);
8763     ok(!lstrcmpA(targetsid, "kiwi"),
8764        "Expected targetsid to be unchanged, got %s\n", targetsid);
8765     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8766
8767     data = MSIPATCHSTATE_SUPERSEDED;
8768     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8769                          (const BYTE *)&data, sizeof(DWORD));
8770     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8771
8772     /* State value is MSIPATCHSTATE_SUPERSEDED */
8773     lstrcpyA(patchcode, "apple");
8774     lstrcpyA(targetprod, "banana");
8775     context = 0xdeadbeef;
8776     lstrcpyA(targetsid, "kiwi");
8777     size = MAX_PATH;
8778     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8779                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8780                            &context, targetsid, &size);
8781     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8782     ok(!lstrcmpA(patchcode, patch),
8783        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8784     ok(!lstrcmpA(targetprod, prodcode),
8785        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8786     ok(context == MSIINSTALLCONTEXT_MACHINE,
8787        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8788     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8789     ok(size == 0, "Expected 0, got %d\n", size);
8790
8791     /* MSIPATCHSTATE_OBSOLETED */
8792
8793     lstrcpyA(patchcode, "apple");
8794     lstrcpyA(targetprod, "banana");
8795     context = 0xdeadbeef;
8796     lstrcpyA(targetsid, "kiwi");
8797     size = MAX_PATH;
8798     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8799                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8800                            &context, targetsid, &size);
8801     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8802     ok(!lstrcmpA(patchcode, "apple"),
8803        "Expected patchcode to be unchanged, got %s\n", patchcode);
8804     ok(!lstrcmpA(targetprod, "banana"),
8805        "Expected targetprod to be unchanged, got %s\n", targetprod);
8806     ok(context == 0xdeadbeef,
8807        "Expected context to be unchanged, got %d\n", context);
8808     ok(!lstrcmpA(targetsid, "kiwi"),
8809        "Expected targetsid to be unchanged, got %s\n", targetsid);
8810     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8811
8812     data = MSIPATCHSTATE_OBSOLETED;
8813     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8814                          (const BYTE *)&data, sizeof(DWORD));
8815     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8816
8817     /* State value is obsoleted */
8818     lstrcpyA(patchcode, "apple");
8819     lstrcpyA(targetprod, "banana");
8820     context = 0xdeadbeef;
8821     lstrcpyA(targetsid, "kiwi");
8822     size = MAX_PATH;
8823     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8824                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8825                            &context, targetsid, &size);
8826     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8827     ok(!lstrcmpA(patchcode, patch),
8828        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8829     ok(!lstrcmpA(targetprod, prodcode),
8830        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8831     ok(context == MSIINSTALLCONTEXT_MACHINE,
8832        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8833     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8834     ok(size == 0, "Expected 0, got %d\n", size);
8835
8836     /* MSIPATCHSTATE_REGISTERED */
8837     /* FIXME */
8838
8839     /* MSIPATCHSTATE_ALL */
8840
8841     /* 1st */
8842     lstrcpyA(patchcode, "apple");
8843     lstrcpyA(targetprod, "banana");
8844     context = 0xdeadbeef;
8845     lstrcpyA(targetsid, "kiwi");
8846     size = MAX_PATH;
8847     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8848                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8849                            &context, targetsid, &size);
8850     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8851     ok(!lstrcmpA(patchcode, patch),
8852        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8853     ok(!lstrcmpA(targetprod, prodcode),
8854        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8855     ok(context == MSIINSTALLCONTEXT_MACHINE,
8856        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8857     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8858     ok(size == 0, "Expected 0, got %d\n", size);
8859
8860     /* same patch in multiple places, only one is enumerated */
8861     lstrcpyA(patchcode, "apple");
8862     lstrcpyA(targetprod, "banana");
8863     context = 0xdeadbeef;
8864     lstrcpyA(targetsid, "kiwi");
8865     size = MAX_PATH;
8866     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8867                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8868                            &context, targetsid, &size);
8869     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8870     ok(!lstrcmpA(patchcode, "apple"),
8871        "Expected patchcode to be unchanged, got %s\n", patchcode);
8872     ok(!lstrcmpA(targetprod, "banana"),
8873        "Expected targetprod to be unchanged, got %s\n", targetprod);
8874     ok(context == 0xdeadbeef,
8875        "Expected context to be unchanged, got %d\n", context);
8876     ok(!lstrcmpA(targetsid, "kiwi"),
8877        "Expected targetsid to be unchanged, got %s\n", targetsid);
8878     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8879
8880     RegDeleteValueA(patches, patch_squashed);
8881     RegDeleteValueA(patches, "Patches");
8882     RegDeleteKeyA(patches, "");
8883     RegCloseKey(patches);
8884     RegDeleteValueA(hpatch, "State");
8885     RegDeleteKeyA(hpatch, "");
8886     RegCloseKey(hpatch);
8887     RegDeleteKeyA(udpatch, "");
8888     RegCloseKey(udpatch);
8889     RegDeleteKeyA(udprod, "");
8890     RegCloseKey(udprod);
8891     RegDeleteKeyA(prodkey, "");
8892     RegCloseKey(prodkey);
8893 }
8894
8895 static void test_MsiEnumPatchesEx(void)
8896 {
8897     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8898     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8899     CHAR patchcode[MAX_PATH];
8900     MSIINSTALLCONTEXT context;
8901     LPSTR usersid;
8902     DWORD size;
8903     UINT r;
8904
8905     if (!pMsiEnumPatchesExA)
8906     {
8907         win_skip("MsiEnumPatchesExA not implemented\n");
8908         return;
8909     }
8910
8911     create_test_guid(prodcode, prod_squashed);
8912     get_user_sid(&usersid);
8913
8914     /* empty szProductCode */
8915     lstrcpyA(patchcode, "apple");
8916     lstrcpyA(targetprod, "banana");
8917     context = 0xdeadbeef;
8918     lstrcpyA(targetsid, "kiwi");
8919     size = MAX_PATH;
8920     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8921                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
8922                            targetsid, &size);
8923     ok(r == ERROR_INVALID_PARAMETER,
8924        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8925     ok(!lstrcmpA(patchcode, "apple"),
8926        "Expected patchcode to be unchanged, got %s\n", patchcode);
8927     ok(!lstrcmpA(targetprod, "banana"),
8928        "Expected targetprod to be unchanged, got %s\n", targetprod);
8929     ok(context == 0xdeadbeef,
8930        "Expected context to be unchanged, got %d\n", context);
8931     ok(!lstrcmpA(targetsid, "kiwi"),
8932        "Expected targetsid to be unchanged, got %s\n", targetsid);
8933     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8934
8935     /* garbage szProductCode */
8936     lstrcpyA(patchcode, "apple");
8937     lstrcpyA(targetprod, "banana");
8938     context = 0xdeadbeef;
8939     lstrcpyA(targetsid, "kiwi");
8940     size = MAX_PATH;
8941     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8942                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
8943                            targetsid, &size);
8944     ok(r == ERROR_INVALID_PARAMETER,
8945        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8946     ok(!lstrcmpA(patchcode, "apple"),
8947        "Expected patchcode to be unchanged, got %s\n", patchcode);
8948     ok(!lstrcmpA(targetprod, "banana"),
8949        "Expected targetprod to be unchanged, got %s\n", targetprod);
8950     ok(context == 0xdeadbeef,
8951        "Expected context to be unchanged, got %d\n", context);
8952     ok(!lstrcmpA(targetsid, "kiwi"),
8953        "Expected targetsid to be unchanged, got %s\n", targetsid);
8954     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8955
8956     /* guid without brackets */
8957     lstrcpyA(patchcode, "apple");
8958     lstrcpyA(targetprod, "banana");
8959     context = 0xdeadbeef;
8960     lstrcpyA(targetsid, "kiwi");
8961     size = MAX_PATH;
8962     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
8963                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
8964                            0, patchcode, targetprod, &context,
8965                            targetsid, &size);
8966     ok(r == ERROR_INVALID_PARAMETER,
8967        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8968     ok(!lstrcmpA(patchcode, "apple"),
8969        "Expected patchcode to be unchanged, got %s\n", patchcode);
8970     ok(!lstrcmpA(targetprod, "banana"),
8971        "Expected targetprod to be unchanged, got %s\n", targetprod);
8972     ok(context == 0xdeadbeef,
8973        "Expected context to be unchanged, got %d\n", context);
8974     ok(!lstrcmpA(targetsid, "kiwi"),
8975        "Expected targetsid to be unchanged, got %s\n", targetsid);
8976     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8977
8978     /* guid with brackets */
8979     lstrcpyA(patchcode, "apple");
8980     lstrcpyA(targetprod, "banana");
8981     context = 0xdeadbeef;
8982     lstrcpyA(targetsid, "kiwi");
8983     size = MAX_PATH;
8984     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
8985                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
8986                            0, patchcode, targetprod, &context,
8987                            targetsid, &size);
8988     ok(r == ERROR_NO_MORE_ITEMS,
8989        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8990     ok(!lstrcmpA(patchcode, "apple"),
8991        "Expected patchcode to be unchanged, got %s\n", patchcode);
8992     ok(!lstrcmpA(targetprod, "banana"),
8993        "Expected targetprod to be unchanged, got %s\n", targetprod);
8994     ok(context == 0xdeadbeef,
8995        "Expected context to be unchanged, got %d\n", context);
8996     ok(!lstrcmpA(targetsid, "kiwi"),
8997        "Expected targetsid to be unchanged, got %s\n", targetsid);
8998     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8999
9000     /* szUserSid is S-1-5-18 */
9001     lstrcpyA(patchcode, "apple");
9002     lstrcpyA(targetprod, "banana");
9003     context = 0xdeadbeef;
9004     lstrcpyA(targetsid, "kiwi");
9005     size = MAX_PATH;
9006     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9007                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9008                            0, patchcode, targetprod, &context,
9009                            targetsid, &size);
9010     ok(r == ERROR_INVALID_PARAMETER,
9011        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9012     ok(!lstrcmpA(patchcode, "apple"),
9013        "Expected patchcode to be unchanged, got %s\n", patchcode);
9014     ok(!lstrcmpA(targetprod, "banana"),
9015        "Expected targetprod to be unchanged, got %s\n", targetprod);
9016     ok(context == 0xdeadbeef,
9017        "Expected context to be unchanged, got %d\n", context);
9018     ok(!lstrcmpA(targetsid, "kiwi"),
9019        "Expected targetsid to be unchanged, got %s\n", targetsid);
9020     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9021
9022     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9023     lstrcpyA(patchcode, "apple");
9024     lstrcpyA(targetprod, "banana");
9025     context = 0xdeadbeef;
9026     lstrcpyA(targetsid, "kiwi");
9027     size = MAX_PATH;
9028     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9029                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9030                            &context, targetsid, &size);
9031     ok(r == ERROR_INVALID_PARAMETER,
9032        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9033     ok(!lstrcmpA(patchcode, "apple"),
9034        "Expected patchcode to be unchanged, got %s\n", patchcode);
9035     ok(!lstrcmpA(targetprod, "banana"),
9036        "Expected targetprod to be unchanged, got %s\n", targetprod);
9037     ok(context == 0xdeadbeef,
9038        "Expected context to be unchanged, got %d\n", context);
9039     ok(!lstrcmpA(targetsid, "kiwi"),
9040        "Expected targetsid to be unchanged, got %s\n", targetsid);
9041     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9042
9043     /* dwContext is out of bounds */
9044     lstrcpyA(patchcode, "apple");
9045     lstrcpyA(targetprod, "banana");
9046     context = 0xdeadbeef;
9047     lstrcpyA(targetsid, "kiwi");
9048     size = MAX_PATH;
9049     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9050                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9051                            &context, targetsid, &size);
9052     ok(r == ERROR_INVALID_PARAMETER,
9053        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9054     ok(!lstrcmpA(patchcode, "apple"),
9055        "Expected patchcode to be unchanged, got %s\n", patchcode);
9056     ok(!lstrcmpA(targetprod, "banana"),
9057        "Expected targetprod to be unchanged, got %s\n", targetprod);
9058     ok(context == 0xdeadbeef,
9059        "Expected context to be unchanged, got %d\n", context);
9060     ok(!lstrcmpA(targetsid, "kiwi"),
9061        "Expected targetsid to be unchanged, got %s\n", targetsid);
9062     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9063
9064     /* dwContext is out of bounds */
9065     lstrcpyA(patchcode, "apple");
9066     lstrcpyA(targetprod, "banana");
9067     context = 0xdeadbeef;
9068     lstrcpyA(targetsid, "kiwi");
9069     size = MAX_PATH;
9070     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9071                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9072                            &context, targetsid, &size);
9073     ok(r == ERROR_INVALID_PARAMETER,
9074        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9075     ok(!lstrcmpA(patchcode, "apple"),
9076        "Expected patchcode to be unchanged, got %s\n", patchcode);
9077     ok(!lstrcmpA(targetprod, "banana"),
9078        "Expected targetprod to be unchanged, got %s\n", targetprod);
9079     ok(context == 0xdeadbeef,
9080        "Expected context to be unchanged, got %d\n", context);
9081     ok(!lstrcmpA(targetsid, "kiwi"),
9082        "Expected targetsid to be unchanged, got %s\n", targetsid);
9083     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9084
9085     /* dwFilter is out of bounds */
9086     lstrcpyA(patchcode, "apple");
9087     lstrcpyA(targetprod, "banana");
9088     context = 0xdeadbeef;
9089     lstrcpyA(targetsid, "kiwi");
9090     size = MAX_PATH;
9091     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9092                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9093                            &context, targetsid, &size);
9094     ok(r == ERROR_INVALID_PARAMETER,
9095        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9096     ok(!lstrcmpA(patchcode, "apple"),
9097        "Expected patchcode to be unchanged, got %s\n", patchcode);
9098     ok(!lstrcmpA(targetprod, "banana"),
9099        "Expected targetprod to be unchanged, got %s\n", targetprod);
9100     ok(context == 0xdeadbeef,
9101        "Expected context to be unchanged, got %d\n", context);
9102     ok(!lstrcmpA(targetsid, "kiwi"),
9103        "Expected targetsid to be unchanged, got %s\n", targetsid);
9104     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9105
9106     /* dwFilter is out of bounds */
9107     lstrcpyA(patchcode, "apple");
9108     lstrcpyA(targetprod, "banana");
9109     context = 0xdeadbeef;
9110     lstrcpyA(targetsid, "kiwi");
9111     size = MAX_PATH;
9112     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9113                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9114                            &context, targetsid, &size);
9115     ok(r == ERROR_INVALID_PARAMETER,
9116        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9117     ok(!lstrcmpA(patchcode, "apple"),
9118        "Expected patchcode to be unchanged, got %s\n", patchcode);
9119     ok(!lstrcmpA(targetprod, "banana"),
9120        "Expected targetprod to be unchanged, got %s\n", targetprod);
9121     ok(context == 0xdeadbeef,
9122        "Expected context to be unchanged, got %d\n", context);
9123     ok(!lstrcmpA(targetsid, "kiwi"),
9124        "Expected targetsid to be unchanged, got %s\n", targetsid);
9125     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9126
9127     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9128     lstrcpyA(patchcode, "apple");
9129     lstrcpyA(targetprod, "banana");
9130     context = 0xdeadbeef;
9131     lstrcpyA(targetsid, "kiwi");
9132     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9133                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9134                            &context, targetsid, NULL);
9135     ok(r == ERROR_INVALID_PARAMETER,
9136        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9137     ok(!lstrcmpA(patchcode, "apple"),
9138        "Expected patchcode to be unchanged, got %s\n", patchcode);
9139     ok(!lstrcmpA(targetprod, "banana"),
9140        "Expected targetprod to be unchanged, got %s\n", targetprod);
9141     ok(context == 0xdeadbeef,
9142        "Expected context to be unchanged, got %d\n", context);
9143     ok(!lstrcmpA(targetsid, "kiwi"),
9144        "Expected targetsid to be unchanged, got %s\n", targetsid);
9145
9146     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9147     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9148     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9149     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9150     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9151     /* FIXME: Successfully test userunmanaged with a different user */
9152     test_MsiEnumPatchesEx_machine();
9153 }
9154
9155 static void test_MsiEnumPatches(void)
9156 {
9157     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9158     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9159     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9160     CHAR transforms[MAX_PATH];
9161     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9162     HKEY prodkey, patches, udprod;
9163     HKEY userkey, hpatch, udpatch;
9164     DWORD size, data;
9165     LPSTR usersid;
9166     LONG res;
9167     UINT r;
9168
9169     create_test_guid(prodcode, prod_squashed);
9170     create_test_guid(patchcode, patch_squashed);
9171     get_user_sid(&usersid);
9172
9173     /* NULL szProduct */
9174     size = MAX_PATH;
9175     lstrcpyA(patch, "apple");
9176     lstrcpyA(transforms, "banana");
9177     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9178     ok(r == ERROR_INVALID_PARAMETER,
9179        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9180     ok(!lstrcmpA(patch, "apple"),
9181        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9182     ok(!lstrcmpA(transforms, "banana"),
9183        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9184     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9185
9186     /* empty szProduct */
9187     size = MAX_PATH;
9188     lstrcpyA(patch, "apple");
9189     lstrcpyA(transforms, "banana");
9190     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9191     ok(r == ERROR_INVALID_PARAMETER,
9192        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9193     ok(!lstrcmpA(patch, "apple"),
9194        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9195     ok(!lstrcmpA(transforms, "banana"),
9196        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9197     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9198
9199     /* garbage szProduct */
9200     size = MAX_PATH;
9201     lstrcpyA(patch, "apple");
9202     lstrcpyA(transforms, "banana");
9203     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9204     ok(r == ERROR_INVALID_PARAMETER,
9205        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9206     ok(!lstrcmpA(patch, "apple"),
9207        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9208     ok(!lstrcmpA(transforms, "banana"),
9209        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9210     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9211
9212     /* guid without brackets */
9213     size = MAX_PATH;
9214     lstrcpyA(patch, "apple");
9215     lstrcpyA(transforms, "banana");
9216     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9217                         transforms, &size);
9218     ok(r == ERROR_INVALID_PARAMETER,
9219        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9220     ok(!lstrcmpA(patch, "apple"),
9221        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9222     ok(!lstrcmpA(transforms, "banana"),
9223        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9224     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9225
9226     /* guid with brackets */
9227     size = MAX_PATH;
9228     lstrcpyA(patch, "apple");
9229     lstrcpyA(transforms, "banana");
9230     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9231                         transforms, &size);
9232     ok(r == ERROR_UNKNOWN_PRODUCT,
9233        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9234     ok(!lstrcmpA(patch, "apple"),
9235        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9236     ok(!lstrcmpA(transforms, "banana"),
9237        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9238     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9239
9240     /* same length as guid, but random */
9241     size = MAX_PATH;
9242     lstrcpyA(patch, "apple");
9243     lstrcpyA(transforms, "banana");
9244     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9245                         transforms, &size);
9246     ok(r == ERROR_INVALID_PARAMETER,
9247        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9248     ok(!lstrcmpA(patch, "apple"),
9249        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9250     ok(!lstrcmpA(transforms, "banana"),
9251        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9252     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9253
9254     /* MSIINSTALLCONTEXT_USERMANAGED */
9255
9256     size = MAX_PATH;
9257     lstrcpyA(patch, "apple");
9258     lstrcpyA(transforms, "banana");
9259     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9260     ok(r == ERROR_UNKNOWN_PRODUCT,
9261        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9262     ok(!lstrcmpA(patch, "apple"),
9263        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9264     ok(!lstrcmpA(transforms, "banana"),
9265        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9266     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9267
9268     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9269     lstrcatA(keypath, usersid);
9270     lstrcatA(keypath, "\\Installer\\Products\\");
9271     lstrcatA(keypath, prod_squashed);
9272
9273     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9274     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9275
9276     /* managed product key exists */
9277     size = MAX_PATH;
9278     lstrcpyA(patch, "apple");
9279     lstrcpyA(transforms, "banana");
9280     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9281     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9282     ok(!lstrcmpA(patch, "apple"),
9283        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9284     ok(!lstrcmpA(transforms, "banana"),
9285        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9286     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9287
9288     res = RegCreateKeyA(prodkey, "Patches", &patches);
9289     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9290
9291     /* patches key exists */
9292     size = MAX_PATH;
9293     lstrcpyA(patch, "apple");
9294     lstrcpyA(transforms, "banana");
9295     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9296     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9297     ok(!lstrcmpA(patch, "apple"),
9298        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9299     ok(!lstrcmpA(transforms, "banana"),
9300        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9301     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9302
9303     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9304                          (const BYTE *)patch_squashed,
9305                          lstrlenA(patch_squashed) + 1);
9306     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9307
9308     /* Patches value exists, is not REG_MULTI_SZ */
9309     size = MAX_PATH;
9310     lstrcpyA(patch, "apple");
9311     lstrcpyA(transforms, "banana");
9312     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9313     ok(r == ERROR_BAD_CONFIGURATION,
9314        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9315     ok(!lstrcmpA(patch, "apple"),
9316        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9317     ok(!lstrcmpA(transforms, "banana"),
9318        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9319     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9320
9321     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9322                          (const BYTE *)"a\0b\0c\0\0", 7);
9323     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9324
9325     /* Patches value exists, is not a squashed guid */
9326     size = MAX_PATH;
9327     lstrcpyA(patch, "apple");
9328     lstrcpyA(transforms, "banana");
9329     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9330     ok(r == ERROR_BAD_CONFIGURATION,
9331        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9332     ok(!lstrcmpA(patch, "apple"),
9333        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9334     ok(!lstrcmpA(transforms, "banana"),
9335        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9336     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9337
9338     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9339     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9340                          (const BYTE *)patch_squashed,
9341                          lstrlenA(patch_squashed) + 2);
9342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9343
9344     /* Patches value exists */
9345     size = MAX_PATH;
9346     lstrcpyA(patch, "apple");
9347     lstrcpyA(transforms, "banana");
9348     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9349     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9350     ok(!lstrcmpA(patch, "apple"),
9351        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9352     ok(!lstrcmpA(transforms, "banana"),
9353        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9354     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9355
9356     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9357                          (const BYTE *)"whatever", 9);
9358     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9359
9360     /* patch squashed value exists */
9361     size = MAX_PATH;
9362     lstrcpyA(patch, "apple");
9363     lstrcpyA(transforms, "banana");
9364     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9365     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9366     ok(!lstrcmpA(patch, patchcode),
9367        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9368     ok(!lstrcmpA(transforms, "whatever"),
9369        "Expected \"whatever\", got \"%s\"\n", transforms);
9370     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9371
9372     /* lpPatchBuf is NULL */
9373     size = MAX_PATH;
9374     lstrcpyA(transforms, "banana");
9375     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9376     ok(r == ERROR_INVALID_PARAMETER,
9377        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9378     ok(!lstrcmpA(transforms, "banana"),
9379        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9380     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9381
9382     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9383     size = MAX_PATH;
9384     lstrcpyA(patch, "apple");
9385     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9386     ok(r == ERROR_INVALID_PARAMETER,
9387        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9388     ok(!lstrcmpA(patch, "apple"),
9389        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9390     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9391
9392     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9393     lstrcpyA(patch, "apple");
9394     lstrcpyA(transforms, "banana");
9395     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9396     ok(r == ERROR_INVALID_PARAMETER,
9397        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9398     ok(!lstrcmpA(patch, "apple"),
9399        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9400     ok(!lstrcmpA(transforms, "banana"),
9401        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9402
9403     /* pcchTransformsBuf is too small */
9404     size = 6;
9405     lstrcpyA(patch, "apple");
9406     lstrcpyA(transforms, "banana");
9407     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9408     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9409     ok(!lstrcmpA(patch, patchcode),
9410        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9411     ok(!lstrcmpA(transforms, "whate"),
9412        "Expected \"whate\", got \"%s\"\n", transforms);
9413     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
9414
9415     /* increase the index */
9416     size = MAX_PATH;
9417     lstrcpyA(patch, "apple");
9418     lstrcpyA(transforms, "banana");
9419     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9420     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9421     ok(!lstrcmpA(patch, "apple"),
9422        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9423     ok(!lstrcmpA(transforms, "banana"),
9424        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9425     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9426
9427     /* increase again */
9428     size = MAX_PATH;
9429     lstrcpyA(patch, "apple");
9430     lstrcpyA(transforms, "banana");
9431     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9432     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9433     ok(!lstrcmpA(patch, "apple"),
9434        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9435     ok(!lstrcmpA(transforms, "banana"),
9436        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9437     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9438
9439     RegDeleteValueA(patches, "Patches");
9440     RegDeleteKeyA(patches, "");
9441     RegCloseKey(patches);
9442     RegDeleteKeyA(prodkey, "");
9443     RegCloseKey(prodkey);
9444
9445     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9446
9447     size = MAX_PATH;
9448     lstrcpyA(patch, "apple");
9449     lstrcpyA(transforms, "banana");
9450     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9451     ok(r == ERROR_UNKNOWN_PRODUCT,
9452        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9453     ok(!lstrcmpA(patch, "apple"),
9454        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9455     ok(!lstrcmpA(transforms, "banana"),
9456        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9457     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9458
9459     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9460     lstrcatA(keypath, prod_squashed);
9461
9462     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9463     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9464
9465     /* current user product key exists */
9466     size = MAX_PATH;
9467     lstrcpyA(patch, "apple");
9468     lstrcpyA(transforms, "banana");
9469     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9470     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9471     ok(!lstrcmpA(patch, "apple"),
9472        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9473     ok(!lstrcmpA(transforms, "banana"),
9474        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9475     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9476
9477     res = RegCreateKeyA(prodkey, "Patches", &patches);
9478     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9479
9480     /* Patches key exists */
9481     size = MAX_PATH;
9482     lstrcpyA(patch, "apple");
9483     lstrcpyA(transforms, "banana");
9484     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9485     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9486     ok(!lstrcmpA(patch, "apple"),
9487        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9488     ok(!lstrcmpA(transforms, "banana"),
9489        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9490     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9491
9492     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9493                          (const BYTE *)patch_squashed,
9494                          lstrlenA(patch_squashed) + 1);
9495     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9496
9497     /* Patches value exists, is not REG_MULTI_SZ */
9498     size = MAX_PATH;
9499     lstrcpyA(patch, "apple");
9500     lstrcpyA(transforms, "banana");
9501     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9502     ok(r == ERROR_BAD_CONFIGURATION,
9503        "Expected ERROR_BAD_CONFIGURATION, 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     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9511                          (const BYTE *)"a\0b\0c\0\0", 7);
9512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9513
9514     /* Patches value exists, is not a squashed guid */
9515     size = MAX_PATH;
9516     lstrcpyA(patch, "apple");
9517     lstrcpyA(transforms, "banana");
9518     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9519     ok(r == ERROR_BAD_CONFIGURATION,
9520        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9521     ok(!lstrcmpA(patch, "apple"),
9522        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9523     ok(!lstrcmpA(transforms, "banana"),
9524        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9525     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9526
9527     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9528     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9529                          (const BYTE *)patch_squashed,
9530                          lstrlenA(patch_squashed) + 2);
9531     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9532
9533     /* Patches value exists */
9534     size = MAX_PATH;
9535     lstrcpyA(patch, "apple");
9536     lstrcpyA(transforms, "banana");
9537     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9538     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9539     ok(!lstrcmpA(patch, "apple"),
9540        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9541     ok(!lstrcmpA(transforms, "banana"),
9542        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9543     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9544
9545     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9546                          (const BYTE *)"whatever", 9);
9547     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9548
9549     /* patch code value exists */
9550     size = MAX_PATH;
9551     lstrcpyA(patch, "apple");
9552     lstrcpyA(transforms, "banana");
9553     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9554     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, 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     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9562     lstrcatA(keypath, usersid);
9563     lstrcatA(keypath, "\\Patches\\");
9564     lstrcatA(keypath, patch_squashed);
9565
9566     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
9567     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9568
9569     /* userdata patch key exists */
9570     size = MAX_PATH;
9571     lstrcpyA(patch, "apple");
9572     lstrcpyA(transforms, "banana");
9573     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9574     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9575     ok(!lstrcmpA(patch, patchcode),
9576        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9577     ok(!lstrcmpA(transforms, "whatever"),
9578        "Expected \"whatever\", got \"%s\"\n", transforms);
9579     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9580
9581     RegDeleteKeyA(userkey, "");
9582     RegCloseKey(userkey);
9583     RegDeleteValueA(patches, patch_squashed);
9584     RegDeleteValueA(patches, "Patches");
9585     RegDeleteKeyA(patches, "");
9586     RegCloseKey(patches);
9587     RegDeleteKeyA(prodkey, "");
9588     RegCloseKey(prodkey);
9589
9590     /* MSIINSTALLCONTEXT_MACHINE */
9591
9592     size = MAX_PATH;
9593     lstrcpyA(patch, "apple");
9594     lstrcpyA(transforms, "banana");
9595     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9596     ok(r == ERROR_UNKNOWN_PRODUCT,
9597        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9598     ok(!lstrcmpA(patch, "apple"),
9599        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9600     ok(!lstrcmpA(transforms, "banana"),
9601        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9602     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9603
9604     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9605     lstrcatA(keypath, prod_squashed);
9606
9607     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9608     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9609
9610     /* local product key exists */
9611     size = MAX_PATH;
9612     lstrcpyA(patch, "apple");
9613     lstrcpyA(transforms, "banana");
9614     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9615     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9616     ok(!lstrcmpA(patch, "apple"),
9617        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9618     ok(!lstrcmpA(transforms, "banana"),
9619        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9620     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9621
9622     res = RegCreateKeyA(prodkey, "Patches", &patches);
9623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9624
9625     /* Patches key exists */
9626     size = MAX_PATH;
9627     lstrcpyA(patch, "apple");
9628     lstrcpyA(transforms, "banana");
9629     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9630     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9631     ok(!lstrcmpA(patch, "apple"),
9632        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9633     ok(!lstrcmpA(transforms, "banana"),
9634        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9635     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9636
9637     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9638                          (const BYTE *)patch_squashed,
9639                          lstrlenA(patch_squashed) + 1);
9640     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9641
9642     /* Patches value exists, is not REG_MULTI_SZ */
9643     size = MAX_PATH;
9644     lstrcpyA(patch, "apple");
9645     lstrcpyA(transforms, "banana");
9646     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9647     ok(r == ERROR_BAD_CONFIGURATION,
9648        "Expected ERROR_BAD_CONFIGURATION, 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     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9656                          (const BYTE *)"a\0b\0c\0\0", 7);
9657     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9658
9659     /* Patches value exists, is not a squashed guid */
9660     size = MAX_PATH;
9661     lstrcpyA(patch, "apple");
9662     lstrcpyA(transforms, "banana");
9663     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9664     ok(r == ERROR_BAD_CONFIGURATION,
9665        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9666     ok(!lstrcmpA(patch, "apple"),
9667        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9668     ok(!lstrcmpA(transforms, "banana"),
9669        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9670     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9671
9672     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9673     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9674                          (const BYTE *)patch_squashed,
9675                          lstrlenA(patch_squashed) + 2);
9676     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9677
9678     /* Patches value exists */
9679     size = MAX_PATH;
9680     lstrcpyA(patch, "apple");
9681     lstrcpyA(transforms, "banana");
9682     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9683     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9684     ok(!lstrcmpA(patch, "apple"),
9685        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9686     ok(!lstrcmpA(transforms, "banana"),
9687        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9688     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9689
9690     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9691                          (const BYTE *)"whatever", 9);
9692     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9693
9694     /* patch code value exists */
9695     size = MAX_PATH;
9696     lstrcpyA(patch, "apple");
9697     lstrcpyA(transforms, "banana");
9698     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9699     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9700     ok(!lstrcmpA(patch, patchcode),
9701        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9702     ok(!lstrcmpA(transforms, "whatever"),
9703        "Expected \"whatever\", got \"%s\"\n", transforms);
9704     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9705
9706     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9707     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9708     lstrcatA(keypath, prod_squashed);
9709
9710     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9711     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9712
9713     /* local UserData product key exists */
9714     size = MAX_PATH;
9715     lstrcpyA(patch, "apple");
9716     lstrcpyA(transforms, "banana");
9717     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9718     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9719     ok(!lstrcmpA(patch, patchcode),
9720        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9721     ok(!lstrcmpA(transforms, "whatever"),
9722        "Expected \"whatever\", got \"%s\"\n", transforms);
9723     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9724
9725     res = RegCreateKeyA(udprod, "Patches", &udpatch);
9726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9727
9728     /* local UserData Patches key exists */
9729     size = MAX_PATH;
9730     lstrcpyA(patch, "apple");
9731     lstrcpyA(transforms, "banana");
9732     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9733     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9734     ok(!lstrcmpA(patch, patchcode),
9735        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9736     ok(!lstrcmpA(transforms, "whatever"),
9737        "Expected \"whatever\", got \"%s\"\n", transforms);
9738     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9739
9740     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
9741     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9742
9743     /* local UserData Product patch key exists */
9744     size = MAX_PATH;
9745     lstrcpyA(patch, "apple");
9746     lstrcpyA(transforms, "banana");
9747     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9748     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9749     ok(!lstrcmpA(patch, "apple"),
9750        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9751     ok(!lstrcmpA(transforms, "banana"),
9752        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9753     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9754
9755     data = MSIPATCHSTATE_APPLIED;
9756     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9757                          (const BYTE *)&data, sizeof(DWORD));
9758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9759
9760     /* State value exists */
9761     size = MAX_PATH;
9762     lstrcpyA(patch, "apple");
9763     lstrcpyA(transforms, "banana");
9764     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9765     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9766     ok(!lstrcmpA(patch, patchcode),
9767        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9768     ok(!lstrcmpA(transforms, "whatever"),
9769        "Expected \"whatever\", got \"%s\"\n", transforms);
9770     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9771
9772     /* now duplicate some of the tests for the W version */
9773
9774     /* pcchTransformsBuf is too small */
9775     size = 6;
9776     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
9777     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9778     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9779     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9780     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9781     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9782     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
9783     ok(!lstrcmpA(patch, patchcode),
9784        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9785     ok(!lstrcmpA(transforms, "whate"),
9786        "Expected \"whate\", got \"%s\"\n", transforms);
9787     ok(size == 8, "Expected 8, got %d\n", size);
9788
9789     /* patch code value exists */
9790     size = MAX_PATH;
9791     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9792     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9793     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9794     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9795     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9796     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
9797     ok(!lstrcmpA(patch, patchcode),
9798        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9799     ok(!lstrcmpA(transforms, "whatever"),
9800        "Expected \"whatever\", got \"%s\"\n", transforms);
9801     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9802
9803     RegDeleteValueA(patches, patch_squashed);
9804     RegDeleteValueA(patches, "Patches");
9805     RegDeleteKeyA(patches, "");
9806     RegCloseKey(patches);
9807     RegDeleteValueA(hpatch, "State");
9808     RegDeleteKeyA(hpatch, "");
9809     RegCloseKey(hpatch);
9810     RegDeleteKeyA(udpatch, "");
9811     RegCloseKey(udpatch);
9812     RegDeleteKeyA(udprod, "");
9813     RegCloseKey(udprod);
9814     RegDeleteKeyA(prodkey, "");
9815     RegCloseKey(prodkey);
9816 }
9817
9818 static void test_MsiGetPatchInfoEx(void)
9819 {
9820     CHAR keypath[MAX_PATH], val[MAX_PATH];
9821     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9822     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9823     HKEY prodkey, patches, udprod, props;
9824     HKEY hpatch, udpatch, prodpatches;
9825     LPSTR usersid;
9826     DWORD size;
9827     LONG res;
9828     UINT r;
9829
9830     if (!pMsiGetPatchInfoExA)
9831     {
9832         win_skip("MsiGetPatchInfoEx not implemented\n");
9833         return;
9834     }
9835
9836     create_test_guid(prodcode, prod_squashed);
9837     create_test_guid(patchcode, patch_squashed);
9838     get_user_sid(&usersid);
9839
9840     /* NULL szPatchCode */
9841     lstrcpyA(val, "apple");
9842     size = MAX_PATH;
9843     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9844                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9845     ok(r == ERROR_INVALID_PARAMETER,
9846        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9847     ok(!lstrcmpA(val, "apple"),
9848        "Expected val to be unchanged, got \"%s\"\n", val);
9849     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9850
9851     /* empty szPatchCode */
9852     size = MAX_PATH;
9853     lstrcpyA(val, "apple");
9854     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9855                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9856     ok(r == ERROR_INVALID_PARAMETER,
9857        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9858     ok(!lstrcmpA(val, "apple"),
9859        "Expected val to be unchanged, got \"%s\"\n", val);
9860     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9861
9862     /* garbage szPatchCode */
9863     size = MAX_PATH;
9864     lstrcpyA(val, "apple");
9865     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
9866                             MSIINSTALLCONTEXT_USERMANAGED,
9867                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9868     ok(r == ERROR_INVALID_PARAMETER,
9869        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9870     ok(!lstrcmpA(val, "apple"),
9871        "Expected val to be unchanged, got \"%s\"\n", val);
9872     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9873
9874     /* guid without brackets */
9875     size = MAX_PATH;
9876     lstrcpyA(val, "apple");
9877     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
9878                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9879                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9880     ok(r == ERROR_INVALID_PARAMETER,
9881        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9882     ok(!lstrcmpA(val, "apple"),
9883        "Expected val to be unchanged, got \"%s\"\n", val);
9884     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9885
9886     /* guid with brackets */
9887     size = MAX_PATH;
9888     lstrcpyA(val, "apple");
9889     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
9890                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9891                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9892     ok(r == ERROR_UNKNOWN_PRODUCT,
9893        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9894     ok(!lstrcmpA(val, "apple"),
9895        "Expected val to be unchanged, got \"%s\"\n", val);
9896     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9897
9898     /* same length as guid, but random */
9899     size = MAX_PATH;
9900     lstrcpyA(val, "apple");
9901     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
9902                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9903                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9904     ok(r == ERROR_INVALID_PARAMETER,
9905        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9906     ok(!lstrcmpA(val, "apple"),
9907        "Expected val to be unchanged, got \"%s\"\n", val);
9908     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9909
9910     /* NULL szProductCode */
9911     lstrcpyA(val, "apple");
9912     size = MAX_PATH;
9913     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9914                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9915     ok(r == ERROR_INVALID_PARAMETER,
9916        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9917     ok(!lstrcmpA(val, "apple"),
9918        "Expected val to be unchanged, got \"%s\"\n", val);
9919     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9920
9921     /* empty szProductCode */
9922     size = MAX_PATH;
9923     lstrcpyA(val, "apple");
9924     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
9925                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9926     ok(r == ERROR_INVALID_PARAMETER,
9927        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9928     ok(!lstrcmpA(val, "apple"),
9929        "Expected val to be unchanged, got \"%s\"\n", val);
9930     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9931
9932     /* garbage szProductCode */
9933     size = MAX_PATH;
9934     lstrcpyA(val, "apple");
9935     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
9936                             MSIINSTALLCONTEXT_USERMANAGED,
9937                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9938     ok(r == ERROR_INVALID_PARAMETER,
9939        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9940     ok(!lstrcmpA(val, "apple"),
9941        "Expected val to be unchanged, got \"%s\"\n", val);
9942     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9943
9944     /* guid without brackets */
9945     size = MAX_PATH;
9946     lstrcpyA(val, "apple");
9947     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
9948                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9949                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9950     ok(r == ERROR_INVALID_PARAMETER,
9951        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9952     ok(!lstrcmpA(val, "apple"),
9953        "Expected val to be unchanged, got \"%s\"\n", val);
9954     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9955
9956     /* guid with brackets */
9957     size = MAX_PATH;
9958     lstrcpyA(val, "apple");
9959     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
9960                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9961                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9962     ok(r == ERROR_UNKNOWN_PRODUCT,
9963        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9964     ok(!lstrcmpA(val, "apple"),
9965        "Expected val to be unchanged, got \"%s\"\n", val);
9966     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9967
9968     /* same length as guid, but random */
9969     size = MAX_PATH;
9970     lstrcpyA(val, "apple");
9971     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
9972                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9973                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9974     ok(r == ERROR_INVALID_PARAMETER,
9975        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9976     ok(!lstrcmpA(val, "apple"),
9977        "Expected val to be unchanged, got \"%s\"\n", val);
9978     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9979
9980     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
9981     size = MAX_PATH;
9982     lstrcpyA(val, "apple");
9983     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9984                             MSIINSTALLCONTEXT_USERMANAGED,
9985                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9986     ok(r == ERROR_INVALID_PARAMETER,
9987        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9988     ok(!lstrcmpA(val, "apple"),
9989        "Expected val to be unchanged, got \"%s\"\n", val);
9990     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9991
9992     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
9993     size = MAX_PATH;
9994     lstrcpyA(val, "apple");
9995     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9996                             MSIINSTALLCONTEXT_USERUNMANAGED,
9997                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9998     ok(r == ERROR_INVALID_PARAMETER,
9999        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10000     ok(!lstrcmpA(val, "apple"),
10001        "Expected val to be unchanged, got \"%s\"\n", val);
10002     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10003
10004     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10005     size = MAX_PATH;
10006     lstrcpyA(val, "apple");
10007     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10008                             MSIINSTALLCONTEXT_MACHINE,
10009                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10010     ok(r == ERROR_INVALID_PARAMETER,
10011        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10012     ok(!lstrcmpA(val, "apple"),
10013        "Expected val to be unchanged, got \"%s\"\n", val);
10014     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10015
10016     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10017     size = MAX_PATH;
10018     lstrcpyA(val, "apple");
10019     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10020                             MSIINSTALLCONTEXT_MACHINE,
10021                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10022     ok(r == ERROR_INVALID_PARAMETER,
10023        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10024     ok(!lstrcmpA(val, "apple"),
10025        "Expected val to be unchanged, got \"%s\"\n", val);
10026     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10027
10028     /* dwContext is out of range */
10029     size = MAX_PATH;
10030     lstrcpyA(val, "apple");
10031     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10032                             MSIINSTALLCONTEXT_NONE,
10033                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10034     ok(r == ERROR_INVALID_PARAMETER,
10035        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10036     ok(!lstrcmpA(val, "apple"),
10037        "Expected val to be unchanged, got \"%s\"\n", val);
10038     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10039
10040     /* dwContext is out of range */
10041     size = MAX_PATH;
10042     lstrcpyA(val, "apple");
10043     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10044                             MSIINSTALLCONTEXT_ALL,
10045                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10046     ok(r == ERROR_INVALID_PARAMETER,
10047        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10048     ok(!lstrcmpA(val, "apple"),
10049        "Expected val to be unchanged, got \"%s\"\n", val);
10050     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10051
10052     /* dwContext is invalid */
10053     size = MAX_PATH;
10054     lstrcpyA(val, "apple");
10055     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10056                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10057     ok(r == ERROR_INVALID_PARAMETER,
10058        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10059     ok(!lstrcmpA(val, "apple"),
10060        "Expected val to be unchanged, got \"%s\"\n", val);
10061     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10062
10063     /* MSIINSTALLCONTEXT_USERMANAGED */
10064
10065     size = MAX_PATH;
10066     lstrcpyA(val, "apple");
10067     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10068                             MSIINSTALLCONTEXT_USERMANAGED,
10069                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10070     ok(r == ERROR_UNKNOWN_PRODUCT,
10071        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10072     ok(!lstrcmpA(val, "apple"),
10073        "Expected val to be unchanged, got \"%s\"\n", val);
10074     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10075
10076     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10077     lstrcatA(keypath, usersid);
10078     lstrcatA(keypath, "\\Products\\");
10079     lstrcatA(keypath, prod_squashed);
10080
10081     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10083
10084     /* local UserData product key exists */
10085     size = MAX_PATH;
10086     lstrcpyA(val, "apple");
10087     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10088                             MSIINSTALLCONTEXT_USERMANAGED,
10089                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10090     ok(r == ERROR_UNKNOWN_PRODUCT,
10091        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10092     ok(!lstrcmpA(val, "apple"),
10093        "Expected val to be unchanged, got \"%s\"\n", val);
10094     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10095
10096     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10097     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10098
10099     /* InstallProperties key exists */
10100     size = MAX_PATH;
10101     lstrcpyA(val, "apple");
10102     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10103                             MSIINSTALLCONTEXT_USERMANAGED,
10104                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10105     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10106     ok(!lstrcmpA(val, "apple"),
10107        "Expected val to be unchanged, got \"%s\"\n", val);
10108     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10109
10110     res = RegCreateKeyA(udprod, "Patches", &patches);
10111     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10112
10113     /* Patches key exists */
10114     size = MAX_PATH;
10115     lstrcpyA(val, "apple");
10116     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10117                             MSIINSTALLCONTEXT_USERMANAGED,
10118                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10119     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10120     ok(!lstrcmpA(val, "apple"),
10121        "Expected val to be unchanged, got \"%s\"\n", val);
10122     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10123
10124     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10125     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10126
10127     /* Patches key exists */
10128     size = MAX_PATH;
10129     lstrcpyA(val, "apple");
10130     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10131                             MSIINSTALLCONTEXT_USERMANAGED,
10132                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10133     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10134     ok(!lstrcmpA(val, "apple"),
10135        "Expected val to be unchanged, got \"%s\"\n", val);
10136     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10137
10138     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10139     lstrcatA(keypath, usersid);
10140     lstrcatA(keypath, "\\Installer\\Products\\");
10141     lstrcatA(keypath, prod_squashed);
10142
10143     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10144     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10145
10146     /* managed product key exists */
10147     size = MAX_PATH;
10148     lstrcpyA(val, "apple");
10149     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10150                             MSIINSTALLCONTEXT_USERMANAGED,
10151                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10152     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10153     ok(!lstrcmpA(val, "apple"),
10154        "Expected val to be unchanged, got \"%s\"\n", val);
10155     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10156
10157     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10159
10160     /* Patches key exists */
10161     size = MAX_PATH;
10162     lstrcpyA(val, "apple");
10163     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10164                             MSIINSTALLCONTEXT_USERMANAGED,
10165                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10166     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10167     ok(!lstrcmpA(val, "apple"),
10168        "Expected val to be unchanged, got \"%s\"\n", val);
10169     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10170
10171     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10172                          (const BYTE *)"transforms", 11);
10173     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10174
10175     /* specific patch value exists */
10176     size = MAX_PATH;
10177     lstrcpyA(val, "apple");
10178     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10179                             MSIINSTALLCONTEXT_USERMANAGED,
10180                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10181     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10182     ok(!lstrcmpA(val, "apple"),
10183        "Expected val to be unchanged, got \"%s\"\n", val);
10184     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10185
10186     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10187     lstrcatA(keypath, usersid);
10188     lstrcatA(keypath, "\\Patches\\");
10189     lstrcatA(keypath, patch_squashed);
10190
10191     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10192     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10193
10194     /* UserData Patches key exists */
10195     size = MAX_PATH;
10196     lstrcpyA(val, "apple");
10197     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10198                             MSIINSTALLCONTEXT_USERMANAGED,
10199                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10200     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10201     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10202     ok(size == 0, "Expected 0, got %d\n", size);
10203
10204     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10205                          (const BYTE *)"pack", 5);
10206     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10207
10208     /* ManagedLocalPatch value exists */
10209     size = MAX_PATH;
10210     lstrcpyA(val, "apple");
10211     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10212                             MSIINSTALLCONTEXT_USERMANAGED,
10213                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10214     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10215     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10216     ok(size == 4, "Expected 4, got %d\n", size);
10217
10218     size = MAX_PATH;
10219     lstrcpyA(val, "apple");
10220     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10221                             MSIINSTALLCONTEXT_USERMANAGED,
10222                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10223     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10224     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10225     ok(size == 10, "Expected 10, got %d\n", size);
10226
10227     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10228                          (const BYTE *)"mydate", 7);
10229     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10230
10231     /* Installed value exists */
10232     size = MAX_PATH;
10233     lstrcpyA(val, "apple");
10234     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10235                             MSIINSTALLCONTEXT_USERMANAGED,
10236                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10237     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10238     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10239     ok(size == 6, "Expected 6, got %d\n", size);
10240
10241     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10242                          (const BYTE *)"yes", 4);
10243     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10244
10245     /* Uninstallable value exists */
10246     size = MAX_PATH;
10247     lstrcpyA(val, "apple");
10248     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10249                             MSIINSTALLCONTEXT_USERMANAGED,
10250                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10252     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10253     ok(size == 3, "Expected 3, got %d\n", size);
10254
10255     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10256                          (const BYTE *)"good", 5);
10257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10258
10259     /* State value exists */
10260     size = MAX_PATH;
10261     lstrcpyA(val, "apple");
10262     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10263                             MSIINSTALLCONTEXT_USERMANAGED,
10264                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10265     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10266     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10267     ok(size == 4, "Expected 4, got %d\n", size);
10268
10269     size = 1;
10270     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10271                          (const BYTE *)&size, sizeof(DWORD));
10272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10273
10274     /* State value exists */
10275     size = MAX_PATH;
10276     lstrcpyA(val, "apple");
10277     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10278                             MSIINSTALLCONTEXT_USERMANAGED,
10279                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10280     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10281     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10282     ok(size == 1, "Expected 1, got %d\n", size);
10283
10284     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10285                          (const BYTE *)"display", 8);
10286     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10287
10288     /* DisplayName value exists */
10289     size = MAX_PATH;
10290     lstrcpyA(val, "apple");
10291     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10292                             MSIINSTALLCONTEXT_USERMANAGED,
10293                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10294     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10295     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10296     ok(size == 7, "Expected 7, got %d\n", size);
10297
10298     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10299                          (const BYTE *)"moreinfo", 9);
10300     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10301
10302     /* MoreInfoURL value exists */
10303     size = MAX_PATH;
10304     lstrcpyA(val, "apple");
10305     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10306                             MSIINSTALLCONTEXT_USERMANAGED,
10307                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10308     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10309     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10310     ok(size == 8, "Expected 8, got %d\n", size);
10311
10312     /* szProperty is invalid */
10313     size = MAX_PATH;
10314     lstrcpyA(val, "apple");
10315     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10316                             MSIINSTALLCONTEXT_USERMANAGED,
10317                             "IDontExist", val, &size);
10318     ok(r == ERROR_UNKNOWN_PROPERTY,
10319        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10320     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10321     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10322
10323     /* lpValue is NULL, while pcchValue is non-NULL */
10324     size = MAX_PATH;
10325     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10326                             MSIINSTALLCONTEXT_USERMANAGED,
10327                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10328     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10329     ok(size == 16, "Expected 16, got %d\n", size);
10330
10331     /* pcchValue is NULL, while lpValue is non-NULL */
10332     lstrcpyA(val, "apple");
10333     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10334                             MSIINSTALLCONTEXT_USERMANAGED,
10335                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10336     ok(r == ERROR_INVALID_PARAMETER,
10337        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10338     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10339
10340     /* both lpValue and pcchValue are NULL */
10341     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10342                             MSIINSTALLCONTEXT_USERMANAGED,
10343                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10344     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10345
10346     /* pcchValue doesn't have enough room for NULL terminator */
10347     size = 8;
10348     lstrcpyA(val, "apple");
10349     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10350                             MSIINSTALLCONTEXT_USERMANAGED,
10351                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10352     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10353     ok(!lstrcmpA(val, "moreinf"),
10354        "Expected \"moreinf\", got \"%s\"\n", val);
10355     ok(size == 16, "Expected 16, got %d\n", size);
10356
10357     /* pcchValue has exactly enough room for NULL terminator */
10358     size = 9;
10359     lstrcpyA(val, "apple");
10360     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10361                             MSIINSTALLCONTEXT_USERMANAGED,
10362                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10364     ok(!lstrcmpA(val, "moreinfo"),
10365        "Expected \"moreinfo\", got \"%s\"\n", val);
10366     ok(size == 8, "Expected 8, got %d\n", size);
10367
10368     /* pcchValue is too small, lpValue is NULL */
10369     size = 0;
10370     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10371                             MSIINSTALLCONTEXT_USERMANAGED,
10372                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10373     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10374     ok(size == 16, "Expected 16, got %d\n", size);
10375
10376     RegDeleteValueA(prodpatches, patch_squashed);
10377     RegDeleteKeyA(prodpatches, "");
10378     RegCloseKey(prodpatches);
10379     RegDeleteKeyA(prodkey, "");
10380     RegCloseKey(prodkey);
10381
10382     /* UserData is sufficient for all properties
10383      * except INSTALLPROPERTY_TRANSFORMS
10384      */
10385     size = MAX_PATH;
10386     lstrcpyA(val, "apple");
10387     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10388                             MSIINSTALLCONTEXT_USERMANAGED,
10389                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10390     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10391     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10392     ok(size == 4, "Expected 4, got %d\n", size);
10393
10394     /* UserData is sufficient for all properties
10395      * except INSTALLPROPERTY_TRANSFORMS
10396      */
10397     size = MAX_PATH;
10398     lstrcpyA(val, "apple");
10399     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10400                             MSIINSTALLCONTEXT_USERMANAGED,
10401                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10402     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10403     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10404     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10405
10406     RegDeleteValueA(hpatch, "MoreInfoURL");
10407     RegDeleteValueA(hpatch, "Display");
10408     RegDeleteValueA(hpatch, "State");
10409     RegDeleteValueA(hpatch, "Uninstallable");
10410     RegDeleteValueA(hpatch, "Installed");
10411     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10412     RegDeleteKeyA(udpatch, "");
10413     RegCloseKey(udpatch);
10414     RegDeleteKeyA(hpatch, "");
10415     RegCloseKey(hpatch);
10416     RegDeleteKeyA(patches, "");
10417     RegCloseKey(patches);
10418     RegDeleteKeyA(props, "");
10419     RegCloseKey(props);
10420     RegDeleteKeyA(udprod, "");
10421     RegCloseKey(udprod);
10422
10423     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10424
10425     size = MAX_PATH;
10426     lstrcpyA(val, "apple");
10427     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10428                             MSIINSTALLCONTEXT_USERUNMANAGED,
10429                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10430     ok(r == ERROR_UNKNOWN_PRODUCT,
10431        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10432     ok(!lstrcmpA(val, "apple"),
10433        "Expected val to be unchanged, got \"%s\"\n", val);
10434     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10435
10436     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10437     lstrcatA(keypath, usersid);
10438     lstrcatA(keypath, "\\Products\\");
10439     lstrcatA(keypath, prod_squashed);
10440
10441     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10442     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10443
10444     /* local UserData product key exists */
10445     size = MAX_PATH;
10446     lstrcpyA(val, "apple");
10447     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10448                             MSIINSTALLCONTEXT_USERUNMANAGED,
10449                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10450     ok(r == ERROR_UNKNOWN_PRODUCT,
10451        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10452     ok(!lstrcmpA(val, "apple"),
10453        "Expected val to be unchanged, got \"%s\"\n", val);
10454     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10455
10456     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10457     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10458
10459     /* InstallProperties key exists */
10460     size = MAX_PATH;
10461     lstrcpyA(val, "apple");
10462     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10463                             MSIINSTALLCONTEXT_USERUNMANAGED,
10464                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10465     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10466     ok(!lstrcmpA(val, "apple"),
10467        "Expected val to be unchanged, got \"%s\"\n", val);
10468     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10469
10470     res = RegCreateKeyA(udprod, "Patches", &patches);
10471     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10472
10473     /* Patches key exists */
10474     size = MAX_PATH;
10475     lstrcpyA(val, "apple");
10476     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10477                             MSIINSTALLCONTEXT_USERUNMANAGED,
10478                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10479     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10480     ok(!lstrcmpA(val, "apple"),
10481        "Expected val to be unchanged, got \"%s\"\n", val);
10482     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10483
10484     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10485     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10486
10487     /* Patches key exists */
10488     size = MAX_PATH;
10489     lstrcpyA(val, "apple");
10490     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10491                             MSIINSTALLCONTEXT_USERUNMANAGED,
10492                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10493     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10494     ok(!lstrcmpA(val, "apple"),
10495        "Expected val to be unchanged, got \"%s\"\n", val);
10496     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10497
10498     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10499     lstrcatA(keypath, prod_squashed);
10500
10501     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10502     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10503
10504     /* current user product key exists */
10505     size = MAX_PATH;
10506     lstrcpyA(val, "apple");
10507     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10508                             MSIINSTALLCONTEXT_USERUNMANAGED,
10509                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10510     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10511     ok(!lstrcmpA(val, "apple"),
10512        "Expected val to be unchanged, got \"%s\"\n", val);
10513     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10514
10515     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10516     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10517
10518     /* Patches key exists */
10519     size = MAX_PATH;
10520     lstrcpyA(val, "apple");
10521     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10522                             MSIINSTALLCONTEXT_USERUNMANAGED,
10523                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10524     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10525     ok(!lstrcmpA(val, "apple"),
10526        "Expected val to be unchanged, got \"%s\"\n", val);
10527     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10528
10529     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10530                          (const BYTE *)"transforms", 11);
10531     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10532
10533     /* specific patch value exists */
10534     size = MAX_PATH;
10535     lstrcpyA(val, "apple");
10536     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10537                             MSIINSTALLCONTEXT_USERUNMANAGED,
10538                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10539     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10540     ok(!lstrcmpA(val, "apple"),
10541        "Expected val to be unchanged, got \"%s\"\n", val);
10542     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10543
10544     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10545     lstrcatA(keypath, usersid);
10546     lstrcatA(keypath, "\\Patches\\");
10547     lstrcatA(keypath, patch_squashed);
10548
10549     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10551
10552     /* UserData Patches key exists */
10553     size = MAX_PATH;
10554     lstrcpyA(val, "apple");
10555     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10556                             MSIINSTALLCONTEXT_USERUNMANAGED,
10557                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10558     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10559     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10560     ok(size == 0, "Expected 0, got %d\n", size);
10561
10562     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10563                          (const BYTE *)"pack", 5);
10564     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10565
10566     /* LocalPatch value exists */
10567     size = MAX_PATH;
10568     lstrcpyA(val, "apple");
10569     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10570                             MSIINSTALLCONTEXT_USERUNMANAGED,
10571                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10572     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10573     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10574     ok(size == 4, "Expected 4, got %d\n", size);
10575
10576     size = MAX_PATH;
10577     lstrcpyA(val, "apple");
10578     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10579                             MSIINSTALLCONTEXT_USERUNMANAGED,
10580                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10581     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10582     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10583     ok(size == 10, "Expected 10, got %d\n", size);
10584
10585     RegDeleteValueA(prodpatches, patch_squashed);
10586     RegDeleteKeyA(prodpatches, "");
10587     RegCloseKey(prodpatches);
10588     RegDeleteKeyA(prodkey, "");
10589     RegCloseKey(prodkey);
10590
10591     /* UserData is sufficient for all properties
10592      * except INSTALLPROPERTY_TRANSFORMS
10593      */
10594     size = MAX_PATH;
10595     lstrcpyA(val, "apple");
10596     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10597                             MSIINSTALLCONTEXT_USERUNMANAGED,
10598                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10599     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10600     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10601     ok(size == 4, "Expected 4, got %d\n", size);
10602
10603     /* UserData is sufficient for all properties
10604      * except INSTALLPROPERTY_TRANSFORMS
10605      */
10606     size = MAX_PATH;
10607     lstrcpyA(val, "apple");
10608     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10609                             MSIINSTALLCONTEXT_USERUNMANAGED,
10610                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10611     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10612     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10613     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10614
10615     RegDeleteValueA(udpatch, "LocalPackage");
10616     RegDeleteKeyA(udpatch, "");
10617     RegCloseKey(udpatch);
10618     RegDeleteKeyA(hpatch, "");
10619     RegCloseKey(hpatch);
10620     RegDeleteKeyA(patches, "");
10621     RegCloseKey(patches);
10622     RegDeleteKeyA(props, "");
10623     RegCloseKey(props);
10624     RegDeleteKeyA(udprod, "");
10625     RegCloseKey(udprod);
10626
10627     /* MSIINSTALLCONTEXT_MACHINE */
10628
10629     size = MAX_PATH;
10630     lstrcpyA(val, "apple");
10631     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10632                             MSIINSTALLCONTEXT_MACHINE,
10633                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10634     ok(r == ERROR_UNKNOWN_PRODUCT,
10635        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10636     ok(!lstrcmpA(val, "apple"),
10637        "Expected val to be unchanged, got \"%s\"\n", val);
10638     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10639
10640     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10641     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10642     lstrcatA(keypath, prod_squashed);
10643
10644     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10645     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10646
10647     /* local UserData product key exists */
10648     size = MAX_PATH;
10649     lstrcpyA(val, "apple");
10650     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10651                             MSIINSTALLCONTEXT_MACHINE,
10652                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10653     ok(r == ERROR_UNKNOWN_PRODUCT,
10654        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10655     ok(!lstrcmpA(val, "apple"),
10656        "Expected val to be unchanged, got \"%s\"\n", val);
10657     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10658
10659     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10660     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10661
10662     /* InstallProperties key exists */
10663     size = MAX_PATH;
10664     lstrcpyA(val, "apple");
10665     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10666                             MSIINSTALLCONTEXT_MACHINE,
10667                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10668     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10669     ok(!lstrcmpA(val, "apple"),
10670        "Expected val to be unchanged, got \"%s\"\n", val);
10671     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10672
10673     res = RegCreateKeyA(udprod, "Patches", &patches);
10674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10675
10676     /* Patches key exists */
10677     size = MAX_PATH;
10678     lstrcpyA(val, "apple");
10679     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10680                             MSIINSTALLCONTEXT_MACHINE,
10681                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10682     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10683     ok(!lstrcmpA(val, "apple"),
10684        "Expected val to be unchanged, got \"%s\"\n", val);
10685     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10686
10687     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10688     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10689
10690     /* Patches key exists */
10691     size = MAX_PATH;
10692     lstrcpyA(val, "apple");
10693     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10694                             MSIINSTALLCONTEXT_MACHINE,
10695                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10696     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10697     ok(!lstrcmpA(val, "apple"),
10698        "Expected val to be unchanged, got \"%s\"\n", val);
10699     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10700
10701     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10702     lstrcatA(keypath, prod_squashed);
10703
10704     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10705     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10706
10707     /* local product key exists */
10708     size = MAX_PATH;
10709     lstrcpyA(val, "apple");
10710     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10711                             MSIINSTALLCONTEXT_MACHINE,
10712                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10713     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10714     ok(!lstrcmpA(val, "apple"),
10715        "Expected val to be unchanged, got \"%s\"\n", val);
10716     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10717
10718     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10720
10721     /* Patches key exists */
10722     size = MAX_PATH;
10723     lstrcpyA(val, "apple");
10724     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10725                             MSIINSTALLCONTEXT_MACHINE,
10726                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10727     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10728     ok(!lstrcmpA(val, "apple"),
10729        "Expected val to be unchanged, got \"%s\"\n", val);
10730     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10731
10732     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10733                          (const BYTE *)"transforms", 11);
10734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10735
10736     /* specific patch value exists */
10737     size = MAX_PATH;
10738     lstrcpyA(val, "apple");
10739     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10740                             MSIINSTALLCONTEXT_MACHINE,
10741                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10742     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10743     ok(!lstrcmpA(val, "apple"),
10744        "Expected val to be unchanged, got \"%s\"\n", val);
10745     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10746
10747     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10748     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
10749     lstrcatA(keypath, patch_squashed);
10750
10751     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10752     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10753
10754     /* UserData Patches key exists */
10755     size = MAX_PATH;
10756     lstrcpyA(val, "apple");
10757     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10758                             MSIINSTALLCONTEXT_MACHINE,
10759                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10760     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10761     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10762     ok(size == 0, "Expected 0, got %d\n", size);
10763
10764     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10765                          (const BYTE *)"pack", 5);
10766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10767
10768     /* LocalPatch value exists */
10769     size = MAX_PATH;
10770     lstrcpyA(val, "apple");
10771     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10772                             MSIINSTALLCONTEXT_MACHINE,
10773                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10774     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10775     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10776     ok(size == 4, "Expected 4, got %d\n", size);
10777
10778     size = MAX_PATH;
10779     lstrcpyA(val, "apple");
10780     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10781                             MSIINSTALLCONTEXT_MACHINE,
10782                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10783     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10784     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10785     ok(size == 10, "Expected 10, got %d\n", size);
10786
10787     RegDeleteValueA(prodpatches, patch_squashed);
10788     RegDeleteKeyA(prodpatches, "");
10789     RegCloseKey(prodpatches);
10790     RegDeleteKeyA(prodkey, "");
10791     RegCloseKey(prodkey);
10792
10793     /* UserData is sufficient for all properties
10794      * except INSTALLPROPERTY_TRANSFORMS
10795      */
10796     size = MAX_PATH;
10797     lstrcpyA(val, "apple");
10798     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10799                             MSIINSTALLCONTEXT_MACHINE,
10800                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10801     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10802     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10803     ok(size == 4, "Expected 4, got %d\n", size);
10804
10805     /* UserData is sufficient for all properties
10806      * except INSTALLPROPERTY_TRANSFORMS
10807      */
10808     size = MAX_PATH;
10809     lstrcpyA(val, "apple");
10810     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10811                             MSIINSTALLCONTEXT_MACHINE,
10812                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10813     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10814     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10815     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10816
10817     RegDeleteValueA(udpatch, "LocalPackage");
10818     RegDeleteKeyA(udpatch, "");
10819     RegCloseKey(udpatch);
10820     RegDeleteKeyA(hpatch, "");
10821     RegCloseKey(hpatch);
10822     RegDeleteKeyA(patches, "");
10823     RegCloseKey(patches);
10824     RegDeleteKeyA(props, "");
10825     RegCloseKey(props);
10826     RegDeleteKeyA(udprod, "");
10827     RegCloseKey(udprod);
10828 }
10829
10830 START_TEST(msi)
10831 {
10832     init_functionpointers();
10833
10834     test_usefeature();
10835     test_null();
10836     test_getcomponentpath();
10837     test_MsiGetFileHash();
10838
10839     if (!pConvertSidToStringSidA)
10840         skip("ConvertSidToStringSidA not implemented\n");
10841     else
10842     {
10843         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
10844         test_MsiQueryProductState();
10845         test_MsiQueryFeatureState();
10846         test_MsiQueryComponentState();
10847         test_MsiGetComponentPath();
10848         test_MsiGetProductCode();
10849         test_MsiEnumClients();
10850         test_MsiGetProductInfo();
10851         test_MsiGetProductInfoEx();
10852         test_MsiGetUserInfo();
10853         test_MsiOpenProduct();
10854         test_MsiEnumPatchesEx();
10855         test_MsiEnumPatches();
10856         test_MsiGetPatchInfoEx();
10857     }
10858
10859     test_MsiGetFileVersion();
10860 }