msi: Destroy streams cache when applying a transform.
[wine] / dlls / msi / tests / msi.c
1 /*
2  * tests for Microsoft Installer functionality
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_MSI 300
22
23 #include <stdio.h>
24 #include <windows.h>
25 #include <msi.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <sddl.h>
29
30 #include "wine/test.h"
31
32 static const char msifile[] = "winetest.msi";
33
34 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
35
36 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
37     (LPCSTR, LPCSTR, LPSTR, DWORD*);
38 static UINT (WINAPI *pMsiGetFileHashA)
39     (LPCSTR, DWORD, PMSIFILEHASHINFO);
40 static UINT (WINAPI *pMsiGetProductInfoExA)
41     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
42 static UINT (WINAPI *pMsiOpenPackageExA)
43     (LPCSTR, DWORD, MSIHANDLE*);
44 static UINT (WINAPI *pMsiOpenPackageExW)
45     (LPCWSTR, DWORD, MSIHANDLE*);
46 static UINT (WINAPI *pMsiEnumPatchesExA)
47     (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
48     MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
49 static UINT (WINAPI *pMsiQueryComponentStateA)
50     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
51 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
52     (LPCSTR, LPCSTR ,DWORD, DWORD);
53 static UINT (WINAPI *pMsiGetPatchInfoExA)
54     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
55
56 static void init_functionpointers(void)
57 {
58     HMODULE hmsi = GetModuleHandleA("msi.dll");
59     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
60
61 #define GET_PROC(dll, func) \
62     p ## func = (void *)GetProcAddress(dll, #func); \
63     if(!p ## func) \
64       trace("GetProcAddress(%s) failed\n", #func);
65
66     GET_PROC(hmsi, MsiGetComponentPathA)
67     GET_PROC(hmsi, MsiGetFileHashA)
68     GET_PROC(hmsi, MsiGetProductInfoExA)
69     GET_PROC(hmsi, MsiOpenPackageExA)
70     GET_PROC(hmsi, MsiOpenPackageExW)
71     GET_PROC(hmsi, MsiEnumPatchesExA)
72     GET_PROC(hmsi, MsiQueryComponentStateA)
73     GET_PROC(hmsi, MsiUseFeatureExA)
74     GET_PROC(hmsi, MsiGetPatchInfoExA)
75
76     GET_PROC(hadvapi32, ConvertSidToStringSidA)
77
78 #undef GET_PROC
79 }
80
81 static UINT run_query(MSIHANDLE hdb, const char *query)
82 {
83     MSIHANDLE hview = 0;
84     UINT r;
85
86     r = MsiDatabaseOpenView(hdb, query, &hview);
87     if (r != ERROR_SUCCESS)
88         return r;
89
90     r = MsiViewExecute(hview, 0);
91     if (r == ERROR_SUCCESS)
92         r = MsiViewClose(hview);
93     MsiCloseHandle(hview);
94     return r;
95 }
96
97 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
98 {
99     UINT res;
100     MSIHANDLE suminfo;
101
102     /* build summary info */
103     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
104     ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
105
106     res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
107                                     "Installation Database");
108     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
109
110     res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
111                                     "Installation Database");
112     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
113
114     res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
115                                     "Wine Hackers");
116     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
117
118     res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
119                                     ";1033");
120     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
121
122     res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
123                                     "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
124     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
125
126     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
127     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
128
129     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
130     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
131
132     res = MsiSummaryInfoPersist(suminfo);
133     ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
134
135     res = MsiCloseHandle(suminfo);
136     ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
137
138     return res;
139 }
140
141 static MSIHANDLE create_package_db(LPSTR prodcode)
142 {
143     MSIHANDLE hdb = 0;
144     CHAR query[MAX_PATH];
145     UINT res;
146
147     DeleteFile(msifile);
148
149     /* create an empty database */
150     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
151     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
152     if (res != ERROR_SUCCESS)
153         return hdb;
154
155     res = MsiDatabaseCommit(hdb);
156     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
157
158     set_summary_info(hdb, prodcode);
159
160     res = run_query(hdb,
161             "CREATE TABLE `Directory` ( "
162             "`Directory` CHAR(255) NOT NULL, "
163             "`Directory_Parent` CHAR(255), "
164             "`DefaultDir` CHAR(255) NOT NULL "
165             "PRIMARY KEY `Directory`)");
166     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
167
168     res = run_query(hdb,
169             "CREATE TABLE `Property` ( "
170             "`Property` CHAR(72) NOT NULL, "
171             "`Value` CHAR(255) "
172             "PRIMARY KEY `Property`)");
173     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
174
175     sprintf(query, "INSERT INTO `Property` "
176             "(`Property`, `Value`) "
177             "VALUES( 'ProductCode', '%s' )", prodcode);
178     res = run_query(hdb, query);
179     ok(res == ERROR_SUCCESS , "Failed\n");
180
181     res = MsiDatabaseCommit(hdb);
182     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
183
184     return hdb;
185 }
186
187 static void test_usefeature(void)
188 {
189     INSTALLSTATE r;
190
191     if (!pMsiUseFeatureExA)
192     {
193         win_skip("MsiUseFeatureExA not implemented\n");
194         return;
195     }
196
197     r = MsiQueryFeatureState(NULL,NULL);
198     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
199
200     r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
201     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
202
203     r = pMsiUseFeatureExA(NULL,NULL,0,0);
204     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
205
206     r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
207     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
208
209     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
210                          NULL, -2, 0 );
211     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
212
213     r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}", 
214                          "WORDVIEWFiles", -2, 0 );
215     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
216
217     r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}", 
218                          "WORDVIEWFiles", -2, 0 );
219     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
220
221     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
222                          "WORDVIEWFiles", -2, 1 );
223     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
224 }
225
226 static void test_null(void)
227 {
228     MSIHANDLE hpkg;
229     UINT r;
230     HKEY hkey;
231     DWORD dwType, cbData;
232     LPBYTE lpData = NULL;
233     INSTALLSTATE state;
234
235     r = pMsiOpenPackageExW(NULL, 0, &hpkg);
236     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
237
238     state = MsiQueryProductStateW(NULL);
239     ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
240
241     r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
242     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
243
244     r = MsiConfigureFeatureW(NULL, NULL, 0);
245     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
246
247     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
248     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
249
250     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", 0);
251     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
252
253     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", INSTALLSTATE_DEFAULT);
254     ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
255
256     /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
257      * necessary registry values */
258
259     /* empty product string */
260     r = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", &hkey);
261     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
262
263     r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
264     ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
265     if ( r == ERROR_SUCCESS )
266     {
267         lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
268         if (!lpData)
269             skip("Out of memory\n");
270         else
271         {
272             r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
273             ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
274         }
275     }
276
277     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
278     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
279
280     r = MsiGetProductInfoA("", "", NULL, NULL);
281     ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
282
283     if (lpData)
284     {
285         r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
286         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
287
288         HeapFree(GetProcessHeap(), 0, lpData);
289     }
290     else
291     {
292         r = RegDeleteValueA(hkey, NULL);
293         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
294     }
295
296     r = RegCloseKey(hkey);
297     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
298
299     /* empty attribute */
300     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", &hkey);
301     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
302
303     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
304     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
305
306     r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
307     ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
308
309     r = RegCloseKey(hkey);
310     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
311
312     r = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}");
313     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
314 }
315
316 static void test_getcomponentpath(void)
317 {
318     INSTALLSTATE r;
319     char buffer[0x100];
320     DWORD sz;
321
322     if(!pMsiGetComponentPathA)
323         return;
324
325     r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
326     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
327
328     r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
329     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
330
331     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
332     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
333
334     sz = sizeof buffer;
335     buffer[0]=0;
336     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
337     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
338
339     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
340         "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
341     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
342
343     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
344         "{00000000-0000-0000-0000-00000000}", buffer, &sz );
345     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
346
347     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
348         "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
349     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
350
351     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
352                             "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
353     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
354 }
355
356 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
357 {
358     HANDLE file;
359     DWORD written;
360
361     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
362     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
363     WriteFile(file, data, strlen(data), &written, NULL);
364
365     if (size)
366     {
367         SetFilePointer(file, size, NULL, FILE_BEGIN);
368         SetEndOfFile(file);
369     }
370
371     CloseHandle(file);
372 }
373
374 #define HASHSIZE sizeof(MSIFILEHASHINFO)
375
376 static const struct
377 {
378     LPCSTR data;
379     DWORD size;
380     MSIFILEHASHINFO hash;
381 } hash_data[] =
382 {
383     { "abc", 0,
384       { HASHSIZE,
385         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
386       },
387     },
388
389     { "C:\\Program Files\\msitest\\caesar\n", 0,
390       { HASHSIZE,
391         { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
392       },
393     },
394
395     { "C:\\Program Files\\msitest\\caesar\n", 500,
396       { HASHSIZE,
397         { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
398       },
399     },
400 };
401
402 static void test_MsiGetFileHash(void)
403 {
404     const char name[] = "msitest.bin";
405     UINT r;
406     MSIFILEHASHINFO hash;
407     DWORD i;
408
409     if (!pMsiGetFileHashA)
410     {
411         win_skip("MsiGetFileHash not implemented\n");
412         return;
413     }
414
415     hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
416
417     /* szFilePath is NULL */
418     r = pMsiGetFileHashA(NULL, 0, &hash);
419     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
420
421     /* szFilePath is empty */
422     r = pMsiGetFileHashA("", 0, &hash);
423     ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
424        "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
425
426     /* szFilePath is nonexistent */
427     r = pMsiGetFileHashA(name, 0, &hash);
428     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
429
430     /* dwOptions is non-zero */
431     r = pMsiGetFileHashA(name, 1, &hash);
432     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
433
434     /* pHash.dwFileHashInfoSize is not correct */
435     hash.dwFileHashInfoSize = 0;
436     r = pMsiGetFileHashA(name, 0, &hash);
437     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
438
439     /* pHash is NULL */
440     r = pMsiGetFileHashA(name, 0, NULL);
441     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
442
443     for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
444     {
445         int ret;
446
447         create_file(name, hash_data[i].data, hash_data[i].size);
448
449         memset(&hash, 0, sizeof(MSIFILEHASHINFO));
450         hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
451
452         r = pMsiGetFileHashA(name, 0, &hash);
453         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
454
455         ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
456         ok(ret == 0 ||
457            broken(ret != 0), /* win95 */
458            "Hash incorrect\n");
459
460         DeleteFile(name);
461     }
462 }
463
464 /* copied from dlls/msi/registry.c */
465 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
466 {
467     DWORD i,n=1;
468     GUID guid;
469
470     if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
471         return FALSE;
472
473     for(i=0; i<8; i++)
474         out[7-i] = in[n++];
475     n++;
476     for(i=0; i<4; i++)
477         out[11-i] = in[n++];
478     n++;
479     for(i=0; i<4; i++)
480         out[15-i] = in[n++];
481     n++;
482     for(i=0; i<2; i++)
483     {
484         out[17+i*2] = in[n++];
485         out[16+i*2] = in[n++];
486     }
487     n++;
488     for( ; i<8; i++)
489     {
490         out[17+i*2] = in[n++];
491         out[16+i*2] = in[n++];
492     }
493     out[32]=0;
494     return TRUE;
495 }
496
497 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
498 {
499     WCHAR guidW[MAX_PATH];
500     WCHAR squashedW[MAX_PATH];
501     GUID guid;
502     HRESULT hr;
503     int size;
504
505     hr = CoCreateGuid(&guid);
506     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
507
508     size = StringFromGUID2(&guid, guidW, MAX_PATH);
509     ok(size == 39, "Expected 39, got %d\n", hr);
510
511     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
512     squash_guid(guidW, squashedW);
513     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
514 }
515
516 static void get_user_sid(LPSTR *usersid)
517 {
518     HANDLE token;
519     DWORD size;
520     PTOKEN_USER user;
521
522     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
523
524     size = 0;
525     GetTokenInformation(token, TokenUser, NULL, size, &size);
526     user = HeapAlloc(GetProcessHeap(), 0, size);
527
528     GetTokenInformation(token, TokenUser, user, size, &size);
529     pConvertSidToStringSidA(user->User.Sid, usersid);
530
531     HeapFree(GetProcessHeap(), 0, user);
532     CloseHandle(token);
533 }
534
535 static void test_MsiQueryProductState(void)
536 {
537     CHAR prodcode[MAX_PATH];
538     CHAR prod_squashed[MAX_PATH];
539     CHAR keypath[MAX_PATH*2];
540     LPSTR usersid;
541     INSTALLSTATE state;
542     LONG res;
543     HKEY userkey, localkey, props;
544     HKEY prodkey;
545     DWORD data;
546
547     create_test_guid(prodcode, prod_squashed);
548     get_user_sid(&usersid);
549
550     /* NULL prodcode */
551     state = MsiQueryProductStateA(NULL);
552     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
553
554     /* empty prodcode */
555     state = MsiQueryProductStateA("");
556     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
557
558     /* garbage prodcode */
559     state = MsiQueryProductStateA("garbage");
560     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
561
562     /* guid without brackets */
563     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
564     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
565
566     /* guid with brackets */
567     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
568     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
569
570     /* same length as guid, but random */
571     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
572     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
573
574     /* MSIINSTALLCONTEXT_USERUNMANAGED */
575
576     state = MsiQueryProductStateA(prodcode);
577     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
578
579     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
580     lstrcatA(keypath, prod_squashed);
581
582     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
583     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
584
585     /* user product key exists */
586     state = MsiQueryProductStateA(prodcode);
587     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
588
589     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
590     lstrcatA(keypath, prodcode);
591
592     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
594
595     /* local uninstall key exists */
596     state = MsiQueryProductStateA(prodcode);
597     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
598
599     data = 1;
600     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
602
603     /* WindowsInstaller value exists */
604     state = MsiQueryProductStateA(prodcode);
605     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
606
607     RegDeleteValueA(localkey, "WindowsInstaller");
608     RegDeleteKeyA(localkey, "");
609
610     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
611     lstrcatA(keypath, usersid);
612     lstrcatA(keypath, "\\Products\\");
613     lstrcatA(keypath, prod_squashed);
614
615     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
616     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
617
618     /* local product key exists */
619     state = MsiQueryProductStateA(prodcode);
620     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
621
622     res = RegCreateKeyA(localkey, "InstallProperties", &props);
623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
624
625     /* install properties key exists */
626     state = MsiQueryProductStateA(prodcode);
627     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
628
629     data = 1;
630     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
631     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
632
633     /* WindowsInstaller value exists */
634     state = MsiQueryProductStateA(prodcode);
635     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
636
637     data = 2;
638     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
639     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
640
641     /* WindowsInstaller value is not 1 */
642     state = MsiQueryProductStateA(prodcode);
643     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
644
645     RegDeleteKeyA(userkey, "");
646
647     /* user product key does not exist */
648     state = MsiQueryProductStateA(prodcode);
649     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
650
651     RegDeleteValueA(props, "WindowsInstaller");
652     RegDeleteKeyA(props, "");
653     RegCloseKey(props);
654     RegDeleteKeyA(localkey, "");
655     RegCloseKey(localkey);
656     RegDeleteKeyA(userkey, "");
657     RegCloseKey(userkey);
658
659     /* MSIINSTALLCONTEXT_USERMANAGED */
660
661     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
662     lstrcatA(keypath, usersid);
663     lstrcatA(keypath, "\\Installer\\Products\\");
664     lstrcatA(keypath, prod_squashed);
665
666     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
668
669     state = MsiQueryProductStateA(prodcode);
670     ok(state == INSTALLSTATE_ADVERTISED,
671        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
672
673     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
674     lstrcatA(keypath, usersid);
675     lstrcatA(keypath, "\\Products\\");
676     lstrcatA(keypath, prod_squashed);
677
678     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
680
681     state = MsiQueryProductStateA(prodcode);
682     ok(state == INSTALLSTATE_ADVERTISED,
683        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
684
685     res = RegCreateKeyA(localkey, "InstallProperties", &props);
686     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
687
688     state = MsiQueryProductStateA(prodcode);
689     ok(state == INSTALLSTATE_ADVERTISED,
690        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
691
692     data = 1;
693     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
694     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
695
696     /* WindowsInstaller value exists */
697     state = MsiQueryProductStateA(prodcode);
698     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
699
700     RegDeleteValueA(props, "WindowsInstaller");
701     RegDeleteKeyA(props, "");
702     RegCloseKey(props);
703     RegDeleteKeyA(localkey, "");
704     RegCloseKey(localkey);
705     RegDeleteKeyA(prodkey, "");
706     RegCloseKey(prodkey);
707
708     /* MSIINSTALLCONTEXT_MACHINE */
709
710     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
711     lstrcatA(keypath, prod_squashed);
712
713     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
714     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
715
716     state = MsiQueryProductStateA(prodcode);
717     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
718
719     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
720     lstrcatA(keypath, "S-1-5-18\\Products\\");
721     lstrcatA(keypath, prod_squashed);
722
723     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
724     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
725
726     state = MsiQueryProductStateA(prodcode);
727     ok(state == INSTALLSTATE_ADVERTISED,
728        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
729
730     res = RegCreateKeyA(localkey, "InstallProperties", &props);
731     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
732
733     state = MsiQueryProductStateA(prodcode);
734     ok(state == INSTALLSTATE_ADVERTISED,
735        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
736
737     data = 1;
738     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
739     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
740
741     /* WindowsInstaller value exists */
742     state = MsiQueryProductStateA(prodcode);
743     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
744
745     RegDeleteValueA(props, "WindowsInstaller");
746     RegDeleteKeyA(props, "");
747     RegCloseKey(props);
748     RegDeleteKeyA(localkey, "");
749     RegCloseKey(localkey);
750     RegDeleteKeyA(prodkey, "");
751     RegCloseKey(prodkey);
752
753     LocalFree(usersid);
754 }
755
756 static const char table_enc85[] =
757 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
758 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
759 "yz{}~";
760
761 /*
762  *  Encodes a base85 guid given a GUID pointer
763  *  Caller should provide a 21 character buffer for the encoded string.
764  */
765 static void encode_base85_guid( GUID *guid, LPWSTR str )
766 {
767     unsigned int x, *p, i;
768
769     p = (unsigned int*) guid;
770     for( i=0; i<4; i++ )
771     {
772         x = p[i];
773         *str++ = table_enc85[x%85];
774         x = x/85;
775         *str++ = table_enc85[x%85];
776         x = x/85;
777         *str++ = table_enc85[x%85];
778         x = x/85;
779         *str++ = table_enc85[x%85];
780         x = x/85;
781         *str++ = table_enc85[x%85];
782     }
783     *str = 0;
784 }
785
786 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
787 {
788     WCHAR guidW[MAX_PATH];
789     WCHAR base85W[MAX_PATH];
790     WCHAR squashedW[MAX_PATH];
791     GUID guid;
792     HRESULT hr;
793     int size;
794
795     hr = CoCreateGuid(&guid);
796     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
797
798     size = StringFromGUID2(&guid, guidW, MAX_PATH);
799     ok(size == 39, "Expected 39, got %d\n", hr);
800
801     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
802     encode_base85_guid(&guid, base85W);
803     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
804     squash_guid(guidW, squashedW);
805     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
806 }
807
808 static void test_MsiQueryFeatureState(void)
809 {
810     HKEY userkey, localkey, compkey, compkey2;
811     CHAR prodcode[MAX_PATH];
812     CHAR prod_squashed[MAX_PATH];
813     CHAR component[MAX_PATH];
814     CHAR comp_base85[MAX_PATH];
815     CHAR comp_squashed[MAX_PATH], comp_squashed2[MAX_PATH];
816     CHAR keypath[MAX_PATH*2];
817     INSTALLSTATE state;
818     LPSTR usersid;
819     LONG res;
820
821     create_test_guid(prodcode, prod_squashed);
822     compose_base85_guid(component, comp_base85, comp_squashed);
823     compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
824     get_user_sid(&usersid);
825
826     /* NULL prodcode */
827     state = MsiQueryFeatureStateA(NULL, "feature");
828     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
829
830     /* empty prodcode */
831     state = MsiQueryFeatureStateA("", "feature");
832     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
833
834     /* garbage prodcode */
835     state = MsiQueryFeatureStateA("garbage", "feature");
836     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
837
838     /* guid without brackets */
839     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
840     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
841
842     /* guid with brackets */
843     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
844     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
845
846     /* same length as guid, but random */
847     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
848     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
849
850     /* NULL szFeature */
851     state = MsiQueryFeatureStateA(prodcode, NULL);
852     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
853
854     /* empty szFeature */
855     state = MsiQueryFeatureStateA(prodcode, "");
856     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
857
858     /* feature key does not exist yet */
859     state = MsiQueryFeatureStateA(prodcode, "feature");
860     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
861
862     /* MSIINSTALLCONTEXT_USERUNMANAGED */
863
864     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
865     lstrcatA(keypath, prod_squashed);
866
867     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
868     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
869
870     /* feature key exists */
871     state = MsiQueryFeatureStateA(prodcode, "feature");
872     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
873
874     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
875     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
876
877     /* feature value exists */
878     state = MsiQueryFeatureStateA(prodcode, "feature");
879     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
880
881     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
882     lstrcatA(keypath, usersid);
883     lstrcatA(keypath, "\\Products\\");
884     lstrcatA(keypath, prod_squashed);
885     lstrcatA(keypath, "\\Features");
886
887     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
889
890     /* userdata features key exists */
891     state = MsiQueryFeatureStateA(prodcode, "feature");
892     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
893
894     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
895     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
896
897     state = MsiQueryFeatureStateA(prodcode, "feature");
898     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
899
900     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
901     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
902
903     state = MsiQueryFeatureStateA(prodcode, "feature");
904     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
905
906     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
907     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
908
909     state = MsiQueryFeatureStateA(prodcode, "feature");
910     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
911
912     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
913     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
914
915     state = MsiQueryFeatureStateA(prodcode, "feature");
916     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
917
918     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
919     lstrcatA(keypath, usersid);
920     lstrcatA(keypath, "\\Components\\");
921     lstrcatA(keypath, comp_squashed);
922
923     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
924     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
925
926     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
927     lstrcatA(keypath, usersid);
928     lstrcatA(keypath, "\\Components\\");
929     lstrcatA(keypath, comp_squashed2);
930
931     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2);
932     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
933
934     state = MsiQueryFeatureStateA(prodcode, "feature");
935     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
936
937     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
938     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
939
940     state = MsiQueryFeatureStateA(prodcode, "feature");
941     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
942
943     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
945
946     state = MsiQueryFeatureStateA(prodcode, "feature");
947     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
948
949     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
951
952     /* INSTALLSTATE_LOCAL */
953     state = MsiQueryFeatureStateA(prodcode, "feature");
954     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
955
956     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
958
959     /* INSTALLSTATE_SOURCE */
960     state = MsiQueryFeatureStateA(prodcode, "feature");
961     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
962
963     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
965
966     /* bad INSTALLSTATE_SOURCE */
967     state = MsiQueryFeatureStateA(prodcode, "feature");
968     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
969
970     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
972
973     /* INSTALLSTATE_SOURCE */
974     state = MsiQueryFeatureStateA(prodcode, "feature");
975     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
976
977     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
978     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
979
980     /* bad INSTALLSTATE_SOURCE */
981     state = MsiQueryFeatureStateA(prodcode, "feature");
982     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
983
984     RegDeleteValueA(compkey, prod_squashed);
985     RegDeleteValueA(compkey2, prod_squashed);
986     RegDeleteKeyA(compkey, "");
987     RegDeleteKeyA(compkey2, "");
988     RegDeleteValueA(localkey, "feature");
989     RegDeleteValueA(userkey, "feature");
990     RegDeleteKeyA(userkey, "");
991     RegCloseKey(compkey);
992     RegCloseKey(compkey2);
993     RegCloseKey(localkey);
994     RegCloseKey(userkey);
995
996     /* MSIINSTALLCONTEXT_USERMANAGED */
997
998     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
999     lstrcatA(keypath, usersid);
1000     lstrcatA(keypath, "\\Installer\\Features\\");
1001     lstrcatA(keypath, prod_squashed);
1002
1003     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
1004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1005
1006     /* feature key exists */
1007     state = MsiQueryFeatureStateA(prodcode, "feature");
1008     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1009
1010     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1012
1013     /* feature value exists */
1014     state = MsiQueryFeatureStateA(prodcode, "feature");
1015     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1016
1017     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1018     lstrcatA(keypath, usersid);
1019     lstrcatA(keypath, "\\Products\\");
1020     lstrcatA(keypath, prod_squashed);
1021     lstrcatA(keypath, "\\Features");
1022
1023     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1024     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1025
1026     /* userdata features key exists */
1027     state = MsiQueryFeatureStateA(prodcode, "feature");
1028     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1029
1030     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1032
1033     state = MsiQueryFeatureStateA(prodcode, "feature");
1034     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1035
1036     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1037     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1038
1039     state = MsiQueryFeatureStateA(prodcode, "feature");
1040     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1041
1042     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1044
1045     state = MsiQueryFeatureStateA(prodcode, "feature");
1046     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1047
1048     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1049     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1050
1051     state = MsiQueryFeatureStateA(prodcode, "feature");
1052     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1053
1054     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1055     lstrcatA(keypath, usersid);
1056     lstrcatA(keypath, "\\Components\\");
1057     lstrcatA(keypath, comp_squashed);
1058
1059     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1061
1062     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1063     lstrcatA(keypath, usersid);
1064     lstrcatA(keypath, "\\Components\\");
1065     lstrcatA(keypath, comp_squashed2);
1066
1067     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2);
1068     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1069
1070     state = MsiQueryFeatureStateA(prodcode, "feature");
1071     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1072
1073     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1074     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1075
1076     state = MsiQueryFeatureStateA(prodcode, "feature");
1077     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1078
1079     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1081
1082     state = MsiQueryFeatureStateA(prodcode, "feature");
1083     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1084
1085     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1087
1088     state = MsiQueryFeatureStateA(prodcode, "feature");
1089     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1090
1091     RegDeleteValueA(compkey, prod_squashed);
1092     RegDeleteValueA(compkey2, prod_squashed);
1093     RegDeleteKeyA(compkey, "");
1094     RegDeleteKeyA(compkey2, "");
1095     RegDeleteValueA(localkey, "feature");
1096     RegDeleteValueA(userkey, "feature");
1097     RegDeleteKeyA(userkey, "");
1098     RegCloseKey(compkey);
1099     RegCloseKey(compkey2);
1100     RegCloseKey(localkey);
1101     RegCloseKey(userkey);
1102
1103     /* MSIINSTALLCONTEXT_MACHINE */
1104
1105     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1106     lstrcatA(keypath, prod_squashed);
1107
1108     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
1109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1110
1111     /* feature key exists */
1112     state = MsiQueryFeatureStateA(prodcode, "feature");
1113     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1114
1115     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 1);
1116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1117
1118     /* feature value exists */
1119     state = MsiQueryFeatureStateA(prodcode, "feature");
1120     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1121
1122     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1123     lstrcatA(keypath, "S-1-5-18\\Products\\");
1124     lstrcatA(keypath, prod_squashed);
1125     lstrcatA(keypath, "\\Features");
1126
1127     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1129
1130     /* userdata features key exists */
1131     state = MsiQueryFeatureStateA(prodcode, "feature");
1132     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1133
1134     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1136
1137     state = MsiQueryFeatureStateA(prodcode, "feature");
1138     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1139
1140     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1142
1143     state = MsiQueryFeatureStateA(prodcode, "feature");
1144     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1145
1146     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1148
1149     state = MsiQueryFeatureStateA(prodcode, "feature");
1150     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1151
1152     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
1153     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1154
1155     state = MsiQueryFeatureStateA(prodcode, "feature");
1156     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1157
1158     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1159     lstrcatA(keypath, "S-1-5-18\\Components\\");
1160     lstrcatA(keypath, comp_squashed);
1161
1162     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1163     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1164
1165     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1166     lstrcatA(keypath, "S-1-5-18\\Components\\");
1167     lstrcatA(keypath, comp_squashed2);
1168
1169     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2);
1170     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1171
1172     state = MsiQueryFeatureStateA(prodcode, "feature");
1173     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1174
1175     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1176     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1177
1178     state = MsiQueryFeatureStateA(prodcode, "feature");
1179     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1180
1181     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
1182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1183
1184     state = MsiQueryFeatureStateA(prodcode, "feature");
1185     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1186
1187     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
1188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1189
1190     state = MsiQueryFeatureStateA(prodcode, "feature");
1191     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1192
1193     RegDeleteValueA(compkey, prod_squashed);
1194     RegDeleteValueA(compkey2, prod_squashed);
1195     RegDeleteKeyA(compkey, "");
1196     RegDeleteKeyA(compkey2, "");
1197     RegDeleteValueA(localkey, "feature");
1198     RegDeleteValueA(userkey, "feature");
1199     RegDeleteKeyA(userkey, "");
1200     RegCloseKey(compkey);
1201     RegCloseKey(compkey2);
1202     RegCloseKey(localkey);
1203     RegCloseKey(userkey);
1204     LocalFree(usersid);
1205 }
1206
1207 static void test_MsiQueryComponentState(void)
1208 {
1209     HKEY compkey, prodkey;
1210     CHAR prodcode[MAX_PATH];
1211     CHAR prod_squashed[MAX_PATH];
1212     CHAR component[MAX_PATH];
1213     CHAR comp_base85[MAX_PATH];
1214     CHAR comp_squashed[MAX_PATH];
1215     CHAR keypath[MAX_PATH];
1216     INSTALLSTATE state;
1217     LPSTR usersid;
1218     LONG res;
1219     UINT r;
1220
1221     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1222
1223     if (!pMsiQueryComponentStateA)
1224     {
1225         win_skip("MsiQueryComponentStateA not implemented\n");
1226         return;
1227     }
1228
1229     create_test_guid(prodcode, prod_squashed);
1230     compose_base85_guid(component, comp_base85, comp_squashed);
1231     get_user_sid(&usersid);
1232
1233     /* NULL szProductCode */
1234     state = MAGIC_ERROR;
1235     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1236     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1237     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1238
1239     /* empty szProductCode */
1240     state = MAGIC_ERROR;
1241     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1242     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1243     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1244
1245     /* random szProductCode */
1246     state = MAGIC_ERROR;
1247     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1248     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1249     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1250
1251     /* GUID-length szProductCode */
1252     state = MAGIC_ERROR;
1253     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1254     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1255     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1256
1257     /* GUID-length with brackets */
1258     state = MAGIC_ERROR;
1259     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1260     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1261     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1262
1263     /* actual GUID */
1264     state = MAGIC_ERROR;
1265     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1266     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1267     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1268
1269     state = MAGIC_ERROR;
1270     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1271     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1272     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1273
1274     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1275     lstrcatA(keypath, prod_squashed);
1276
1277     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1279
1280     state = MAGIC_ERROR;
1281     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1282     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1283     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1284
1285     RegDeleteKeyA(prodkey, "");
1286     RegCloseKey(prodkey);
1287
1288     /* create local system product key */
1289     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1290     lstrcatA(keypath, prod_squashed);
1291     lstrcatA(keypath, "\\InstallProperties");
1292
1293     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1294     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1295
1296     /* local system product key exists */
1297     state = MAGIC_ERROR;
1298     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1299     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1300     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1301
1302     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1304
1305     /* LocalPackage value exists */
1306     state = MAGIC_ERROR;
1307     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1308     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1309     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1310
1311     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1312     lstrcatA(keypath, comp_squashed);
1313
1314     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1315     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1316
1317     /* component key exists */
1318     state = MAGIC_ERROR;
1319     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1320     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1321     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1322
1323     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1325
1326     /* component\product exists */
1327     state = MAGIC_ERROR;
1328     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1329     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1330     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1331        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1332
1333     /* NULL component, product exists */
1334     state = MAGIC_ERROR;
1335     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1336     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1337     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1338
1339     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1340     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1341
1342     /* INSTALLSTATE_LOCAL */
1343     state = MAGIC_ERROR;
1344     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1345     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1346     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1347
1348     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1349     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1350
1351     /* INSTALLSTATE_SOURCE */
1352     state = MAGIC_ERROR;
1353     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1355     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1356
1357     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1358     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1359
1360     /* bad INSTALLSTATE_SOURCE */
1361     state = MAGIC_ERROR;
1362     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1364     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1365
1366     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1368
1369     /* INSTALLSTATE_SOURCE */
1370     state = MAGIC_ERROR;
1371     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1372     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1373     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1374
1375     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1377
1378     /* bad INSTALLSTATE_SOURCE */
1379     state = MAGIC_ERROR;
1380     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1381     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1382     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1383
1384     RegDeleteValueA(prodkey, "LocalPackage");
1385     RegDeleteKeyA(prodkey, "");
1386     RegDeleteValueA(compkey, prod_squashed);
1387     RegDeleteKeyA(prodkey, "");
1388     RegCloseKey(prodkey);
1389     RegCloseKey(compkey);
1390
1391     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1392
1393     state = MAGIC_ERROR;
1394     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1395     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1396     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1397
1398     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1399     lstrcatA(keypath, prod_squashed);
1400
1401     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1403
1404     state = MAGIC_ERROR;
1405     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1406     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1407     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1408
1409     RegDeleteKeyA(prodkey, "");
1410     RegCloseKey(prodkey);
1411
1412     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1413     lstrcatA(keypath, usersid);
1414     lstrcatA(keypath, "\\Products\\");
1415     lstrcatA(keypath, prod_squashed);
1416     lstrcatA(keypath, "\\InstallProperties");
1417
1418     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1419     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1420
1421     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1423
1424     RegCloseKey(prodkey);
1425
1426     state = MAGIC_ERROR;
1427     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1428     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1429     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1430
1431     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1432     lstrcatA(keypath, usersid);
1433     lstrcatA(keypath, "\\Components\\");
1434     lstrcatA(keypath, comp_squashed);
1435
1436     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1437     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1438
1439     /* component key exists */
1440     state = MAGIC_ERROR;
1441     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1442     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1443     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1444
1445     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1447
1448     /* component\product exists */
1449     state = MAGIC_ERROR;
1450     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1452     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1453        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1454
1455     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1457
1458     state = MAGIC_ERROR;
1459     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1460     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1461     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1462
1463     /* MSIINSTALLCONTEXT_USERMANAGED */
1464
1465     state = MAGIC_ERROR;
1466     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1467     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1468     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1469
1470     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1471     lstrcatA(keypath, prod_squashed);
1472
1473     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1474     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1475
1476     state = MAGIC_ERROR;
1477     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1478     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1479     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1480
1481     RegDeleteKeyA(prodkey, "");
1482     RegCloseKey(prodkey);
1483
1484     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1485     lstrcatA(keypath, usersid);
1486     lstrcatA(keypath, "\\Installer\\Products\\");
1487     lstrcatA(keypath, prod_squashed);
1488
1489     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1490     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1491
1492     state = MAGIC_ERROR;
1493     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1494     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1495     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1496
1497     RegDeleteKeyA(prodkey, "");
1498     RegCloseKey(prodkey);
1499
1500     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1501     lstrcatA(keypath, usersid);
1502     lstrcatA(keypath, "\\Products\\");
1503     lstrcatA(keypath, prod_squashed);
1504     lstrcatA(keypath, "\\InstallProperties");
1505
1506     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1507     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1508
1509     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1510     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1511
1512     state = MAGIC_ERROR;
1513     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1514     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1515     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1516
1517     RegDeleteValueA(prodkey, "LocalPackage");
1518     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1519     RegDeleteKeyA(prodkey, "");
1520     RegDeleteValueA(compkey, prod_squashed);
1521     RegDeleteKeyA(compkey, "");
1522     RegCloseKey(prodkey);
1523     RegCloseKey(compkey);
1524     LocalFree(usersid);
1525 }
1526
1527 static void test_MsiGetComponentPath(void)
1528 {
1529     HKEY compkey, prodkey, installprop;
1530     CHAR prodcode[MAX_PATH];
1531     CHAR prod_squashed[MAX_PATH];
1532     CHAR component[MAX_PATH];
1533     CHAR comp_base85[MAX_PATH];
1534     CHAR comp_squashed[MAX_PATH];
1535     CHAR keypath[MAX_PATH];
1536     CHAR path[MAX_PATH];
1537     INSTALLSTATE state;
1538     LPSTR usersid;
1539     DWORD size, val;
1540     LONG res;
1541
1542     create_test_guid(prodcode, prod_squashed);
1543     compose_base85_guid(component, comp_base85, comp_squashed);
1544     get_user_sid(&usersid);
1545
1546     /* NULL szProduct */
1547     size = MAX_PATH;
1548     state = MsiGetComponentPathA(NULL, component, path, &size);
1549     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1550     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1551
1552     /* NULL szComponent */
1553     size = MAX_PATH;
1554     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1555     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1556     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1557
1558     /* NULL lpPathBuf */
1559     size = MAX_PATH;
1560     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1561     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1562     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1563
1564     /* NULL pcchBuf */
1565     size = MAX_PATH;
1566     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1567     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1568     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1569
1570     /* all params valid */
1571     size = MAX_PATH;
1572     state = MsiGetComponentPathA(prodcode, component, path, &size);
1573     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1574     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1575
1576     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1577     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1578     lstrcatA(keypath, comp_squashed);
1579
1580     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1581     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1582
1583     /* local system component key exists */
1584     size = MAX_PATH;
1585     state = MsiGetComponentPathA(prodcode, component, path, &size);
1586     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1587     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1588
1589     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1590     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1591
1592     /* product value exists */
1593     size = MAX_PATH;
1594     state = MsiGetComponentPathA(prodcode, component, path, &size);
1595     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1596     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1597     ok(size == 10, "Expected 10, got %d\n", size);
1598
1599     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1600     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1601     lstrcatA(keypath, prod_squashed);
1602     lstrcatA(keypath, "\\InstallProperties");
1603
1604     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1605     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1606
1607     val = 1;
1608     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1609     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1610
1611     /* install properties key exists */
1612     size = MAX_PATH;
1613     state = MsiGetComponentPathA(prodcode, component, path, &size);
1614     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1615     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1616     ok(size == 10, "Expected 10, got %d\n", size);
1617
1618     create_file("C:\\imapath", "C:\\imapath", 11);
1619
1620     /* file exists */
1621     size = MAX_PATH;
1622     state = MsiGetComponentPathA(prodcode, component, path, &size);
1623     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1624     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1625     ok(size == 10, "Expected 10, got %d\n", size);
1626
1627     RegDeleteValueA(compkey, prod_squashed);
1628     RegDeleteKeyA(compkey, "");
1629     RegDeleteValueA(installprop, "WindowsInstaller");
1630     RegDeleteKeyA(installprop, "");
1631     RegCloseKey(compkey);
1632     RegCloseKey(installprop);
1633     DeleteFileA("C:\\imapath");
1634
1635     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1636     lstrcatA(keypath, "Installer\\UserData\\");
1637     lstrcatA(keypath, usersid);
1638     lstrcatA(keypath, "\\Components\\");
1639     lstrcatA(keypath, comp_squashed);
1640
1641     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1643
1644     /* user managed component key exists */
1645     size = MAX_PATH;
1646     state = MsiGetComponentPathA(prodcode, component, path, &size);
1647     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1648     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1649
1650     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1651     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1652
1653     /* product value exists */
1654     size = MAX_PATH;
1655     state = MsiGetComponentPathA(prodcode, component, path, &size);
1656     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1657     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1658     ok(size == 10, "Expected 10, got %d\n", size);
1659
1660     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1661     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1662     lstrcatA(keypath, prod_squashed);
1663     lstrcatA(keypath, "\\InstallProperties");
1664
1665     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1667
1668     val = 1;
1669     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1670     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1671
1672     /* install properties key exists */
1673     size = MAX_PATH;
1674     state = MsiGetComponentPathA(prodcode, component, path, &size);
1675     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1676     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1677     ok(size == 10, "Expected 10, got %d\n", size);
1678
1679     create_file("C:\\imapath", "C:\\imapath", 11);
1680
1681     /* file exists */
1682     size = MAX_PATH;
1683     state = MsiGetComponentPathA(prodcode, component, path, &size);
1684     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1685     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1686     ok(size == 10, "Expected 10, got %d\n", size);
1687
1688     RegDeleteValueA(compkey, prod_squashed);
1689     RegDeleteKeyA(compkey, "");
1690     RegDeleteValueA(installprop, "WindowsInstaller");
1691     RegDeleteKeyA(installprop, "");
1692     RegCloseKey(compkey);
1693     RegCloseKey(installprop);
1694     DeleteFileA("C:\\imapath");
1695
1696     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1697     lstrcatA(keypath, "Installer\\Managed\\");
1698     lstrcatA(keypath, usersid);
1699     lstrcatA(keypath, "\\Installer\\Products\\");
1700     lstrcatA(keypath, prod_squashed);
1701
1702     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1703     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1704
1705     /* user managed product key exists */
1706     size = MAX_PATH;
1707     state = MsiGetComponentPathA(prodcode, component, path, &size);
1708     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1709     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1710
1711     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1712     lstrcatA(keypath, "Installer\\UserData\\");
1713     lstrcatA(keypath, usersid);
1714     lstrcatA(keypath, "\\Components\\");
1715     lstrcatA(keypath, comp_squashed);
1716
1717     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1718     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1719
1720     /* user managed component key exists */
1721     size = MAX_PATH;
1722     state = MsiGetComponentPathA(prodcode, component, path, &size);
1723     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1724     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1725
1726     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1728
1729     /* product value exists */
1730     size = MAX_PATH;
1731     state = MsiGetComponentPathA(prodcode, component, path, &size);
1732     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1733     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1734     ok(size == 10, "Expected 10, got %d\n", size);
1735
1736     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1737     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1738     lstrcatA(keypath, prod_squashed);
1739     lstrcatA(keypath, "\\InstallProperties");
1740
1741     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1742     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1743
1744     val = 1;
1745     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1747
1748     /* install properties key exists */
1749     size = MAX_PATH;
1750     state = MsiGetComponentPathA(prodcode, component, path, &size);
1751     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1752     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1753     ok(size == 10, "Expected 10, got %d\n", size);
1754
1755     create_file("C:\\imapath", "C:\\imapath", 11);
1756
1757     /* file exists */
1758     size = MAX_PATH;
1759     state = MsiGetComponentPathA(prodcode, component, path, &size);
1760     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1761     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1762     ok(size == 10, "Expected 10, got %d\n", size);
1763
1764     RegDeleteValueA(compkey, prod_squashed);
1765     RegDeleteKeyA(prodkey, "");
1766     RegDeleteKeyA(compkey, "");
1767     RegDeleteValueA(installprop, "WindowsInstaller");
1768     RegDeleteKeyA(installprop, "");
1769     RegCloseKey(prodkey);
1770     RegCloseKey(compkey);
1771     RegCloseKey(installprop);
1772     DeleteFileA("C:\\imapath");
1773
1774     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1775     lstrcatA(keypath, prod_squashed);
1776
1777     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1779
1780     /* user unmanaged product key exists */
1781     size = MAX_PATH;
1782     state = MsiGetComponentPathA(prodcode, component, path, &size);
1783     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1784     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1785
1786     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1787     lstrcatA(keypath, "Installer\\UserData\\");
1788     lstrcatA(keypath, usersid);
1789     lstrcatA(keypath, "\\Components\\");
1790     lstrcatA(keypath, comp_squashed);
1791
1792     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1793     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1794
1795     /* user unmanaged component key exists */
1796     size = MAX_PATH;
1797     state = MsiGetComponentPathA(prodcode, component, path, &size);
1798     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1799     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1800
1801     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1803
1804     /* product value exists */
1805     size = MAX_PATH;
1806     state = MsiGetComponentPathA(prodcode, component, path, &size);
1807     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1808     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1809     ok(size == 10, "Expected 10, got %d\n", size);
1810
1811     create_file("C:\\imapath", "C:\\imapath", 11);
1812
1813     /* file exists */
1814     size = MAX_PATH;
1815     state = MsiGetComponentPathA(prodcode, component, path, &size);
1816     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1817     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1818     ok(size == 10, "Expected 10, got %d\n", size);
1819
1820     RegDeleteValueA(compkey, prod_squashed);
1821     RegDeleteKeyA(prodkey, "");
1822     RegDeleteKeyA(compkey, "");
1823     RegCloseKey(prodkey);
1824     RegCloseKey(compkey);
1825     DeleteFileA("C:\\imapath");
1826
1827     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1828     lstrcatA(keypath, prod_squashed);
1829
1830     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1831     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1832
1833     /* local classes product key exists */
1834     size = MAX_PATH;
1835     state = MsiGetComponentPathA(prodcode, component, path, &size);
1836     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1837     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1838
1839     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1840     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1841     lstrcatA(keypath, comp_squashed);
1842
1843     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1845
1846     /* local user component key exists */
1847     size = MAX_PATH;
1848     state = MsiGetComponentPathA(prodcode, component, path, &size);
1849     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1850     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1851
1852     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1854
1855     /* product value exists */
1856     size = MAX_PATH;
1857     state = MsiGetComponentPathA(prodcode, component, path, &size);
1858     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1859     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1860     ok(size == 10, "Expected 10, got %d\n", size);
1861
1862     create_file("C:\\imapath", "C:\\imapath", 11);
1863
1864     /* file exists */
1865     size = MAX_PATH;
1866     state = MsiGetComponentPathA(prodcode, component, path, &size);
1867     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1868     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1869     ok(size == 10, "Expected 10, got %d\n", size);
1870
1871     RegDeleteValueA(compkey, prod_squashed);
1872     RegDeleteKeyA(prodkey, "");
1873     RegDeleteKeyA(compkey, "");
1874     RegCloseKey(prodkey);
1875     RegCloseKey(compkey);
1876     DeleteFileA("C:\\imapath");
1877     LocalFree(usersid);
1878 }
1879
1880 static void test_MsiGetProductCode(void)
1881 {
1882     HKEY compkey, prodkey;
1883     CHAR prodcode[MAX_PATH];
1884     CHAR prod_squashed[MAX_PATH];
1885     CHAR prodcode2[MAX_PATH];
1886     CHAR prod2_squashed[MAX_PATH];
1887     CHAR component[MAX_PATH];
1888     CHAR comp_base85[MAX_PATH];
1889     CHAR comp_squashed[MAX_PATH];
1890     CHAR keypath[MAX_PATH];
1891     CHAR product[MAX_PATH];
1892     LPSTR usersid;
1893     LONG res;
1894     UINT r;
1895
1896     create_test_guid(prodcode, prod_squashed);
1897     create_test_guid(prodcode2, prod2_squashed);
1898     compose_base85_guid(component, comp_base85, comp_squashed);
1899     get_user_sid(&usersid);
1900
1901     /* szComponent is NULL */
1902     lstrcpyA(product, "prod");
1903     r = MsiGetProductCodeA(NULL, product);
1904     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1905     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1906
1907     /* szComponent is empty */
1908     lstrcpyA(product, "prod");
1909     r = MsiGetProductCodeA("", product);
1910     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1911     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1912
1913     /* garbage szComponent */
1914     lstrcpyA(product, "prod");
1915     r = MsiGetProductCodeA("garbage", product);
1916     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1917     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1918
1919     /* guid without brackets */
1920     lstrcpyA(product, "prod");
1921     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
1922     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1923     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1924
1925     /* guid with brackets */
1926     lstrcpyA(product, "prod");
1927     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
1928     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1929     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1930
1931     /* same length as guid, but random */
1932     lstrcpyA(product, "prod");
1933     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
1934     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1935     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1936
1937     /* all params correct, szComponent not published */
1938     lstrcpyA(product, "prod");
1939     r = MsiGetProductCodeA(component, product);
1940     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1941     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1942
1943     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1944     lstrcatA(keypath, "Installer\\UserData\\");
1945     lstrcatA(keypath, usersid);
1946     lstrcatA(keypath, "\\Components\\");
1947     lstrcatA(keypath, comp_squashed);
1948
1949     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1951
1952     /* user unmanaged component key exists */
1953     lstrcpyA(product, "prod");
1954     r = MsiGetProductCodeA(component, product);
1955     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1956     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1957
1958     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1959     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1960
1961     /* product value exists */
1962     lstrcpyA(product, "prod");
1963     r = MsiGetProductCodeA(component, product);
1964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1965     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1966
1967     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1968     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1969
1970     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1971     lstrcatA(keypath, "Installer\\Managed\\");
1972     lstrcatA(keypath, usersid);
1973     lstrcatA(keypath, "\\Installer\\Products\\");
1974     lstrcatA(keypath, prod_squashed);
1975
1976     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1978
1979     /* user managed product key of first product exists */
1980     lstrcpyA(product, "prod");
1981     r = MsiGetProductCodeA(component, product);
1982     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1983     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1984
1985     RegDeleteKeyA(prodkey, "");
1986     RegCloseKey(prodkey);
1987
1988     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1989     lstrcatA(keypath, prod_squashed);
1990
1991     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1992     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1993
1994     /* user unmanaged product key exists */
1995     lstrcpyA(product, "prod");
1996     r = MsiGetProductCodeA(component, product);
1997     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1998     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1999
2000     RegDeleteKeyA(prodkey, "");
2001     RegCloseKey(prodkey);
2002
2003     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2004     lstrcatA(keypath, prod_squashed);
2005
2006     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2007     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2008
2009     /* local classes product key exists */
2010     lstrcpyA(product, "prod");
2011     r = MsiGetProductCodeA(component, product);
2012     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2013     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2014
2015     RegDeleteKeyA(prodkey, "");
2016     RegCloseKey(prodkey);
2017
2018     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2019     lstrcatA(keypath, "Installer\\Managed\\");
2020     lstrcatA(keypath, usersid);
2021     lstrcatA(keypath, "\\Installer\\Products\\");
2022     lstrcatA(keypath, prod2_squashed);
2023
2024     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2026
2027     /* user managed product key of second product exists */
2028     lstrcpyA(product, "prod");
2029     r = MsiGetProductCodeA(component, product);
2030     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2031     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2032
2033     RegDeleteKeyA(prodkey, "");
2034     RegCloseKey(prodkey);
2035     RegDeleteValueA(compkey, prod_squashed);
2036     RegDeleteValueA(compkey, prod2_squashed);
2037     RegDeleteKeyA(compkey, "");
2038     RegCloseKey(compkey);
2039
2040     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2041     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2042     lstrcatA(keypath, comp_squashed);
2043
2044     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2045     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2046
2047     /* local user component key exists */
2048     lstrcpyA(product, "prod");
2049     r = MsiGetProductCodeA(component, product);
2050     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2051     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2052
2053     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2054     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2055
2056     /* product value exists */
2057     lstrcpyA(product, "prod");
2058     r = MsiGetProductCodeA(component, product);
2059     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2060     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2061
2062     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2063     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2064
2065     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2066     lstrcatA(keypath, "Installer\\Managed\\");
2067     lstrcatA(keypath, usersid);
2068     lstrcatA(keypath, "\\Installer\\Products\\");
2069     lstrcatA(keypath, prod_squashed);
2070
2071     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2073
2074     /* user managed product key of first product exists */
2075     lstrcpyA(product, "prod");
2076     r = MsiGetProductCodeA(component, product);
2077     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2078     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2079
2080     RegDeleteKeyA(prodkey, "");
2081     RegCloseKey(prodkey);
2082
2083     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2084     lstrcatA(keypath, prod_squashed);
2085
2086     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2087     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2088
2089     /* user unmanaged product key exists */
2090     lstrcpyA(product, "prod");
2091     r = MsiGetProductCodeA(component, product);
2092     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2093     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2094
2095     RegDeleteKeyA(prodkey, "");
2096     RegCloseKey(prodkey);
2097
2098     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2099     lstrcatA(keypath, prod_squashed);
2100
2101     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2102     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2103
2104     /* local classes product key exists */
2105     lstrcpyA(product, "prod");
2106     r = MsiGetProductCodeA(component, product);
2107     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2108     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2109
2110     RegDeleteKeyA(prodkey, "");
2111     RegCloseKey(prodkey);
2112
2113     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2114     lstrcatA(keypath, "Installer\\Managed\\");
2115     lstrcatA(keypath, usersid);
2116     lstrcatA(keypath, "\\Installer\\Products\\");
2117     lstrcatA(keypath, prod2_squashed);
2118
2119     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2120     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2121
2122     /* user managed product key of second product exists */
2123     lstrcpyA(product, "prod");
2124     r = MsiGetProductCodeA(component, product);
2125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2126     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2127
2128     RegDeleteKeyA(prodkey, "");
2129     RegCloseKey(prodkey);
2130     RegDeleteValueA(compkey, prod_squashed);
2131     RegDeleteValueA(compkey, prod2_squashed);
2132     RegDeleteKeyA(compkey, "");
2133     RegCloseKey(compkey);
2134     LocalFree(usersid);
2135 }
2136
2137 static void test_MsiEnumClients(void)
2138 {
2139     HKEY compkey;
2140     CHAR prodcode[MAX_PATH];
2141     CHAR prod_squashed[MAX_PATH];
2142     CHAR prodcode2[MAX_PATH];
2143     CHAR prod2_squashed[MAX_PATH];
2144     CHAR component[MAX_PATH];
2145     CHAR comp_base85[MAX_PATH];
2146     CHAR comp_squashed[MAX_PATH];
2147     CHAR product[MAX_PATH];
2148     CHAR keypath[MAX_PATH];
2149     LPSTR usersid;
2150     LONG res;
2151     UINT r;
2152
2153     create_test_guid(prodcode, prod_squashed);
2154     create_test_guid(prodcode2, prod2_squashed);
2155     compose_base85_guid(component, comp_base85, comp_squashed);
2156     get_user_sid(&usersid);
2157
2158     /* NULL szComponent */
2159     product[0] = '\0';
2160     r = MsiEnumClientsA(NULL, 0, product);
2161     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2162     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2163
2164     /* empty szComponent */
2165     product[0] = '\0';
2166     r = MsiEnumClientsA("", 0, product);
2167     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2168     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2169
2170     /* NULL lpProductBuf */
2171     r = MsiEnumClientsA(component, 0, NULL);
2172     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2173
2174     /* all params correct, component missing */
2175     product[0] = '\0';
2176     r = MsiEnumClientsA(component, 0, product);
2177     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2178     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2179
2180     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2181     lstrcatA(keypath, "Installer\\UserData\\");
2182     lstrcatA(keypath, usersid);
2183     lstrcatA(keypath, "\\Components\\");
2184     lstrcatA(keypath, comp_squashed);
2185
2186     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2188
2189     /* user unmanaged component key exists */
2190     product[0] = '\0';
2191     r = MsiEnumClientsA(component, 0, product);
2192     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2193     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2194
2195     /* index > 0, no products exist */
2196     product[0] = '\0';
2197     r = MsiEnumClientsA(component, 1, product);
2198     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2199     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2200
2201     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2203
2204     /* product value exists */
2205     r = MsiEnumClientsA(component, 0, product);
2206     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2207     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2208
2209     /* try index 0 again */
2210     product[0] = '\0';
2211     r = MsiEnumClientsA(component, 0, product);
2212     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2213     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2214
2215     /* try index 1, second product value does not exist */
2216     product[0] = '\0';
2217     r = MsiEnumClientsA(component, 1, product);
2218     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2219     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2220
2221     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2222     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2223
2224     /* try index 1, second product value does exist */
2225     product[0] = '\0';
2226     r = MsiEnumClientsA(component, 1, product);
2227     todo_wine
2228     {
2229         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2230         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2231     }
2232
2233     /* start the enumeration over */
2234     product[0] = '\0';
2235     r = MsiEnumClientsA(component, 0, product);
2236     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2237     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2238        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2239
2240     /* correctly query second product */
2241     product[0] = '\0';
2242     r = MsiEnumClientsA(component, 1, product);
2243     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2244     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2245        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2246
2247     RegDeleteValueA(compkey, prod_squashed);
2248     RegDeleteValueA(compkey, prod2_squashed);
2249     RegDeleteKeyA(compkey, "");
2250     RegCloseKey(compkey);
2251
2252     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2253     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2254     lstrcatA(keypath, comp_squashed);
2255
2256     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2258
2259     /* user local component key exists */
2260     product[0] = '\0';
2261     r = MsiEnumClientsA(component, 0, product);
2262     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2263     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2264
2265     /* index > 0, no products exist */
2266     product[0] = '\0';
2267     r = MsiEnumClientsA(component, 1, product);
2268     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2269     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2270
2271     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2273
2274     /* product value exists */
2275     product[0] = '\0';
2276     r = MsiEnumClientsA(component, 0, product);
2277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2278     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2279
2280     /* try index 0 again */
2281     product[0] = '\0';
2282     r = MsiEnumClientsA(component, 0, product);
2283     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2284
2285     /* try index 1, second product value does not exist */
2286     product[0] = '\0';
2287     r = MsiEnumClientsA(component, 1, product);
2288     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2289     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2290
2291     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2292     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2293
2294     /* try index 1, second product value does exist */
2295     product[0] = '\0';
2296     r = MsiEnumClientsA(component, 1, product);
2297     todo_wine
2298     {
2299         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2300         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2301     }
2302
2303     /* start the enumeration over */
2304     product[0] = '\0';
2305     r = MsiEnumClientsA(component, 0, product);
2306     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2307     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2308        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2309
2310     /* correctly query second product */
2311     product[0] = '\0';
2312     r = MsiEnumClientsA(component, 1, product);
2313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2314     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2315        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2316
2317     RegDeleteValueA(compkey, prod_squashed);
2318     RegDeleteValueA(compkey, prod2_squashed);
2319     RegDeleteKeyA(compkey, "");
2320     RegCloseKey(compkey);
2321     LocalFree(usersid);
2322 }
2323
2324 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2325                              LPSTR *langcheck, LPDWORD langchecksz)
2326 {
2327     LPSTR version;
2328     VS_FIXEDFILEINFO *ffi;
2329     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2330     USHORT *lang;
2331
2332     version = HeapAlloc(GetProcessHeap(), 0, size);
2333     GetFileVersionInfoA(path, 0, size, version);
2334
2335     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2336     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2337     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2338             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2339             LOWORD(ffi->dwFileVersionLS));
2340     *verchecksz = lstrlenA(*vercheck);
2341
2342     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2343     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2344     sprintf(*langcheck, "%d", *lang);
2345     *langchecksz = lstrlenA(*langcheck);
2346
2347     HeapFree(GetProcessHeap(), 0, version);
2348 }
2349
2350 static void test_MsiGetFileVersion(void)
2351 {
2352     UINT r;
2353     DWORD versz, langsz;
2354     char version[MAX_PATH];
2355     char lang[MAX_PATH];
2356     char path[MAX_PATH];
2357     LPSTR vercheck, langcheck;
2358     DWORD verchecksz, langchecksz;
2359
2360     /* NULL szFilePath */
2361     versz = MAX_PATH;
2362     langsz = MAX_PATH;
2363     lstrcpyA(version, "version");
2364     lstrcpyA(lang, "lang");
2365     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2366     ok(r == ERROR_INVALID_PARAMETER,
2367        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2368     ok(!lstrcmpA(version, "version"),
2369        "Expected version to be unchanged, got %s\n", version);
2370     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2371     ok(!lstrcmpA(lang, "lang"),
2372        "Expected lang to be unchanged, got %s\n", lang);
2373     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2374
2375     /* empty szFilePath */
2376     versz = MAX_PATH;
2377     langsz = MAX_PATH;
2378     lstrcpyA(version, "version");
2379     lstrcpyA(lang, "lang");
2380     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2381     ok(r == ERROR_FILE_NOT_FOUND,
2382        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2383     ok(!lstrcmpA(version, "version"),
2384        "Expected version to be unchanged, got %s\n", version);
2385     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2386     ok(!lstrcmpA(lang, "lang"),
2387        "Expected lang to be unchanged, got %s\n", lang);
2388     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2389
2390     /* nonexistent szFilePath */
2391     versz = MAX_PATH;
2392     langsz = MAX_PATH;
2393     lstrcpyA(version, "version");
2394     lstrcpyA(lang, "lang");
2395     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2396     ok(r == ERROR_FILE_NOT_FOUND,
2397        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2398     ok(!lstrcmpA(version, "version"),
2399        "Expected version to be unchanged, got %s\n", version);
2400     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2401     ok(!lstrcmpA(lang, "lang"),
2402        "Expected lang to be unchanged, got %s\n", lang);
2403     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2404
2405     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2406     versz = MAX_PATH;
2407     langsz = MAX_PATH;
2408     lstrcpyA(version, "version");
2409     lstrcpyA(lang, "lang");
2410     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2411     ok(r == ERROR_INVALID_PARAMETER,
2412        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2413     ok(!lstrcmpA(version, "version"),
2414        "Expected version to be unchanged, got %s\n", version);
2415     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2416     ok(!lstrcmpA(lang, "lang"),
2417        "Expected lang to be unchanged, got %s\n", lang);
2418     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2419
2420     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2421     versz = MAX_PATH;
2422     langsz = MAX_PATH;
2423     lstrcpyA(version, "version");
2424     lstrcpyA(lang, "lang");
2425     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2426     ok(r == ERROR_INVALID_PARAMETER,
2427        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2428     ok(!lstrcmpA(version, "version"),
2429        "Expected version to be unchanged, got %s\n", version);
2430     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2431     ok(!lstrcmpA(lang, "lang"),
2432        "Expected lang to be unchanged, got %s\n", lang);
2433     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2434
2435     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2436     versz = 0;
2437     langsz = MAX_PATH;
2438     lstrcpyA(version, "version");
2439     lstrcpyA(lang, "lang");
2440     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2441     ok(r == ERROR_FILE_NOT_FOUND,
2442        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2443     ok(!lstrcmpA(version, "version"),
2444        "Expected version to be unchanged, got %s\n", version);
2445     ok(versz == 0, "Expected 0, got %d\n", versz);
2446     ok(!lstrcmpA(lang, "lang"),
2447        "Expected lang to be unchanged, got %s\n", lang);
2448     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2449
2450     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2451     versz = MAX_PATH;
2452     langsz = 0;
2453     lstrcpyA(version, "version");
2454     lstrcpyA(lang, "lang");
2455     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2456     ok(r == ERROR_FILE_NOT_FOUND,
2457        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2458     ok(!lstrcmpA(version, "version"),
2459        "Expected version to be unchanged, got %s\n", version);
2460     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2461     ok(!lstrcmpA(lang, "lang"),
2462        "Expected lang to be unchanged, got %s\n", lang);
2463     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2464
2465     /* nonexistent szFilePath, rest NULL */
2466     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2467     ok(r == ERROR_FILE_NOT_FOUND,
2468        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2469
2470     create_file("ver.txt", "ver.txt", 20);
2471
2472     /* file exists, no version information */
2473     versz = MAX_PATH;
2474     langsz = MAX_PATH;
2475     lstrcpyA(version, "version");
2476     lstrcpyA(lang, "lang");
2477     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2478     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2479     ok(!lstrcmpA(version, "version"),
2480        "Expected version to be unchanged, got %s\n", version);
2481     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2482     ok(!lstrcmpA(lang, "lang"),
2483        "Expected lang to be unchanged, got %s\n", lang);
2484     ok(r == ERROR_FILE_INVALID,
2485        "Expected ERROR_FILE_INVALID, got %d\n", r);
2486
2487     DeleteFileA("ver.txt");
2488
2489     /* relative path, has version information */
2490     versz = MAX_PATH;
2491     langsz = MAX_PATH;
2492     lstrcpyA(version, "version");
2493     lstrcpyA(lang, "lang");
2494     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2495     todo_wine
2496     {
2497         ok(r == ERROR_FILE_NOT_FOUND,
2498            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2499         ok(!lstrcmpA(version, "version"),
2500            "Expected version to be unchanged, got %s\n", version);
2501         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2502         ok(!lstrcmpA(lang, "lang"),
2503            "Expected lang to be unchanged, got %s\n", lang);
2504         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2505     }
2506
2507     GetSystemDirectoryA(path, MAX_PATH);
2508     lstrcatA(path, "\\kernel32.dll");
2509
2510     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2511
2512     /* absolute path, has version information */
2513     versz = MAX_PATH;
2514     langsz = MAX_PATH;
2515     lstrcpyA(version, "version");
2516     lstrcpyA(lang, "lang");
2517     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2518     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2519     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2520     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2521     ok(!lstrcmpA(version, vercheck),
2522         "Expected %s, got %s\n", vercheck, version);
2523
2524     /* only check version */
2525     versz = MAX_PATH;
2526     lstrcpyA(version, "version");
2527     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2528     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2529     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2530     ok(!lstrcmpA(version, vercheck),
2531        "Expected %s, got %s\n", vercheck, version);
2532
2533     /* only check language */
2534     langsz = MAX_PATH;
2535     lstrcpyA(lang, "lang");
2536     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2537     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2538     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2539
2540     /* check neither version nor language */
2541     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2542     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2543
2544     /* get pcchVersionBuf */
2545     versz = MAX_PATH;
2546     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2547     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2548     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2549
2550     /* get pcchLangBuf */
2551     langsz = MAX_PATH;
2552     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2553     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2554     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
2555
2556     /* pcchVersionBuf not big enough */
2557     versz = 5;
2558     lstrcpyA(version, "version");
2559     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2560     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2561     ok(!strncmp(version, vercheck, 4),
2562        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2563     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2564
2565     /* pcchLangBuf not big enough */
2566     langsz = 3;
2567     lstrcpyA(lang, "lang");
2568     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2569     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2570     ok(!strncmp(lang, langcheck, 2),
2571        "Expected first character of %s, got %s\n", langcheck, lang);
2572     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
2573
2574     HeapFree(GetProcessHeap(), 0, vercheck);
2575     HeapFree(GetProcessHeap(), 0, langcheck);
2576 }
2577
2578 static void test_MsiGetProductInfo(void)
2579 {
2580     UINT r;
2581     LONG res;
2582     HKEY propkey, source;
2583     HKEY prodkey, localkey;
2584     CHAR prodcode[MAX_PATH];
2585     CHAR prod_squashed[MAX_PATH];
2586     CHAR packcode[MAX_PATH];
2587     CHAR pack_squashed[MAX_PATH];
2588     CHAR buf[MAX_PATH];
2589     CHAR keypath[MAX_PATH];
2590     LPSTR usersid;
2591     DWORD sz, val = 42;
2592
2593     create_test_guid(prodcode, prod_squashed);
2594     create_test_guid(packcode, pack_squashed);
2595     get_user_sid(&usersid);
2596
2597     /* NULL szProduct */
2598     sz = MAX_PATH;
2599     lstrcpyA(buf, "apple");
2600     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2601     ok(r == ERROR_INVALID_PARAMETER,
2602        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2603     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2604     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2605
2606     /* empty szProduct */
2607     sz = MAX_PATH;
2608     lstrcpyA(buf, "apple");
2609     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2610     ok(r == ERROR_INVALID_PARAMETER,
2611        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2612     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2613     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2614
2615     /* garbage szProduct */
2616     sz = MAX_PATH;
2617     lstrcpyA(buf, "apple");
2618     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2619     ok(r == ERROR_INVALID_PARAMETER,
2620        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2621     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2622     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2623
2624     /* guid without brackets */
2625     sz = MAX_PATH;
2626     lstrcpyA(buf, "apple");
2627     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2628                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2629     ok(r == ERROR_INVALID_PARAMETER,
2630        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2631     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2632     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2633
2634     /* guid with brackets */
2635     sz = MAX_PATH;
2636     lstrcpyA(buf, "apple");
2637     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2638                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2639     ok(r == ERROR_UNKNOWN_PRODUCT,
2640        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2641     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2642     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2643
2644     /* same length as guid, but random */
2645     sz = MAX_PATH;
2646     lstrcpyA(buf, "apple");
2647     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2648                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2649     ok(r == ERROR_INVALID_PARAMETER,
2650        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2651     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2652     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2653
2654     /* not installed, NULL szAttribute */
2655     sz = MAX_PATH;
2656     lstrcpyA(buf, "apple");
2657     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2658     ok(r == ERROR_INVALID_PARAMETER,
2659        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2660     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2661     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2662
2663     /* not installed, NULL lpValueBuf */
2664     sz = MAX_PATH;
2665     lstrcpyA(buf, "apple");
2666     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2667     ok(r == ERROR_UNKNOWN_PRODUCT,
2668        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2669     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2670     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2671
2672     /* not installed, NULL pcchValueBuf */
2673     sz = MAX_PATH;
2674     lstrcpyA(buf, "apple");
2675     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2676     ok(r == ERROR_INVALID_PARAMETER,
2677        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2678     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2679     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2680
2681     /* created guid cannot possibly be an installed product code */
2682     sz = MAX_PATH;
2683     lstrcpyA(buf, "apple");
2684     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2685     ok(r == ERROR_UNKNOWN_PRODUCT,
2686        "Expected ERROR_UNKNOWN_PRODUCT, 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     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2691     lstrcatA(keypath, usersid);
2692     lstrcatA(keypath, "\\Installer\\Products\\");
2693     lstrcatA(keypath, prod_squashed);
2694
2695     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2696     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2697
2698     /* managed product code exists */
2699     sz = MAX_PATH;
2700     lstrcpyA(buf, "apple");
2701     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2702     ok(r == ERROR_UNKNOWN_PROPERTY,
2703        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2704     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2705     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2706
2707     RegDeleteKeyA(prodkey, "");
2708     RegCloseKey(prodkey);
2709
2710     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2711     lstrcatA(keypath, usersid);
2712     lstrcatA(keypath, "\\Products\\");
2713     lstrcatA(keypath, prod_squashed);
2714
2715     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2717
2718     /* local user product code exists */
2719     sz = MAX_PATH;
2720     lstrcpyA(buf, "apple");
2721     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2722     ok(r == ERROR_UNKNOWN_PRODUCT,
2723        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2724     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2725     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2726
2727     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2728     lstrcatA(keypath, usersid);
2729     lstrcatA(keypath, "\\Installer\\Products\\");
2730     lstrcatA(keypath, prod_squashed);
2731
2732     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2733     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2734
2735     /* both local and managed product code exist */
2736     sz = MAX_PATH;
2737     lstrcpyA(buf, "apple");
2738     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2739     ok(r == ERROR_UNKNOWN_PROPERTY,
2740        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2741     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2742     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2743
2744     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2745     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2746
2747     /* InstallProperties key exists */
2748     sz = MAX_PATH;
2749     lstrcpyA(buf, "apple");
2750     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2751     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2752     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2753     ok(sz == 0, "Expected 0, got %d\n", sz);
2754
2755     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2756     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2757
2758     /* HelpLink value exists */
2759     sz = MAX_PATH;
2760     lstrcpyA(buf, "apple");
2761     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2762     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2763     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2764     ok(sz == 4, "Expected 4, got %d\n", sz);
2765
2766     /* pcchBuf is NULL */
2767     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
2768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2769
2770     /* lpValueBuf is NULL */
2771     sz = MAX_PATH;
2772     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2773     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2774     ok(sz == 4, "Expected 4, got %d\n", sz);
2775
2776     /* lpValueBuf is NULL, pcchValueBuf is too small */
2777     sz = 2;
2778     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2779     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2780     ok(sz == 4, "Expected 4, got %d\n", sz);
2781
2782     /* lpValueBuf is non-NULL, pcchValueBuf is too small */
2783     sz = 2;
2784     lstrcpyA(buf, "apple");
2785     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2786     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
2787     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2788     ok(sz == 4, "Expected 4, got %d\n", sz);
2789
2790     /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
2791     sz = 4;
2792     lstrcpyA(buf, "apple");
2793     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2794     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2795     ok(!lstrcmpA(buf, "apple"),
2796        "Expected buf to remain unchanged, got \"%s\"\n", buf);
2797     ok(sz == 4, "Expected 4, got %d\n", sz);
2798
2799     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
2800     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2801
2802     /* random property not supported by MSI, value exists */
2803     sz = MAX_PATH;
2804     lstrcpyA(buf, "apple");
2805     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
2806     ok(r == ERROR_UNKNOWN_PROPERTY,
2807        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2808     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2809     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2810
2811     RegDeleteValueA(propkey, "IMadeThis");
2812     RegDeleteValueA(propkey, "HelpLink");
2813     RegDeleteKeyA(propkey, "");
2814     RegDeleteKeyA(localkey, "");
2815     RegDeleteKeyA(prodkey, "");
2816     RegCloseKey(propkey);
2817     RegCloseKey(localkey);
2818     RegCloseKey(prodkey);
2819
2820     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2821     lstrcatA(keypath, prod_squashed);
2822
2823     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2824     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2825
2826     /* user product key exists */
2827     sz = MAX_PATH;
2828     lstrcpyA(buf, "apple");
2829     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2830     ok(r == ERROR_UNKNOWN_PROPERTY,
2831        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2832     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2833     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2834
2835     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2836     lstrcatA(keypath, usersid);
2837     lstrcatA(keypath, "\\Products\\");
2838     lstrcatA(keypath, prod_squashed);
2839
2840     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2841     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2842
2843     /* local user product key exists */
2844     sz = MAX_PATH;
2845     lstrcpyA(buf, "apple");
2846     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2847     ok(r == ERROR_UNKNOWN_PROPERTY,
2848        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2849     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2850     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2851
2852     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2854
2855     /* InstallProperties key exists */
2856     sz = MAX_PATH;
2857     lstrcpyA(buf, "apple");
2858     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2859     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2860     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2861     ok(sz == 0, "Expected 0, got %d\n", sz);
2862
2863     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2864     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2865
2866     /* HelpLink value exists */
2867     sz = MAX_PATH;
2868     lstrcpyA(buf, "apple");
2869     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2870     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2871     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2872     ok(sz == 4, "Expected 4, got %d\n", sz);
2873
2874     RegDeleteValueA(propkey, "HelpLink");
2875     RegDeleteKeyA(propkey, "");
2876     RegDeleteKeyA(localkey, "");
2877     RegDeleteKeyA(prodkey, "");
2878     RegCloseKey(propkey);
2879     RegCloseKey(localkey);
2880     RegCloseKey(prodkey);
2881
2882     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2883     lstrcatA(keypath, prod_squashed);
2884
2885     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2887
2888     /* classes product key exists */
2889     sz = MAX_PATH;
2890     lstrcpyA(buf, "apple");
2891     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2892     ok(r == ERROR_UNKNOWN_PROPERTY,
2893        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2894     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2895     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2896
2897     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2898     lstrcatA(keypath, usersid);
2899     lstrcatA(keypath, "\\Products\\");
2900     lstrcatA(keypath, prod_squashed);
2901
2902     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2903     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2904
2905     /* local user product key exists */
2906     sz = MAX_PATH;
2907     lstrcpyA(buf, "apple");
2908     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2909     ok(r == ERROR_UNKNOWN_PROPERTY,
2910        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2911     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2912     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2913
2914     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2915     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2916
2917     /* InstallProperties key exists */
2918     sz = MAX_PATH;
2919     lstrcpyA(buf, "apple");
2920     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2921     ok(r == ERROR_UNKNOWN_PROPERTY,
2922        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2923     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2924     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2925
2926     RegDeleteKeyA(propkey, "");
2927     RegDeleteKeyA(localkey, "");
2928     RegCloseKey(propkey);
2929     RegCloseKey(localkey);
2930
2931     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2932     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
2933     lstrcatA(keypath, prod_squashed);
2934
2935     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2936     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2937
2938     /* Local System product key exists */
2939     sz = MAX_PATH;
2940     lstrcpyA(buf, "apple");
2941     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2942     ok(r == ERROR_UNKNOWN_PROPERTY,
2943         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2944     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2945     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2946
2947     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2948     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2949
2950     /* InstallProperties key exists */
2951     sz = MAX_PATH;
2952     lstrcpyA(buf, "apple");
2953     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2954     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2955     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2956     ok(sz == 0, "Expected 0, got %d\n", sz);
2957
2958     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2959     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2960
2961     /* HelpLink value exists */
2962     sz = MAX_PATH;
2963     lstrcpyA(buf, "apple");
2964     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2965     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2966     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2967     ok(sz == 4, "Expected 4, got %d\n", sz);
2968
2969     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
2970                          (const BYTE *)&val, sizeof(DWORD));
2971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2972
2973     /* HelpLink type is REG_DWORD */
2974     sz = MAX_PATH;
2975     lstrcpyA(buf, "apple");
2976     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2978     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2979     ok(sz == 2, "Expected 2, got %d\n", sz);
2980
2981     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
2982     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2983
2984     /* DisplayName value exists */
2985     sz = MAX_PATH;
2986     lstrcpyA(buf, "apple");
2987     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2988     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2989     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
2990     ok(sz == 4, "Expected 4, got %d\n", sz);
2991
2992     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
2993                          (const BYTE *)&val, sizeof(DWORD));
2994     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2995
2996     /* DisplayName type is REG_DWORD */
2997     sz = MAX_PATH;
2998     lstrcpyA(buf, "apple");
2999     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3000     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3001     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3002     ok(sz == 2, "Expected 2, got %d\n", sz);
3003
3004     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3006
3007     /* DisplayVersion value exists */
3008     sz = MAX_PATH;
3009     lstrcpyA(buf, "apple");
3010     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3012     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3013     ok(sz == 5, "Expected 5, got %d\n", sz);
3014
3015     res = RegSetValueExA(propkey, "DisplayVersion", 0,
3016                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3017     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3018
3019     /* DisplayVersion type is REG_DWORD */
3020     sz = MAX_PATH;
3021     lstrcpyA(buf, "apple");
3022     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3023     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3024     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3025     ok(sz == 2, "Expected 2, got %d\n", sz);
3026
3027     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3028     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3029
3030     /* HelpTelephone value exists */
3031     sz = MAX_PATH;
3032     lstrcpyA(buf, "apple");
3033     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3034     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3035     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3036     ok(sz == 4, "Expected 4, got %d\n", sz);
3037
3038     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3039                          (const BYTE *)&val, sizeof(DWORD));
3040     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3041
3042     /* HelpTelephone type is REG_DWORD */
3043     sz = MAX_PATH;
3044     lstrcpyA(buf, "apple");
3045     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3046     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3047     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3048     ok(sz == 2, "Expected 2, got %d\n", sz);
3049
3050     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3051     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3052
3053     /* InstallLocation value exists */
3054     sz = MAX_PATH;
3055     lstrcpyA(buf, "apple");
3056     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3057     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3058     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3059     ok(sz == 3, "Expected 3, got %d\n", sz);
3060
3061     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3062                          (const BYTE *)&val, sizeof(DWORD));
3063     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3064
3065     /* InstallLocation type is REG_DWORD */
3066     sz = MAX_PATH;
3067     lstrcpyA(buf, "apple");
3068     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3069     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3070     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3071     ok(sz == 2, "Expected 2, got %d\n", sz);
3072
3073     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3074     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3075
3076     /* InstallSource value exists */
3077     sz = MAX_PATH;
3078     lstrcpyA(buf, "apple");
3079     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3080     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3081     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3082     ok(sz == 6, "Expected 6, got %d\n", sz);
3083
3084     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3085                          (const BYTE *)&val, sizeof(DWORD));
3086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3087
3088     /* InstallSource type is REG_DWORD */
3089     sz = MAX_PATH;
3090     lstrcpyA(buf, "apple");
3091     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3092     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3093     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3094     ok(sz == 2, "Expected 2, got %d\n", sz);
3095
3096     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3097     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3098
3099     /* InstallDate value exists */
3100     sz = MAX_PATH;
3101     lstrcpyA(buf, "apple");
3102     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3103     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3104     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3105     ok(sz == 4, "Expected 4, got %d\n", sz);
3106
3107     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3108                          (const BYTE *)&val, sizeof(DWORD));
3109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3110
3111     /* InstallDate type is REG_DWORD */
3112     sz = MAX_PATH;
3113     lstrcpyA(buf, "apple");
3114     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3115     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3116     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3117     ok(sz == 2, "Expected 2, got %d\n", sz);
3118
3119     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3120     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3121
3122     /* Publisher value exists */
3123     sz = MAX_PATH;
3124     lstrcpyA(buf, "apple");
3125     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3126     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3127     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3128     ok(sz == 3, "Expected 3, got %d\n", sz);
3129
3130     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3131                          (const BYTE *)&val, sizeof(DWORD));
3132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3133
3134     /* Publisher type is REG_DWORD */
3135     sz = MAX_PATH;
3136     lstrcpyA(buf, "apple");
3137     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3138     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3139     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3140     ok(sz == 2, "Expected 2, got %d\n", sz);
3141
3142     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3143     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3144
3145     /* LocalPackage value exists */
3146     sz = MAX_PATH;
3147     lstrcpyA(buf, "apple");
3148     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3149     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3150     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3151     ok(sz == 4, "Expected 4, got %d\n", sz);
3152
3153     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3154                          (const BYTE *)&val, sizeof(DWORD));
3155     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3156
3157     /* LocalPackage type is REG_DWORD */
3158     sz = MAX_PATH;
3159     lstrcpyA(buf, "apple");
3160     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3161     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3162     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3163     ok(sz == 2, "Expected 2, got %d\n", sz);
3164
3165     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3166     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3167
3168     /* UrlInfoAbout value exists */
3169     sz = MAX_PATH;
3170     lstrcpyA(buf, "apple");
3171     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3172     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3173     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3174     ok(sz == 5, "Expected 5, got %d\n", sz);
3175
3176     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3177                          (const BYTE *)&val, sizeof(DWORD));
3178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3179
3180     /* UrlInfoAbout type is REG_DWORD */
3181     sz = MAX_PATH;
3182     lstrcpyA(buf, "apple");
3183     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3184     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3185     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3186     ok(sz == 2, "Expected 2, got %d\n", sz);
3187
3188     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3190
3191     /* UrlUpdateInfo value exists */
3192     sz = MAX_PATH;
3193     lstrcpyA(buf, "apple");
3194     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3195     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3196     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3197     ok(sz == 4, "Expected 4, got %d\n", sz);
3198
3199     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3200                          (const BYTE *)&val, sizeof(DWORD));
3201     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3202
3203     /* UrlUpdateInfo type is REG_DWORD */
3204     sz = MAX_PATH;
3205     lstrcpyA(buf, "apple");
3206     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3207     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3208     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3209     ok(sz == 2, "Expected 2, got %d\n", sz);
3210
3211     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3212     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3213
3214     /* VersionMinor value exists */
3215     sz = MAX_PATH;
3216     lstrcpyA(buf, "apple");
3217     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3218     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3219     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3220     ok(sz == 1, "Expected 1, got %d\n", sz);
3221
3222     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3223                          (const BYTE *)&val, sizeof(DWORD));
3224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3225
3226     /* VersionMinor type is REG_DWORD */
3227     sz = MAX_PATH;
3228     lstrcpyA(buf, "apple");
3229     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3230     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3231     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3232     ok(sz == 2, "Expected 2, got %d\n", sz);
3233
3234     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3235     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3236
3237     /* VersionMajor value exists */
3238     sz = MAX_PATH;
3239     lstrcpyA(buf, "apple");
3240     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3241     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3242     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3243     ok(sz == 1, "Expected 1, got %d\n", sz);
3244
3245     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3246                          (const BYTE *)&val, sizeof(DWORD));
3247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3248
3249     /* VersionMajor type is REG_DWORD */
3250     sz = MAX_PATH;
3251     lstrcpyA(buf, "apple");
3252     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3253     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3254     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3255     ok(sz == 2, "Expected 2, got %d\n", sz);
3256
3257     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3258     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3259
3260     /* ProductID value exists */
3261     sz = MAX_PATH;
3262     lstrcpyA(buf, "apple");
3263     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3264     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3265     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3266     ok(sz == 2, "Expected 2, got %d\n", sz);
3267
3268     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3269                          (const BYTE *)&val, sizeof(DWORD));
3270     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3271
3272     /* ProductID type is REG_DWORD */
3273     sz = MAX_PATH;
3274     lstrcpyA(buf, "apple");
3275     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3276     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3277     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3278     ok(sz == 2, "Expected 2, got %d\n", sz);
3279
3280     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3281     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3282
3283     /* RegCompany value exists */
3284     sz = MAX_PATH;
3285     lstrcpyA(buf, "apple");
3286     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3287     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3288     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3289     ok(sz == 4, "Expected 4, got %d\n", sz);
3290
3291     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3292                          (const BYTE *)&val, sizeof(DWORD));
3293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3294
3295     /* RegCompany type is REG_DWORD */
3296     sz = MAX_PATH;
3297     lstrcpyA(buf, "apple");
3298     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3299     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3300     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3301     ok(sz == 2, "Expected 2, got %d\n", sz);
3302
3303     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3305
3306     /* RegOwner value exists */
3307     sz = MAX_PATH;
3308     lstrcpyA(buf, "apple");
3309     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3310     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3311     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3312     ok(sz == 3, "Expected 3, got %d\n", sz);
3313
3314     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3315                          (const BYTE *)&val, sizeof(DWORD));
3316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3317
3318     /* RegOwner type is REG_DWORD */
3319     sz = MAX_PATH;
3320     lstrcpyA(buf, "apple");
3321     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3322     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3323     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3324     ok(sz == 2, "Expected 2, got %d\n", sz);
3325
3326     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3327     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3328
3329     /* InstanceType value exists */
3330     sz = MAX_PATH;
3331     lstrcpyA(buf, "apple");
3332     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3333     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3334     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3335     ok(sz == 0, "Expected 0, got %d\n", sz);
3336
3337     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3338                          (const BYTE *)&val, sizeof(DWORD));
3339     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3340
3341     /* InstanceType type is REG_DWORD */
3342     sz = MAX_PATH;
3343     lstrcpyA(buf, "apple");
3344     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3345     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3346     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3347     ok(sz == 0, "Expected 0, got %d\n", sz);
3348
3349     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3351
3352     /* InstanceType value exists */
3353     sz = MAX_PATH;
3354     lstrcpyA(buf, "apple");
3355     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3357     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3358     ok(sz == 4, "Expected 4, got %d\n", sz);
3359
3360     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3361                          (const BYTE *)&val, sizeof(DWORD));
3362     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3363
3364     /* InstanceType type is REG_DWORD */
3365     sz = MAX_PATH;
3366     lstrcpyA(buf, "apple");
3367     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3368     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3369     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3370     ok(sz == 2, "Expected 2, got %d\n", sz);
3371
3372     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3373     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3374
3375     /* Transforms value exists */
3376     sz = MAX_PATH;
3377     lstrcpyA(buf, "apple");
3378     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3379     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3380     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3381     ok(sz == 0, "Expected 0, got %d\n", sz);
3382
3383     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3384                          (const BYTE *)&val, sizeof(DWORD));
3385     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3386
3387     /* Transforms type is REG_DWORD */
3388     sz = MAX_PATH;
3389     lstrcpyA(buf, "apple");
3390     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3391     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3392     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3393     ok(sz == 0, "Expected 0, got %d\n", sz);
3394
3395     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3396     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3397
3398     /* Transforms value exists */
3399     sz = MAX_PATH;
3400     lstrcpyA(buf, "apple");
3401     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3402     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3403     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3404     ok(sz == 6, "Expected 6, got %d\n", sz);
3405
3406     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3407                          (const BYTE *)&val, sizeof(DWORD));
3408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3409
3410     /* Transforms type is REG_DWORD */
3411     sz = MAX_PATH;
3412     lstrcpyA(buf, "apple");
3413     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3414     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3415     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3416     ok(sz == 2, "Expected 2, got %d\n", sz);
3417
3418     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3419     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3420
3421     /* Language value exists */
3422     sz = MAX_PATH;
3423     lstrcpyA(buf, "apple");
3424     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3425     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3426     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3427     ok(sz == 0, "Expected 0, got %d\n", sz);
3428
3429     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3430                          (const BYTE *)&val, sizeof(DWORD));
3431     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3432
3433     /* Language type is REG_DWORD */
3434     sz = MAX_PATH;
3435     lstrcpyA(buf, "apple");
3436     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3437     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3438     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3439     ok(sz == 0, "Expected 0, got %d\n", sz);
3440
3441     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3442     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3443
3444     /* Language value exists */
3445     sz = MAX_PATH;
3446     lstrcpyA(buf, "apple");
3447     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3448     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3449     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3450     ok(sz == 4, "Expected 4, got %d\n", sz);
3451
3452     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3453                          (const BYTE *)&val, sizeof(DWORD));
3454     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3455
3456     /* Language type is REG_DWORD */
3457     sz = MAX_PATH;
3458     lstrcpyA(buf, "apple");
3459     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3460     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3461     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3462     ok(sz == 2, "Expected 2, got %d\n", sz);
3463
3464     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3465     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3466
3467     /* ProductName value exists */
3468     sz = MAX_PATH;
3469     lstrcpyA(buf, "apple");
3470     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3471     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3472     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3473     ok(sz == 0, "Expected 0, got %d\n", sz);
3474
3475     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3476                          (const BYTE *)&val, sizeof(DWORD));
3477     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3478
3479     /* ProductName type is REG_DWORD */
3480     sz = MAX_PATH;
3481     lstrcpyA(buf, "apple");
3482     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3483     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3484     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3485     ok(sz == 0, "Expected 0, got %d\n", sz);
3486
3487     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3488     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3489
3490     /* ProductName value exists */
3491     sz = MAX_PATH;
3492     lstrcpyA(buf, "apple");
3493     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3494     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3495     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3496     ok(sz == 4, "Expected 4, got %d\n", sz);
3497
3498     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3499                          (const BYTE *)&val, sizeof(DWORD));
3500     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3501
3502     /* ProductName type is REG_DWORD */
3503     sz = MAX_PATH;
3504     lstrcpyA(buf, "apple");
3505     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3506     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3507     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3508     ok(sz == 2, "Expected 2, got %d\n", sz);
3509
3510     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3511     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3512
3513     /* Assignment value exists */
3514     sz = MAX_PATH;
3515     lstrcpyA(buf, "apple");
3516     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3517     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3518     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3519     ok(sz == 0, "Expected 0, got %d\n", sz);
3520
3521     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3522                          (const BYTE *)&val, sizeof(DWORD));
3523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3524
3525     /* Assignment type is REG_DWORD */
3526     sz = MAX_PATH;
3527     lstrcpyA(buf, "apple");
3528     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3529     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3530     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3531     ok(sz == 0, "Expected 0, got %d\n", sz);
3532
3533     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3534     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3535
3536     /* Assignment value exists */
3537     sz = MAX_PATH;
3538     lstrcpyA(buf, "apple");
3539     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3540     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3541     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3542     ok(sz == 2, "Expected 2, got %d\n", sz);
3543
3544     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3545                          (const BYTE *)&val, sizeof(DWORD));
3546     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3547
3548     /* Assignment type is REG_DWORD */
3549     sz = MAX_PATH;
3550     lstrcpyA(buf, "apple");
3551     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3552     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3553     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3554     ok(sz == 2, "Expected 2, got %d\n", sz);
3555
3556     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3557     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3558
3559     /* PackageCode value exists */
3560     sz = MAX_PATH;
3561     lstrcpyA(buf, "apple");
3562     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3563     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3564     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3565     ok(sz == 0, "Expected 0, got %d\n", sz);
3566
3567     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3568                          (const BYTE *)&val, sizeof(DWORD));
3569     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3570
3571     /* PackageCode type is REG_DWORD */
3572     sz = MAX_PATH;
3573     lstrcpyA(buf, "apple");
3574     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3575     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3576     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3577     ok(sz == 0, "Expected 0, got %d\n", sz);
3578
3579     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3580     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3581
3582     /* PackageCode value exists */
3583     sz = MAX_PATH;
3584     lstrcpyA(buf, "apple");
3585     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3586     ok(r == ERROR_BAD_CONFIGURATION,
3587        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3588     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3589     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3590
3591     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3592                          (const BYTE *)&val, sizeof(DWORD));
3593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3594
3595     /* PackageCode type is REG_DWORD */
3596     sz = MAX_PATH;
3597     lstrcpyA(buf, "apple");
3598     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3599     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3600     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3601     ok(sz == 2, "Expected 2, got %d\n", sz);
3602
3603     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3605
3606     /* PackageCode value exists */
3607     sz = MAX_PATH;
3608     lstrcpyA(buf, "apple");
3609     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3610     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3611     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3612     ok(sz == 38, "Expected 38, got %d\n", sz);
3613
3614     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3615     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3616
3617     /* Version value exists */
3618     sz = MAX_PATH;
3619     lstrcpyA(buf, "apple");
3620     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3621     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3622     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3623     ok(sz == 0, "Expected 0, got %d\n", sz);
3624
3625     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3626                          (const BYTE *)&val, sizeof(DWORD));
3627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3628
3629     /* Version type is REG_DWORD */
3630     sz = MAX_PATH;
3631     lstrcpyA(buf, "apple");
3632     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3633     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3634     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3635     ok(sz == 0, "Expected 0, got %d\n", sz);
3636
3637     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3639
3640     /* Version value exists */
3641     sz = MAX_PATH;
3642     lstrcpyA(buf, "apple");
3643     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3644     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3645     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3646     ok(sz == 3, "Expected 3, got %d\n", sz);
3647
3648     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3649                          (const BYTE *)&val, sizeof(DWORD));
3650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3651
3652     /* Version type is REG_DWORD */
3653     sz = MAX_PATH;
3654     lstrcpyA(buf, "apple");
3655     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3656     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3657     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3658     ok(sz == 2, "Expected 2, got %d\n", sz);
3659
3660     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3661     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3662
3663     /* ProductIcon value exists */
3664     sz = MAX_PATH;
3665     lstrcpyA(buf, "apple");
3666     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3667     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3668     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3669     ok(sz == 0, "Expected 0, got %d\n", sz);
3670
3671     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3672                          (const BYTE *)&val, sizeof(DWORD));
3673     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3674
3675     /* ProductIcon type is REG_DWORD */
3676     sz = MAX_PATH;
3677     lstrcpyA(buf, "apple");
3678     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3679     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3680     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3681     ok(sz == 0, "Expected 0, got %d\n", sz);
3682
3683     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3685
3686     /* ProductIcon value exists */
3687     sz = MAX_PATH;
3688     lstrcpyA(buf, "apple");
3689     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3690     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3691     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3692     ok(sz == 3, "Expected 3, got %d\n", sz);
3693
3694     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3695                          (const BYTE *)&val, sizeof(DWORD));
3696     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3697
3698     /* ProductIcon type is REG_DWORD */
3699     sz = MAX_PATH;
3700     lstrcpyA(buf, "apple");
3701     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3702     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3703     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3704     ok(sz == 2, "Expected 2, got %d\n", sz);
3705
3706     /* SourceList key does not exist */
3707     sz = MAX_PATH;
3708     lstrcpyA(buf, "apple");
3709     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3710     ok(r == ERROR_UNKNOWN_PRODUCT,
3711        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3712     ok(!lstrcmpA(buf, "apple"),
3713        "Expected buf to be unchanged, got \"%s\"\n", buf);
3714     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
3715
3716     res = RegCreateKeyA(prodkey, "SourceList", &source);
3717     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3718
3719     /* SourceList key exists, but PackageName val does not exist */
3720     sz = MAX_PATH;
3721     lstrcpyA(buf, "apple");
3722     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3723     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3724     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3725     ok(sz == 0, "Expected 0, got %d\n", sz);
3726
3727     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3729
3730     /* PackageName val exists */
3731     sz = MAX_PATH;
3732     lstrcpyA(buf, "apple");
3733     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3734     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3735     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
3736     ok(sz == 8, "Expected 8, got %d\n", sz);
3737
3738     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
3739                          (const BYTE *)&val, sizeof(DWORD));
3740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3741
3742     /* PackageName type is REG_DWORD */
3743     sz = MAX_PATH;
3744     lstrcpyA(buf, "apple");
3745     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3746     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3747     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3748     ok(sz == 2, "Expected 2, got %d\n", sz);
3749
3750     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3752
3753     /* Authorized value exists */
3754     sz = MAX_PATH;
3755     lstrcpyA(buf, "apple");
3756     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3757     if (r != ERROR_UNKNOWN_PROPERTY)
3758     {
3759         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3760         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3761         ok(sz == 0, "Expected 0, got %d\n", sz);
3762     }
3763
3764     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
3765                          (const BYTE *)&val, sizeof(DWORD));
3766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3767
3768     /* AuthorizedLUAApp type is REG_DWORD */
3769     sz = MAX_PATH;
3770     lstrcpyA(buf, "apple");
3771     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3772     if (r != ERROR_UNKNOWN_PROPERTY)
3773     {
3774         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3775         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3776         ok(sz == 0, "Expected 0, got %d\n", sz);
3777     }
3778
3779     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3780     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3781
3782     /* Authorized value exists */
3783     sz = MAX_PATH;
3784     lstrcpyA(buf, "apple");
3785     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3786     if (r != ERROR_UNKNOWN_PROPERTY)
3787     {
3788         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3789         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
3790         ok(sz == 4, "Expected 4, got %d\n", sz);
3791     }
3792
3793     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
3794                          (const BYTE *)&val, sizeof(DWORD));
3795     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3796
3797     /* AuthorizedLUAApp type is REG_DWORD */
3798     sz = MAX_PATH;
3799     lstrcpyA(buf, "apple");
3800     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3801     if (r != ERROR_UNKNOWN_PROPERTY)
3802     {
3803         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3804         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3805         ok(sz == 2, "Expected 2, got %d\n", sz);
3806     }
3807
3808     RegDeleteValueA(propkey, "HelpLink");
3809     RegDeleteValueA(propkey, "DisplayName");
3810     RegDeleteValueA(propkey, "DisplayVersion");
3811     RegDeleteValueA(propkey, "HelpTelephone");
3812     RegDeleteValueA(propkey, "InstallLocation");
3813     RegDeleteValueA(propkey, "InstallSource");
3814     RegDeleteValueA(propkey, "InstallDate");
3815     RegDeleteValueA(propkey, "Publisher");
3816     RegDeleteValueA(propkey, "LocalPackage");
3817     RegDeleteValueA(propkey, "UrlInfoAbout");
3818     RegDeleteValueA(propkey, "UrlUpdateInfo");
3819     RegDeleteValueA(propkey, "VersionMinor");
3820     RegDeleteValueA(propkey, "VersionMajor");
3821     RegDeleteValueA(propkey, "ProductID");
3822     RegDeleteValueA(propkey, "RegCompany");
3823     RegDeleteValueA(propkey, "RegOwner");
3824     RegDeleteValueA(propkey, "InstanceType");
3825     RegDeleteValueA(propkey, "Transforms");
3826     RegDeleteValueA(propkey, "Language");
3827     RegDeleteValueA(propkey, "ProductName");
3828     RegDeleteValueA(propkey, "Assignment");
3829     RegDeleteValueA(propkey, "PackageCode");
3830     RegDeleteValueA(propkey, "Version");
3831     RegDeleteValueA(propkey, "ProductIcon");
3832     RegDeleteValueA(propkey, "AuthorizedLUAApp");
3833     RegDeleteKeyA(propkey, "");
3834     RegDeleteKeyA(localkey, "");
3835     RegDeleteValueA(prodkey, "InstanceType");
3836     RegDeleteValueA(prodkey, "Transforms");
3837     RegDeleteValueA(prodkey, "Language");
3838     RegDeleteValueA(prodkey, "ProductName");
3839     RegDeleteValueA(prodkey, "Assignment");
3840     RegDeleteValueA(prodkey, "PackageCode");
3841     RegDeleteValueA(prodkey, "Version");
3842     RegDeleteValueA(prodkey, "ProductIcon");
3843     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
3844     RegDeleteValueA(source, "PackageName");
3845     RegDeleteKeyA(source, "");
3846     RegDeleteKeyA(prodkey, "");
3847     RegCloseKey(propkey);
3848     RegCloseKey(localkey);
3849     RegCloseKey(source);
3850     RegCloseKey(prodkey);
3851     LocalFree(usersid);
3852 }
3853
3854 static void test_MsiGetProductInfoEx(void)
3855 {
3856     UINT r;
3857     LONG res;
3858     HKEY propkey, userkey;
3859     HKEY prodkey, localkey;
3860     CHAR prodcode[MAX_PATH];
3861     CHAR prod_squashed[MAX_PATH];
3862     CHAR packcode[MAX_PATH];
3863     CHAR pack_squashed[MAX_PATH];
3864     CHAR buf[MAX_PATH];
3865     CHAR keypath[MAX_PATH];
3866     LPSTR usersid;
3867     DWORD sz;
3868
3869     if (!pMsiGetProductInfoExA)
3870     {
3871         win_skip("MsiGetProductInfoExA is not available\n");
3872         return;
3873     }
3874
3875     create_test_guid(prodcode, prod_squashed);
3876     create_test_guid(packcode, pack_squashed);
3877     get_user_sid(&usersid);
3878
3879     /* NULL szProductCode */
3880     sz = MAX_PATH;
3881     lstrcpyA(buf, "apple");
3882     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3883                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3884     ok(r == ERROR_INVALID_PARAMETER,
3885        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3886     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3887     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3888
3889     /* empty szProductCode */
3890     sz = MAX_PATH;
3891     lstrcpyA(buf, "apple");
3892     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3893                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3894     ok(r == ERROR_INVALID_PARAMETER,
3895        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3896     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3897     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3898
3899     /* garbage szProductCode */
3900     sz = MAX_PATH;
3901     lstrcpyA(buf, "apple");
3902     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3903                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3904     ok(r == ERROR_INVALID_PARAMETER,
3905        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3906     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3907     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3908
3909     /* guid without brackets */
3910     sz = MAX_PATH;
3911     lstrcpyA(buf, "apple");
3912     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
3913                               MSIINSTALLCONTEXT_USERUNMANAGED,
3914                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3915     ok(r == ERROR_INVALID_PARAMETER,
3916        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3917     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3918     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3919
3920     /* guid with brackets */
3921     sz = MAX_PATH;
3922     lstrcpyA(buf, "apple");
3923     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
3924                               MSIINSTALLCONTEXT_USERUNMANAGED,
3925                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3926     ok(r == ERROR_UNKNOWN_PRODUCT,
3927        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3928     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3929     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3930
3931     /* szValue is non-NULL while pcchValue is NULL */
3932     lstrcpyA(buf, "apple");
3933     r = pMsiGetProductInfoExA(prodcode, usersid,
3934                               MSIINSTALLCONTEXT_USERUNMANAGED,
3935                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
3936     ok(r == ERROR_INVALID_PARAMETER,
3937        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3938     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3939
3940     /* dwContext is out of range */
3941     sz = MAX_PATH;
3942     lstrcpyA(buf, "apple");
3943     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
3944                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3945     ok(r == ERROR_INVALID_PARAMETER,
3946        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3947     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3948     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3949
3950     /* szProperty is NULL */
3951     sz = MAX_PATH;
3952     lstrcpyA(buf, "apple");
3953     r = pMsiGetProductInfoExA(prodcode, usersid,
3954                               MSIINSTALLCONTEXT_USERUNMANAGED,
3955                               NULL, buf, &sz);
3956     ok(r == ERROR_INVALID_PARAMETER,
3957        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3958     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3959     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3960
3961     /* szProperty is empty */
3962     sz = MAX_PATH;
3963     lstrcpyA(buf, "apple");
3964     r = pMsiGetProductInfoExA(prodcode, usersid,
3965                               MSIINSTALLCONTEXT_USERUNMANAGED,
3966                               "", buf, &sz);
3967     ok(r == ERROR_INVALID_PARAMETER,
3968        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3969     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3970     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3971
3972     /* szProperty is not a valid property */
3973     sz = MAX_PATH;
3974     lstrcpyA(buf, "apple");
3975     r = pMsiGetProductInfoExA(prodcode, usersid,
3976                               MSIINSTALLCONTEXT_USERUNMANAGED,
3977                               "notvalid", buf, &sz);
3978     ok(r == ERROR_UNKNOWN_PRODUCT,
3979        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3980     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3981     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3982
3983     /* same length as guid, but random */
3984     sz = MAX_PATH;
3985     lstrcpyA(buf, "apple");
3986     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
3987                               MSIINSTALLCONTEXT_USERUNMANAGED,
3988                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3989     ok(r == ERROR_INVALID_PARAMETER,
3990        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3991     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3992     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3993
3994     /* MSIINSTALLCONTEXT_USERUNMANAGED */
3995
3996     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3997     lstrcatA(keypath, usersid);
3998     lstrcatA(keypath, "\\Products\\");
3999     lstrcatA(keypath, prod_squashed);
4000
4001     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4002     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4003
4004     /* local user product key exists */
4005     sz = MAX_PATH;
4006     lstrcpyA(buf, "apple");
4007     r = pMsiGetProductInfoExA(prodcode, usersid,
4008                               MSIINSTALLCONTEXT_USERUNMANAGED,
4009                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4010     ok(r == ERROR_UNKNOWN_PRODUCT,
4011        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4012     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4013     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4014
4015     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4016     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4017
4018     /* InstallProperties key exists */
4019     sz = MAX_PATH;
4020     lstrcpyA(buf, "apple");
4021     r = pMsiGetProductInfoExA(prodcode, usersid,
4022                               MSIINSTALLCONTEXT_USERUNMANAGED,
4023                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4024     ok(r == ERROR_UNKNOWN_PRODUCT,
4025        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4026     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4027     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4028
4029     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4030     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4031
4032     /* LocalPackage value exists */
4033     sz = MAX_PATH;
4034     lstrcpyA(buf, "apple");
4035     r = pMsiGetProductInfoExA(prodcode, usersid,
4036                               MSIINSTALLCONTEXT_USERUNMANAGED,
4037                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4038     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4039     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4040     ok(sz == 1, "Expected 1, got %d\n", sz);
4041
4042     RegDeleteValueA(propkey, "LocalPackage");
4043
4044     /* LocalPackage value must exist */
4045     sz = MAX_PATH;
4046     lstrcpyA(buf, "apple");
4047     r = pMsiGetProductInfoExA(prodcode, usersid,
4048                               MSIINSTALLCONTEXT_USERUNMANAGED,
4049                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4050     ok(r == ERROR_UNKNOWN_PRODUCT,
4051        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4052     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4053     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4054
4055     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4056     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4057
4058     /* LocalPackage exists, but HelpLink does not exist */
4059     sz = MAX_PATH;
4060     lstrcpyA(buf, "apple");
4061     r = pMsiGetProductInfoExA(prodcode, usersid,
4062                               MSIINSTALLCONTEXT_USERUNMANAGED,
4063                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4064     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4065     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4066     ok(sz == 0, "Expected 0, got %d\n", sz);
4067
4068     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4069     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4070
4071     /* HelpLink value exists */
4072     sz = MAX_PATH;
4073     lstrcpyA(buf, "apple");
4074     r = pMsiGetProductInfoExA(prodcode, usersid,
4075                               MSIINSTALLCONTEXT_USERUNMANAGED,
4076                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4077     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4078     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4079     ok(sz == 4, "Expected 4, got %d\n", sz);
4080
4081     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4083
4084     /* HelpTelephone value exists */
4085     sz = MAX_PATH;
4086     lstrcpyA(buf, "apple");
4087     r = pMsiGetProductInfoExA(prodcode, usersid,
4088                               MSIINSTALLCONTEXT_USERUNMANAGED,
4089                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4090     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4091     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4092     ok(sz == 5, "Expected 5, got %d\n", sz);
4093
4094     /* szValue and pcchValue are NULL */
4095     r = pMsiGetProductInfoExA(prodcode, usersid,
4096                               MSIINSTALLCONTEXT_USERUNMANAGED,
4097                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4098     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4099
4100     /* pcchValue is exactly 5 */
4101     sz = 5;
4102     lstrcpyA(buf, "apple");
4103     r = pMsiGetProductInfoExA(prodcode, usersid,
4104                               MSIINSTALLCONTEXT_USERUNMANAGED,
4105                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4106     ok(r == ERROR_MORE_DATA,
4107        "Expected ERROR_MORE_DATA, got %d\n", r);
4108     ok(sz == 10, "Expected 10, got %d\n", sz);
4109
4110     /* szValue is NULL, pcchValue is exactly 5 */
4111     sz = 5;
4112     r = pMsiGetProductInfoExA(prodcode, usersid,
4113                               MSIINSTALLCONTEXT_USERUNMANAGED,
4114                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4115     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4116     ok(sz == 10, "Expected 10, got %d\n", sz);
4117
4118     /* szValue is NULL, pcchValue is MAX_PATH */
4119     sz = MAX_PATH;
4120     r = pMsiGetProductInfoExA(prodcode, usersid,
4121                               MSIINSTALLCONTEXT_USERUNMANAGED,
4122                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4123     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4124     ok(sz == 10, "Expected 10, got %d\n", sz);
4125
4126     /* pcchValue is exactly 0 */
4127     sz = 0;
4128     lstrcpyA(buf, "apple");
4129     r = pMsiGetProductInfoExA(prodcode, usersid,
4130                               MSIINSTALLCONTEXT_USERUNMANAGED,
4131                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4132     ok(r == ERROR_MORE_DATA,
4133        "Expected ERROR_MORE_DATA, got %d\n", r);
4134     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4135     ok(sz == 10, "Expected 10, got %d\n", sz);
4136
4137     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4138     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4139
4140     /* szProperty is not a valid property */
4141     sz = MAX_PATH;
4142     lstrcpyA(buf, "apple");
4143     r = pMsiGetProductInfoExA(prodcode, usersid,
4144                               MSIINSTALLCONTEXT_USERUNMANAGED,
4145                               "notvalid", buf, &sz);
4146     ok(r == ERROR_UNKNOWN_PROPERTY,
4147        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4148     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4149     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4150
4151     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4152     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4153
4154     /* InstallDate value exists */
4155     sz = MAX_PATH;
4156     lstrcpyA(buf, "apple");
4157     r = pMsiGetProductInfoExA(prodcode, usersid,
4158                               MSIINSTALLCONTEXT_USERUNMANAGED,
4159                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4160     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4161     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4162     ok(sz == 4, "Expected 4, got %d\n", sz);
4163
4164     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4165     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4166
4167     /* DisplayName value exists */
4168     sz = MAX_PATH;
4169     lstrcpyA(buf, "apple");
4170     r = pMsiGetProductInfoExA(prodcode, usersid,
4171                               MSIINSTALLCONTEXT_USERUNMANAGED,
4172                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4173     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4174     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4175     ok(sz == 4, "Expected 4, got %d\n", sz);
4176
4177     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4179
4180     /* InstallLocation value exists */
4181     sz = MAX_PATH;
4182     lstrcpyA(buf, "apple");
4183     r = pMsiGetProductInfoExA(prodcode, usersid,
4184                               MSIINSTALLCONTEXT_USERUNMANAGED,
4185                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4186     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4187     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4188     ok(sz == 3, "Expected 3, got %d\n", sz);
4189
4190     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4191     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4192
4193     /* InstallSource value exists */
4194     sz = MAX_PATH;
4195     lstrcpyA(buf, "apple");
4196     r = pMsiGetProductInfoExA(prodcode, usersid,
4197                               MSIINSTALLCONTEXT_USERUNMANAGED,
4198                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4199     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4200     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4201     ok(sz == 6, "Expected 6, got %d\n", sz);
4202
4203     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4205
4206     /* LocalPackage value exists */
4207     sz = MAX_PATH;
4208     lstrcpyA(buf, "apple");
4209     r = pMsiGetProductInfoExA(prodcode, usersid,
4210                               MSIINSTALLCONTEXT_USERUNMANAGED,
4211                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4212     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4213     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4214     ok(sz == 5, "Expected 5, got %d\n", sz);
4215
4216     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4218
4219     /* Publisher value exists */
4220     sz = MAX_PATH;
4221     lstrcpyA(buf, "apple");
4222     r = pMsiGetProductInfoExA(prodcode, usersid,
4223                               MSIINSTALLCONTEXT_USERUNMANAGED,
4224                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4225     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4226     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4227     ok(sz == 3, "Expected 3, got %d\n", sz);
4228
4229     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4230     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4231
4232     /* URLInfoAbout value exists */
4233     sz = MAX_PATH;
4234     lstrcpyA(buf, "apple");
4235     r = pMsiGetProductInfoExA(prodcode, usersid,
4236                               MSIINSTALLCONTEXT_USERUNMANAGED,
4237                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4239     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4240     ok(sz == 5, "Expected 5, got %d\n", sz);
4241
4242     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4243     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4244
4245     /* URLUpdateInfo value exists */
4246     sz = MAX_PATH;
4247     lstrcpyA(buf, "apple");
4248     r = pMsiGetProductInfoExA(prodcode, usersid,
4249                               MSIINSTALLCONTEXT_USERUNMANAGED,
4250                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4252     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4253     ok(sz == 6, "Expected 6, got %d\n", sz);
4254
4255     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4257
4258     /* VersionMinor value exists */
4259     sz = MAX_PATH;
4260     lstrcpyA(buf, "apple");
4261     r = pMsiGetProductInfoExA(prodcode, usersid,
4262                               MSIINSTALLCONTEXT_USERUNMANAGED,
4263                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4264     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4265     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4266     ok(sz == 1, "Expected 1, got %d\n", sz);
4267
4268     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4269     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4270
4271     /* VersionMajor value exists */
4272     sz = MAX_PATH;
4273     lstrcpyA(buf, "apple");
4274     r = pMsiGetProductInfoExA(prodcode, usersid,
4275                               MSIINSTALLCONTEXT_USERUNMANAGED,
4276                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4278     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4279     ok(sz == 1, "Expected 1, got %d\n", sz);
4280
4281     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4283
4284     /* DisplayVersion value exists */
4285     sz = MAX_PATH;
4286     lstrcpyA(buf, "apple");
4287     r = pMsiGetProductInfoExA(prodcode, usersid,
4288                               MSIINSTALLCONTEXT_USERUNMANAGED,
4289                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4290     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4291     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4292     ok(sz == 5, "Expected 5, got %d\n", sz);
4293
4294     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4295     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4296
4297     /* ProductID value exists */
4298     sz = MAX_PATH;
4299     lstrcpyA(buf, "apple");
4300     r = pMsiGetProductInfoExA(prodcode, usersid,
4301                               MSIINSTALLCONTEXT_USERUNMANAGED,
4302                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4303     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4304     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4305     ok(sz == 2, "Expected 2, got %d\n", sz);
4306
4307     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4309
4310     /* RegCompany value exists */
4311     sz = MAX_PATH;
4312     lstrcpyA(buf, "apple");
4313     r = pMsiGetProductInfoExA(prodcode, usersid,
4314                               MSIINSTALLCONTEXT_USERUNMANAGED,
4315                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4316     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4317     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4318     ok(sz == 4, "Expected 4, got %d\n", sz);
4319
4320     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4321     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4322
4323     /* RegOwner value exists */
4324     sz = MAX_PATH;
4325     lstrcpyA(buf, "apple");
4326     r = pMsiGetProductInfoExA(prodcode, usersid,
4327                               MSIINSTALLCONTEXT_USERUNMANAGED,
4328                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4329     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4330     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4331     ok(sz == 5, "Expected 5, got %d\n", sz);
4332
4333     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4334     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4335
4336     /* Transforms value exists */
4337     sz = MAX_PATH;
4338     lstrcpyA(buf, "apple");
4339     r = pMsiGetProductInfoExA(prodcode, usersid,
4340                               MSIINSTALLCONTEXT_USERUNMANAGED,
4341                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4342     ok(r == ERROR_UNKNOWN_PRODUCT,
4343        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4344     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4345     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4346
4347     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4349
4350     /* Language value exists */
4351     sz = MAX_PATH;
4352     lstrcpyA(buf, "apple");
4353     r = pMsiGetProductInfoExA(prodcode, usersid,
4354                               MSIINSTALLCONTEXT_USERUNMANAGED,
4355                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4356     ok(r == ERROR_UNKNOWN_PRODUCT,
4357        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4358     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4359     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4360
4361     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4362     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4363
4364     /* ProductName value exists */
4365     sz = MAX_PATH;
4366     lstrcpyA(buf, "apple");
4367     r = pMsiGetProductInfoExA(prodcode, usersid,
4368                               MSIINSTALLCONTEXT_USERUNMANAGED,
4369                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4370     ok(r == ERROR_UNKNOWN_PRODUCT,
4371        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4372     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4373     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4374
4375     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4377
4378     /* FIXME */
4379
4380     /* AssignmentType value exists */
4381     sz = MAX_PATH;
4382     lstrcpyA(buf, "apple");
4383     r = pMsiGetProductInfoExA(prodcode, usersid,
4384                               MSIINSTALLCONTEXT_USERUNMANAGED,
4385                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4386     ok(r == ERROR_UNKNOWN_PRODUCT,
4387        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4388     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4389     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4390
4391     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4392     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4393
4394     /* PackageCode value exists */
4395     sz = MAX_PATH;
4396     lstrcpyA(buf, "apple");
4397     r = pMsiGetProductInfoExA(prodcode, usersid,
4398                               MSIINSTALLCONTEXT_USERUNMANAGED,
4399                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4400     ok(r == ERROR_UNKNOWN_PRODUCT,
4401        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4402     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4403     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4404
4405     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4406     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4407
4408     /* Version value exists */
4409     sz = MAX_PATH;
4410     lstrcpyA(buf, "apple");
4411     r = pMsiGetProductInfoExA(prodcode, usersid,
4412                               MSIINSTALLCONTEXT_USERUNMANAGED,
4413                               INSTALLPROPERTY_VERSION, buf, &sz);
4414     ok(r == ERROR_UNKNOWN_PRODUCT,
4415        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4416     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4417     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4418
4419     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4420     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4421
4422     /* ProductIcon value exists */
4423     sz = MAX_PATH;
4424     lstrcpyA(buf, "apple");
4425     r = pMsiGetProductInfoExA(prodcode, usersid,
4426                               MSIINSTALLCONTEXT_USERUNMANAGED,
4427                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4428     ok(r == ERROR_UNKNOWN_PRODUCT,
4429        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4430     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4431     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4432
4433     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4435
4436     /* PackageName value exists */
4437     sz = MAX_PATH;
4438     lstrcpyA(buf, "apple");
4439     r = pMsiGetProductInfoExA(prodcode, usersid,
4440                               MSIINSTALLCONTEXT_USERUNMANAGED,
4441                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4442     ok(r == ERROR_UNKNOWN_PRODUCT,
4443        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4444     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4445     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4446
4447     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4448     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4449
4450     /* AuthorizedLUAApp value exists */
4451     sz = MAX_PATH;
4452     lstrcpyA(buf, "apple");
4453     r = pMsiGetProductInfoExA(prodcode, usersid,
4454                               MSIINSTALLCONTEXT_USERUNMANAGED,
4455                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4456     ok(r == ERROR_UNKNOWN_PRODUCT,
4457        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4458     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4459     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4460
4461     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4462     RegDeleteValueA(propkey, "PackageName");
4463     RegDeleteValueA(propkey, "ProductIcon");
4464     RegDeleteValueA(propkey, "Version");
4465     RegDeleteValueA(propkey, "PackageCode");
4466     RegDeleteValueA(propkey, "AssignmentType");
4467     RegDeleteValueA(propkey, "ProductName");
4468     RegDeleteValueA(propkey, "Language");
4469     RegDeleteValueA(propkey, "Transforms");
4470     RegDeleteValueA(propkey, "RegOwner");
4471     RegDeleteValueA(propkey, "RegCompany");
4472     RegDeleteValueA(propkey, "ProductID");
4473     RegDeleteValueA(propkey, "DisplayVersion");
4474     RegDeleteValueA(propkey, "VersionMajor");
4475     RegDeleteValueA(propkey, "VersionMinor");
4476     RegDeleteValueA(propkey, "URLUpdateInfo");
4477     RegDeleteValueA(propkey, "URLInfoAbout");
4478     RegDeleteValueA(propkey, "Publisher");
4479     RegDeleteValueA(propkey, "LocalPackage");
4480     RegDeleteValueA(propkey, "InstallSource");
4481     RegDeleteValueA(propkey, "InstallLocation");
4482     RegDeleteValueA(propkey, "DisplayName");
4483     RegDeleteValueA(propkey, "InstallDate");
4484     RegDeleteValueA(propkey, "HelpTelephone");
4485     RegDeleteValueA(propkey, "HelpLink");
4486     RegDeleteValueA(propkey, "LocalPackage");
4487     RegDeleteKeyA(propkey, "");
4488     RegCloseKey(propkey);
4489     RegDeleteKeyA(localkey, "");
4490     RegCloseKey(localkey);
4491
4492     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4493     lstrcatA(keypath, usersid);
4494     lstrcatA(keypath, "\\Installer\\Products\\");
4495     lstrcatA(keypath, prod_squashed);
4496
4497     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
4498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4499
4500     /* user product key exists */
4501     sz = MAX_PATH;
4502     lstrcpyA(buf, "apple");
4503     r = pMsiGetProductInfoExA(prodcode, usersid,
4504                               MSIINSTALLCONTEXT_USERUNMANAGED,
4505                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4506     ok(r == ERROR_UNKNOWN_PRODUCT,
4507        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4508     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4509     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4510
4511     RegDeleteKeyA(userkey, "");
4512     RegCloseKey(userkey);
4513
4514     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4515     lstrcatA(keypath, prod_squashed);
4516
4517     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4518     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4519
4520     sz = MAX_PATH;
4521     lstrcpyA(buf, "apple");
4522     r = pMsiGetProductInfoExA(prodcode, usersid,
4523                               MSIINSTALLCONTEXT_USERUNMANAGED,
4524                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4525     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4526     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4527     ok(sz == 1, "Expected 1, got %d\n", sz);
4528
4529     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4530     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4531
4532     /* HelpLink value exists */
4533     sz = MAX_PATH;
4534     lstrcpyA(buf, "apple");
4535     r = pMsiGetProductInfoExA(prodcode, usersid,
4536                               MSIINSTALLCONTEXT_USERUNMANAGED,
4537                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4538     ok(r == ERROR_UNKNOWN_PROPERTY,
4539        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4540     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4541     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4542
4543     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4544     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4545
4546     /* HelpTelephone value exists */
4547     sz = MAX_PATH;
4548     lstrcpyA(buf, "apple");
4549     r = pMsiGetProductInfoExA(prodcode, usersid,
4550                               MSIINSTALLCONTEXT_USERUNMANAGED,
4551                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4552     ok(r == ERROR_UNKNOWN_PROPERTY,
4553        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4554     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4555     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4556
4557     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4558     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4559
4560     /* InstallDate value exists */
4561     sz = MAX_PATH;
4562     lstrcpyA(buf, "apple");
4563     r = pMsiGetProductInfoExA(prodcode, usersid,
4564                               MSIINSTALLCONTEXT_USERUNMANAGED,
4565                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4566     ok(r == ERROR_UNKNOWN_PROPERTY,
4567        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4568     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4569     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4570
4571     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4572     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4573
4574     /* DisplayName value exists */
4575     sz = MAX_PATH;
4576     lstrcpyA(buf, "apple");
4577     r = pMsiGetProductInfoExA(prodcode, usersid,
4578                               MSIINSTALLCONTEXT_USERUNMANAGED,
4579                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4580     ok(r == ERROR_UNKNOWN_PROPERTY,
4581        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4582     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4583     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4584
4585     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4586     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4587
4588     /* InstallLocation value exists */
4589     sz = MAX_PATH;
4590     lstrcpyA(buf, "apple");
4591     r = pMsiGetProductInfoExA(prodcode, usersid,
4592                               MSIINSTALLCONTEXT_USERUNMANAGED,
4593                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4594     ok(r == ERROR_UNKNOWN_PROPERTY,
4595        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4596     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4597     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4598
4599     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4600     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4601
4602     /* InstallSource value exists */
4603     sz = MAX_PATH;
4604     lstrcpyA(buf, "apple");
4605     r = pMsiGetProductInfoExA(prodcode, usersid,
4606                               MSIINSTALLCONTEXT_USERUNMANAGED,
4607                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4608     ok(r == ERROR_UNKNOWN_PROPERTY,
4609        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4610     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4611     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4612
4613     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4614     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4615
4616     /* LocalPackage value exists */
4617     sz = MAX_PATH;
4618     lstrcpyA(buf, "apple");
4619     r = pMsiGetProductInfoExA(prodcode, usersid,
4620                               MSIINSTALLCONTEXT_USERUNMANAGED,
4621                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4622     ok(r == ERROR_UNKNOWN_PROPERTY,
4623        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4624     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4625     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4626
4627     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4628     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4629
4630     /* Publisher value exists */
4631     sz = MAX_PATH;
4632     lstrcpyA(buf, "apple");
4633     r = pMsiGetProductInfoExA(prodcode, usersid,
4634                               MSIINSTALLCONTEXT_USERUNMANAGED,
4635                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4636     ok(r == ERROR_UNKNOWN_PROPERTY,
4637        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4638     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4639     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4640
4641     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4643
4644     /* URLInfoAbout value exists */
4645     sz = MAX_PATH;
4646     lstrcpyA(buf, "apple");
4647     r = pMsiGetProductInfoExA(prodcode, usersid,
4648                               MSIINSTALLCONTEXT_USERUNMANAGED,
4649                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4650     ok(r == ERROR_UNKNOWN_PROPERTY,
4651        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4652     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4653     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4654
4655     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4657
4658     /* URLUpdateInfo value exists */
4659     sz = MAX_PATH;
4660     lstrcpyA(buf, "apple");
4661     r = pMsiGetProductInfoExA(prodcode, usersid,
4662                               MSIINSTALLCONTEXT_USERUNMANAGED,
4663                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4664     ok(r == ERROR_UNKNOWN_PROPERTY,
4665        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4666     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4667     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4668
4669     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4670     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4671
4672     /* VersionMinor value exists */
4673     sz = MAX_PATH;
4674     lstrcpyA(buf, "apple");
4675     r = pMsiGetProductInfoExA(prodcode, usersid,
4676                               MSIINSTALLCONTEXT_USERUNMANAGED,
4677                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4678     ok(r == ERROR_UNKNOWN_PROPERTY,
4679        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4680     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4681     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4682
4683     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4685
4686     /* VersionMajor value exists */
4687     sz = MAX_PATH;
4688     lstrcpyA(buf, "apple");
4689     r = pMsiGetProductInfoExA(prodcode, usersid,
4690                               MSIINSTALLCONTEXT_USERUNMANAGED,
4691                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4692     ok(r == ERROR_UNKNOWN_PROPERTY,
4693        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4694     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4695     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4696
4697     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4698     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4699
4700     /* DisplayVersion value exists */
4701     sz = MAX_PATH;
4702     lstrcpyA(buf, "apple");
4703     r = pMsiGetProductInfoExA(prodcode, usersid,
4704                               MSIINSTALLCONTEXT_USERUNMANAGED,
4705                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4706     ok(r == ERROR_UNKNOWN_PROPERTY,
4707        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4708     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4709     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4710
4711     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4713
4714     /* ProductID value exists */
4715     sz = MAX_PATH;
4716     lstrcpyA(buf, "apple");
4717     r = pMsiGetProductInfoExA(prodcode, usersid,
4718                               MSIINSTALLCONTEXT_USERUNMANAGED,
4719                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4720     ok(r == ERROR_UNKNOWN_PROPERTY,
4721        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4722     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4723     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4724
4725     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4727
4728     /* RegCompany value exists */
4729     sz = MAX_PATH;
4730     lstrcpyA(buf, "apple");
4731     r = pMsiGetProductInfoExA(prodcode, usersid,
4732                               MSIINSTALLCONTEXT_USERUNMANAGED,
4733                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4734     ok(r == ERROR_UNKNOWN_PROPERTY,
4735        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4736     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4737     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4738
4739     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4741
4742     /* RegOwner value exists */
4743     sz = MAX_PATH;
4744     lstrcpyA(buf, "apple");
4745     r = pMsiGetProductInfoExA(prodcode, usersid,
4746                               MSIINSTALLCONTEXT_USERUNMANAGED,
4747                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4748     ok(r == ERROR_UNKNOWN_PROPERTY,
4749        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4750     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4751     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4752
4753     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4754     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4755
4756     /* Transforms value exists */
4757     sz = MAX_PATH;
4758     lstrcpyA(buf, "apple");
4759     r = pMsiGetProductInfoExA(prodcode, usersid,
4760                               MSIINSTALLCONTEXT_USERUNMANAGED,
4761                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4762     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4763     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
4764     ok(sz == 5, "Expected 5, got %d\n", sz);
4765
4766     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4767     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4768
4769     /* Language value exists */
4770     sz = MAX_PATH;
4771     lstrcpyA(buf, "apple");
4772     r = pMsiGetProductInfoExA(prodcode, usersid,
4773                               MSIINSTALLCONTEXT_USERUNMANAGED,
4774                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4775     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4776     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4777     ok(sz == 4, "Expected 4, got %d\n", sz);
4778
4779     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4780     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4781
4782     /* ProductName value exists */
4783     sz = MAX_PATH;
4784     lstrcpyA(buf, "apple");
4785     r = pMsiGetProductInfoExA(prodcode, usersid,
4786                               MSIINSTALLCONTEXT_USERUNMANAGED,
4787                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4788     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4789     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4790     ok(sz == 4, "Expected 4, got %d\n", sz);
4791
4792     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4793     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4794
4795     /* FIXME */
4796
4797     /* AssignmentType value exists */
4798     sz = MAX_PATH;
4799     lstrcpyA(buf, "apple");
4800     r = pMsiGetProductInfoExA(prodcode, usersid,
4801                               MSIINSTALLCONTEXT_USERUNMANAGED,
4802                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4803     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4804     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4805     ok(sz == 0, "Expected 0, got %d\n", sz);
4806
4807     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4808     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4809
4810     /* FIXME */
4811
4812     /* PackageCode value exists */
4813     sz = MAX_PATH;
4814     lstrcpyA(buf, "apple");
4815     r = pMsiGetProductInfoExA(prodcode, usersid,
4816                               MSIINSTALLCONTEXT_USERUNMANAGED,
4817                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4818     todo_wine
4819     {
4820         ok(r == ERROR_BAD_CONFIGURATION,
4821            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4822         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4823         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4824     }
4825
4826     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4827     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4828
4829     /* Version value exists */
4830     sz = MAX_PATH;
4831     lstrcpyA(buf, "apple");
4832     r = pMsiGetProductInfoExA(prodcode, usersid,
4833                               MSIINSTALLCONTEXT_USERUNMANAGED,
4834                               INSTALLPROPERTY_VERSION, buf, &sz);
4835     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4836     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4837     ok(sz == 3, "Expected 3, got %d\n", sz);
4838
4839     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4840     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4841
4842     /* ProductIcon value exists */
4843     sz = MAX_PATH;
4844     lstrcpyA(buf, "apple");
4845     r = pMsiGetProductInfoExA(prodcode, usersid,
4846                               MSIINSTALLCONTEXT_USERUNMANAGED,
4847                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4848     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4849     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
4850     ok(sz == 4, "Expected 4, got %d\n", sz);
4851
4852     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4854
4855     /* PackageName value exists */
4856     sz = MAX_PATH;
4857     lstrcpyA(buf, "apple");
4858     r = pMsiGetProductInfoExA(prodcode, usersid,
4859                               MSIINSTALLCONTEXT_USERUNMANAGED,
4860                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4861     todo_wine
4862     {
4863         ok(r == ERROR_UNKNOWN_PRODUCT,
4864            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4865         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4866         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4867     }
4868
4869     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4870     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4871
4872     /* AuthorizedLUAApp value exists */
4873     sz = MAX_PATH;
4874     lstrcpyA(buf, "apple");
4875     r = pMsiGetProductInfoExA(prodcode, usersid,
4876                               MSIINSTALLCONTEXT_USERUNMANAGED,
4877                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4878     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4879     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4880     ok(sz == 4, "Expected 4, got %d\n", sz);
4881
4882     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4883     RegDeleteValueA(prodkey, "PackageName");
4884     RegDeleteValueA(prodkey, "ProductIcon");
4885     RegDeleteValueA(prodkey, "Version");
4886     RegDeleteValueA(prodkey, "PackageCode");
4887     RegDeleteValueA(prodkey, "AssignmentType");
4888     RegDeleteValueA(prodkey, "ProductName");
4889     RegDeleteValueA(prodkey, "Language");
4890     RegDeleteValueA(prodkey, "Transforms");
4891     RegDeleteValueA(prodkey, "RegOwner");
4892     RegDeleteValueA(prodkey, "RegCompany");
4893     RegDeleteValueA(prodkey, "ProductID");
4894     RegDeleteValueA(prodkey, "DisplayVersion");
4895     RegDeleteValueA(prodkey, "VersionMajor");
4896     RegDeleteValueA(prodkey, "VersionMinor");
4897     RegDeleteValueA(prodkey, "URLUpdateInfo");
4898     RegDeleteValueA(prodkey, "URLInfoAbout");
4899     RegDeleteValueA(prodkey, "Publisher");
4900     RegDeleteValueA(prodkey, "LocalPackage");
4901     RegDeleteValueA(prodkey, "InstallSource");
4902     RegDeleteValueA(prodkey, "InstallLocation");
4903     RegDeleteValueA(prodkey, "DisplayName");
4904     RegDeleteValueA(prodkey, "InstallDate");
4905     RegDeleteValueA(prodkey, "HelpTelephone");
4906     RegDeleteValueA(prodkey, "HelpLink");
4907     RegDeleteValueA(prodkey, "LocalPackage");
4908     RegDeleteKeyA(prodkey, "");
4909     RegCloseKey(prodkey);
4910
4911     /* MSIINSTALLCONTEXT_USERMANAGED */
4912
4913     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4914     lstrcatA(keypath, usersid);
4915     lstrcatA(keypath, "\\Products\\");
4916     lstrcatA(keypath, prod_squashed);
4917
4918     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4919     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4920
4921     /* local user product key exists */
4922     sz = MAX_PATH;
4923     lstrcpyA(buf, "apple");
4924     r = pMsiGetProductInfoExA(prodcode, usersid,
4925                               MSIINSTALLCONTEXT_USERMANAGED,
4926                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4927     ok(r == ERROR_UNKNOWN_PRODUCT,
4928        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4929     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4930     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4931
4932     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4933     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4934
4935     /* InstallProperties key exists */
4936     sz = MAX_PATH;
4937     lstrcpyA(buf, "apple");
4938     r = pMsiGetProductInfoExA(prodcode, usersid,
4939                               MSIINSTALLCONTEXT_USERMANAGED,
4940                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4941     ok(r == ERROR_UNKNOWN_PRODUCT,
4942        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4943     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4944     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4945
4946     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4947     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4948
4949     /* ManagedLocalPackage value exists */
4950     sz = MAX_PATH;
4951     lstrcpyA(buf, "apple");
4952     r = pMsiGetProductInfoExA(prodcode, usersid,
4953                               MSIINSTALLCONTEXT_USERMANAGED,
4954                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4955     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4956     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4957     ok(sz == 1, "Expected 1, got %d\n", sz);
4958
4959     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4960     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4961
4962     /* HelpLink value exists */
4963     sz = MAX_PATH;
4964     lstrcpyA(buf, "apple");
4965     r = pMsiGetProductInfoExA(prodcode, usersid,
4966                               MSIINSTALLCONTEXT_USERMANAGED,
4967                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4968     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4969     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4970     ok(sz == 4, "Expected 4, got %d\n", sz);
4971
4972     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4973     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4974
4975     /* HelpTelephone value exists */
4976     sz = MAX_PATH;
4977     lstrcpyA(buf, "apple");
4978     r = pMsiGetProductInfoExA(prodcode, usersid,
4979                               MSIINSTALLCONTEXT_USERMANAGED,
4980                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4981     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4982     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4983     ok(sz == 5, "Expected 5, got %d\n", sz);
4984
4985     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4987
4988     /* InstallDate value exists */
4989     sz = MAX_PATH;
4990     lstrcpyA(buf, "apple");
4991     r = pMsiGetProductInfoExA(prodcode, usersid,
4992                               MSIINSTALLCONTEXT_USERMANAGED,
4993                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4994     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4995     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4996     ok(sz == 4, "Expected 4, got %d\n", sz);
4997
4998     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4999     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5000
5001     /* DisplayName value exists */
5002     sz = MAX_PATH;
5003     lstrcpyA(buf, "apple");
5004     r = pMsiGetProductInfoExA(prodcode, usersid,
5005                               MSIINSTALLCONTEXT_USERMANAGED,
5006                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5007     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5008     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5009     ok(sz == 4, "Expected 4, got %d\n", sz);
5010
5011     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5012     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5013
5014     /* InstallLocation value exists */
5015     sz = MAX_PATH;
5016     lstrcpyA(buf, "apple");
5017     r = pMsiGetProductInfoExA(prodcode, usersid,
5018                               MSIINSTALLCONTEXT_USERMANAGED,
5019                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5020     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5021     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5022     ok(sz == 3, "Expected 3, got %d\n", sz);
5023
5024     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5026
5027     /* InstallSource value exists */
5028     sz = MAX_PATH;
5029     lstrcpyA(buf, "apple");
5030     r = pMsiGetProductInfoExA(prodcode, usersid,
5031                               MSIINSTALLCONTEXT_USERMANAGED,
5032                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5033     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5034     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5035     ok(sz == 6, "Expected 6, got %d\n", sz);
5036
5037     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5038     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5039
5040     /* LocalPackage value exists */
5041     sz = MAX_PATH;
5042     lstrcpyA(buf, "apple");
5043     r = pMsiGetProductInfoExA(prodcode, usersid,
5044                               MSIINSTALLCONTEXT_USERMANAGED,
5045                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5046     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5047     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5048     ok(sz == 5, "Expected 5, got %d\n", sz);
5049
5050     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5051     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5052
5053     /* Publisher value exists */
5054     sz = MAX_PATH;
5055     lstrcpyA(buf, "apple");
5056     r = pMsiGetProductInfoExA(prodcode, usersid,
5057                               MSIINSTALLCONTEXT_USERMANAGED,
5058                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5059     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5060     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5061     ok(sz == 3, "Expected 3, got %d\n", sz);
5062
5063     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5064     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5065
5066     /* URLInfoAbout value exists */
5067     sz = MAX_PATH;
5068     lstrcpyA(buf, "apple");
5069     r = pMsiGetProductInfoExA(prodcode, usersid,
5070                               MSIINSTALLCONTEXT_USERMANAGED,
5071                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5073     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5074     ok(sz == 5, "Expected 5, got %d\n", sz);
5075
5076     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5077     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5078
5079     /* URLUpdateInfo value exists */
5080     sz = MAX_PATH;
5081     lstrcpyA(buf, "apple");
5082     r = pMsiGetProductInfoExA(prodcode, usersid,
5083                               MSIINSTALLCONTEXT_USERMANAGED,
5084                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5085     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5086     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5087     ok(sz == 6, "Expected 6, got %d\n", sz);
5088
5089     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5090     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5091
5092     /* VersionMinor value exists */
5093     sz = MAX_PATH;
5094     lstrcpyA(buf, "apple");
5095     r = pMsiGetProductInfoExA(prodcode, usersid,
5096                               MSIINSTALLCONTEXT_USERMANAGED,
5097                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5098     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5099     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5100     ok(sz == 1, "Expected 1, got %d\n", sz);
5101
5102     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5103     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5104
5105     /* VersionMajor value exists */
5106     sz = MAX_PATH;
5107     lstrcpyA(buf, "apple");
5108     r = pMsiGetProductInfoExA(prodcode, usersid,
5109                               MSIINSTALLCONTEXT_USERMANAGED,
5110                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5111     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5112     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5113     ok(sz == 1, "Expected 1, got %d\n", sz);
5114
5115     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5117
5118     /* DisplayVersion value exists */
5119     sz = MAX_PATH;
5120     lstrcpyA(buf, "apple");
5121     r = pMsiGetProductInfoExA(prodcode, usersid,
5122                               MSIINSTALLCONTEXT_USERMANAGED,
5123                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5124     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5125     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5126     ok(sz == 5, "Expected 5, got %d\n", sz);
5127
5128     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5130
5131     /* ProductID value exists */
5132     sz = MAX_PATH;
5133     lstrcpyA(buf, "apple");
5134     r = pMsiGetProductInfoExA(prodcode, usersid,
5135                               MSIINSTALLCONTEXT_USERMANAGED,
5136                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5137     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5138     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5139     ok(sz == 2, "Expected 2, got %d\n", sz);
5140
5141     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5142     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5143
5144     /* RegCompany value exists */
5145     sz = MAX_PATH;
5146     lstrcpyA(buf, "apple");
5147     r = pMsiGetProductInfoExA(prodcode, usersid,
5148                               MSIINSTALLCONTEXT_USERMANAGED,
5149                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5150     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5151     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5152     ok(sz == 4, "Expected 4, got %d\n", sz);
5153
5154     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5155     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5156
5157     /* RegOwner value exists */
5158     sz = MAX_PATH;
5159     lstrcpyA(buf, "apple");
5160     r = pMsiGetProductInfoExA(prodcode, usersid,
5161                               MSIINSTALLCONTEXT_USERMANAGED,
5162                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5163     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5164     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5165     ok(sz == 5, "Expected 5, got %d\n", sz);
5166
5167     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5168     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5169
5170     /* Transforms value exists */
5171     sz = MAX_PATH;
5172     lstrcpyA(buf, "apple");
5173     r = pMsiGetProductInfoExA(prodcode, usersid,
5174                               MSIINSTALLCONTEXT_USERMANAGED,
5175                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5176     ok(r == ERROR_UNKNOWN_PRODUCT,
5177        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5178     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5179     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5180
5181     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5183
5184     /* Language value exists */
5185     sz = MAX_PATH;
5186     lstrcpyA(buf, "apple");
5187     r = pMsiGetProductInfoExA(prodcode, usersid,
5188                               MSIINSTALLCONTEXT_USERMANAGED,
5189                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5190     ok(r == ERROR_UNKNOWN_PRODUCT,
5191        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5192     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5193     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5194
5195     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5197
5198     /* ProductName value exists */
5199     sz = MAX_PATH;
5200     lstrcpyA(buf, "apple");
5201     r = pMsiGetProductInfoExA(prodcode, usersid,
5202                               MSIINSTALLCONTEXT_USERMANAGED,
5203                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5204     ok(r == ERROR_UNKNOWN_PRODUCT,
5205        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5206     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5207     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5208
5209     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5211
5212     /* FIXME */
5213
5214     /* AssignmentType value exists */
5215     sz = MAX_PATH;
5216     lstrcpyA(buf, "apple");
5217     r = pMsiGetProductInfoExA(prodcode, usersid,
5218                               MSIINSTALLCONTEXT_USERMANAGED,
5219                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5220     ok(r == ERROR_UNKNOWN_PRODUCT,
5221        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5222     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5223     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5224
5225     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5227
5228     /* PackageCode value exists */
5229     sz = MAX_PATH;
5230     lstrcpyA(buf, "apple");
5231     r = pMsiGetProductInfoExA(prodcode, usersid,
5232                               MSIINSTALLCONTEXT_USERMANAGED,
5233                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5234     ok(r == ERROR_UNKNOWN_PRODUCT,
5235        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5236     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5237     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5238
5239     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5240     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5241
5242     /* Version value exists */
5243     sz = MAX_PATH;
5244     lstrcpyA(buf, "apple");
5245     r = pMsiGetProductInfoExA(prodcode, usersid,
5246                               MSIINSTALLCONTEXT_USERMANAGED,
5247                               INSTALLPROPERTY_VERSION, buf, &sz);
5248     ok(r == ERROR_UNKNOWN_PRODUCT,
5249        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5250     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5251     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5252
5253     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5255
5256     /* ProductIcon value exists */
5257     sz = MAX_PATH;
5258     lstrcpyA(buf, "apple");
5259     r = pMsiGetProductInfoExA(prodcode, usersid,
5260                               MSIINSTALLCONTEXT_USERMANAGED,
5261                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5262     ok(r == ERROR_UNKNOWN_PRODUCT,
5263        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5264     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5265     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5266
5267     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5268     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5269
5270     /* PackageName value exists */
5271     sz = MAX_PATH;
5272     lstrcpyA(buf, "apple");
5273     r = pMsiGetProductInfoExA(prodcode, usersid,
5274                               MSIINSTALLCONTEXT_USERMANAGED,
5275                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5276     ok(r == ERROR_UNKNOWN_PRODUCT,
5277        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5278     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5279     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5280
5281     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5283
5284     /* AuthorizedLUAApp value exists */
5285     sz = MAX_PATH;
5286     lstrcpyA(buf, "apple");
5287     r = pMsiGetProductInfoExA(prodcode, usersid,
5288                               MSIINSTALLCONTEXT_USERMANAGED,
5289                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5290     ok(r == ERROR_UNKNOWN_PRODUCT,
5291        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5292     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5293     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5294
5295     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5296     RegDeleteValueA(propkey, "PackageName");
5297     RegDeleteValueA(propkey, "ProductIcon");
5298     RegDeleteValueA(propkey, "Version");
5299     RegDeleteValueA(propkey, "PackageCode");
5300     RegDeleteValueA(propkey, "AssignmentType");
5301     RegDeleteValueA(propkey, "ProductName");
5302     RegDeleteValueA(propkey, "Language");
5303     RegDeleteValueA(propkey, "Transforms");
5304     RegDeleteValueA(propkey, "RegOwner");
5305     RegDeleteValueA(propkey, "RegCompany");
5306     RegDeleteValueA(propkey, "ProductID");
5307     RegDeleteValueA(propkey, "DisplayVersion");
5308     RegDeleteValueA(propkey, "VersionMajor");
5309     RegDeleteValueA(propkey, "VersionMinor");
5310     RegDeleteValueA(propkey, "URLUpdateInfo");
5311     RegDeleteValueA(propkey, "URLInfoAbout");
5312     RegDeleteValueA(propkey, "Publisher");
5313     RegDeleteValueA(propkey, "LocalPackage");
5314     RegDeleteValueA(propkey, "InstallSource");
5315     RegDeleteValueA(propkey, "InstallLocation");
5316     RegDeleteValueA(propkey, "DisplayName");
5317     RegDeleteValueA(propkey, "InstallDate");
5318     RegDeleteValueA(propkey, "HelpTelephone");
5319     RegDeleteValueA(propkey, "HelpLink");
5320     RegDeleteValueA(propkey, "ManagedLocalPackage");
5321     RegDeleteKeyA(propkey, "");
5322     RegCloseKey(propkey);
5323     RegDeleteKeyA(localkey, "");
5324     RegCloseKey(localkey);
5325
5326     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5327     lstrcatA(keypath, usersid);
5328     lstrcatA(keypath, "\\Installer\\Products\\");
5329     lstrcatA(keypath, prod_squashed);
5330
5331     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5333
5334     /* user product key exists */
5335     sz = MAX_PATH;
5336     lstrcpyA(buf, "apple");
5337     r = pMsiGetProductInfoExA(prodcode, usersid,
5338                               MSIINSTALLCONTEXT_USERMANAGED,
5339                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5340     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5341     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5342     ok(sz == 1, "Expected 1, got %d\n", sz);
5343
5344     RegDeleteKeyA(userkey, "");
5345     RegCloseKey(userkey);
5346
5347     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5348     lstrcatA(keypath, prod_squashed);
5349
5350     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5352
5353     /* current user product key exists */
5354     sz = MAX_PATH;
5355     lstrcpyA(buf, "apple");
5356     r = pMsiGetProductInfoExA(prodcode, usersid,
5357                               MSIINSTALLCONTEXT_USERMANAGED,
5358                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5359     ok(r == ERROR_UNKNOWN_PRODUCT,
5360        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5361     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5362     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5363
5364     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5366
5367     /* HelpLink value exists, user product key does not exist */
5368     sz = MAX_PATH;
5369     lstrcpyA(buf, "apple");
5370     r = pMsiGetProductInfoExA(prodcode, usersid,
5371                               MSIINSTALLCONTEXT_USERMANAGED,
5372                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5373     ok(r == ERROR_UNKNOWN_PRODUCT,
5374        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5375     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5376     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5377
5378     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5379     lstrcatA(keypath, usersid);
5380     lstrcatA(keypath, "\\Installer\\Products\\");
5381     lstrcatA(keypath, prod_squashed);
5382
5383     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5384     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5385
5386     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5387     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5388
5389     /* HelpLink value exists, user product key does exist */
5390     sz = MAX_PATH;
5391     lstrcpyA(buf, "apple");
5392     r = pMsiGetProductInfoExA(prodcode, usersid,
5393                               MSIINSTALLCONTEXT_USERMANAGED,
5394                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5395     ok(r == ERROR_UNKNOWN_PROPERTY,
5396        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5397     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5398     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5399
5400     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5401     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5402
5403     /* HelpTelephone value exists */
5404     sz = MAX_PATH;
5405     lstrcpyA(buf, "apple");
5406     r = pMsiGetProductInfoExA(prodcode, usersid,
5407                               MSIINSTALLCONTEXT_USERMANAGED,
5408                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5409     ok(r == ERROR_UNKNOWN_PROPERTY,
5410        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5411     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5412     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5413
5414     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5415     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5416
5417     /* InstallDate value exists */
5418     sz = MAX_PATH;
5419     lstrcpyA(buf, "apple");
5420     r = pMsiGetProductInfoExA(prodcode, usersid,
5421                               MSIINSTALLCONTEXT_USERMANAGED,
5422                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5423     ok(r == ERROR_UNKNOWN_PROPERTY,
5424        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5425     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5426     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5427
5428     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5429     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5430
5431     /* DisplayName value exists */
5432     sz = MAX_PATH;
5433     lstrcpyA(buf, "apple");
5434     r = pMsiGetProductInfoExA(prodcode, usersid,
5435                               MSIINSTALLCONTEXT_USERMANAGED,
5436                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5437     ok(r == ERROR_UNKNOWN_PROPERTY,
5438        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5439     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5440     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5441
5442     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5443     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5444
5445     /* InstallLocation value exists */
5446     sz = MAX_PATH;
5447     lstrcpyA(buf, "apple");
5448     r = pMsiGetProductInfoExA(prodcode, usersid,
5449                               MSIINSTALLCONTEXT_USERMANAGED,
5450                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5451     ok(r == ERROR_UNKNOWN_PROPERTY,
5452        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5453     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5454     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5455
5456     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5457     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5458
5459     /* InstallSource value exists */
5460     sz = MAX_PATH;
5461     lstrcpyA(buf, "apple");
5462     r = pMsiGetProductInfoExA(prodcode, usersid,
5463                               MSIINSTALLCONTEXT_USERMANAGED,
5464                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5465     ok(r == ERROR_UNKNOWN_PROPERTY,
5466        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5467     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5468     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5469
5470     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5471     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5472
5473     /* LocalPackage value exists */
5474     sz = MAX_PATH;
5475     lstrcpyA(buf, "apple");
5476     r = pMsiGetProductInfoExA(prodcode, usersid,
5477                               MSIINSTALLCONTEXT_USERMANAGED,
5478                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5479     ok(r == ERROR_UNKNOWN_PROPERTY,
5480        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5481     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5482     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5483
5484     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5485     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5486
5487     /* Publisher value exists */
5488     sz = MAX_PATH;
5489     lstrcpyA(buf, "apple");
5490     r = pMsiGetProductInfoExA(prodcode, usersid,
5491                               MSIINSTALLCONTEXT_USERMANAGED,
5492                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5493     ok(r == ERROR_UNKNOWN_PROPERTY,
5494        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5495     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5496     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5497
5498     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5499     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5500
5501     /* URLInfoAbout value exists */
5502     sz = MAX_PATH;
5503     lstrcpyA(buf, "apple");
5504     r = pMsiGetProductInfoExA(prodcode, usersid,
5505                               MSIINSTALLCONTEXT_USERMANAGED,
5506                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5507     ok(r == ERROR_UNKNOWN_PROPERTY,
5508        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5509     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5510     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5511
5512     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5513     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5514
5515     /* URLUpdateInfo value exists */
5516     sz = MAX_PATH;
5517     lstrcpyA(buf, "apple");
5518     r = pMsiGetProductInfoExA(prodcode, usersid,
5519                               MSIINSTALLCONTEXT_USERMANAGED,
5520                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5521     ok(r == ERROR_UNKNOWN_PROPERTY,
5522        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5523     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5524     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5525
5526     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5527     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5528
5529     /* VersionMinor value exists */
5530     sz = MAX_PATH;
5531     lstrcpyA(buf, "apple");
5532     r = pMsiGetProductInfoExA(prodcode, usersid,
5533                               MSIINSTALLCONTEXT_USERMANAGED,
5534                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5535     ok(r == ERROR_UNKNOWN_PROPERTY,
5536        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5537     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5538     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5539
5540     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5541     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5542
5543     /* VersionMajor value exists */
5544     sz = MAX_PATH;
5545     lstrcpyA(buf, "apple");
5546     r = pMsiGetProductInfoExA(prodcode, usersid,
5547                               MSIINSTALLCONTEXT_USERMANAGED,
5548                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5549     ok(r == ERROR_UNKNOWN_PROPERTY,
5550        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5551     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5552     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5553
5554     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5555     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5556
5557     /* DisplayVersion value exists */
5558     sz = MAX_PATH;
5559     lstrcpyA(buf, "apple");
5560     r = pMsiGetProductInfoExA(prodcode, usersid,
5561                               MSIINSTALLCONTEXT_USERMANAGED,
5562                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5563     ok(r == ERROR_UNKNOWN_PROPERTY,
5564        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5565     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5566     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5567
5568     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5569     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5570
5571     /* ProductID value exists */
5572     sz = MAX_PATH;
5573     lstrcpyA(buf, "apple");
5574     r = pMsiGetProductInfoExA(prodcode, usersid,
5575                               MSIINSTALLCONTEXT_USERMANAGED,
5576                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5577     ok(r == ERROR_UNKNOWN_PROPERTY,
5578        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5579     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5580     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5581
5582     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5583     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5584
5585     /* RegCompany value exists */
5586     sz = MAX_PATH;
5587     lstrcpyA(buf, "apple");
5588     r = pMsiGetProductInfoExA(prodcode, usersid,
5589                               MSIINSTALLCONTEXT_USERMANAGED,
5590                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5591     ok(r == ERROR_UNKNOWN_PROPERTY,
5592        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5593     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5594     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5595
5596     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5597     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5598
5599     /* RegOwner value exists */
5600     sz = MAX_PATH;
5601     lstrcpyA(buf, "apple");
5602     r = pMsiGetProductInfoExA(prodcode, usersid,
5603                               MSIINSTALLCONTEXT_USERMANAGED,
5604                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5605     ok(r == ERROR_UNKNOWN_PROPERTY,
5606        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5607     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5608     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5609
5610     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5612
5613     /* Transforms value exists */
5614     sz = MAX_PATH;
5615     lstrcpyA(buf, "apple");
5616     r = pMsiGetProductInfoExA(prodcode, usersid,
5617                               MSIINSTALLCONTEXT_USERMANAGED,
5618                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5619     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5620     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5621     ok(sz == 5, "Expected 5, got %d\n", sz);
5622
5623     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5625
5626     /* Language value exists */
5627     sz = MAX_PATH;
5628     lstrcpyA(buf, "apple");
5629     r = pMsiGetProductInfoExA(prodcode, usersid,
5630                               MSIINSTALLCONTEXT_USERMANAGED,
5631                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5632     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5633     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5634     ok(sz == 4, "Expected 4, got %d\n", sz);
5635
5636     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5637     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5638
5639     /* ProductName value exists */
5640     sz = MAX_PATH;
5641     lstrcpyA(buf, "apple");
5642     r = pMsiGetProductInfoExA(prodcode, usersid,
5643                               MSIINSTALLCONTEXT_USERMANAGED,
5644                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5645     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5646     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5647     ok(sz == 4, "Expected 4, got %d\n", sz);
5648
5649     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5651
5652     /* FIXME */
5653
5654     /* AssignmentType value exists */
5655     sz = MAX_PATH;
5656     lstrcpyA(buf, "apple");
5657     r = pMsiGetProductInfoExA(prodcode, usersid,
5658                               MSIINSTALLCONTEXT_USERMANAGED,
5659                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5660     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5661     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5662     ok(sz == 0, "Expected 0, got %d\n", sz);
5663
5664     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5665     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5666
5667     /* FIXME */
5668
5669     /* PackageCode value exists */
5670     sz = MAX_PATH;
5671     lstrcpyA(buf, "apple");
5672     r = pMsiGetProductInfoExA(prodcode, usersid,
5673                               MSIINSTALLCONTEXT_USERMANAGED,
5674                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5675     todo_wine
5676     {
5677         ok(r == ERROR_BAD_CONFIGURATION,
5678            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5679         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5680         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5681     }
5682
5683     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5685
5686     /* Version value exists */
5687     sz = MAX_PATH;
5688     lstrcpyA(buf, "apple");
5689     r = pMsiGetProductInfoExA(prodcode, usersid,
5690                               MSIINSTALLCONTEXT_USERMANAGED,
5691                               INSTALLPROPERTY_VERSION, buf, &sz);
5692     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5693     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5694     ok(sz == 3, "Expected 3, got %d\n", sz);
5695
5696     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5697     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5698
5699     /* ProductIcon value exists */
5700     sz = MAX_PATH;
5701     lstrcpyA(buf, "apple");
5702     r = pMsiGetProductInfoExA(prodcode, usersid,
5703                               MSIINSTALLCONTEXT_USERMANAGED,
5704                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5705     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5706     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5707     ok(sz == 4, "Expected 4, got %d\n", sz);
5708
5709     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5711
5712     /* PackageName value exists */
5713     sz = MAX_PATH;
5714     lstrcpyA(buf, "apple");
5715     r = pMsiGetProductInfoExA(prodcode, usersid,
5716                               MSIINSTALLCONTEXT_USERMANAGED,
5717                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5718     todo_wine
5719     {
5720         ok(r == ERROR_UNKNOWN_PRODUCT,
5721            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5722         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5723         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5724     }
5725
5726     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5728
5729     /* AuthorizedLUAApp value exists */
5730     sz = MAX_PATH;
5731     lstrcpyA(buf, "apple");
5732     r = pMsiGetProductInfoExA(prodcode, usersid,
5733                               MSIINSTALLCONTEXT_USERMANAGED,
5734                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5735     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5736     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5737     ok(sz == 4, "Expected 4, got %d\n", sz);
5738
5739     RegDeleteValueA(userkey, "AuthorizedLUAApp");
5740     RegDeleteValueA(userkey, "PackageName");
5741     RegDeleteValueA(userkey, "ProductIcon");
5742     RegDeleteValueA(userkey, "Version");
5743     RegDeleteValueA(userkey, "PackageCode");
5744     RegDeleteValueA(userkey, "AssignmentType");
5745     RegDeleteValueA(userkey, "ProductName");
5746     RegDeleteValueA(userkey, "Language");
5747     RegDeleteValueA(userkey, "Transforms");
5748     RegDeleteValueA(userkey, "RegOwner");
5749     RegDeleteValueA(userkey, "RegCompany");
5750     RegDeleteValueA(userkey, "ProductID");
5751     RegDeleteValueA(userkey, "DisplayVersion");
5752     RegDeleteValueA(userkey, "VersionMajor");
5753     RegDeleteValueA(userkey, "VersionMinor");
5754     RegDeleteValueA(userkey, "URLUpdateInfo");
5755     RegDeleteValueA(userkey, "URLInfoAbout");
5756     RegDeleteValueA(userkey, "Publisher");
5757     RegDeleteValueA(userkey, "LocalPackage");
5758     RegDeleteValueA(userkey, "InstallSource");
5759     RegDeleteValueA(userkey, "InstallLocation");
5760     RegDeleteValueA(userkey, "DisplayName");
5761     RegDeleteValueA(userkey, "InstallDate");
5762     RegDeleteValueA(userkey, "HelpTelephone");
5763     RegDeleteValueA(userkey, "HelpLink");
5764     RegDeleteKeyA(userkey, "");
5765     RegCloseKey(userkey);
5766     RegDeleteKeyA(prodkey, "");
5767     RegCloseKey(prodkey);
5768
5769     /* MSIINSTALLCONTEXT_MACHINE */
5770
5771     /* szUserSid is non-NULL */
5772     sz = MAX_PATH;
5773     lstrcpyA(buf, "apple");
5774     r = pMsiGetProductInfoExA(prodcode, usersid,
5775                               MSIINSTALLCONTEXT_MACHINE,
5776                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5777     ok(r == ERROR_INVALID_PARAMETER,
5778        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5779     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5780     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5781
5782     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
5783     lstrcatA(keypath, prod_squashed);
5784
5785     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5786     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5787
5788     /* local system product key exists */
5789     sz = MAX_PATH;
5790     lstrcpyA(buf, "apple");
5791     r = pMsiGetProductInfoExA(prodcode, NULL,
5792                               MSIINSTALLCONTEXT_MACHINE,
5793                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5794     ok(r == ERROR_UNKNOWN_PRODUCT,
5795        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5796     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5797     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5798
5799     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5800     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5801
5802     /* InstallProperties key exists */
5803     sz = MAX_PATH;
5804     lstrcpyA(buf, "apple");
5805     r = pMsiGetProductInfoExA(prodcode, NULL,
5806                               MSIINSTALLCONTEXT_MACHINE,
5807                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5808     ok(r == ERROR_UNKNOWN_PRODUCT,
5809        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5810     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5811     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5812
5813     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5814     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5815
5816     /* LocalPackage value exists */
5817     sz = MAX_PATH;
5818     lstrcpyA(buf, "apple");
5819     r = pMsiGetProductInfoExA(prodcode, NULL,
5820                               MSIINSTALLCONTEXT_MACHINE,
5821                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5822     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5823     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5824     ok(sz == 1, "Expected 1, got %d\n", sz);
5825
5826     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5827     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5828
5829     /* HelpLink value exists */
5830     sz = MAX_PATH;
5831     lstrcpyA(buf, "apple");
5832     r = pMsiGetProductInfoExA(prodcode, NULL,
5833                               MSIINSTALLCONTEXT_MACHINE,
5834                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5835     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5836     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5837     ok(sz == 4, "Expected 4, got %d\n", sz);
5838
5839     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5840     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5841
5842     /* HelpTelephone value exists */
5843     sz = MAX_PATH;
5844     lstrcpyA(buf, "apple");
5845     r = pMsiGetProductInfoExA(prodcode, NULL,
5846                               MSIINSTALLCONTEXT_MACHINE,
5847                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5848     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5849     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5850     ok(sz == 5, "Expected 5, got %d\n", sz);
5851
5852     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5854
5855     /* InstallDate value exists */
5856     sz = MAX_PATH;
5857     lstrcpyA(buf, "apple");
5858     r = pMsiGetProductInfoExA(prodcode, NULL,
5859                               MSIINSTALLCONTEXT_MACHINE,
5860                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5861     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5862     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5863     ok(sz == 4, "Expected 4, got %d\n", sz);
5864
5865     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5866     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5867
5868     /* DisplayName value exists */
5869     sz = MAX_PATH;
5870     lstrcpyA(buf, "apple");
5871     r = pMsiGetProductInfoExA(prodcode, NULL,
5872                               MSIINSTALLCONTEXT_MACHINE,
5873                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5874     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5875     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5876     ok(sz == 4, "Expected 4, got %d\n", sz);
5877
5878     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5880
5881     /* InstallLocation value exists */
5882     sz = MAX_PATH;
5883     lstrcpyA(buf, "apple");
5884     r = pMsiGetProductInfoExA(prodcode, NULL,
5885                               MSIINSTALLCONTEXT_MACHINE,
5886                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5887     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5888     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5889     ok(sz == 3, "Expected 3, got %d\n", sz);
5890
5891     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5892     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5893
5894     /* InstallSource value exists */
5895     sz = MAX_PATH;
5896     lstrcpyA(buf, "apple");
5897     r = pMsiGetProductInfoExA(prodcode, NULL,
5898                               MSIINSTALLCONTEXT_MACHINE,
5899                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5900     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5901     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5902     ok(sz == 6, "Expected 6, got %d\n", sz);
5903
5904     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5906
5907     /* LocalPackage value exists */
5908     sz = MAX_PATH;
5909     lstrcpyA(buf, "apple");
5910     r = pMsiGetProductInfoExA(prodcode, NULL,
5911                               MSIINSTALLCONTEXT_MACHINE,
5912                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5913     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5914     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5915     ok(sz == 5, "Expected 5, got %d\n", sz);
5916
5917     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5918     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5919
5920     /* Publisher value exists */
5921     sz = MAX_PATH;
5922     lstrcpyA(buf, "apple");
5923     r = pMsiGetProductInfoExA(prodcode, NULL,
5924                               MSIINSTALLCONTEXT_MACHINE,
5925                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5926     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5927     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5928     ok(sz == 3, "Expected 3, got %d\n", sz);
5929
5930     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5931     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5932
5933     /* URLInfoAbout value exists */
5934     sz = MAX_PATH;
5935     lstrcpyA(buf, "apple");
5936     r = pMsiGetProductInfoExA(prodcode, NULL,
5937                               MSIINSTALLCONTEXT_MACHINE,
5938                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5939     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5940     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5941     ok(sz == 5, "Expected 5, got %d\n", sz);
5942
5943     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5945
5946     /* URLUpdateInfo value exists */
5947     sz = MAX_PATH;
5948     lstrcpyA(buf, "apple");
5949     r = pMsiGetProductInfoExA(prodcode, NULL,
5950                               MSIINSTALLCONTEXT_MACHINE,
5951                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5953     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5954     ok(sz == 6, "Expected 6, got %d\n", sz);
5955
5956     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5958
5959     /* VersionMinor value exists */
5960     sz = MAX_PATH;
5961     lstrcpyA(buf, "apple");
5962     r = pMsiGetProductInfoExA(prodcode, NULL,
5963                               MSIINSTALLCONTEXT_MACHINE,
5964                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5965     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5966     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5967     ok(sz == 1, "Expected 1, got %d\n", sz);
5968
5969     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5970     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5971
5972     /* VersionMajor value exists */
5973     sz = MAX_PATH;
5974     lstrcpyA(buf, "apple");
5975     r = pMsiGetProductInfoExA(prodcode, NULL,
5976                               MSIINSTALLCONTEXT_MACHINE,
5977                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5978     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5979     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5980     ok(sz == 1, "Expected 1, got %d\n", sz);
5981
5982     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5984
5985     /* DisplayVersion value exists */
5986     sz = MAX_PATH;
5987     lstrcpyA(buf, "apple");
5988     r = pMsiGetProductInfoExA(prodcode, NULL,
5989                               MSIINSTALLCONTEXT_MACHINE,
5990                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5991     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5992     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5993     ok(sz == 5, "Expected 5, got %d\n", sz);
5994
5995     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5997
5998     /* ProductID value exists */
5999     sz = MAX_PATH;
6000     lstrcpyA(buf, "apple");
6001     r = pMsiGetProductInfoExA(prodcode, NULL,
6002                               MSIINSTALLCONTEXT_MACHINE,
6003                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6004     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6005     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6006     ok(sz == 2, "Expected 2, got %d\n", sz);
6007
6008     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6010
6011     /* RegCompany value exists */
6012     sz = MAX_PATH;
6013     lstrcpyA(buf, "apple");
6014     r = pMsiGetProductInfoExA(prodcode, NULL,
6015                               MSIINSTALLCONTEXT_MACHINE,
6016                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6017     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6018     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6019     ok(sz == 4, "Expected 4, got %d\n", sz);
6020
6021     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6022     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6023
6024     /* RegOwner value exists */
6025     sz = MAX_PATH;
6026     lstrcpyA(buf, "apple");
6027     r = pMsiGetProductInfoExA(prodcode, NULL,
6028                               MSIINSTALLCONTEXT_MACHINE,
6029                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6030     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6031     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6032     ok(sz == 5, "Expected 5, got %d\n", sz);
6033
6034     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6035     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6036
6037     /* Transforms value exists */
6038     sz = MAX_PATH;
6039     lstrcpyA(buf, "apple");
6040     r = pMsiGetProductInfoExA(prodcode, NULL,
6041                               MSIINSTALLCONTEXT_MACHINE,
6042                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6043     ok(r == ERROR_UNKNOWN_PRODUCT,
6044        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6045     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6046     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6047
6048     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6049     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6050
6051     /* Language value exists */
6052     sz = MAX_PATH;
6053     lstrcpyA(buf, "apple");
6054     r = pMsiGetProductInfoExA(prodcode, NULL,
6055                               MSIINSTALLCONTEXT_MACHINE,
6056                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6057     ok(r == ERROR_UNKNOWN_PRODUCT,
6058        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6059     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6060     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6061
6062     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6063     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6064
6065     /* ProductName value exists */
6066     sz = MAX_PATH;
6067     lstrcpyA(buf, "apple");
6068     r = pMsiGetProductInfoExA(prodcode, NULL,
6069                               MSIINSTALLCONTEXT_MACHINE,
6070                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6071     ok(r == ERROR_UNKNOWN_PRODUCT,
6072        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6073     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6074     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6075
6076     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6077     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6078
6079     /* FIXME */
6080
6081     /* AssignmentType value exists */
6082     sz = MAX_PATH;
6083     lstrcpyA(buf, "apple");
6084     r = pMsiGetProductInfoExA(prodcode, NULL,
6085                               MSIINSTALLCONTEXT_MACHINE,
6086                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6087     ok(r == ERROR_UNKNOWN_PRODUCT,
6088        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6089     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6090     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6091
6092     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6094
6095     /* PackageCode value exists */
6096     sz = MAX_PATH;
6097     lstrcpyA(buf, "apple");
6098     r = pMsiGetProductInfoExA(prodcode, NULL,
6099                               MSIINSTALLCONTEXT_MACHINE,
6100                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6101     ok(r == ERROR_UNKNOWN_PRODUCT,
6102        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6103     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6104     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6105
6106     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6107     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6108
6109     /* Version value exists */
6110     sz = MAX_PATH;
6111     lstrcpyA(buf, "apple");
6112     r = pMsiGetProductInfoExA(prodcode, NULL,
6113                               MSIINSTALLCONTEXT_MACHINE,
6114                               INSTALLPROPERTY_VERSION, buf, &sz);
6115     ok(r == ERROR_UNKNOWN_PRODUCT,
6116        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6117     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6118     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6119
6120     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6121     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6122
6123     /* ProductIcon value exists */
6124     sz = MAX_PATH;
6125     lstrcpyA(buf, "apple");
6126     r = pMsiGetProductInfoExA(prodcode, NULL,
6127                               MSIINSTALLCONTEXT_MACHINE,
6128                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6129     ok(r == ERROR_UNKNOWN_PRODUCT,
6130        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6131     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6132     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6133
6134     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6136
6137     /* PackageName value exists */
6138     sz = MAX_PATH;
6139     lstrcpyA(buf, "apple");
6140     r = pMsiGetProductInfoExA(prodcode, NULL,
6141                               MSIINSTALLCONTEXT_MACHINE,
6142                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6143     ok(r == ERROR_UNKNOWN_PRODUCT,
6144        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6145     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6146     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6147
6148     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6149     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6150
6151     /* AuthorizedLUAApp value exists */
6152     sz = MAX_PATH;
6153     lstrcpyA(buf, "apple");
6154     r = pMsiGetProductInfoExA(prodcode, NULL,
6155                               MSIINSTALLCONTEXT_MACHINE,
6156                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6157     ok(r == ERROR_UNKNOWN_PRODUCT,
6158        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6159     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6160     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6161
6162     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6163     RegDeleteValueA(propkey, "PackageName");
6164     RegDeleteValueA(propkey, "ProductIcon");
6165     RegDeleteValueA(propkey, "Version");
6166     RegDeleteValueA(propkey, "PackageCode");
6167     RegDeleteValueA(propkey, "AssignmentType");
6168     RegDeleteValueA(propkey, "ProductName");
6169     RegDeleteValueA(propkey, "Language");
6170     RegDeleteValueA(propkey, "Transforms");
6171     RegDeleteValueA(propkey, "RegOwner");
6172     RegDeleteValueA(propkey, "RegCompany");
6173     RegDeleteValueA(propkey, "ProductID");
6174     RegDeleteValueA(propkey, "DisplayVersion");
6175     RegDeleteValueA(propkey, "VersionMajor");
6176     RegDeleteValueA(propkey, "VersionMinor");
6177     RegDeleteValueA(propkey, "URLUpdateInfo");
6178     RegDeleteValueA(propkey, "URLInfoAbout");
6179     RegDeleteValueA(propkey, "Publisher");
6180     RegDeleteValueA(propkey, "LocalPackage");
6181     RegDeleteValueA(propkey, "InstallSource");
6182     RegDeleteValueA(propkey, "InstallLocation");
6183     RegDeleteValueA(propkey, "DisplayName");
6184     RegDeleteValueA(propkey, "InstallDate");
6185     RegDeleteValueA(propkey, "HelpTelephone");
6186     RegDeleteValueA(propkey, "HelpLink");
6187     RegDeleteValueA(propkey, "LocalPackage");
6188     RegDeleteKeyA(propkey, "");
6189     RegCloseKey(propkey);
6190     RegDeleteKeyA(localkey, "");
6191     RegCloseKey(localkey);
6192
6193     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6194     lstrcatA(keypath, prod_squashed);
6195
6196     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6198
6199     /* local classes product key exists */
6200     sz = MAX_PATH;
6201     lstrcpyA(buf, "apple");
6202     r = pMsiGetProductInfoExA(prodcode, NULL,
6203                               MSIINSTALLCONTEXT_MACHINE,
6204                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6205     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6206     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6207     ok(sz == 1, "Expected 1, got %d\n", sz);
6208
6209     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6211
6212     /* HelpLink value exists */
6213     sz = MAX_PATH;
6214     lstrcpyA(buf, "apple");
6215     r = pMsiGetProductInfoExA(prodcode, NULL,
6216                               MSIINSTALLCONTEXT_MACHINE,
6217                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6218     ok(r == ERROR_UNKNOWN_PROPERTY,
6219        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6220     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6221     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6222
6223     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6225
6226     /* HelpTelephone value exists */
6227     sz = MAX_PATH;
6228     lstrcpyA(buf, "apple");
6229     r = pMsiGetProductInfoExA(prodcode, NULL,
6230                               MSIINSTALLCONTEXT_MACHINE,
6231                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6232     ok(r == ERROR_UNKNOWN_PROPERTY,
6233        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6234     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6235     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6236
6237     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6239
6240     /* InstallDate value exists */
6241     sz = MAX_PATH;
6242     lstrcpyA(buf, "apple");
6243     r = pMsiGetProductInfoExA(prodcode, NULL,
6244                               MSIINSTALLCONTEXT_MACHINE,
6245                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6246     ok(r == ERROR_UNKNOWN_PROPERTY,
6247        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6248     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6249     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6250
6251     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6252     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6253
6254     /* DisplayName value exists */
6255     sz = MAX_PATH;
6256     lstrcpyA(buf, "apple");
6257     r = pMsiGetProductInfoExA(prodcode, NULL,
6258                               MSIINSTALLCONTEXT_MACHINE,
6259                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6260     ok(r == ERROR_UNKNOWN_PROPERTY,
6261        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6262     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6263     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6264
6265     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6267
6268     /* InstallLocation value exists */
6269     sz = MAX_PATH;
6270     lstrcpyA(buf, "apple");
6271     r = pMsiGetProductInfoExA(prodcode, NULL,
6272                               MSIINSTALLCONTEXT_MACHINE,
6273                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6274     ok(r == ERROR_UNKNOWN_PROPERTY,
6275        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6276     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6277     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6278
6279     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6281
6282     /* InstallSource value exists */
6283     sz = MAX_PATH;
6284     lstrcpyA(buf, "apple");
6285     r = pMsiGetProductInfoExA(prodcode, NULL,
6286                               MSIINSTALLCONTEXT_MACHINE,
6287                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6288     ok(r == ERROR_UNKNOWN_PROPERTY,
6289        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6290     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6291     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6292
6293     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6294     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6295
6296     /* LocalPackage value exists */
6297     sz = MAX_PATH;
6298     lstrcpyA(buf, "apple");
6299     r = pMsiGetProductInfoExA(prodcode, NULL,
6300                               MSIINSTALLCONTEXT_MACHINE,
6301                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6302     ok(r == ERROR_UNKNOWN_PROPERTY,
6303        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6304     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6305     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6306
6307     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6309
6310     /* Publisher value exists */
6311     sz = MAX_PATH;
6312     lstrcpyA(buf, "apple");
6313     r = pMsiGetProductInfoExA(prodcode, NULL,
6314                               MSIINSTALLCONTEXT_MACHINE,
6315                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6316     ok(r == ERROR_UNKNOWN_PROPERTY,
6317        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6318     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6319     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6320
6321     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6322     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6323
6324     /* URLInfoAbout value exists */
6325     sz = MAX_PATH;
6326     lstrcpyA(buf, "apple");
6327     r = pMsiGetProductInfoExA(prodcode, NULL,
6328                               MSIINSTALLCONTEXT_MACHINE,
6329                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6330     ok(r == ERROR_UNKNOWN_PROPERTY,
6331        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6332     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6333     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6334
6335     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6337
6338     /* URLUpdateInfo value exists */
6339     sz = MAX_PATH;
6340     lstrcpyA(buf, "apple");
6341     r = pMsiGetProductInfoExA(prodcode, NULL,
6342                               MSIINSTALLCONTEXT_MACHINE,
6343                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6344     ok(r == ERROR_UNKNOWN_PROPERTY,
6345        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6346     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6347     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6348
6349     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6351
6352     /* VersionMinor value exists */
6353     sz = MAX_PATH;
6354     lstrcpyA(buf, "apple");
6355     r = pMsiGetProductInfoExA(prodcode, NULL,
6356                               MSIINSTALLCONTEXT_MACHINE,
6357                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6358     ok(r == ERROR_UNKNOWN_PROPERTY,
6359        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6360     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6361     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6362
6363     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6364     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6365
6366     /* VersionMajor value exists */
6367     sz = MAX_PATH;
6368     lstrcpyA(buf, "apple");
6369     r = pMsiGetProductInfoExA(prodcode, NULL,
6370                               MSIINSTALLCONTEXT_MACHINE,
6371                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6372     ok(r == ERROR_UNKNOWN_PROPERTY,
6373        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6374     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6375     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6376
6377     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6378     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6379
6380     /* DisplayVersion value exists */
6381     sz = MAX_PATH;
6382     lstrcpyA(buf, "apple");
6383     r = pMsiGetProductInfoExA(prodcode, NULL,
6384                               MSIINSTALLCONTEXT_MACHINE,
6385                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6386     ok(r == ERROR_UNKNOWN_PROPERTY,
6387        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6388     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6389     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6390
6391     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6392     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6393
6394     /* ProductID value exists */
6395     sz = MAX_PATH;
6396     lstrcpyA(buf, "apple");
6397     r = pMsiGetProductInfoExA(prodcode, NULL,
6398                               MSIINSTALLCONTEXT_MACHINE,
6399                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6400     ok(r == ERROR_UNKNOWN_PROPERTY,
6401        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6402     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6403     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6404
6405     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6406     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6407
6408     /* RegCompany value exists */
6409     sz = MAX_PATH;
6410     lstrcpyA(buf, "apple");
6411     r = pMsiGetProductInfoExA(prodcode, NULL,
6412                               MSIINSTALLCONTEXT_MACHINE,
6413                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6414     ok(r == ERROR_UNKNOWN_PROPERTY,
6415        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6416     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6417     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6418
6419     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6420     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6421
6422     /* RegOwner value exists */
6423     sz = MAX_PATH;
6424     lstrcpyA(buf, "apple");
6425     r = pMsiGetProductInfoExA(prodcode, NULL,
6426                               MSIINSTALLCONTEXT_MACHINE,
6427                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6428     ok(r == ERROR_UNKNOWN_PROPERTY,
6429        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6430     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6431     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6432
6433     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6435
6436     /* Transforms value exists */
6437     sz = MAX_PATH;
6438     lstrcpyA(buf, "apple");
6439     r = pMsiGetProductInfoExA(prodcode, NULL,
6440                               MSIINSTALLCONTEXT_MACHINE,
6441                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6442     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6443     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6444     ok(sz == 5, "Expected 5, got %d\n", sz);
6445
6446     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6447     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6448
6449     /* Language value exists */
6450     sz = MAX_PATH;
6451     lstrcpyA(buf, "apple");
6452     r = pMsiGetProductInfoExA(prodcode, NULL,
6453                               MSIINSTALLCONTEXT_MACHINE,
6454                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6455     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6456     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6457     ok(sz == 4, "Expected 4, got %d\n", sz);
6458
6459     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6460     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6461
6462     /* ProductName value exists */
6463     sz = MAX_PATH;
6464     lstrcpyA(buf, "apple");
6465     r = pMsiGetProductInfoExA(prodcode, NULL,
6466                               MSIINSTALLCONTEXT_MACHINE,
6467                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6468     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6469     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6470     ok(sz == 4, "Expected 4, got %d\n", sz);
6471
6472     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6473     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6474
6475     /* FIXME */
6476
6477     /* AssignmentType value exists */
6478     sz = MAX_PATH;
6479     lstrcpyA(buf, "apple");
6480     r = pMsiGetProductInfoExA(prodcode, NULL,
6481                               MSIINSTALLCONTEXT_MACHINE,
6482                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6483     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6484     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6485     ok(sz == 0, "Expected 0, got %d\n", sz);
6486
6487     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6488     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6489
6490     /* FIXME */
6491
6492     /* PackageCode value exists */
6493     sz = MAX_PATH;
6494     lstrcpyA(buf, "apple");
6495     r = pMsiGetProductInfoExA(prodcode, NULL,
6496                               MSIINSTALLCONTEXT_MACHINE,
6497                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6498     todo_wine
6499     {
6500         ok(r == ERROR_BAD_CONFIGURATION,
6501            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6502         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6503         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6504     }
6505
6506     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6507     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6508
6509     /* Version value exists */
6510     sz = MAX_PATH;
6511     lstrcpyA(buf, "apple");
6512     r = pMsiGetProductInfoExA(prodcode, NULL,
6513                               MSIINSTALLCONTEXT_MACHINE,
6514                               INSTALLPROPERTY_VERSION, buf, &sz);
6515     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6516     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6517     ok(sz == 3, "Expected 3, got %d\n", sz);
6518
6519     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6520     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6521
6522     /* ProductIcon value exists */
6523     sz = MAX_PATH;
6524     lstrcpyA(buf, "apple");
6525     r = pMsiGetProductInfoExA(prodcode, NULL,
6526                               MSIINSTALLCONTEXT_MACHINE,
6527                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6528     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6529     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6530     ok(sz == 4, "Expected 4, got %d\n", sz);
6531
6532     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6534
6535     /* PackageName value exists */
6536     sz = MAX_PATH;
6537     lstrcpyA(buf, "apple");
6538     r = pMsiGetProductInfoExA(prodcode, NULL,
6539                               MSIINSTALLCONTEXT_MACHINE,
6540                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6541     todo_wine
6542     {
6543         ok(r == ERROR_UNKNOWN_PRODUCT,
6544            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6545         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6546         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6547     }
6548
6549     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6551
6552     /* AuthorizedLUAApp value exists */
6553     sz = MAX_PATH;
6554     lstrcpyA(buf, "apple");
6555     r = pMsiGetProductInfoExA(prodcode, NULL,
6556                               MSIINSTALLCONTEXT_MACHINE,
6557                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6558     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6559     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6560     ok(sz == 4, "Expected 4, got %d\n", sz);
6561
6562     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6563     RegDeleteValueA(prodkey, "PackageName");
6564     RegDeleteValueA(prodkey, "ProductIcon");
6565     RegDeleteValueA(prodkey, "Version");
6566     RegDeleteValueA(prodkey, "PackageCode");
6567     RegDeleteValueA(prodkey, "AssignmentType");
6568     RegDeleteValueA(prodkey, "ProductName");
6569     RegDeleteValueA(prodkey, "Language");
6570     RegDeleteValueA(prodkey, "Transforms");
6571     RegDeleteValueA(prodkey, "RegOwner");
6572     RegDeleteValueA(prodkey, "RegCompany");
6573     RegDeleteValueA(prodkey, "ProductID");
6574     RegDeleteValueA(prodkey, "DisplayVersion");
6575     RegDeleteValueA(prodkey, "VersionMajor");
6576     RegDeleteValueA(prodkey, "VersionMinor");
6577     RegDeleteValueA(prodkey, "URLUpdateInfo");
6578     RegDeleteValueA(prodkey, "URLInfoAbout");
6579     RegDeleteValueA(prodkey, "Publisher");
6580     RegDeleteValueA(prodkey, "LocalPackage");
6581     RegDeleteValueA(prodkey, "InstallSource");
6582     RegDeleteValueA(prodkey, "InstallLocation");
6583     RegDeleteValueA(prodkey, "DisplayName");
6584     RegDeleteValueA(prodkey, "InstallDate");
6585     RegDeleteValueA(prodkey, "HelpTelephone");
6586     RegDeleteValueA(prodkey, "HelpLink");
6587     RegDeleteKeyA(prodkey, "");
6588     RegCloseKey(prodkey);
6589     LocalFree(usersid);
6590 }
6591
6592 #define INIT_USERINFO() \
6593     lstrcpyA(user, "apple"); \
6594     lstrcpyA(org, "orange"); \
6595     lstrcpyA(serial, "banana"); \
6596     usersz = orgsz = serialsz = MAX_PATH;
6597
6598 static void test_MsiGetUserInfo(void)
6599 {
6600     USERINFOSTATE state;
6601     CHAR user[MAX_PATH];
6602     CHAR org[MAX_PATH];
6603     CHAR serial[MAX_PATH];
6604     DWORD usersz, orgsz, serialsz;
6605     CHAR keypath[MAX_PATH * 2];
6606     CHAR prodcode[MAX_PATH];
6607     CHAR prod_squashed[MAX_PATH];
6608     HKEY prodkey, userprod, props;
6609     LPSTR usersid;
6610     LONG res;
6611
6612     create_test_guid(prodcode, prod_squashed);
6613     get_user_sid(&usersid);
6614
6615     /* NULL szProduct */
6616     INIT_USERINFO();
6617     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6618     ok(state == USERINFOSTATE_INVALIDARG,
6619        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6620     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6621     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6622     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6623     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6624     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6625     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6626
6627     /* empty szProductCode */
6628     INIT_USERINFO();
6629     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6630     ok(state == USERINFOSTATE_INVALIDARG,
6631        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6632     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6633     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6634     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6635     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6636     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6637     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6638
6639     /* garbage szProductCode */
6640     INIT_USERINFO();
6641     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6642     ok(state == USERINFOSTATE_INVALIDARG,
6643        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6644     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6645     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6646     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6647     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6648     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6649     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6650
6651     /* guid without brackets */
6652     INIT_USERINFO();
6653     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6654                             user, &usersz, org, &orgsz, serial, &serialsz);
6655     ok(state == USERINFOSTATE_INVALIDARG,
6656        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6657     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6658     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
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     /* guid with brackets */
6665     INIT_USERINFO();
6666     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6667                             user, &usersz, org, &orgsz, serial, &serialsz);
6668     ok(state == USERINFOSTATE_UNKNOWN,
6669        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6670     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6671     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6672     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6673     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6674     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6675     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6676
6677     /* NULL lpUserNameBuf */
6678     INIT_USERINFO();
6679     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6680     ok(state == USERINFOSTATE_UNKNOWN,
6681        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6682     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6683     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6684     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6685     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6686     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6687
6688     /* NULL pcchUserNameBuf */
6689     INIT_USERINFO();
6690     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6691     ok(state == USERINFOSTATE_INVALIDARG,
6692        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6693     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6694     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6695     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6696     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6697     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6698
6699     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6700     INIT_USERINFO();
6701     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6702     ok(state == USERINFOSTATE_UNKNOWN,
6703        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6704     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6705     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6706     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6707     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6708
6709     /* NULL lpOrgNameBuf */
6710     INIT_USERINFO();
6711     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6712     ok(state == USERINFOSTATE_UNKNOWN,
6713        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6714     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6715     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6716     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6717     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6718     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6719
6720     /* NULL pcchOrgNameBuf */
6721     INIT_USERINFO();
6722     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
6723     ok(state == USERINFOSTATE_INVALIDARG,
6724        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6725     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6726     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6727     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6728     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6729     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6730
6731     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
6732     INIT_USERINFO();
6733     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
6734     ok(state == USERINFOSTATE_UNKNOWN,
6735        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6736     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6737     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6738     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6739     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6740
6741     /* NULL lpSerialBuf */
6742     INIT_USERINFO();
6743     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
6744     ok(state == USERINFOSTATE_UNKNOWN,
6745        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6746     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6747     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6748     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6749     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6750     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6751
6752     /* NULL pcchSerialBuf */
6753     INIT_USERINFO();
6754     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
6755     ok(state == USERINFOSTATE_INVALIDARG,
6756        "Expected USERINFOSTATE_INVALIDARG, 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, "Expected MAX_PATH, got %d\n", usersz);
6761     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6762
6763     /* both lpSerialBuf and pcchSerialBuf NULL */
6764     INIT_USERINFO();
6765     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
6766     ok(state == USERINFOSTATE_UNKNOWN,
6767        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6768     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6769     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6770     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6771     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6772
6773     /* MSIINSTALLCONTEXT_USERMANAGED */
6774
6775     /* create local system product key */
6776     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6777     lstrcatA(keypath, usersid);
6778     lstrcatA(keypath, "\\Installer\\Products\\");
6779     lstrcatA(keypath, prod_squashed);
6780
6781     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6783
6784     /* managed product key exists */
6785     INIT_USERINFO();
6786     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6787     ok(state == USERINFOSTATE_ABSENT,
6788        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6789     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6790     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6791     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6792     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6793     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6794     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6795
6796     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6797     lstrcatA(keypath, "Installer\\UserData\\");
6798     lstrcatA(keypath, usersid);
6799     lstrcatA(keypath, "\\Products\\");
6800     lstrcatA(keypath, prod_squashed);
6801
6802     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6803     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6804
6805     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6806     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6807
6808     /* InstallProperties key exists */
6809     INIT_USERINFO();
6810     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6811     ok(state == USERINFOSTATE_ABSENT,
6812        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6813     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6814     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6815     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6816     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6817     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6818     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6819
6820     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6821     INIT_USERINFO();
6822     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6823     ok(state == USERINFOSTATE_ABSENT,
6824        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6825     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6826     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6827     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6828     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6829
6830     /* RegOwner, RegCompany don't exist, out params are NULL */
6831     INIT_USERINFO();
6832     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6833     ok(state == USERINFOSTATE_ABSENT,
6834        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6835     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6836     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6837
6838     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6839     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6840
6841     /* RegOwner value exists */
6842     INIT_USERINFO();
6843     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6844     ok(state == USERINFOSTATE_ABSENT,
6845        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6846     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6847     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6848     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6849     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6850     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6851     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6852
6853     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6854     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6855
6856     /* RegCompany value exists */
6857     INIT_USERINFO();
6858     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6859     ok(state == USERINFOSTATE_ABSENT,
6860        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6861     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6862     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6863     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6864     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6865     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6866     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6867
6868     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6869     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6870
6871     /* ProductID value exists */
6872     INIT_USERINFO();
6873     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6874     ok(state == USERINFOSTATE_PRESENT,
6875        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6876     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6877     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6878     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6879     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6880     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6881     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6882
6883     /* pcchUserNameBuf is too small */
6884     INIT_USERINFO();
6885     usersz = 0;
6886     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6887     ok(state == USERINFOSTATE_MOREDATA,
6888        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6889     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6890     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6891     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6892     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6893     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6894     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6895
6896     /* pcchUserNameBuf has no room for NULL terminator */
6897     INIT_USERINFO();
6898     usersz = 5;
6899     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6900     ok(state == USERINFOSTATE_MOREDATA,
6901        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6902     todo_wine
6903     {
6904         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6905     }
6906     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6907     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6908     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6909     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6910     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6911
6912     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
6913     INIT_USERINFO();
6914     usersz = 0;
6915     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6916     ok(state == USERINFOSTATE_PRESENT,
6917        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6918     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6919     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6920     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6921     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6922     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6923     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6924
6925     RegDeleteValueA(props, "ProductID");
6926     RegDeleteValueA(props, "RegCompany");
6927     RegDeleteValueA(props, "RegOwner");
6928     RegDeleteKeyA(props, "");
6929     RegCloseKey(props);
6930     RegDeleteKeyA(userprod, "");
6931     RegCloseKey(userprod);
6932     RegDeleteKeyA(prodkey, "");
6933     RegCloseKey(prodkey);
6934
6935     /* MSIINSTALLCONTEXT_USERUNMANAGED */
6936
6937     /* create local system product key */
6938     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6939     lstrcatA(keypath, prod_squashed);
6940
6941     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6943
6944     /* product key exists */
6945     INIT_USERINFO();
6946     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6947     ok(state == USERINFOSTATE_ABSENT,
6948        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6949     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6950     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6951     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6952     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6953     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6954     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6955
6956     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6957     lstrcatA(keypath, "Installer\\UserData\\");
6958     lstrcatA(keypath, usersid);
6959     lstrcatA(keypath, "\\Products\\");
6960     lstrcatA(keypath, prod_squashed);
6961
6962     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6964
6965     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6966     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6967
6968     /* InstallProperties key exists */
6969     INIT_USERINFO();
6970     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6971     ok(state == USERINFOSTATE_ABSENT,
6972        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6973     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6974     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6975     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6976     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6977     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6978     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6979
6980     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6981     INIT_USERINFO();
6982     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6983     ok(state == USERINFOSTATE_ABSENT,
6984        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6985     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6986     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6987     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6988     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6989
6990     /* RegOwner, RegCompany don't exist, out params are NULL */
6991     INIT_USERINFO();
6992     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6993     ok(state == USERINFOSTATE_ABSENT,
6994        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6995     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6996     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6997
6998     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6999     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7000
7001     /* RegOwner value exists */
7002     INIT_USERINFO();
7003     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7004     ok(state == USERINFOSTATE_ABSENT,
7005        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7006     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7007     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7008     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7009     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7010     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7011     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7012
7013     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7014     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7015
7016     /* RegCompany value exists */
7017     INIT_USERINFO();
7018     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7019     ok(state == USERINFOSTATE_ABSENT,
7020        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7021     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7022     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7023     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7024     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7025     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7026     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7027
7028     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7029     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7030
7031     /* ProductID value exists */
7032     INIT_USERINFO();
7033     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7034     ok(state == USERINFOSTATE_PRESENT,
7035        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7036     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7037     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7038     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7039     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7040     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7041     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7042
7043     RegDeleteValueA(props, "ProductID");
7044     RegDeleteValueA(props, "RegCompany");
7045     RegDeleteValueA(props, "RegOwner");
7046     RegDeleteKeyA(props, "");
7047     RegCloseKey(props);
7048     RegDeleteKeyA(userprod, "");
7049     RegCloseKey(userprod);
7050     RegDeleteKeyA(prodkey, "");
7051     RegCloseKey(prodkey);
7052
7053     /* MSIINSTALLCONTEXT_MACHINE */
7054
7055     /* create local system product key */
7056     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7057     lstrcatA(keypath, prod_squashed);
7058
7059     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7061
7062     /* product key 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, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7068     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7069     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7070     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7071     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7072     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7073
7074     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7075     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7076     lstrcatA(keypath, "\\Products\\");
7077     lstrcatA(keypath, prod_squashed);
7078
7079     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
7080     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7081
7082     res = RegCreateKeyA(userprod, "InstallProperties", &props);
7083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7084
7085     /* InstallProperties key exists */
7086     INIT_USERINFO();
7087     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7088     ok(state == USERINFOSTATE_ABSENT,
7089        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7090     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7091     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7092     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7093     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7094     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7095     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7096
7097     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7098     INIT_USERINFO();
7099     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7100     ok(state == USERINFOSTATE_ABSENT,
7101        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7102     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7103     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7104     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7105     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7106
7107     /* RegOwner, RegCompany don't exist, out params are NULL */
7108     INIT_USERINFO();
7109     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7110     ok(state == USERINFOSTATE_ABSENT,
7111        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7112     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7113     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7114
7115     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7117
7118     /* RegOwner value exists */
7119     INIT_USERINFO();
7120     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7121     ok(state == USERINFOSTATE_ABSENT,
7122        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7123     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7124     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7125     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7126     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7127     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7128     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7129
7130     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7131     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7132
7133     /* RegCompany value exists */
7134     INIT_USERINFO();
7135     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7136     ok(state == USERINFOSTATE_ABSENT,
7137        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7138     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7139     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7140     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7141     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7142     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7143     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7144
7145     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7146     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7147
7148     /* ProductID value exists */
7149     INIT_USERINFO();
7150     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7151     ok(state == USERINFOSTATE_PRESENT,
7152        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7153     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7154     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7155     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7156     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7157     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7158     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7159
7160     RegDeleteValueA(props, "ProductID");
7161     RegDeleteValueA(props, "RegCompany");
7162     RegDeleteValueA(props, "RegOwner");
7163     RegDeleteKeyA(props, "");
7164     RegCloseKey(props);
7165     RegDeleteKeyA(userprod, "");
7166     RegCloseKey(userprod);
7167     RegDeleteKeyA(prodkey, "");
7168     RegCloseKey(prodkey);
7169     LocalFree(usersid);
7170 }
7171
7172 static void test_MsiOpenProduct(void)
7173 {
7174     MSIHANDLE hprod, hdb;
7175     CHAR val[MAX_PATH];
7176     CHAR path[MAX_PATH];
7177     CHAR keypath[MAX_PATH*2];
7178     CHAR prodcode[MAX_PATH];
7179     CHAR prod_squashed[MAX_PATH];
7180     HKEY prodkey, userkey, props;
7181     LPSTR usersid;
7182     DWORD size;
7183     LONG res;
7184     UINT r;
7185
7186     GetCurrentDirectoryA(MAX_PATH, path);
7187     lstrcatA(path, "\\");
7188
7189     create_test_guid(prodcode, prod_squashed);
7190     get_user_sid(&usersid);
7191
7192     hdb = create_package_db(prodcode);
7193     MsiCloseHandle(hdb);
7194
7195     /* NULL szProduct */
7196     hprod = 0xdeadbeef;
7197     r = MsiOpenProductA(NULL, &hprod);
7198     ok(r == ERROR_INVALID_PARAMETER,
7199        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7200     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7201
7202     /* empty szProduct */
7203     hprod = 0xdeadbeef;
7204     r = MsiOpenProductA("", &hprod);
7205     ok(r == ERROR_INVALID_PARAMETER,
7206        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7207     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7208
7209     /* garbage szProduct */
7210     hprod = 0xdeadbeef;
7211     r = MsiOpenProductA("garbage", &hprod);
7212     ok(r == ERROR_INVALID_PARAMETER,
7213        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7214     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7215
7216     /* guid without brackets */
7217     hprod = 0xdeadbeef;
7218     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7219     ok(r == ERROR_INVALID_PARAMETER,
7220        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7221     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7222
7223     /* guid with brackets */
7224     hprod = 0xdeadbeef;
7225     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7226     ok(r == ERROR_UNKNOWN_PRODUCT,
7227        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7228     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7229
7230     /* same length as guid, but random */
7231     hprod = 0xdeadbeef;
7232     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7233     ok(r == ERROR_INVALID_PARAMETER,
7234        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7235     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7236
7237     /* hProduct is NULL */
7238     hprod = 0xdeadbeef;
7239     r = MsiOpenProductA(prodcode, NULL);
7240     ok(r == ERROR_INVALID_PARAMETER,
7241        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7242     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7243
7244     /* MSIINSTALLCONTEXT_USERMANAGED */
7245
7246     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7247     lstrcatA(keypath, "Installer\\Managed\\");
7248     lstrcatA(keypath, usersid);
7249     lstrcatA(keypath, "\\Installer\\Products\\");
7250     lstrcatA(keypath, prod_squashed);
7251
7252     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7253     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7254
7255     /* managed product key exists */
7256     hprod = 0xdeadbeef;
7257     r = MsiOpenProductA(prodcode, &hprod);
7258     ok(r == ERROR_UNKNOWN_PRODUCT,
7259        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7260     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7261
7262     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7263     lstrcatA(keypath, "Installer\\UserData\\");
7264     lstrcatA(keypath, usersid);
7265     lstrcatA(keypath, "\\Products\\");
7266     lstrcatA(keypath, prod_squashed);
7267
7268     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7269     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7270
7271     /* user product key exists */
7272     hprod = 0xdeadbeef;
7273     r = MsiOpenProductA(prodcode, &hprod);
7274     ok(r == ERROR_UNKNOWN_PRODUCT,
7275        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7276     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7277
7278     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7279     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7280
7281     /* InstallProperties key exists */
7282     hprod = 0xdeadbeef;
7283     r = MsiOpenProductA(prodcode, &hprod);
7284     ok(r == ERROR_UNKNOWN_PRODUCT,
7285        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7286     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7287
7288     lstrcpyA(val, path);
7289     lstrcatA(val, "\\winetest.msi");
7290     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7291                          (const BYTE *)val, lstrlenA(val) + 1);
7292     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7293
7294     /* ManagedLocalPackage value exists */
7295     hprod = 0xdeadbeef;
7296     r = MsiOpenProductA(prodcode, &hprod);
7297     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7298     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7299
7300     size = MAX_PATH;
7301     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7303     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7304     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7305
7306     MsiCloseHandle(hprod);
7307
7308     RegDeleteValueA(props, "ManagedLocalPackage");
7309     RegDeleteKeyA(props, "");
7310     RegCloseKey(props);
7311     RegDeleteKeyA(userkey, "");
7312     RegCloseKey(userkey);
7313     RegDeleteKeyA(prodkey, "");
7314     RegCloseKey(prodkey);
7315
7316     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7317
7318     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7319     lstrcatA(keypath, prod_squashed);
7320
7321     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7322     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7323
7324     /* unmanaged product key exists */
7325     hprod = 0xdeadbeef;
7326     r = MsiOpenProductA(prodcode, &hprod);
7327     ok(r == ERROR_UNKNOWN_PRODUCT,
7328        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7329     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7330
7331     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7332     lstrcatA(keypath, "Installer\\UserData\\");
7333     lstrcatA(keypath, usersid);
7334     lstrcatA(keypath, "\\Products\\");
7335     lstrcatA(keypath, prod_squashed);
7336
7337     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7339
7340     /* user product key exists */
7341     hprod = 0xdeadbeef;
7342     r = MsiOpenProductA(prodcode, &hprod);
7343     ok(r == ERROR_UNKNOWN_PRODUCT,
7344        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7345     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7346
7347     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7349
7350     /* InstallProperties 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     lstrcpyA(val, path);
7358     lstrcatA(val, "\\winetest.msi");
7359     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7360                          (const BYTE *)val, lstrlenA(val) + 1);
7361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7362
7363     /* LocalPackage value exists */
7364     hprod = 0xdeadbeef;
7365     r = MsiOpenProductA(prodcode, &hprod);
7366     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7367     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7368
7369     size = MAX_PATH;
7370     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7372     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7373     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7374
7375     MsiCloseHandle(hprod);
7376
7377     RegDeleteValueA(props, "LocalPackage");
7378     RegDeleteKeyA(props, "");
7379     RegCloseKey(props);
7380     RegDeleteKeyA(userkey, "");
7381     RegCloseKey(userkey);
7382     RegDeleteKeyA(prodkey, "");
7383     RegCloseKey(prodkey);
7384
7385     /* MSIINSTALLCONTEXT_MACHINE */
7386
7387     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7388     lstrcatA(keypath, prod_squashed);
7389
7390     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7391     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7392
7393     /* managed product key exists */
7394     hprod = 0xdeadbeef;
7395     r = MsiOpenProductA(prodcode, &hprod);
7396     ok(r == ERROR_UNKNOWN_PRODUCT,
7397        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7398     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7399
7400     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7401     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7402     lstrcatA(keypath, prod_squashed);
7403
7404     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7405     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7406
7407     /* user product key exists */
7408     hprod = 0xdeadbeef;
7409     r = MsiOpenProductA(prodcode, &hprod);
7410     ok(r == ERROR_UNKNOWN_PRODUCT,
7411        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7412     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7413
7414     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7415     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7416
7417     /* InstallProperties key exists */
7418     hprod = 0xdeadbeef;
7419     r = MsiOpenProductA(prodcode, &hprod);
7420     ok(r == ERROR_UNKNOWN_PRODUCT,
7421        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7422     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7423
7424     lstrcpyA(val, path);
7425     lstrcatA(val, "\\winetest.msi");
7426     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7427                          (const BYTE *)val, lstrlenA(val) + 1);
7428     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7429
7430     /* LocalPackage value exists */
7431     hprod = 0xdeadbeef;
7432     r = MsiOpenProductA(prodcode, &hprod);
7433     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7434     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7435
7436     size = MAX_PATH;
7437     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7438     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7439     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7440     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7441
7442     MsiCloseHandle(hprod);
7443
7444     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7445                          (const BYTE *)"winetest.msi", 13);
7446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7447
7448     /* LocalPackage has just the package name */
7449     hprod = 0xdeadbeef;
7450     r = MsiOpenProductA(prodcode, &hprod);
7451     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7452        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7453     if (r == ERROR_SUCCESS)
7454         MsiCloseHandle(hprod);
7455     else
7456         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7457
7458     lstrcpyA(val, path);
7459     lstrcatA(val, "\\winetest.msi");
7460     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7461                          (const BYTE *)val, lstrlenA(val) + 1);
7462     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7463
7464     DeleteFileA(msifile);
7465
7466     /* local package does not exist */
7467     hprod = 0xdeadbeef;
7468     r = MsiOpenProductA(prodcode, &hprod);
7469     ok(r == ERROR_UNKNOWN_PRODUCT,
7470        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7471     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7472
7473     RegDeleteValueA(props, "LocalPackage");
7474     RegDeleteKeyA(props, "");
7475     RegCloseKey(props);
7476     RegDeleteKeyA(userkey, "");
7477     RegCloseKey(userkey);
7478     RegDeleteKeyA(prodkey, "");
7479     RegCloseKey(prodkey);
7480
7481     DeleteFileA(msifile);
7482     LocalFree(usersid);
7483 }
7484
7485 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7486 {
7487     MSIINSTALLCONTEXT context;
7488     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7489     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7490     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7491     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7492     HKEY prodkey, patches, udprod, udpatch, hpatch;
7493     DWORD size, data;
7494     LONG res;
7495     UINT r;
7496
7497     create_test_guid(prodcode, prod_squashed);
7498     create_test_guid(patch, patch_squashed);
7499
7500     /* MSIPATCHSTATE_APPLIED */
7501
7502     lstrcpyA(patchcode, "apple");
7503     lstrcpyA(targetprod, "banana");
7504     context = 0xdeadbeef;
7505     lstrcpyA(targetsid, "kiwi");
7506     size = MAX_PATH;
7507     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7508                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7509                            &context, targetsid, &size);
7510     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7511     ok(!lstrcmpA(patchcode, "apple"),
7512        "Expected patchcode to be unchanged, got %s\n", patchcode);
7513     ok(!lstrcmpA(targetprod, "banana"),
7514        "Expected targetprod to be unchanged, got %s\n", targetprod);
7515     ok(context == 0xdeadbeef,
7516        "Expected context to be unchanged, got %d\n", context);
7517     ok(!lstrcmpA(targetsid, "kiwi"),
7518        "Expected targetsid to be unchanged, got %s\n", targetsid);
7519     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7520
7521     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7522     lstrcatA(keypath, expectedsid);
7523     lstrcatA(keypath, "\\Installer\\Products\\");
7524     lstrcatA(keypath, prod_squashed);
7525
7526     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7527     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7528
7529     /* managed product key exists */
7530     lstrcpyA(patchcode, "apple");
7531     lstrcpyA(targetprod, "banana");
7532     context = 0xdeadbeef;
7533     lstrcpyA(targetsid, "kiwi");
7534     size = MAX_PATH;
7535     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7536                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7537                            &context, targetsid, &size);
7538     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7539     ok(!lstrcmpA(patchcode, "apple"),
7540        "Expected patchcode to be unchanged, got %s\n", patchcode);
7541     ok(!lstrcmpA(targetprod, "banana"),
7542        "Expected targetprod to be unchanged, got %s\n", targetprod);
7543     ok(context == 0xdeadbeef,
7544        "Expected context to be unchanged, got %d\n", context);
7545     ok(!lstrcmpA(targetsid, "kiwi"),
7546        "Expected targetsid to be unchanged, got %s\n", targetsid);
7547     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7548
7549     res = RegCreateKeyA(prodkey, "Patches", &patches);
7550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7551
7552     /* patches key exists */
7553     lstrcpyA(patchcode, "apple");
7554     lstrcpyA(targetprod, "banana");
7555     context = 0xdeadbeef;
7556     lstrcpyA(targetsid, "kiwi");
7557     size = MAX_PATH;
7558     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7559                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7560                            &context, targetsid, &size);
7561     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7562     ok(!lstrcmpA(patchcode, "apple"),
7563        "Expected patchcode to be unchanged, got %s\n", patchcode);
7564     ok(!lstrcmpA(targetprod, "banana"),
7565        "Expected targetprod to be unchanged, got %s\n", targetprod);
7566     ok(context == 0xdeadbeef,
7567        "Expected context to be unchanged, got %d\n", context);
7568     ok(!lstrcmpA(targetsid, "kiwi"),
7569        "Expected targetsid to be unchanged, got %s\n", targetsid);
7570     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7571
7572     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7573                          (const BYTE *)patch_squashed,
7574                          lstrlenA(patch_squashed) + 1);
7575     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7576
7577     /* Patches value exists, is not REG_MULTI_SZ */
7578     lstrcpyA(patchcode, "apple");
7579     lstrcpyA(targetprod, "banana");
7580     context = 0xdeadbeef;
7581     lstrcpyA(targetsid, "kiwi");
7582     size = MAX_PATH;
7583     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7584                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7585                            &context, targetsid, &size);
7586     ok(r == ERROR_BAD_CONFIGURATION,
7587        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7588     ok(!lstrcmpA(patchcode, "apple"),
7589        "Expected patchcode to be unchanged, got %s\n", patchcode);
7590     ok(!lstrcmpA(targetprod, "banana"),
7591        "Expected targetprod to be unchanged, got %s\n", targetprod);
7592     ok(context == 0xdeadbeef,
7593        "Expected context to be unchanged, got %d\n", context);
7594     ok(!lstrcmpA(targetsid, "kiwi"),
7595        "Expected targetsid to be unchanged, got %s\n", targetsid);
7596     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7597
7598     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7599                          (const BYTE *)"a\0b\0c\0\0", 7);
7600     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7601
7602     /* Patches value exists, is not a squashed guid */
7603     lstrcpyA(patchcode, "apple");
7604     lstrcpyA(targetprod, "banana");
7605     context = 0xdeadbeef;
7606     lstrcpyA(targetsid, "kiwi");
7607     size = MAX_PATH;
7608     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7609                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7610                            &context, targetsid, &size);
7611     ok(r == ERROR_BAD_CONFIGURATION,
7612        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7613     ok(!lstrcmpA(patchcode, "apple"),
7614        "Expected patchcode to be unchanged, got %s\n", patchcode);
7615     ok(!lstrcmpA(targetprod, "banana"),
7616        "Expected targetprod to be unchanged, got %s\n", targetprod);
7617     ok(context == 0xdeadbeef,
7618        "Expected context to be unchanged, got %d\n", context);
7619     ok(!lstrcmpA(targetsid, "kiwi"),
7620        "Expected targetsid to be unchanged, got %s\n", targetsid);
7621     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7622
7623     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
7624     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7625                          (const BYTE *)patch_squashed,
7626                          lstrlenA(patch_squashed) + 2);
7627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7628
7629     /* Patches value exists */
7630     lstrcpyA(patchcode, "apple");
7631     lstrcpyA(targetprod, "banana");
7632     context = 0xdeadbeef;
7633     lstrcpyA(targetsid, "kiwi");
7634     size = MAX_PATH;
7635     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7636                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7637                            &context, targetsid, &size);
7638     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7639     ok(!lstrcmpA(patchcode, "apple"),
7640        "Expected patchcode to be unchanged, got %s\n", patchcode);
7641     ok(!lstrcmpA(targetprod, "banana"),
7642        "Expected targetprod to be unchanged, got %s\n", targetprod);
7643     ok(context == 0xdeadbeef,
7644        "Expected context to be unchanged, got %d\n", context);
7645     ok(!lstrcmpA(targetsid, "kiwi"),
7646        "Expected targetsid to be unchanged, got %s\n", targetsid);
7647     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7648
7649     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7650                          (const BYTE *)"whatever", 9);
7651     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7652
7653     /* patch squashed value exists */
7654     lstrcpyA(patchcode, "apple");
7655     lstrcpyA(targetprod, "banana");
7656     context = 0xdeadbeef;
7657     lstrcpyA(targetsid, "kiwi");
7658     size = MAX_PATH;
7659     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7660                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7661                            &context, targetsid, &size);
7662     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7663     ok(!lstrcmpA(patchcode, patch),
7664        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7665     ok(!lstrcmpA(targetprod, prodcode),
7666        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7667     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7668        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7669     ok(!lstrcmpA(targetsid, expectedsid),
7670        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7671     ok(size == lstrlenA(expectedsid),
7672        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7673
7674     /* increase the index */
7675     lstrcpyA(patchcode, "apple");
7676     lstrcpyA(targetprod, "banana");
7677     context = 0xdeadbeef;
7678     lstrcpyA(targetsid, "kiwi");
7679     size = MAX_PATH;
7680     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7681                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7682                            &context, targetsid, &size);
7683     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7684     ok(!lstrcmpA(patchcode, "apple"),
7685        "Expected patchcode to be unchanged, got %s\n", patchcode);
7686     ok(!lstrcmpA(targetprod, "banana"),
7687        "Expected targetprod to be unchanged, got %s\n", targetprod);
7688     ok(context == 0xdeadbeef,
7689        "Expected context to be unchanged, got %d\n", context);
7690     ok(!lstrcmpA(targetsid, "kiwi"),
7691        "Expected targetsid to be unchanged, got %s\n", targetsid);
7692     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7693
7694     /* increase again */
7695     lstrcpyA(patchcode, "apple");
7696     lstrcpyA(targetprod, "banana");
7697     context = 0xdeadbeef;
7698     lstrcpyA(targetsid, "kiwi");
7699     size = MAX_PATH;
7700     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7701                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
7702                            &context, targetsid, &size);
7703     ok(r == ERROR_INVALID_PARAMETER,
7704        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7705     ok(!lstrcmpA(patchcode, "apple"),
7706        "Expected patchcode to be unchanged, got %s\n", patchcode);
7707     ok(!lstrcmpA(targetprod, "banana"),
7708        "Expected targetprod to be unchanged, got %s\n", targetprod);
7709     ok(context == 0xdeadbeef,
7710        "Expected context to be unchanged, got %d\n", context);
7711     ok(!lstrcmpA(targetsid, "kiwi"),
7712        "Expected targetsid to be unchanged, got %s\n", targetsid);
7713     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7714
7715     /* szPatchCode is NULL */
7716     lstrcpyA(targetprod, "banana");
7717     context = 0xdeadbeef;
7718     lstrcpyA(targetsid, "kiwi");
7719     size = MAX_PATH;
7720     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7721                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
7722                            &context, targetsid, &size);
7723     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7724     ok(!lstrcmpA(targetprod, prodcode),
7725        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7726     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7727        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7728     ok(!lstrcmpA(targetsid, expectedsid),
7729        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7730     ok(size == lstrlenA(expectedsid),
7731        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7732
7733     /* szTargetProductCode is NULL */
7734     lstrcpyA(patchcode, "apple");
7735     context = 0xdeadbeef;
7736     lstrcpyA(targetsid, "kiwi");
7737     size = MAX_PATH;
7738     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7739                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
7740                            &context, targetsid, &size);
7741     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7742     ok(!lstrcmpA(patchcode, patch),
7743        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7744     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7745        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7746     ok(!lstrcmpA(targetsid, expectedsid),
7747        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7748     ok(size == lstrlenA(expectedsid),
7749        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7750
7751     /* pdwTargetProductContext is NULL */
7752     lstrcpyA(patchcode, "apple");
7753     lstrcpyA(targetprod, "banana");
7754     lstrcpyA(targetsid, "kiwi");
7755     size = MAX_PATH;
7756     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7757                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7758                            NULL, 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(!lstrcmpA(targetsid, expectedsid),
7765        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7766     ok(size == lstrlenA(expectedsid),
7767        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7768
7769     /* szTargetUserSid is NULL */
7770     lstrcpyA(patchcode, "apple");
7771     lstrcpyA(targetprod, "banana");
7772     context = 0xdeadbeef;
7773     size = MAX_PATH;
7774     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7775                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7776                            &context, NULL, &size);
7777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7778     ok(!lstrcmpA(patchcode, patch),
7779        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7780     ok(!lstrcmpA(targetprod, prodcode),
7781        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7782     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7783        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7784     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7785        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
7786
7787     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
7788     lstrcpyA(patchcode, "apple");
7789     lstrcpyA(targetprod, "banana");
7790     context = 0xdeadbeef;
7791     lstrcpyA(targetsid, "kiwi");
7792     size = lstrlenA(expectedsid);
7793     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7794                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7795                            &context, targetsid, &size);
7796     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
7797     ok(!lstrcmpA(patchcode, patch),
7798        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7799     ok(!lstrcmpA(targetprod, prodcode),
7800        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7801     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7802        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7803     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
7804        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7805     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7806        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
7807
7808     /* pcchTargetUserSid has enough room for NULL terminator */
7809     lstrcpyA(patchcode, "apple");
7810     lstrcpyA(targetprod, "banana");
7811     context = 0xdeadbeef;
7812     lstrcpyA(targetsid, "kiwi");
7813     size = lstrlenA(expectedsid) + 1;
7814     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7815                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7816                            &context, targetsid, &size);
7817     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7818     ok(!lstrcmpA(patchcode, patch),
7819        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7820     ok(!lstrcmpA(targetprod, prodcode),
7821        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7822     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7823        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7824     ok(!lstrcmpA(targetsid, expectedsid),
7825        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7826     ok(size == lstrlenA(expectedsid),
7827        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7828
7829     /* both szTargetuserSid and pcchTargetUserSid are NULL */
7830     lstrcpyA(patchcode, "apple");
7831     lstrcpyA(targetprod, "banana");
7832     context = 0xdeadbeef;
7833     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7834                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7835                            &context, NULL, NULL);
7836     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7837     ok(!lstrcmpA(patchcode, patch),
7838        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7839     ok(!lstrcmpA(targetprod, prodcode),
7840        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7841     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7842        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7843
7844     /* MSIPATCHSTATE_SUPERSEDED */
7845
7846     lstrcpyA(patchcode, "apple");
7847     lstrcpyA(targetprod, "banana");
7848     context = 0xdeadbeef;
7849     lstrcpyA(targetsid, "kiwi");
7850     size = MAX_PATH;
7851     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7852                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7853                            &context, targetsid, &size);
7854     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7855     ok(!lstrcmpA(patchcode, "apple"),
7856        "Expected patchcode to be unchanged, got %s\n", patchcode);
7857     ok(!lstrcmpA(targetprod, "banana"),
7858        "Expected targetprod to be unchanged, got %s\n", targetprod);
7859     ok(context == 0xdeadbeef,
7860        "Expected context to be unchanged, got %d\n", context);
7861     ok(!lstrcmpA(targetsid, "kiwi"),
7862        "Expected targetsid to be unchanged, got %s\n", targetsid);
7863     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7864
7865     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
7866     lstrcatA(keypath, expectedsid);
7867     lstrcatA(keypath, "\\Products\\");
7868     lstrcatA(keypath, prod_squashed);
7869
7870     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
7871     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7872
7873     /* UserData product key exists */
7874     lstrcpyA(patchcode, "apple");
7875     lstrcpyA(targetprod, "banana");
7876     context = 0xdeadbeef;
7877     lstrcpyA(targetsid, "kiwi");
7878     size = MAX_PATH;
7879     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7880                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7881                            &context, targetsid, &size);
7882     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7883     ok(!lstrcmpA(patchcode, "apple"),
7884        "Expected patchcode to be unchanged, got %s\n", patchcode);
7885     ok(!lstrcmpA(targetprod, "banana"),
7886        "Expected targetprod to be unchanged, got %s\n", targetprod);
7887     ok(context == 0xdeadbeef,
7888        "Expected context to be unchanged, got %d\n", context);
7889     ok(!lstrcmpA(targetsid, "kiwi"),
7890        "Expected targetsid to be unchanged, got %s\n", targetsid);
7891     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7892
7893     res = RegCreateKeyA(udprod, "Patches", &udpatch);
7894     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7895
7896     /* UserData patches key exists */
7897     lstrcpyA(patchcode, "apple");
7898     lstrcpyA(targetprod, "banana");
7899     context = 0xdeadbeef;
7900     lstrcpyA(targetsid, "kiwi");
7901     size = MAX_PATH;
7902     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7903                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7904                            &context, targetsid, &size);
7905     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7906     ok(!lstrcmpA(patchcode, "apple"),
7907        "Expected patchcode to be unchanged, got %s\n", patchcode);
7908     ok(!lstrcmpA(targetprod, "banana"),
7909        "Expected targetprod to be unchanged, got %s\n", targetprod);
7910     ok(context == 0xdeadbeef,
7911        "Expected context to be unchanged, got %d\n", context);
7912     ok(!lstrcmpA(targetsid, "kiwi"),
7913        "Expected targetsid to be unchanged, got %s\n", targetsid);
7914     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7915
7916     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
7917     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7918
7919     /* specific UserData patch key exists */
7920     lstrcpyA(patchcode, "apple");
7921     lstrcpyA(targetprod, "banana");
7922     context = 0xdeadbeef;
7923     lstrcpyA(targetsid, "kiwi");
7924     size = MAX_PATH;
7925     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7926                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7927                            &context, targetsid, &size);
7928     ok(r == ERROR_BAD_CONFIGURATION,
7929        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7930     ok(!lstrcmpA(patchcode, "apple"),
7931        "Expected patchcode to be unchanged, got %s\n", patchcode);
7932     ok(!lstrcmpA(targetprod, "banana"),
7933        "Expected targetprod to be unchanged, got %s\n", targetprod);
7934     ok(context == 0xdeadbeef,
7935        "Expected context to be unchanged, got %d\n", context);
7936     ok(!lstrcmpA(targetsid, "kiwi"),
7937        "Expected targetsid to be unchanged, got %s\n", targetsid);
7938     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7939
7940     data = MSIPATCHSTATE_SUPERSEDED;
7941     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
7942                          (const BYTE *)&data, sizeof(DWORD));
7943     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7944
7945     /* State value exists */
7946     lstrcpyA(patchcode, "apple");
7947     lstrcpyA(targetprod, "banana");
7948     context = 0xdeadbeef;
7949     lstrcpyA(targetsid, "kiwi");
7950     size = MAX_PATH;
7951     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7952                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
7953                            &context, targetsid, &size);
7954     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7955     ok(!lstrcmpA(patchcode, patch),
7956        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7957     ok(!lstrcmpA(targetprod, prodcode),
7958        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7959     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7960        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7961     ok(!lstrcmpA(targetsid, expectedsid),
7962        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7963     ok(size == lstrlenA(expectedsid),
7964        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7965
7966     /* MSIPATCHSTATE_OBSOLETED */
7967
7968     lstrcpyA(patchcode, "apple");
7969     lstrcpyA(targetprod, "banana");
7970     context = 0xdeadbeef;
7971     lstrcpyA(targetsid, "kiwi");
7972     size = MAX_PATH;
7973     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7974                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
7975                            &context, targetsid, &size);
7976     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7977     ok(!lstrcmpA(patchcode, "apple"),
7978        "Expected patchcode to be unchanged, got %s\n", patchcode);
7979     ok(!lstrcmpA(targetprod, "banana"),
7980        "Expected targetprod to be unchanged, got %s\n", targetprod);
7981     ok(context == 0xdeadbeef,
7982        "Expected context to be unchanged, got %d\n", context);
7983     ok(!lstrcmpA(targetsid, "kiwi"),
7984        "Expected targetsid to be unchanged, got %s\n", targetsid);
7985     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7986
7987     data = MSIPATCHSTATE_OBSOLETED;
7988     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
7989                          (const BYTE *)&data, sizeof(DWORD));
7990     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7991
7992     /* State value is obsoleted */
7993     lstrcpyA(patchcode, "apple");
7994     lstrcpyA(targetprod, "banana");
7995     context = 0xdeadbeef;
7996     lstrcpyA(targetsid, "kiwi");
7997     size = MAX_PATH;
7998     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7999                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8000                            &context, targetsid, &size);
8001     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8002     ok(!lstrcmpA(patchcode, patch),
8003        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8004     ok(!lstrcmpA(targetprod, prodcode),
8005        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8006     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8007        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8008     ok(!lstrcmpA(targetsid, expectedsid),
8009        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8010     ok(size == lstrlenA(expectedsid),
8011        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8012
8013     /* MSIPATCHSTATE_REGISTERED */
8014     /* FIXME */
8015
8016     /* MSIPATCHSTATE_ALL */
8017
8018     /* 1st */
8019     lstrcpyA(patchcode, "apple");
8020     lstrcpyA(targetprod, "banana");
8021     context = 0xdeadbeef;
8022     lstrcpyA(targetsid, "kiwi");
8023     size = MAX_PATH;
8024     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8025                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8026                            &context, targetsid, &size);
8027     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8028     ok(!lstrcmpA(patchcode, patch),
8029        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8030     ok(!lstrcmpA(targetprod, prodcode),
8031        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8032     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8033        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8034     ok(!lstrcmpA(targetsid, expectedsid),
8035        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8036     ok(size == lstrlenA(expectedsid),
8037        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8038
8039     /* same patch in multiple places, only one is enumerated */
8040     lstrcpyA(patchcode, "apple");
8041     lstrcpyA(targetprod, "banana");
8042     context = 0xdeadbeef;
8043     lstrcpyA(targetsid, "kiwi");
8044     size = MAX_PATH;
8045     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8046                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8047                            &context, targetsid, &size);
8048     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8049     ok(!lstrcmpA(patchcode, "apple"),
8050        "Expected patchcode to be unchanged, got %s\n", patchcode);
8051     ok(!lstrcmpA(targetprod, "banana"),
8052        "Expected targetprod to be unchanged, got %s\n", targetprod);
8053     ok(context == 0xdeadbeef,
8054        "Expected context to be unchanged, got %d\n", context);
8055     ok(!lstrcmpA(targetsid, "kiwi"),
8056        "Expected targetsid to be unchanged, got %s\n", targetsid);
8057     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8058
8059     RegDeleteValueA(hpatch, "State");
8060     RegDeleteKeyA(hpatch, "");
8061     RegCloseKey(hpatch);
8062     RegDeleteKeyA(udpatch, "");
8063     RegCloseKey(udpatch);
8064     RegDeleteKeyA(udprod, "");
8065     RegCloseKey(udprod);
8066     RegDeleteValueA(patches, "Patches");
8067     RegDeleteKeyA(patches, "");
8068     RegCloseKey(patches);
8069     RegDeleteKeyA(prodkey, "");
8070     RegCloseKey(prodkey);
8071 }
8072
8073 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8074 {
8075     MSIINSTALLCONTEXT context;
8076     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8077     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8078     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8079     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8080     HKEY prodkey, patches, udprod, udpatch;
8081     HKEY userkey, hpatch;
8082     DWORD size, data;
8083     LONG res;
8084     UINT r;
8085
8086     create_test_guid(prodcode, prod_squashed);
8087     create_test_guid(patch, patch_squashed);
8088
8089     /* MSIPATCHSTATE_APPLIED */
8090
8091     lstrcpyA(patchcode, "apple");
8092     lstrcpyA(targetprod, "banana");
8093     context = 0xdeadbeef;
8094     lstrcpyA(targetsid, "kiwi");
8095     size = MAX_PATH;
8096     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8097                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8098                            &context, targetsid, &size);
8099     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8100     ok(!lstrcmpA(patchcode, "apple"),
8101        "Expected patchcode to be unchanged, got %s\n", patchcode);
8102     ok(!lstrcmpA(targetprod, "banana"),
8103        "Expected targetprod to be unchanged, got %s\n", targetprod);
8104     ok(context == 0xdeadbeef,
8105        "Expected context to be unchanged, got %d\n", context);
8106     ok(!lstrcmpA(targetsid, "kiwi"),
8107        "Expected targetsid to be unchanged, got %s\n", targetsid);
8108     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8109
8110     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8111     lstrcatA(keypath, prod_squashed);
8112
8113     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8114     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8115
8116     /* current user product key exists */
8117     lstrcpyA(patchcode, "apple");
8118     lstrcpyA(targetprod, "banana");
8119     context = 0xdeadbeef;
8120     lstrcpyA(targetsid, "kiwi");
8121     size = MAX_PATH;
8122     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8123                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8124                            &context, targetsid, &size);
8125     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8126     ok(!lstrcmpA(patchcode, "apple"),
8127        "Expected patchcode to be unchanged, got %s\n", patchcode);
8128     ok(!lstrcmpA(targetprod, "banana"),
8129        "Expected targetprod to be unchanged, got %s\n", targetprod);
8130     ok(context == 0xdeadbeef,
8131        "Expected context to be unchanged, got %d\n", context);
8132     ok(!lstrcmpA(targetsid, "kiwi"),
8133        "Expected targetsid to be unchanged, got %s\n", targetsid);
8134     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8135
8136     res = RegCreateKeyA(prodkey, "Patches", &patches);
8137     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8138
8139     /* Patches key exists */
8140     lstrcpyA(patchcode, "apple");
8141     lstrcpyA(targetprod, "banana");
8142     context = 0xdeadbeef;
8143     lstrcpyA(targetsid, "kiwi");
8144     size = MAX_PATH;
8145     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8146                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8147                            &context, targetsid, &size);
8148     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8149     ok(!lstrcmpA(patchcode, "apple"),
8150        "Expected patchcode to be unchanged, got %s\n", patchcode);
8151     ok(!lstrcmpA(targetprod, "banana"),
8152        "Expected targetprod to be unchanged, got %s\n", targetprod);
8153     ok(context == 0xdeadbeef,
8154        "Expected context to be unchanged, got %d\n", context);
8155     ok(!lstrcmpA(targetsid, "kiwi"),
8156        "Expected targetsid to be unchanged, got %s\n", targetsid);
8157     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8158
8159     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8160                          (const BYTE *)patch_squashed,
8161                          lstrlenA(patch_squashed) + 1);
8162     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8163
8164     /* Patches value exists, is not REG_MULTI_SZ */
8165     lstrcpyA(patchcode, "apple");
8166     lstrcpyA(targetprod, "banana");
8167     context = 0xdeadbeef;
8168     lstrcpyA(targetsid, "kiwi");
8169     size = MAX_PATH;
8170     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8171                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8172                            &context, targetsid, &size);
8173     ok(r == ERROR_BAD_CONFIGURATION,
8174        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8175     ok(!lstrcmpA(patchcode, "apple"),
8176        "Expected patchcode to be unchanged, got %s\n", patchcode);
8177     ok(!lstrcmpA(targetprod, "banana"),
8178        "Expected targetprod to be unchanged, got %s\n", targetprod);
8179     ok(context == 0xdeadbeef,
8180        "Expected context to be unchanged, got %d\n", context);
8181     ok(!lstrcmpA(targetsid, "kiwi"),
8182        "Expected targetsid to be unchanged, got %s\n", targetsid);
8183     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8184
8185     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8186                          (const BYTE *)"a\0b\0c\0\0", 7);
8187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8188
8189     /* Patches value exists, is not a squashed guid */
8190     lstrcpyA(patchcode, "apple");
8191     lstrcpyA(targetprod, "banana");
8192     context = 0xdeadbeef;
8193     lstrcpyA(targetsid, "kiwi");
8194     size = MAX_PATH;
8195     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8196                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8197                            &context, targetsid, &size);
8198     ok(r == ERROR_BAD_CONFIGURATION,
8199        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8200     ok(!lstrcmpA(patchcode, "apple"),
8201        "Expected patchcode to be unchanged, got %s\n", patchcode);
8202     ok(!lstrcmpA(targetprod, "banana"),
8203        "Expected targetprod to be unchanged, got %s\n", targetprod);
8204     ok(context == 0xdeadbeef,
8205        "Expected context to be unchanged, got %d\n", context);
8206     ok(!lstrcmpA(targetsid, "kiwi"),
8207        "Expected targetsid to be unchanged, got %s\n", targetsid);
8208     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8209
8210     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8211                          (const BYTE *)patch_squashed,
8212                          lstrlenA(patch_squashed) + 1);
8213     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8214
8215     /* Patches value exists */
8216     lstrcpyA(patchcode, "apple");
8217     lstrcpyA(targetprod, "banana");
8218     context = 0xdeadbeef;
8219     lstrcpyA(targetsid, "kiwi");
8220     size = MAX_PATH;
8221     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8222                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8223                            &context, targetsid, &size);
8224     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8225     ok(!lstrcmpA(patchcode, "apple"),
8226        "Expected patchcode to be unchanged, got %s\n", patchcode);
8227     ok(!lstrcmpA(targetprod, "banana"),
8228        "Expected targetprod to be unchanged, got %s\n", targetprod);
8229     ok(context == 0xdeadbeef,
8230        "Expected context to be unchanged, got %d\n", context);
8231     ok(!lstrcmpA(targetsid, "kiwi"),
8232        "Expected targetsid to be unchanged, got %s\n", targetsid);
8233     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8234
8235     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8236                          (const BYTE *)"whatever", 9);
8237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8238
8239     /* patch code value exists */
8240     lstrcpyA(patchcode, "apple");
8241     lstrcpyA(targetprod, "banana");
8242     context = 0xdeadbeef;
8243     lstrcpyA(targetsid, "kiwi");
8244     size = MAX_PATH;
8245     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8246                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8247                            &context, targetsid, &size);
8248     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8249     ok(!lstrcmpA(patchcode, "apple"),
8250        "Expected patchcode to be unchanged, got %s\n", patchcode);
8251     ok(!lstrcmpA(targetprod, "banana"),
8252        "Expected targetprod to be unchanged, got %s\n", targetprod);
8253     ok(context == 0xdeadbeef,
8254        "Expected context to be unchanged, got %d\n", context);
8255     ok(!lstrcmpA(targetsid, "kiwi"),
8256        "Expected targetsid to be unchanged, got %s\n", targetsid);
8257     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8258
8259     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8260     lstrcatA(keypath, expectedsid);
8261     lstrcatA(keypath, "\\Patches\\");
8262     lstrcatA(keypath, patch_squashed);
8263
8264     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
8265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8266
8267     /* userdata patch key exists */
8268     lstrcpyA(patchcode, "apple");
8269     lstrcpyA(targetprod, "banana");
8270     context = 0xdeadbeef;
8271     lstrcpyA(targetsid, "kiwi");
8272     size = MAX_PATH;
8273     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8274                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8275                            &context, targetsid, &size);
8276     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8277     ok(!lstrcmpA(patchcode, patch),
8278        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8279     ok(!lstrcmpA(targetprod, prodcode),
8280        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8281     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8282        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8283     ok(!lstrcmpA(targetsid, expectedsid),
8284        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8285     ok(size == lstrlenA(expectedsid),
8286        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8287
8288     /* MSIPATCHSTATE_SUPERSEDED */
8289
8290     lstrcpyA(patchcode, "apple");
8291     lstrcpyA(targetprod, "banana");
8292     context = 0xdeadbeef;
8293     lstrcpyA(targetsid, "kiwi");
8294     size = MAX_PATH;
8295     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8296                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8297                            &context, targetsid, &size);
8298     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8299     ok(!lstrcmpA(patchcode, "apple"),
8300        "Expected patchcode to be unchanged, got %s\n", patchcode);
8301     ok(!lstrcmpA(targetprod, "banana"),
8302        "Expected targetprod to be unchanged, got %s\n", targetprod);
8303     ok(context == 0xdeadbeef,
8304        "Expected context to be unchanged, got %d\n", context);
8305     ok(!lstrcmpA(targetsid, "kiwi"),
8306        "Expected targetsid to be unchanged, got %s\n", targetsid);
8307     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8308
8309     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8310     lstrcatA(keypath, expectedsid);
8311     lstrcatA(keypath, "\\Products\\");
8312     lstrcatA(keypath, prod_squashed);
8313
8314     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8315     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8316
8317     /* UserData product key exists */
8318     lstrcpyA(patchcode, "apple");
8319     lstrcpyA(targetprod, "banana");
8320     context = 0xdeadbeef;
8321     lstrcpyA(targetsid, "kiwi");
8322     size = MAX_PATH;
8323     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8324                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8325                            &context, targetsid, &size);
8326     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8327     ok(!lstrcmpA(patchcode, "apple"),
8328        "Expected patchcode to be unchanged, got %s\n", patchcode);
8329     ok(!lstrcmpA(targetprod, "banana"),
8330        "Expected targetprod to be unchanged, got %s\n", targetprod);
8331     ok(context == 0xdeadbeef,
8332        "Expected context to be unchanged, got %d\n", context);
8333     ok(!lstrcmpA(targetsid, "kiwi"),
8334        "Expected targetsid to be unchanged, got %s\n", targetsid);
8335     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8336
8337     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8339
8340     /* UserData patches key exists */
8341     lstrcpyA(patchcode, "apple");
8342     lstrcpyA(targetprod, "banana");
8343     context = 0xdeadbeef;
8344     lstrcpyA(targetsid, "kiwi");
8345     size = MAX_PATH;
8346     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8347                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8348                            &context, targetsid, &size);
8349     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8350     ok(!lstrcmpA(patchcode, "apple"),
8351        "Expected patchcode to be unchanged, got %s\n", patchcode);
8352     ok(!lstrcmpA(targetprod, "banana"),
8353        "Expected targetprod to be unchanged, got %s\n", targetprod);
8354     ok(context == 0xdeadbeef,
8355        "Expected context to be unchanged, got %d\n", context);
8356     ok(!lstrcmpA(targetsid, "kiwi"),
8357        "Expected targetsid to be unchanged, got %s\n", targetsid);
8358     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8359
8360     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8362
8363     /* specific UserData patch key exists */
8364     lstrcpyA(patchcode, "apple");
8365     lstrcpyA(targetprod, "banana");
8366     context = 0xdeadbeef;
8367     lstrcpyA(targetsid, "kiwi");
8368     size = MAX_PATH;
8369     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8370                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8371                            &context, targetsid, &size);
8372     ok(r == ERROR_BAD_CONFIGURATION,
8373        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8374     ok(!lstrcmpA(patchcode, "apple"),
8375        "Expected patchcode to be unchanged, got %s\n", patchcode);
8376     ok(!lstrcmpA(targetprod, "banana"),
8377        "Expected targetprod to be unchanged, got %s\n", targetprod);
8378     ok(context == 0xdeadbeef,
8379        "Expected context to be unchanged, got %d\n", context);
8380     ok(!lstrcmpA(targetsid, "kiwi"),
8381        "Expected targetsid to be unchanged, got %s\n", targetsid);
8382     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8383
8384     data = MSIPATCHSTATE_SUPERSEDED;
8385     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8386                          (const BYTE *)&data, sizeof(DWORD));
8387     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8388
8389     /* State value exists */
8390     lstrcpyA(patchcode, "apple");
8391     lstrcpyA(targetprod, "banana");
8392     context = 0xdeadbeef;
8393     lstrcpyA(targetsid, "kiwi");
8394     size = MAX_PATH;
8395     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8396                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8397                            &context, targetsid, &size);
8398     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8399     ok(!lstrcmpA(patchcode, patch),
8400        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8401     ok(!lstrcmpA(targetprod, prodcode),
8402        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8403     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8404        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8405     ok(!lstrcmpA(targetsid, expectedsid),
8406        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8407     ok(size == lstrlenA(expectedsid),
8408        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8409
8410     /* MSIPATCHSTATE_OBSOLETED */
8411
8412     lstrcpyA(patchcode, "apple");
8413     lstrcpyA(targetprod, "banana");
8414     context = 0xdeadbeef;
8415     lstrcpyA(targetsid, "kiwi");
8416     size = MAX_PATH;
8417     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8418                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8419                            &context, targetsid, &size);
8420     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8421     ok(!lstrcmpA(patchcode, "apple"),
8422        "Expected patchcode to be unchanged, got %s\n", patchcode);
8423     ok(!lstrcmpA(targetprod, "banana"),
8424        "Expected targetprod to be unchanged, got %s\n", targetprod);
8425     ok(context == 0xdeadbeef,
8426        "Expected context to be unchanged, got %d\n", context);
8427     ok(!lstrcmpA(targetsid, "kiwi"),
8428        "Expected targetsid to be unchanged, got %s\n", targetsid);
8429     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8430
8431     data = MSIPATCHSTATE_OBSOLETED;
8432     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8433                          (const BYTE *)&data, sizeof(DWORD));
8434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8435
8436     /* State value is obsoleted */
8437     lstrcpyA(patchcode, "apple");
8438     lstrcpyA(targetprod, "banana");
8439     context = 0xdeadbeef;
8440     lstrcpyA(targetsid, "kiwi");
8441     size = MAX_PATH;
8442     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8443                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8444                            &context, targetsid, &size);
8445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8446     ok(!lstrcmpA(patchcode, patch),
8447        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8448     ok(!lstrcmpA(targetprod, prodcode),
8449        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8450     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8451        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8452     ok(!lstrcmpA(targetsid, expectedsid),
8453        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8454     ok(size == lstrlenA(expectedsid),
8455        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8456
8457     /* MSIPATCHSTATE_REGISTERED */
8458     /* FIXME */
8459
8460     /* MSIPATCHSTATE_ALL */
8461
8462     /* 1st */
8463     lstrcpyA(patchcode, "apple");
8464     lstrcpyA(targetprod, "banana");
8465     context = 0xdeadbeef;
8466     lstrcpyA(targetsid, "kiwi");
8467     size = MAX_PATH;
8468     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8469                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8470                            &context, targetsid, &size);
8471     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8472     ok(!lstrcmpA(patchcode, patch),
8473        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8474     ok(!lstrcmpA(targetprod, prodcode),
8475        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8476     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8477        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8478     ok(!lstrcmpA(targetsid, expectedsid),
8479        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8480     ok(size == lstrlenA(expectedsid),
8481        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8482
8483     /* same patch in multiple places, only one is enumerated */
8484     lstrcpyA(patchcode, "apple");
8485     lstrcpyA(targetprod, "banana");
8486     context = 0xdeadbeef;
8487     lstrcpyA(targetsid, "kiwi");
8488     size = MAX_PATH;
8489     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8490                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8491                            &context, targetsid, &size);
8492     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8493     ok(!lstrcmpA(patchcode, "apple"),
8494        "Expected patchcode to be unchanged, got %s\n", patchcode);
8495     ok(!lstrcmpA(targetprod, "banana"),
8496        "Expected targetprod to be unchanged, got %s\n", targetprod);
8497     ok(context == 0xdeadbeef,
8498        "Expected context to be unchanged, got %d\n", context);
8499     ok(!lstrcmpA(targetsid, "kiwi"),
8500        "Expected targetsid to be unchanged, got %s\n", targetsid);
8501     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8502
8503     RegDeleteValueA(hpatch, "State");
8504     RegDeleteKeyA(hpatch, "");
8505     RegCloseKey(hpatch);
8506     RegDeleteKeyA(udpatch, "");
8507     RegCloseKey(udpatch);
8508     RegDeleteKeyA(udprod, "");
8509     RegCloseKey(udprod);
8510     RegDeleteKeyA(userkey, "");
8511     RegCloseKey(userkey);
8512     RegDeleteValueA(patches, patch_squashed);
8513     RegDeleteValueA(patches, "Patches");
8514     RegDeleteKeyA(patches, "");
8515     RegCloseKey(patches);
8516     RegDeleteKeyA(prodkey, "");
8517     RegCloseKey(prodkey);
8518 }
8519
8520 static void test_MsiEnumPatchesEx_machine(void)
8521 {
8522     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8523     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8524     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8525     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8526     HKEY prodkey, patches, udprod, udpatch;
8527     HKEY hpatch;
8528     MSIINSTALLCONTEXT context;
8529     DWORD size, data;
8530     LONG res;
8531     UINT r;
8532
8533     create_test_guid(prodcode, prod_squashed);
8534     create_test_guid(patch, patch_squashed);
8535
8536     /* MSIPATCHSTATE_APPLIED */
8537
8538     lstrcpyA(patchcode, "apple");
8539     lstrcpyA(targetprod, "banana");
8540     context = 0xdeadbeef;
8541     lstrcpyA(targetsid, "kiwi");
8542     size = MAX_PATH;
8543     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8544                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8545                            &context, targetsid, &size);
8546     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8547     ok(!lstrcmpA(patchcode, "apple"),
8548        "Expected patchcode to be unchanged, got %s\n", patchcode);
8549     ok(!lstrcmpA(targetprod, "banana"),
8550        "Expected targetprod to be unchanged, got %s\n", targetprod);
8551     ok(context == 0xdeadbeef,
8552        "Expected context to be unchanged, got %d\n", context);
8553     ok(!lstrcmpA(targetsid, "kiwi"),
8554        "Expected targetsid to be unchanged, got %s\n", targetsid);
8555     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8556
8557     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8558     lstrcatA(keypath, prod_squashed);
8559
8560     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
8561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8562
8563     /* local product key exists */
8564     lstrcpyA(patchcode, "apple");
8565     lstrcpyA(targetprod, "banana");
8566     context = 0xdeadbeef;
8567     lstrcpyA(targetsid, "kiwi");
8568     size = MAX_PATH;
8569     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8570                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8571                            &context, targetsid, &size);
8572     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8573     ok(!lstrcmpA(patchcode, "apple"),
8574        "Expected patchcode to be unchanged, got %s\n", patchcode);
8575     ok(!lstrcmpA(targetprod, "banana"),
8576        "Expected targetprod to be unchanged, got %s\n", targetprod);
8577     ok(context == 0xdeadbeef,
8578        "Expected context to be unchanged, got %d\n", context);
8579     ok(!lstrcmpA(targetsid, "kiwi"),
8580        "Expected targetsid to be unchanged, got %s\n", targetsid);
8581     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8582
8583     res = RegCreateKeyA(prodkey, "Patches", &patches);
8584     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8585
8586     /* Patches key exists */
8587     lstrcpyA(patchcode, "apple");
8588     lstrcpyA(targetprod, "banana");
8589     context = 0xdeadbeef;
8590     lstrcpyA(targetsid, "kiwi");
8591     size = MAX_PATH;
8592     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8593                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8594                            &context, targetsid, &size);
8595     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8596     ok(!lstrcmpA(patchcode, "apple"),
8597        "Expected patchcode to be unchanged, got %s\n", patchcode);
8598     ok(!lstrcmpA(targetprod, "banana"),
8599        "Expected targetprod to be unchanged, got %s\n", targetprod);
8600     ok(context == 0xdeadbeef,
8601        "Expected context to be unchanged, got %d\n", context);
8602     ok(!lstrcmpA(targetsid, "kiwi"),
8603        "Expected targetsid to be unchanged, got %s\n", targetsid);
8604     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8605
8606     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8607                          (const BYTE *)patch_squashed,
8608                          lstrlenA(patch_squashed) + 1);
8609     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8610
8611     /* Patches value exists, is not REG_MULTI_SZ */
8612     lstrcpyA(patchcode, "apple");
8613     lstrcpyA(targetprod, "banana");
8614     context = 0xdeadbeef;
8615     lstrcpyA(targetsid, "kiwi");
8616     size = MAX_PATH;
8617     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8618                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8619                            &context, targetsid, &size);
8620     ok(r == ERROR_BAD_CONFIGURATION,
8621        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8622     ok(!lstrcmpA(patchcode, "apple"),
8623        "Expected patchcode to be unchanged, got %s\n", patchcode);
8624     ok(!lstrcmpA(targetprod, "banana"),
8625        "Expected targetprod to be unchanged, got %s\n", targetprod);
8626     ok(context == 0xdeadbeef,
8627        "Expected context to be unchanged, got %d\n", context);
8628     ok(!lstrcmpA(targetsid, "kiwi"),
8629        "Expected targetsid to be unchanged, got %s\n", targetsid);
8630     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8631
8632     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8633                          (const BYTE *)"a\0b\0c\0\0", 7);
8634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8635
8636     /* Patches value exists, is not a squashed guid */
8637     lstrcpyA(patchcode, "apple");
8638     lstrcpyA(targetprod, "banana");
8639     context = 0xdeadbeef;
8640     lstrcpyA(targetsid, "kiwi");
8641     size = MAX_PATH;
8642     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8643                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8644                            &context, targetsid, &size);
8645     ok(r == ERROR_BAD_CONFIGURATION,
8646        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8647     ok(!lstrcmpA(patchcode, "apple"),
8648        "Expected patchcode to be unchanged, got %s\n", patchcode);
8649     ok(!lstrcmpA(targetprod, "banana"),
8650        "Expected targetprod to be unchanged, got %s\n", targetprod);
8651     ok(context == 0xdeadbeef,
8652        "Expected context to be unchanged, got %d\n", context);
8653     ok(!lstrcmpA(targetsid, "kiwi"),
8654        "Expected targetsid to be unchanged, got %s\n", targetsid);
8655     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8656
8657     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8658     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8659                          (const BYTE *)patch_squashed,
8660                          lstrlenA(patch_squashed) + 2);
8661     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8662
8663     /* Patches value exists */
8664     lstrcpyA(patchcode, "apple");
8665     lstrcpyA(targetprod, "banana");
8666     context = 0xdeadbeef;
8667     lstrcpyA(targetsid, "kiwi");
8668     size = MAX_PATH;
8669     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8670                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8671                            &context, targetsid, &size);
8672     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8673     ok(!lstrcmpA(patchcode, "apple"),
8674        "Expected patchcode to be unchanged, got %s\n", patchcode);
8675     ok(!lstrcmpA(targetprod, "banana"),
8676        "Expected targetprod to be unchanged, got %s\n", targetprod);
8677     ok(context == 0xdeadbeef,
8678        "Expected context to be unchanged, got %d\n", context);
8679     ok(!lstrcmpA(targetsid, "kiwi"),
8680        "Expected targetsid to be unchanged, got %s\n", targetsid);
8681     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8682
8683     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8684                          (const BYTE *)"whatever", 9);
8685     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8686
8687     /* patch code value exists */
8688     lstrcpyA(patchcode, "apple");
8689     lstrcpyA(targetprod, "banana");
8690     context = 0xdeadbeef;
8691     lstrcpyA(targetsid, "kiwi");
8692     size = MAX_PATH;
8693     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8694                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8695                            &context, targetsid, &size);
8696     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8697     ok(!lstrcmpA(patchcode, patch),
8698        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8699     ok(!lstrcmpA(targetprod, prodcode),
8700        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8701     ok(context == MSIINSTALLCONTEXT_MACHINE,
8702        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8703     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8704     ok(size == 0, "Expected 0, got %d\n", size);
8705
8706     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8707     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8708     lstrcatA(keypath, prod_squashed);
8709
8710     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8711     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8712
8713     /* local UserData product key exists */
8714     lstrcpyA(patchcode, "apple");
8715     lstrcpyA(targetprod, "banana");
8716     context = 0xdeadbeef;
8717     lstrcpyA(targetsid, "kiwi");
8718     size = MAX_PATH;
8719     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8720                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8721                            &context, targetsid, &size);
8722     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8723     ok(!lstrcmpA(patchcode, patch),
8724        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8725     ok(!lstrcmpA(targetprod, prodcode),
8726        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8727     ok(context == MSIINSTALLCONTEXT_MACHINE,
8728        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8729     ok(!lstrcmpA(targetsid, ""),
8730        "Expected \"\", got \"%s\"\n", targetsid);
8731     ok(size == 0, "Expected 0, got %d\n", size);
8732
8733     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8735
8736     /* local UserData Patches key exists */
8737     lstrcpyA(patchcode, "apple");
8738     lstrcpyA(targetprod, "banana");
8739     context = 0xdeadbeef;
8740     lstrcpyA(targetsid, "kiwi");
8741     size = MAX_PATH;
8742     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8743                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8744                            &context, targetsid, &size);
8745     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8746     ok(!lstrcmpA(patchcode, patch),
8747        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8748     ok(!lstrcmpA(targetprod, prodcode),
8749        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8750     ok(context == MSIINSTALLCONTEXT_MACHINE,
8751        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8752     ok(!lstrcmpA(targetsid, ""),
8753        "Expected \"\", got \"%s\"\n", targetsid);
8754     ok(size == 0, "Expected 0, got %d\n", size);
8755
8756     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8757     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8758
8759     /* local UserData Product patch key exists */
8760     lstrcpyA(patchcode, "apple");
8761     lstrcpyA(targetprod, "banana");
8762     context = 0xdeadbeef;
8763     lstrcpyA(targetsid, "kiwi");
8764     size = MAX_PATH;
8765     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8766                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8767                            &context, targetsid, &size);
8768     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8769     ok(!lstrcmpA(patchcode, "apple"),
8770        "Expected patchcode to be unchanged, got %s\n", patchcode);
8771     ok(!lstrcmpA(targetprod, "banana"),
8772        "Expected targetprod to be unchanged, got %s\n", targetprod);
8773     ok(context == 0xdeadbeef,
8774        "Expected context to be unchanged, got %d\n", context);
8775     ok(!lstrcmpA(targetsid, "kiwi"),
8776        "Expected targetsid to be unchanged, got %s\n", targetsid);
8777     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8778
8779     data = MSIPATCHSTATE_APPLIED;
8780     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8781                          (const BYTE *)&data, sizeof(DWORD));
8782     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8783
8784     /* State value exists */
8785     lstrcpyA(patchcode, "apple");
8786     lstrcpyA(targetprod, "banana");
8787     context = 0xdeadbeef;
8788     lstrcpyA(targetsid, "kiwi");
8789     size = MAX_PATH;
8790     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8791                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8792                            &context, targetsid, &size);
8793     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8794     ok(!lstrcmpA(patchcode, patch),
8795        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8796     ok(!lstrcmpA(targetprod, prodcode),
8797        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8798     ok(context == MSIINSTALLCONTEXT_MACHINE,
8799        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8800     ok(!lstrcmpA(targetsid, ""),
8801        "Expected \"\", got \"%s\"\n", targetsid);
8802     ok(size == 0, "Expected 0, got %d\n", size);
8803
8804     /* MSIPATCHSTATE_SUPERSEDED */
8805
8806     lstrcpyA(patchcode, "apple");
8807     lstrcpyA(targetprod, "banana");
8808     context = 0xdeadbeef;
8809     lstrcpyA(targetsid, "kiwi");
8810     size = MAX_PATH;
8811     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8812                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8813                            &context, targetsid, &size);
8814     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8815     ok(!lstrcmpA(patchcode, "apple"),
8816        "Expected patchcode to be unchanged, got %s\n", patchcode);
8817     ok(!lstrcmpA(targetprod, "banana"),
8818        "Expected targetprod to be unchanged, got %s\n", targetprod);
8819     ok(context == 0xdeadbeef,
8820        "Expected context to be unchanged, got %d\n", context);
8821     ok(!lstrcmpA(targetsid, "kiwi"),
8822        "Expected targetsid to be unchanged, got %s\n", targetsid);
8823     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8824
8825     data = MSIPATCHSTATE_SUPERSEDED;
8826     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8827                          (const BYTE *)&data, sizeof(DWORD));
8828     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8829
8830     /* State value is MSIPATCHSTATE_SUPERSEDED */
8831     lstrcpyA(patchcode, "apple");
8832     lstrcpyA(targetprod, "banana");
8833     context = 0xdeadbeef;
8834     lstrcpyA(targetsid, "kiwi");
8835     size = MAX_PATH;
8836     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8837                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8838                            &context, targetsid, &size);
8839     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8840     ok(!lstrcmpA(patchcode, patch),
8841        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8842     ok(!lstrcmpA(targetprod, prodcode),
8843        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8844     ok(context == MSIINSTALLCONTEXT_MACHINE,
8845        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8846     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8847     ok(size == 0, "Expected 0, got %d\n", size);
8848
8849     /* MSIPATCHSTATE_OBSOLETED */
8850
8851     lstrcpyA(patchcode, "apple");
8852     lstrcpyA(targetprod, "banana");
8853     context = 0xdeadbeef;
8854     lstrcpyA(targetsid, "kiwi");
8855     size = MAX_PATH;
8856     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8857                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8858                            &context, targetsid, &size);
8859     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8860     ok(!lstrcmpA(patchcode, "apple"),
8861        "Expected patchcode to be unchanged, got %s\n", patchcode);
8862     ok(!lstrcmpA(targetprod, "banana"),
8863        "Expected targetprod to be unchanged, got %s\n", targetprod);
8864     ok(context == 0xdeadbeef,
8865        "Expected context to be unchanged, got %d\n", context);
8866     ok(!lstrcmpA(targetsid, "kiwi"),
8867        "Expected targetsid to be unchanged, got %s\n", targetsid);
8868     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8869
8870     data = MSIPATCHSTATE_OBSOLETED;
8871     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8872                          (const BYTE *)&data, sizeof(DWORD));
8873     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8874
8875     /* State value is obsoleted */
8876     lstrcpyA(patchcode, "apple");
8877     lstrcpyA(targetprod, "banana");
8878     context = 0xdeadbeef;
8879     lstrcpyA(targetsid, "kiwi");
8880     size = MAX_PATH;
8881     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8882                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8883                            &context, targetsid, &size);
8884     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8885     ok(!lstrcmpA(patchcode, patch),
8886        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8887     ok(!lstrcmpA(targetprod, prodcode),
8888        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8889     ok(context == MSIINSTALLCONTEXT_MACHINE,
8890        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8891     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8892     ok(size == 0, "Expected 0, got %d\n", size);
8893
8894     /* MSIPATCHSTATE_REGISTERED */
8895     /* FIXME */
8896
8897     /* MSIPATCHSTATE_ALL */
8898
8899     /* 1st */
8900     lstrcpyA(patchcode, "apple");
8901     lstrcpyA(targetprod, "banana");
8902     context = 0xdeadbeef;
8903     lstrcpyA(targetsid, "kiwi");
8904     size = MAX_PATH;
8905     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8906                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8907                            &context, targetsid, &size);
8908     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8909     ok(!lstrcmpA(patchcode, patch),
8910        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8911     ok(!lstrcmpA(targetprod, prodcode),
8912        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8913     ok(context == MSIINSTALLCONTEXT_MACHINE,
8914        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8915     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8916     ok(size == 0, "Expected 0, got %d\n", size);
8917
8918     /* same patch in multiple places, only one is enumerated */
8919     lstrcpyA(patchcode, "apple");
8920     lstrcpyA(targetprod, "banana");
8921     context = 0xdeadbeef;
8922     lstrcpyA(targetsid, "kiwi");
8923     size = MAX_PATH;
8924     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8925                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8926                            &context, targetsid, &size);
8927     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8928     ok(!lstrcmpA(patchcode, "apple"),
8929        "Expected patchcode to be unchanged, got %s\n", patchcode);
8930     ok(!lstrcmpA(targetprod, "banana"),
8931        "Expected targetprod to be unchanged, got %s\n", targetprod);
8932     ok(context == 0xdeadbeef,
8933        "Expected context to be unchanged, got %d\n", context);
8934     ok(!lstrcmpA(targetsid, "kiwi"),
8935        "Expected targetsid to be unchanged, got %s\n", targetsid);
8936     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8937
8938     RegDeleteValueA(patches, patch_squashed);
8939     RegDeleteValueA(patches, "Patches");
8940     RegDeleteKeyA(patches, "");
8941     RegCloseKey(patches);
8942     RegDeleteValueA(hpatch, "State");
8943     RegDeleteKeyA(hpatch, "");
8944     RegCloseKey(hpatch);
8945     RegDeleteKeyA(udpatch, "");
8946     RegCloseKey(udpatch);
8947     RegDeleteKeyA(udprod, "");
8948     RegCloseKey(udprod);
8949     RegDeleteKeyA(prodkey, "");
8950     RegCloseKey(prodkey);
8951 }
8952
8953 static void test_MsiEnumPatchesEx(void)
8954 {
8955     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8956     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8957     CHAR patchcode[MAX_PATH];
8958     MSIINSTALLCONTEXT context;
8959     LPSTR usersid;
8960     DWORD size;
8961     UINT r;
8962
8963     if (!pMsiEnumPatchesExA)
8964     {
8965         win_skip("MsiEnumPatchesExA not implemented\n");
8966         return;
8967     }
8968
8969     create_test_guid(prodcode, prod_squashed);
8970     get_user_sid(&usersid);
8971
8972     /* empty szProductCode */
8973     lstrcpyA(patchcode, "apple");
8974     lstrcpyA(targetprod, "banana");
8975     context = 0xdeadbeef;
8976     lstrcpyA(targetsid, "kiwi");
8977     size = MAX_PATH;
8978     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8979                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
8980                            targetsid, &size);
8981     ok(r == ERROR_INVALID_PARAMETER,
8982        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8983     ok(!lstrcmpA(patchcode, "apple"),
8984        "Expected patchcode to be unchanged, got %s\n", patchcode);
8985     ok(!lstrcmpA(targetprod, "banana"),
8986        "Expected targetprod to be unchanged, got %s\n", targetprod);
8987     ok(context == 0xdeadbeef,
8988        "Expected context to be unchanged, got %d\n", context);
8989     ok(!lstrcmpA(targetsid, "kiwi"),
8990        "Expected targetsid to be unchanged, got %s\n", targetsid);
8991     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8992
8993     /* garbage szProductCode */
8994     lstrcpyA(patchcode, "apple");
8995     lstrcpyA(targetprod, "banana");
8996     context = 0xdeadbeef;
8997     lstrcpyA(targetsid, "kiwi");
8998     size = MAX_PATH;
8999     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9000                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9001                            targetsid, &size);
9002     ok(r == ERROR_INVALID_PARAMETER,
9003        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9004     ok(!lstrcmpA(patchcode, "apple"),
9005        "Expected patchcode to be unchanged, got %s\n", patchcode);
9006     ok(!lstrcmpA(targetprod, "banana"),
9007        "Expected targetprod to be unchanged, got %s\n", targetprod);
9008     ok(context == 0xdeadbeef,
9009        "Expected context to be unchanged, got %d\n", context);
9010     ok(!lstrcmpA(targetsid, "kiwi"),
9011        "Expected targetsid to be unchanged, got %s\n", targetsid);
9012     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9013
9014     /* guid without brackets */
9015     lstrcpyA(patchcode, "apple");
9016     lstrcpyA(targetprod, "banana");
9017     context = 0xdeadbeef;
9018     lstrcpyA(targetsid, "kiwi");
9019     size = MAX_PATH;
9020     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9021                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9022                            0, patchcode, targetprod, &context,
9023                            targetsid, &size);
9024     ok(r == ERROR_INVALID_PARAMETER,
9025        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9026     ok(!lstrcmpA(patchcode, "apple"),
9027        "Expected patchcode to be unchanged, got %s\n", patchcode);
9028     ok(!lstrcmpA(targetprod, "banana"),
9029        "Expected targetprod to be unchanged, got %s\n", targetprod);
9030     ok(context == 0xdeadbeef,
9031        "Expected context to be unchanged, got %d\n", context);
9032     ok(!lstrcmpA(targetsid, "kiwi"),
9033        "Expected targetsid to be unchanged, got %s\n", targetsid);
9034     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9035
9036     /* guid with brackets */
9037     lstrcpyA(patchcode, "apple");
9038     lstrcpyA(targetprod, "banana");
9039     context = 0xdeadbeef;
9040     lstrcpyA(targetsid, "kiwi");
9041     size = MAX_PATH;
9042     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9043                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9044                            0, patchcode, targetprod, &context,
9045                            targetsid, &size);
9046     ok(r == ERROR_NO_MORE_ITEMS,
9047        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9048     ok(!lstrcmpA(patchcode, "apple"),
9049        "Expected patchcode to be unchanged, got %s\n", patchcode);
9050     ok(!lstrcmpA(targetprod, "banana"),
9051        "Expected targetprod to be unchanged, got %s\n", targetprod);
9052     ok(context == 0xdeadbeef,
9053        "Expected context to be unchanged, got %d\n", context);
9054     ok(!lstrcmpA(targetsid, "kiwi"),
9055        "Expected targetsid to be unchanged, got %s\n", targetsid);
9056     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9057
9058     /* szUserSid is S-1-5-18 */
9059     lstrcpyA(patchcode, "apple");
9060     lstrcpyA(targetprod, "banana");
9061     context = 0xdeadbeef;
9062     lstrcpyA(targetsid, "kiwi");
9063     size = MAX_PATH;
9064     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9065                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9066                            0, patchcode, targetprod, &context,
9067                            targetsid, &size);
9068     ok(r == ERROR_INVALID_PARAMETER,
9069        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9070     ok(!lstrcmpA(patchcode, "apple"),
9071        "Expected patchcode to be unchanged, got %s\n", patchcode);
9072     ok(!lstrcmpA(targetprod, "banana"),
9073        "Expected targetprod to be unchanged, got %s\n", targetprod);
9074     ok(context == 0xdeadbeef,
9075        "Expected context to be unchanged, got %d\n", context);
9076     ok(!lstrcmpA(targetsid, "kiwi"),
9077        "Expected targetsid to be unchanged, got %s\n", targetsid);
9078     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9079
9080     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9081     lstrcpyA(patchcode, "apple");
9082     lstrcpyA(targetprod, "banana");
9083     context = 0xdeadbeef;
9084     lstrcpyA(targetsid, "kiwi");
9085     size = MAX_PATH;
9086     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9087                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9088                            &context, targetsid, &size);
9089     ok(r == ERROR_INVALID_PARAMETER,
9090        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9091     ok(!lstrcmpA(patchcode, "apple"),
9092        "Expected patchcode to be unchanged, got %s\n", patchcode);
9093     ok(!lstrcmpA(targetprod, "banana"),
9094        "Expected targetprod to be unchanged, got %s\n", targetprod);
9095     ok(context == 0xdeadbeef,
9096        "Expected context to be unchanged, got %d\n", context);
9097     ok(!lstrcmpA(targetsid, "kiwi"),
9098        "Expected targetsid to be unchanged, got %s\n", targetsid);
9099     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9100
9101     /* dwContext is out of bounds */
9102     lstrcpyA(patchcode, "apple");
9103     lstrcpyA(targetprod, "banana");
9104     context = 0xdeadbeef;
9105     lstrcpyA(targetsid, "kiwi");
9106     size = MAX_PATH;
9107     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9108                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9109                            &context, targetsid, &size);
9110     ok(r == ERROR_INVALID_PARAMETER,
9111        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9112     ok(!lstrcmpA(patchcode, "apple"),
9113        "Expected patchcode to be unchanged, got %s\n", patchcode);
9114     ok(!lstrcmpA(targetprod, "banana"),
9115        "Expected targetprod to be unchanged, got %s\n", targetprod);
9116     ok(context == 0xdeadbeef,
9117        "Expected context to be unchanged, got %d\n", context);
9118     ok(!lstrcmpA(targetsid, "kiwi"),
9119        "Expected targetsid to be unchanged, got %s\n", targetsid);
9120     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9121
9122     /* dwContext is out of bounds */
9123     lstrcpyA(patchcode, "apple");
9124     lstrcpyA(targetprod, "banana");
9125     context = 0xdeadbeef;
9126     lstrcpyA(targetsid, "kiwi");
9127     size = MAX_PATH;
9128     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9129                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9130                            &context, targetsid, &size);
9131     ok(r == ERROR_INVALID_PARAMETER,
9132        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9133     ok(!lstrcmpA(patchcode, "apple"),
9134        "Expected patchcode to be unchanged, got %s\n", patchcode);
9135     ok(!lstrcmpA(targetprod, "banana"),
9136        "Expected targetprod to be unchanged, got %s\n", targetprod);
9137     ok(context == 0xdeadbeef,
9138        "Expected context to be unchanged, got %d\n", context);
9139     ok(!lstrcmpA(targetsid, "kiwi"),
9140        "Expected targetsid to be unchanged, got %s\n", targetsid);
9141     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9142
9143     /* dwFilter is out of bounds */
9144     lstrcpyA(patchcode, "apple");
9145     lstrcpyA(targetprod, "banana");
9146     context = 0xdeadbeef;
9147     lstrcpyA(targetsid, "kiwi");
9148     size = MAX_PATH;
9149     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9150                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9151                            &context, targetsid, &size);
9152     ok(r == ERROR_INVALID_PARAMETER,
9153        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9154     ok(!lstrcmpA(patchcode, "apple"),
9155        "Expected patchcode to be unchanged, got %s\n", patchcode);
9156     ok(!lstrcmpA(targetprod, "banana"),
9157        "Expected targetprod to be unchanged, got %s\n", targetprod);
9158     ok(context == 0xdeadbeef,
9159        "Expected context to be unchanged, got %d\n", context);
9160     ok(!lstrcmpA(targetsid, "kiwi"),
9161        "Expected targetsid to be unchanged, got %s\n", targetsid);
9162     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9163
9164     /* dwFilter is out of bounds */
9165     lstrcpyA(patchcode, "apple");
9166     lstrcpyA(targetprod, "banana");
9167     context = 0xdeadbeef;
9168     lstrcpyA(targetsid, "kiwi");
9169     size = MAX_PATH;
9170     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9171                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9172                            &context, targetsid, &size);
9173     ok(r == ERROR_INVALID_PARAMETER,
9174        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9175     ok(!lstrcmpA(patchcode, "apple"),
9176        "Expected patchcode to be unchanged, got %s\n", patchcode);
9177     ok(!lstrcmpA(targetprod, "banana"),
9178        "Expected targetprod to be unchanged, got %s\n", targetprod);
9179     ok(context == 0xdeadbeef,
9180        "Expected context to be unchanged, got %d\n", context);
9181     ok(!lstrcmpA(targetsid, "kiwi"),
9182        "Expected targetsid to be unchanged, got %s\n", targetsid);
9183     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9184
9185     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9186     lstrcpyA(patchcode, "apple");
9187     lstrcpyA(targetprod, "banana");
9188     context = 0xdeadbeef;
9189     lstrcpyA(targetsid, "kiwi");
9190     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9191                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9192                            &context, targetsid, NULL);
9193     ok(r == ERROR_INVALID_PARAMETER,
9194        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9195     ok(!lstrcmpA(patchcode, "apple"),
9196        "Expected patchcode to be unchanged, got %s\n", patchcode);
9197     ok(!lstrcmpA(targetprod, "banana"),
9198        "Expected targetprod to be unchanged, got %s\n", targetprod);
9199     ok(context == 0xdeadbeef,
9200        "Expected context to be unchanged, got %d\n", context);
9201     ok(!lstrcmpA(targetsid, "kiwi"),
9202        "Expected targetsid to be unchanged, got %s\n", targetsid);
9203
9204     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9205     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9206     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9207     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9208     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9209     /* FIXME: Successfully test userunmanaged with a different user */
9210     test_MsiEnumPatchesEx_machine();
9211     LocalFree(usersid);
9212 }
9213
9214 static void test_MsiEnumPatches(void)
9215 {
9216     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9217     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9218     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9219     CHAR transforms[MAX_PATH];
9220     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9221     HKEY prodkey, patches, udprod;
9222     HKEY userkey, hpatch, udpatch;
9223     DWORD size, data;
9224     LPSTR usersid;
9225     LONG res;
9226     UINT r;
9227
9228     create_test_guid(prodcode, prod_squashed);
9229     create_test_guid(patchcode, patch_squashed);
9230     get_user_sid(&usersid);
9231
9232     /* NULL szProduct */
9233     size = MAX_PATH;
9234     lstrcpyA(patch, "apple");
9235     lstrcpyA(transforms, "banana");
9236     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9237     ok(r == ERROR_INVALID_PARAMETER,
9238        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9239     ok(!lstrcmpA(patch, "apple"),
9240        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9241     ok(!lstrcmpA(transforms, "banana"),
9242        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9243     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9244
9245     /* empty szProduct */
9246     size = MAX_PATH;
9247     lstrcpyA(patch, "apple");
9248     lstrcpyA(transforms, "banana");
9249     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9250     ok(r == ERROR_INVALID_PARAMETER,
9251        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9252     ok(!lstrcmpA(patch, "apple"),
9253        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9254     ok(!lstrcmpA(transforms, "banana"),
9255        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9256     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9257
9258     /* garbage szProduct */
9259     size = MAX_PATH;
9260     lstrcpyA(patch, "apple");
9261     lstrcpyA(transforms, "banana");
9262     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9263     ok(r == ERROR_INVALID_PARAMETER,
9264        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9265     ok(!lstrcmpA(patch, "apple"),
9266        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9267     ok(!lstrcmpA(transforms, "banana"),
9268        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9269     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9270
9271     /* guid without brackets */
9272     size = MAX_PATH;
9273     lstrcpyA(patch, "apple");
9274     lstrcpyA(transforms, "banana");
9275     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9276                         transforms, &size);
9277     ok(r == ERROR_INVALID_PARAMETER,
9278        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9279     ok(!lstrcmpA(patch, "apple"),
9280        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9281     ok(!lstrcmpA(transforms, "banana"),
9282        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9283     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9284
9285     /* guid with brackets */
9286     size = MAX_PATH;
9287     lstrcpyA(patch, "apple");
9288     lstrcpyA(transforms, "banana");
9289     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9290                         transforms, &size);
9291     ok(r == ERROR_UNKNOWN_PRODUCT,
9292        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9293     ok(!lstrcmpA(patch, "apple"),
9294        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9295     ok(!lstrcmpA(transforms, "banana"),
9296        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9297     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9298
9299     /* same length as guid, but random */
9300     size = MAX_PATH;
9301     lstrcpyA(patch, "apple");
9302     lstrcpyA(transforms, "banana");
9303     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9304                         transforms, &size);
9305     ok(r == ERROR_INVALID_PARAMETER,
9306        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9307     ok(!lstrcmpA(patch, "apple"),
9308        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9309     ok(!lstrcmpA(transforms, "banana"),
9310        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9311     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9312
9313     /* MSIINSTALLCONTEXT_USERMANAGED */
9314
9315     size = MAX_PATH;
9316     lstrcpyA(patch, "apple");
9317     lstrcpyA(transforms, "banana");
9318     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9319     ok(r == ERROR_UNKNOWN_PRODUCT,
9320        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9321     ok(!lstrcmpA(patch, "apple"),
9322        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9323     ok(!lstrcmpA(transforms, "banana"),
9324        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9325     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9326
9327     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9328     lstrcatA(keypath, usersid);
9329     lstrcatA(keypath, "\\Installer\\Products\\");
9330     lstrcatA(keypath, prod_squashed);
9331
9332     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9333     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9334
9335     /* managed product key exists */
9336     size = MAX_PATH;
9337     lstrcpyA(patch, "apple");
9338     lstrcpyA(transforms, "banana");
9339     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9340     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9341     ok(!lstrcmpA(patch, "apple"),
9342        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9343     ok(!lstrcmpA(transforms, "banana"),
9344        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9345     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9346
9347     res = RegCreateKeyA(prodkey, "Patches", &patches);
9348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9349
9350     /* patches key exists */
9351     size = MAX_PATH;
9352     lstrcpyA(patch, "apple");
9353     lstrcpyA(transforms, "banana");
9354     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9355     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9356     ok(!lstrcmpA(patch, "apple"),
9357        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9358     ok(!lstrcmpA(transforms, "banana"),
9359        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9360     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9361
9362     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9363                          (const BYTE *)patch_squashed,
9364                          lstrlenA(patch_squashed) + 1);
9365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9366
9367     /* Patches value exists, is not REG_MULTI_SZ */
9368     size = MAX_PATH;
9369     lstrcpyA(patch, "apple");
9370     lstrcpyA(transforms, "banana");
9371     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9372     ok(r == ERROR_BAD_CONFIGURATION,
9373        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9374     ok(!lstrcmpA(patch, "apple"),
9375        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9376     ok(!lstrcmpA(transforms, "banana"),
9377        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9378     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9379
9380     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9381                          (const BYTE *)"a\0b\0c\0\0", 7);
9382     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9383
9384     /* Patches value exists, is not a squashed guid */
9385     size = MAX_PATH;
9386     lstrcpyA(patch, "apple");
9387     lstrcpyA(transforms, "banana");
9388     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9389     ok(r == ERROR_BAD_CONFIGURATION,
9390        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9391     ok(!lstrcmpA(patch, "apple"),
9392        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9393     ok(!lstrcmpA(transforms, "banana"),
9394        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9395     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9396
9397     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9398     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9399                          (const BYTE *)patch_squashed,
9400                          lstrlenA(patch_squashed) + 2);
9401     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9402
9403     /* Patches value exists */
9404     size = MAX_PATH;
9405     lstrcpyA(patch, "apple");
9406     lstrcpyA(transforms, "banana");
9407     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9408     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9409     ok(!lstrcmpA(patch, "apple"),
9410        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9411     ok(!lstrcmpA(transforms, "banana"),
9412        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9413     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9414
9415     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9416                          (const BYTE *)"whatever", 9);
9417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9418
9419     /* patch squashed value exists */
9420     size = MAX_PATH;
9421     lstrcpyA(patch, "apple");
9422     lstrcpyA(transforms, "banana");
9423     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9424     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9425     ok(!lstrcmpA(patch, patchcode),
9426        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9427     ok(!lstrcmpA(transforms, "whatever"),
9428        "Expected \"whatever\", got \"%s\"\n", transforms);
9429     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9430
9431     /* lpPatchBuf is NULL */
9432     size = MAX_PATH;
9433     lstrcpyA(transforms, "banana");
9434     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9435     ok(r == ERROR_INVALID_PARAMETER,
9436        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9437     ok(!lstrcmpA(transforms, "banana"),
9438        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9439     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9440
9441     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9442     size = MAX_PATH;
9443     lstrcpyA(patch, "apple");
9444     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9445     ok(r == ERROR_INVALID_PARAMETER,
9446        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9447     ok(!lstrcmpA(patch, "apple"),
9448        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9449     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9450
9451     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9452     lstrcpyA(patch, "apple");
9453     lstrcpyA(transforms, "banana");
9454     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9455     ok(r == ERROR_INVALID_PARAMETER,
9456        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9457     ok(!lstrcmpA(patch, "apple"),
9458        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9459     ok(!lstrcmpA(transforms, "banana"),
9460        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9461
9462     /* pcchTransformsBuf is too small */
9463     size = 6;
9464     lstrcpyA(patch, "apple");
9465     lstrcpyA(transforms, "banana");
9466     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9467     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9468     ok(!lstrcmpA(patch, patchcode),
9469        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9470     ok(!lstrcmpA(transforms, "whate"),
9471        "Expected \"whate\", got \"%s\"\n", transforms);
9472     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
9473
9474     /* increase the index */
9475     size = MAX_PATH;
9476     lstrcpyA(patch, "apple");
9477     lstrcpyA(transforms, "banana");
9478     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9479     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9480     ok(!lstrcmpA(patch, "apple"),
9481        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9482     ok(!lstrcmpA(transforms, "banana"),
9483        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9484     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9485
9486     /* increase again */
9487     size = MAX_PATH;
9488     lstrcpyA(patch, "apple");
9489     lstrcpyA(transforms, "banana");
9490     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9491     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9492     ok(!lstrcmpA(patch, "apple"),
9493        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9494     ok(!lstrcmpA(transforms, "banana"),
9495        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9496     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9497
9498     RegDeleteValueA(patches, "Patches");
9499     RegDeleteKeyA(patches, "");
9500     RegCloseKey(patches);
9501     RegDeleteKeyA(prodkey, "");
9502     RegCloseKey(prodkey);
9503
9504     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9505
9506     size = MAX_PATH;
9507     lstrcpyA(patch, "apple");
9508     lstrcpyA(transforms, "banana");
9509     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9510     ok(r == ERROR_UNKNOWN_PRODUCT,
9511        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9512     ok(!lstrcmpA(patch, "apple"),
9513        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9514     ok(!lstrcmpA(transforms, "banana"),
9515        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9516     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9517
9518     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9519     lstrcatA(keypath, prod_squashed);
9520
9521     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9522     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9523
9524     /* current user product key exists */
9525     size = MAX_PATH;
9526     lstrcpyA(patch, "apple");
9527     lstrcpyA(transforms, "banana");
9528     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9529     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9530     ok(!lstrcmpA(patch, "apple"),
9531        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9532     ok(!lstrcmpA(transforms, "banana"),
9533        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9534     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9535
9536     res = RegCreateKeyA(prodkey, "Patches", &patches);
9537     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9538
9539     /* Patches key exists */
9540     size = MAX_PATH;
9541     lstrcpyA(patch, "apple");
9542     lstrcpyA(transforms, "banana");
9543     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9544     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9545     ok(!lstrcmpA(patch, "apple"),
9546        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9547     ok(!lstrcmpA(transforms, "banana"),
9548        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9549     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9550
9551     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9552                          (const BYTE *)patch_squashed,
9553                          lstrlenA(patch_squashed) + 1);
9554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9555
9556     /* Patches value exists, is not REG_MULTI_SZ */
9557     size = MAX_PATH;
9558     lstrcpyA(patch, "apple");
9559     lstrcpyA(transforms, "banana");
9560     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9561     ok(r == ERROR_BAD_CONFIGURATION,
9562        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9563     ok(!lstrcmpA(patch, "apple"),
9564        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9565     ok(!lstrcmpA(transforms, "banana"),
9566        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9567     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9568
9569     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9570                          (const BYTE *)"a\0b\0c\0\0", 7);
9571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9572
9573     /* Patches value exists, is not a squashed guid */
9574     size = MAX_PATH;
9575     lstrcpyA(patch, "apple");
9576     lstrcpyA(transforms, "banana");
9577     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9578     ok(r == ERROR_BAD_CONFIGURATION,
9579        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9580     ok(!lstrcmpA(patch, "apple"),
9581        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9582     ok(!lstrcmpA(transforms, "banana"),
9583        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9584     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9585
9586     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9587     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9588                          (const BYTE *)patch_squashed,
9589                          lstrlenA(patch_squashed) + 2);
9590     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9591
9592     /* Patches value exists */
9593     size = MAX_PATH;
9594     lstrcpyA(patch, "apple");
9595     lstrcpyA(transforms, "banana");
9596     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9597     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, 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     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9605                          (const BYTE *)"whatever", 9);
9606     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9607
9608     /* patch code value exists */
9609     size = MAX_PATH;
9610     lstrcpyA(patch, "apple");
9611     lstrcpyA(transforms, "banana");
9612     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9613     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9614     ok(!lstrcmpA(patch, "apple"),
9615        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9616     ok(!lstrcmpA(transforms, "banana"),
9617        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9618     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9619
9620     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9621     lstrcatA(keypath, usersid);
9622     lstrcatA(keypath, "\\Patches\\");
9623     lstrcatA(keypath, patch_squashed);
9624
9625     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
9626     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9627
9628     /* userdata patch key exists */
9629     size = MAX_PATH;
9630     lstrcpyA(patch, "apple");
9631     lstrcpyA(transforms, "banana");
9632     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9633     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9634     ok(!lstrcmpA(patch, patchcode),
9635        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9636     ok(!lstrcmpA(transforms, "whatever"),
9637        "Expected \"whatever\", got \"%s\"\n", transforms);
9638     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9639
9640     RegDeleteKeyA(userkey, "");
9641     RegCloseKey(userkey);
9642     RegDeleteValueA(patches, patch_squashed);
9643     RegDeleteValueA(patches, "Patches");
9644     RegDeleteKeyA(patches, "");
9645     RegCloseKey(patches);
9646     RegDeleteKeyA(prodkey, "");
9647     RegCloseKey(prodkey);
9648
9649     /* MSIINSTALLCONTEXT_MACHINE */
9650
9651     size = MAX_PATH;
9652     lstrcpyA(patch, "apple");
9653     lstrcpyA(transforms, "banana");
9654     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9655     ok(r == ERROR_UNKNOWN_PRODUCT,
9656        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9657     ok(!lstrcmpA(patch, "apple"),
9658        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9659     ok(!lstrcmpA(transforms, "banana"),
9660        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9661     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9662
9663     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9664     lstrcatA(keypath, prod_squashed);
9665
9666     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9668
9669     /* local product key exists */
9670     size = MAX_PATH;
9671     lstrcpyA(patch, "apple");
9672     lstrcpyA(transforms, "banana");
9673     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9674     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9675     ok(!lstrcmpA(patch, "apple"),
9676        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9677     ok(!lstrcmpA(transforms, "banana"),
9678        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9679     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9680
9681     res = RegCreateKeyA(prodkey, "Patches", &patches);
9682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9683
9684     /* Patches key exists */
9685     size = MAX_PATH;
9686     lstrcpyA(patch, "apple");
9687     lstrcpyA(transforms, "banana");
9688     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9689     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9690     ok(!lstrcmpA(patch, "apple"),
9691        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9692     ok(!lstrcmpA(transforms, "banana"),
9693        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9694     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9695
9696     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9697                          (const BYTE *)patch_squashed,
9698                          lstrlenA(patch_squashed) + 1);
9699     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9700
9701     /* Patches value exists, is not REG_MULTI_SZ */
9702     size = MAX_PATH;
9703     lstrcpyA(patch, "apple");
9704     lstrcpyA(transforms, "banana");
9705     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9706     ok(r == ERROR_BAD_CONFIGURATION,
9707        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9708     ok(!lstrcmpA(patch, "apple"),
9709        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9710     ok(!lstrcmpA(transforms, "banana"),
9711        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9712     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9713
9714     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9715                          (const BYTE *)"a\0b\0c\0\0", 7);
9716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9717
9718     /* Patches value exists, is not a squashed guid */
9719     size = MAX_PATH;
9720     lstrcpyA(patch, "apple");
9721     lstrcpyA(transforms, "banana");
9722     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9723     ok(r == ERROR_BAD_CONFIGURATION,
9724        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9725     ok(!lstrcmpA(patch, "apple"),
9726        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9727     ok(!lstrcmpA(transforms, "banana"),
9728        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9729     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9730
9731     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9732     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9733                          (const BYTE *)patch_squashed,
9734                          lstrlenA(patch_squashed) + 2);
9735     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9736
9737     /* Patches value exists */
9738     size = MAX_PATH;
9739     lstrcpyA(patch, "apple");
9740     lstrcpyA(transforms, "banana");
9741     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9742     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9743     ok(!lstrcmpA(patch, "apple"),
9744        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9745     ok(!lstrcmpA(transforms, "banana"),
9746        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9747     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9748
9749     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9750                          (const BYTE *)"whatever", 9);
9751     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9752
9753     /* patch code value exists */
9754     size = MAX_PATH;
9755     lstrcpyA(patch, "apple");
9756     lstrcpyA(transforms, "banana");
9757     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9758     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9759     ok(!lstrcmpA(patch, patchcode),
9760        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9761     ok(!lstrcmpA(transforms, "whatever"),
9762        "Expected \"whatever\", got \"%s\"\n", transforms);
9763     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9764
9765     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9766     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9767     lstrcatA(keypath, prod_squashed);
9768
9769     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9770     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9771
9772     /* local UserData product key exists */
9773     size = MAX_PATH;
9774     lstrcpyA(patch, "apple");
9775     lstrcpyA(transforms, "banana");
9776     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9777     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9778     ok(!lstrcmpA(patch, patchcode),
9779        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9780     ok(!lstrcmpA(transforms, "whatever"),
9781        "Expected \"whatever\", got \"%s\"\n", transforms);
9782     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9783
9784     res = RegCreateKeyA(udprod, "Patches", &udpatch);
9785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9786
9787     /* local UserData Patches key exists */
9788     size = MAX_PATH;
9789     lstrcpyA(patch, "apple");
9790     lstrcpyA(transforms, "banana");
9791     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9792     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9793     ok(!lstrcmpA(patch, patchcode),
9794        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9795     ok(!lstrcmpA(transforms, "whatever"),
9796        "Expected \"whatever\", got \"%s\"\n", transforms);
9797     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9798
9799     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
9800     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9801
9802     /* local UserData Product patch key exists */
9803     size = MAX_PATH;
9804     lstrcpyA(patch, "apple");
9805     lstrcpyA(transforms, "banana");
9806     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9807     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9808     ok(!lstrcmpA(patch, "apple"),
9809        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9810     ok(!lstrcmpA(transforms, "banana"),
9811        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9812     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9813
9814     data = MSIPATCHSTATE_APPLIED;
9815     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9816                          (const BYTE *)&data, sizeof(DWORD));
9817     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9818
9819     /* State value exists */
9820     size = MAX_PATH;
9821     lstrcpyA(patch, "apple");
9822     lstrcpyA(transforms, "banana");
9823     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9824     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9825     ok(!lstrcmpA(patch, patchcode),
9826        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9827     ok(!lstrcmpA(transforms, "whatever"),
9828        "Expected \"whatever\", got \"%s\"\n", transforms);
9829     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9830
9831     /* now duplicate some of the tests for the W version */
9832
9833     /* pcchTransformsBuf is too small */
9834     size = 6;
9835     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
9836     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9837     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9838     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9839     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9840     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9841     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
9842     ok(!lstrcmpA(patch, patchcode),
9843        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9844     ok(!lstrcmpA(transforms, "whate"),
9845        "Expected \"whate\", got \"%s\"\n", transforms);
9846     ok(size == 8, "Expected 8, got %d\n", size);
9847
9848     /* patch code value exists */
9849     size = MAX_PATH;
9850     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9851     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9852     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9853     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9854     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9855     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
9856     ok(!lstrcmpA(patch, patchcode),
9857        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9858     ok(!lstrcmpA(transforms, "whatever"),
9859        "Expected \"whatever\", got \"%s\"\n", transforms);
9860     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9861
9862     RegDeleteValueA(patches, patch_squashed);
9863     RegDeleteValueA(patches, "Patches");
9864     RegDeleteKeyA(patches, "");
9865     RegCloseKey(patches);
9866     RegDeleteValueA(hpatch, "State");
9867     RegDeleteKeyA(hpatch, "");
9868     RegCloseKey(hpatch);
9869     RegDeleteKeyA(udpatch, "");
9870     RegCloseKey(udpatch);
9871     RegDeleteKeyA(udprod, "");
9872     RegCloseKey(udprod);
9873     RegDeleteKeyA(prodkey, "");
9874     RegCloseKey(prodkey);
9875     LocalFree(usersid);
9876 }
9877
9878 static void test_MsiGetPatchInfoEx(void)
9879 {
9880     CHAR keypath[MAX_PATH], val[MAX_PATH];
9881     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9882     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9883     HKEY prodkey, patches, udprod, props;
9884     HKEY hpatch, udpatch, prodpatches;
9885     LPSTR usersid;
9886     DWORD size;
9887     LONG res;
9888     UINT r;
9889
9890     if (!pMsiGetPatchInfoExA)
9891     {
9892         win_skip("MsiGetPatchInfoEx not implemented\n");
9893         return;
9894     }
9895
9896     create_test_guid(prodcode, prod_squashed);
9897     create_test_guid(patchcode, patch_squashed);
9898     get_user_sid(&usersid);
9899
9900     /* NULL szPatchCode */
9901     lstrcpyA(val, "apple");
9902     size = MAX_PATH;
9903     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9904                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9905     ok(r == ERROR_INVALID_PARAMETER,
9906        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9907     ok(!lstrcmpA(val, "apple"),
9908        "Expected val to be unchanged, got \"%s\"\n", val);
9909     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9910
9911     /* empty szPatchCode */
9912     size = MAX_PATH;
9913     lstrcpyA(val, "apple");
9914     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9915                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9916     ok(r == ERROR_INVALID_PARAMETER,
9917        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9918     ok(!lstrcmpA(val, "apple"),
9919        "Expected val to be unchanged, got \"%s\"\n", val);
9920     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9921
9922     /* garbage szPatchCode */
9923     size = MAX_PATH;
9924     lstrcpyA(val, "apple");
9925     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
9926                             MSIINSTALLCONTEXT_USERMANAGED,
9927                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9928     ok(r == ERROR_INVALID_PARAMETER,
9929        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9930     ok(!lstrcmpA(val, "apple"),
9931        "Expected val to be unchanged, got \"%s\"\n", val);
9932     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9933
9934     /* guid without brackets */
9935     size = MAX_PATH;
9936     lstrcpyA(val, "apple");
9937     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
9938                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9939                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9940     ok(r == ERROR_INVALID_PARAMETER,
9941        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9942     ok(!lstrcmpA(val, "apple"),
9943        "Expected val to be unchanged, got \"%s\"\n", val);
9944     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9945
9946     /* guid with brackets */
9947     size = MAX_PATH;
9948     lstrcpyA(val, "apple");
9949     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
9950                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9951                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9952     ok(r == ERROR_UNKNOWN_PRODUCT,
9953        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9954     ok(!lstrcmpA(val, "apple"),
9955        "Expected val to be unchanged, got \"%s\"\n", val);
9956     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9957
9958     /* same length as guid, but random */
9959     size = MAX_PATH;
9960     lstrcpyA(val, "apple");
9961     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
9962                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9963                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9964     ok(r == ERROR_INVALID_PARAMETER,
9965        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9966     ok(!lstrcmpA(val, "apple"),
9967        "Expected val to be unchanged, got \"%s\"\n", val);
9968     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9969
9970     /* NULL szProductCode */
9971     lstrcpyA(val, "apple");
9972     size = MAX_PATH;
9973     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9974                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9975     ok(r == ERROR_INVALID_PARAMETER,
9976        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9977     ok(!lstrcmpA(val, "apple"),
9978        "Expected val to be unchanged, got \"%s\"\n", val);
9979     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9980
9981     /* empty szProductCode */
9982     size = MAX_PATH;
9983     lstrcpyA(val, "apple");
9984     r = pMsiGetPatchInfoExA(patchcode, "", NULL, 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     /* garbage szProductCode */
9993     size = MAX_PATH;
9994     lstrcpyA(val, "apple");
9995     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
9996                             MSIINSTALLCONTEXT_USERMANAGED,
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     /* guid without brackets */
10005     size = MAX_PATH;
10006     lstrcpyA(val, "apple");
10007     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10008                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
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     /* guid with brackets */
10017     size = MAX_PATH;
10018     lstrcpyA(val, "apple");
10019     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10020                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10021                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10022     ok(r == ERROR_UNKNOWN_PRODUCT,
10023        "Expected ERROR_UNKNOWN_PRODUCT, 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     /* same length as guid, but random */
10029     size = MAX_PATH;
10030     lstrcpyA(val, "apple");
10031     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10032                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
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     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10041     size = MAX_PATH;
10042     lstrcpyA(val, "apple");
10043     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10044                             MSIINSTALLCONTEXT_USERMANAGED,
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     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10053     size = MAX_PATH;
10054     lstrcpyA(val, "apple");
10055     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10056                             MSIINSTALLCONTEXT_USERUNMANAGED,
10057                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10058     ok(r == ERROR_INVALID_PARAMETER,
10059        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10060     ok(!lstrcmpA(val, "apple"),
10061        "Expected val to be unchanged, got \"%s\"\n", val);
10062     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10063
10064     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10065     size = MAX_PATH;
10066     lstrcpyA(val, "apple");
10067     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10068                             MSIINSTALLCONTEXT_MACHINE,
10069                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10070     ok(r == ERROR_INVALID_PARAMETER,
10071        "Expected ERROR_INVALID_PARAMETER, 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     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10077     size = MAX_PATH;
10078     lstrcpyA(val, "apple");
10079     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10080                             MSIINSTALLCONTEXT_MACHINE,
10081                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10082     ok(r == ERROR_INVALID_PARAMETER,
10083        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10084     ok(!lstrcmpA(val, "apple"),
10085        "Expected val to be unchanged, got \"%s\"\n", val);
10086     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10087
10088     /* dwContext is out of range */
10089     size = MAX_PATH;
10090     lstrcpyA(val, "apple");
10091     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10092                             MSIINSTALLCONTEXT_NONE,
10093                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10094     ok(r == ERROR_INVALID_PARAMETER,
10095        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10096     ok(!lstrcmpA(val, "apple"),
10097        "Expected val to be unchanged, got \"%s\"\n", val);
10098     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10099
10100     /* dwContext is out of range */
10101     size = MAX_PATH;
10102     lstrcpyA(val, "apple");
10103     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10104                             MSIINSTALLCONTEXT_ALL,
10105                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10106     ok(r == ERROR_INVALID_PARAMETER,
10107        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10108     ok(!lstrcmpA(val, "apple"),
10109        "Expected val to be unchanged, got \"%s\"\n", val);
10110     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10111
10112     /* dwContext is invalid */
10113     size = MAX_PATH;
10114     lstrcpyA(val, "apple");
10115     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10116                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10117     ok(r == ERROR_INVALID_PARAMETER,
10118        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10119     ok(!lstrcmpA(val, "apple"),
10120        "Expected val to be unchanged, got \"%s\"\n", val);
10121     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10122
10123     /* MSIINSTALLCONTEXT_USERMANAGED */
10124
10125     size = MAX_PATH;
10126     lstrcpyA(val, "apple");
10127     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10128                             MSIINSTALLCONTEXT_USERMANAGED,
10129                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10130     ok(r == ERROR_UNKNOWN_PRODUCT,
10131        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10132     ok(!lstrcmpA(val, "apple"),
10133        "Expected val to be unchanged, got \"%s\"\n", val);
10134     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10135
10136     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10137     lstrcatA(keypath, usersid);
10138     lstrcatA(keypath, "\\Products\\");
10139     lstrcatA(keypath, prod_squashed);
10140
10141     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10142     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10143
10144     /* local UserData product key exists */
10145     size = MAX_PATH;
10146     lstrcpyA(val, "apple");
10147     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10148                             MSIINSTALLCONTEXT_USERMANAGED,
10149                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10150     ok(r == ERROR_UNKNOWN_PRODUCT,
10151        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10152     ok(!lstrcmpA(val, "apple"),
10153        "Expected val to be unchanged, got \"%s\"\n", val);
10154     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10155
10156     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10157     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10158
10159     /* InstallProperties key exists */
10160     size = MAX_PATH;
10161     lstrcpyA(val, "apple");
10162     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10163                             MSIINSTALLCONTEXT_USERMANAGED,
10164                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10165     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10166     ok(!lstrcmpA(val, "apple"),
10167        "Expected val to be unchanged, got \"%s\"\n", val);
10168     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10169
10170     res = RegCreateKeyA(udprod, "Patches", &patches);
10171     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10172
10173     /* Patches key exists */
10174     size = MAX_PATH;
10175     lstrcpyA(val, "apple");
10176     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10177                             MSIINSTALLCONTEXT_USERMANAGED,
10178                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10179     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10180     ok(!lstrcmpA(val, "apple"),
10181        "Expected val to be unchanged, got \"%s\"\n", val);
10182     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10183
10184     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10185     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10186
10187     /* Patches key exists */
10188     size = MAX_PATH;
10189     lstrcpyA(val, "apple");
10190     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10191                             MSIINSTALLCONTEXT_USERMANAGED,
10192                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10193     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10194     ok(!lstrcmpA(val, "apple"),
10195        "Expected val to be unchanged, got \"%s\"\n", val);
10196     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10197
10198     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10199     lstrcatA(keypath, usersid);
10200     lstrcatA(keypath, "\\Installer\\Products\\");
10201     lstrcatA(keypath, prod_squashed);
10202
10203     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10205
10206     /* managed product key exists */
10207     size = MAX_PATH;
10208     lstrcpyA(val, "apple");
10209     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10210                             MSIINSTALLCONTEXT_USERMANAGED,
10211                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10212     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10213     ok(!lstrcmpA(val, "apple"),
10214        "Expected val to be unchanged, got \"%s\"\n", val);
10215     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10216
10217     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10218     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10219
10220     /* Patches key exists */
10221     size = MAX_PATH;
10222     lstrcpyA(val, "apple");
10223     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10224                             MSIINSTALLCONTEXT_USERMANAGED,
10225                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10226     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10227     ok(!lstrcmpA(val, "apple"),
10228        "Expected val to be unchanged, got \"%s\"\n", val);
10229     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10230
10231     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10232                          (const BYTE *)"transforms", 11);
10233     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10234
10235     /* specific patch value exists */
10236     size = MAX_PATH;
10237     lstrcpyA(val, "apple");
10238     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10239                             MSIINSTALLCONTEXT_USERMANAGED,
10240                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10241     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10242     ok(!lstrcmpA(val, "apple"),
10243        "Expected val to be unchanged, got \"%s\"\n", val);
10244     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10245
10246     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10247     lstrcatA(keypath, usersid);
10248     lstrcatA(keypath, "\\Patches\\");
10249     lstrcatA(keypath, patch_squashed);
10250
10251     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10252     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10253
10254     /* UserData Patches key exists */
10255     size = MAX_PATH;
10256     lstrcpyA(val, "apple");
10257     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10258                             MSIINSTALLCONTEXT_USERMANAGED,
10259                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10260     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10261     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10262     ok(size == 0, "Expected 0, got %d\n", size);
10263
10264     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10265                          (const BYTE *)"pack", 5);
10266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10267
10268     /* ManagedLocalPatch value exists */
10269     size = MAX_PATH;
10270     lstrcpyA(val, "apple");
10271     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10272                             MSIINSTALLCONTEXT_USERMANAGED,
10273                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10274     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10275     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10276     ok(size == 4, "Expected 4, got %d\n", size);
10277
10278     size = MAX_PATH;
10279     lstrcpyA(val, "apple");
10280     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10281                             MSIINSTALLCONTEXT_USERMANAGED,
10282                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10283     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10284     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10285     ok(size == 10, "Expected 10, got %d\n", size);
10286
10287     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10288                          (const BYTE *)"mydate", 7);
10289     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10290
10291     /* Installed value exists */
10292     size = MAX_PATH;
10293     lstrcpyA(val, "apple");
10294     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10295                             MSIINSTALLCONTEXT_USERMANAGED,
10296                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10297     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10298     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10299     ok(size == 6, "Expected 6, got %d\n", size);
10300
10301     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10302                          (const BYTE *)"yes", 4);
10303     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10304
10305     /* Uninstallable value exists */
10306     size = MAX_PATH;
10307     lstrcpyA(val, "apple");
10308     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10309                             MSIINSTALLCONTEXT_USERMANAGED,
10310                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10311     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10312     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10313     ok(size == 3, "Expected 3, got %d\n", size);
10314
10315     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10316                          (const BYTE *)"good", 5);
10317     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10318
10319     /* State value exists */
10320     size = MAX_PATH;
10321     lstrcpyA(val, "apple");
10322     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10323                             MSIINSTALLCONTEXT_USERMANAGED,
10324                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10326     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10327     ok(size == 4, "Expected 4, got %d\n", size);
10328
10329     size = 1;
10330     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10331                          (const BYTE *)&size, sizeof(DWORD));
10332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10333
10334     /* State value exists */
10335     size = MAX_PATH;
10336     lstrcpyA(val, "apple");
10337     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10338                             MSIINSTALLCONTEXT_USERMANAGED,
10339                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10340     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10341     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10342     ok(size == 1, "Expected 1, got %d\n", size);
10343
10344     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10345                          (const BYTE *)"display", 8);
10346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10347
10348     /* DisplayName value exists */
10349     size = MAX_PATH;
10350     lstrcpyA(val, "apple");
10351     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10352                             MSIINSTALLCONTEXT_USERMANAGED,
10353                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10355     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10356     ok(size == 7, "Expected 7, got %d\n", size);
10357
10358     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10359                          (const BYTE *)"moreinfo", 9);
10360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10361
10362     /* MoreInfoURL value exists */
10363     size = MAX_PATH;
10364     lstrcpyA(val, "apple");
10365     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10366                             MSIINSTALLCONTEXT_USERMANAGED,
10367                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10368     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10369     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10370     ok(size == 8, "Expected 8, got %d\n", size);
10371
10372     /* szProperty is invalid */
10373     size = MAX_PATH;
10374     lstrcpyA(val, "apple");
10375     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10376                             MSIINSTALLCONTEXT_USERMANAGED,
10377                             "IDontExist", val, &size);
10378     ok(r == ERROR_UNKNOWN_PROPERTY,
10379        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10380     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10381     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10382
10383     /* lpValue is NULL, while pcchValue is non-NULL */
10384     size = MAX_PATH;
10385     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10386                             MSIINSTALLCONTEXT_USERMANAGED,
10387                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10388     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10389     ok(size == 16, "Expected 16, got %d\n", size);
10390
10391     /* pcchValue is NULL, while lpValue is non-NULL */
10392     lstrcpyA(val, "apple");
10393     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10394                             MSIINSTALLCONTEXT_USERMANAGED,
10395                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10396     ok(r == ERROR_INVALID_PARAMETER,
10397        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10398     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10399
10400     /* both lpValue and pcchValue are NULL */
10401     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10402                             MSIINSTALLCONTEXT_USERMANAGED,
10403                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10404     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10405
10406     /* pcchValue doesn't have enough room for NULL terminator */
10407     size = 8;
10408     lstrcpyA(val, "apple");
10409     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10410                             MSIINSTALLCONTEXT_USERMANAGED,
10411                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10412     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10413     ok(!lstrcmpA(val, "moreinf"),
10414        "Expected \"moreinf\", got \"%s\"\n", val);
10415     ok(size == 16, "Expected 16, got %d\n", size);
10416
10417     /* pcchValue has exactly enough room for NULL terminator */
10418     size = 9;
10419     lstrcpyA(val, "apple");
10420     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10421                             MSIINSTALLCONTEXT_USERMANAGED,
10422                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10423     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10424     ok(!lstrcmpA(val, "moreinfo"),
10425        "Expected \"moreinfo\", got \"%s\"\n", val);
10426     ok(size == 8, "Expected 8, got %d\n", size);
10427
10428     /* pcchValue is too small, lpValue is NULL */
10429     size = 0;
10430     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10431                             MSIINSTALLCONTEXT_USERMANAGED,
10432                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10433     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10434     ok(size == 16, "Expected 16, got %d\n", size);
10435
10436     RegDeleteValueA(prodpatches, patch_squashed);
10437     RegDeleteKeyA(prodpatches, "");
10438     RegCloseKey(prodpatches);
10439     RegDeleteKeyA(prodkey, "");
10440     RegCloseKey(prodkey);
10441
10442     /* UserData is sufficient for all properties
10443      * except INSTALLPROPERTY_TRANSFORMS
10444      */
10445     size = MAX_PATH;
10446     lstrcpyA(val, "apple");
10447     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10448                             MSIINSTALLCONTEXT_USERMANAGED,
10449                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10450     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10451     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10452     ok(size == 4, "Expected 4, got %d\n", size);
10453
10454     /* UserData is sufficient for all properties
10455      * except INSTALLPROPERTY_TRANSFORMS
10456      */
10457     size = MAX_PATH;
10458     lstrcpyA(val, "apple");
10459     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10460                             MSIINSTALLCONTEXT_USERMANAGED,
10461                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10462     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10463     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10464     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10465
10466     RegDeleteValueA(hpatch, "MoreInfoURL");
10467     RegDeleteValueA(hpatch, "Display");
10468     RegDeleteValueA(hpatch, "State");
10469     RegDeleteValueA(hpatch, "Uninstallable");
10470     RegDeleteValueA(hpatch, "Installed");
10471     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10472     RegDeleteKeyA(udpatch, "");
10473     RegCloseKey(udpatch);
10474     RegDeleteKeyA(hpatch, "");
10475     RegCloseKey(hpatch);
10476     RegDeleteKeyA(patches, "");
10477     RegCloseKey(patches);
10478     RegDeleteKeyA(props, "");
10479     RegCloseKey(props);
10480     RegDeleteKeyA(udprod, "");
10481     RegCloseKey(udprod);
10482
10483     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10484
10485     size = MAX_PATH;
10486     lstrcpyA(val, "apple");
10487     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10488                             MSIINSTALLCONTEXT_USERUNMANAGED,
10489                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10490     ok(r == ERROR_UNKNOWN_PRODUCT,
10491        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10492     ok(!lstrcmpA(val, "apple"),
10493        "Expected val to be unchanged, got \"%s\"\n", val);
10494     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10495
10496     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10497     lstrcatA(keypath, usersid);
10498     lstrcatA(keypath, "\\Products\\");
10499     lstrcatA(keypath, prod_squashed);
10500
10501     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10502     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10503
10504     /* local UserData 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_PRODUCT,
10511        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10512     ok(!lstrcmpA(val, "apple"),
10513        "Expected val to be unchanged, got \"%s\"\n", val);
10514     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10515
10516     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10517     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10518
10519     /* InstallProperties key exists */
10520     size = MAX_PATH;
10521     lstrcpyA(val, "apple");
10522     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10523                             MSIINSTALLCONTEXT_USERUNMANAGED,
10524                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10525     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10526     ok(!lstrcmpA(val, "apple"),
10527        "Expected val to be unchanged, got \"%s\"\n", val);
10528     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10529
10530     res = RegCreateKeyA(udprod, "Patches", &patches);
10531     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10532
10533     /* Patches key exists */
10534     size = MAX_PATH;
10535     lstrcpyA(val, "apple");
10536     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10537                             MSIINSTALLCONTEXT_USERUNMANAGED,
10538                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10539     ok(r == ERROR_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     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10545     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10546
10547     /* Patches key exists */
10548     size = MAX_PATH;
10549     lstrcpyA(val, "apple");
10550     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10551                             MSIINSTALLCONTEXT_USERUNMANAGED,
10552                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10553     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10554     ok(!lstrcmpA(val, "apple"),
10555        "Expected val to be unchanged, got \"%s\"\n", val);
10556     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10557
10558     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10559     lstrcatA(keypath, prod_squashed);
10560
10561     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10562     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10563
10564     /* current user product key exists */
10565     size = MAX_PATH;
10566     lstrcpyA(val, "apple");
10567     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10568                             MSIINSTALLCONTEXT_USERUNMANAGED,
10569                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10570     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10571     ok(!lstrcmpA(val, "apple"),
10572        "Expected val to be unchanged, got \"%s\"\n", val);
10573     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10574
10575     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10576     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10577
10578     /* Patches key exists */
10579     size = MAX_PATH;
10580     lstrcpyA(val, "apple");
10581     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10582                             MSIINSTALLCONTEXT_USERUNMANAGED,
10583                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10584     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10585     ok(!lstrcmpA(val, "apple"),
10586        "Expected val to be unchanged, got \"%s\"\n", val);
10587     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10588
10589     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10590                          (const BYTE *)"transforms", 11);
10591     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10592
10593     /* specific patch value exists */
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_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10600     ok(!lstrcmpA(val, "apple"),
10601        "Expected val to be unchanged, got \"%s\"\n", val);
10602     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10603
10604     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10605     lstrcatA(keypath, usersid);
10606     lstrcatA(keypath, "\\Patches\\");
10607     lstrcatA(keypath, patch_squashed);
10608
10609     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10611
10612     /* UserData Patches key exists */
10613     size = MAX_PATH;
10614     lstrcpyA(val, "apple");
10615     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10616                             MSIINSTALLCONTEXT_USERUNMANAGED,
10617                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10619     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10620     ok(size == 0, "Expected 0, got %d\n", size);
10621
10622     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10623                          (const BYTE *)"pack", 5);
10624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10625
10626     /* LocalPatch value exists */
10627     size = MAX_PATH;
10628     lstrcpyA(val, "apple");
10629     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10630                             MSIINSTALLCONTEXT_USERUNMANAGED,
10631                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10632     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10633     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10634     ok(size == 4, "Expected 4, got %d\n", size);
10635
10636     size = MAX_PATH;
10637     lstrcpyA(val, "apple");
10638     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10639                             MSIINSTALLCONTEXT_USERUNMANAGED,
10640                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10641     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10642     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10643     ok(size == 10, "Expected 10, got %d\n", size);
10644
10645     RegDeleteValueA(prodpatches, patch_squashed);
10646     RegDeleteKeyA(prodpatches, "");
10647     RegCloseKey(prodpatches);
10648     RegDeleteKeyA(prodkey, "");
10649     RegCloseKey(prodkey);
10650
10651     /* UserData is sufficient for all properties
10652      * except INSTALLPROPERTY_TRANSFORMS
10653      */
10654     size = MAX_PATH;
10655     lstrcpyA(val, "apple");
10656     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10657                             MSIINSTALLCONTEXT_USERUNMANAGED,
10658                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10659     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10660     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10661     ok(size == 4, "Expected 4, got %d\n", size);
10662
10663     /* UserData is sufficient for all properties
10664      * except INSTALLPROPERTY_TRANSFORMS
10665      */
10666     size = MAX_PATH;
10667     lstrcpyA(val, "apple");
10668     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10669                             MSIINSTALLCONTEXT_USERUNMANAGED,
10670                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10671     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10672     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10673     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10674
10675     RegDeleteValueA(udpatch, "LocalPackage");
10676     RegDeleteKeyA(udpatch, "");
10677     RegCloseKey(udpatch);
10678     RegDeleteKeyA(hpatch, "");
10679     RegCloseKey(hpatch);
10680     RegDeleteKeyA(patches, "");
10681     RegCloseKey(patches);
10682     RegDeleteKeyA(props, "");
10683     RegCloseKey(props);
10684     RegDeleteKeyA(udprod, "");
10685     RegCloseKey(udprod);
10686
10687     /* MSIINSTALLCONTEXT_MACHINE */
10688
10689     size = MAX_PATH;
10690     lstrcpyA(val, "apple");
10691     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10692                             MSIINSTALLCONTEXT_MACHINE,
10693                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10694     ok(r == ERROR_UNKNOWN_PRODUCT,
10695        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10696     ok(!lstrcmpA(val, "apple"),
10697        "Expected val to be unchanged, got \"%s\"\n", val);
10698     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10699
10700     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10701     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10702     lstrcatA(keypath, prod_squashed);
10703
10704     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10705     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10706
10707     /* local UserData 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_PRODUCT,
10714        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10715     ok(!lstrcmpA(val, "apple"),
10716        "Expected val to be unchanged, got \"%s\"\n", val);
10717     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10718
10719     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10721
10722     /* InstallProperties key exists */
10723     size = MAX_PATH;
10724     lstrcpyA(val, "apple");
10725     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10726                             MSIINSTALLCONTEXT_MACHINE,
10727                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10728     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10729     ok(!lstrcmpA(val, "apple"),
10730        "Expected val to be unchanged, got \"%s\"\n", val);
10731     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10732
10733     res = RegCreateKeyA(udprod, "Patches", &patches);
10734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10735
10736     /* Patches key 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     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10748     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10749
10750     /* Patches key exists */
10751     size = MAX_PATH;
10752     lstrcpyA(val, "apple");
10753     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10754                             MSIINSTALLCONTEXT_MACHINE,
10755                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10756     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10757     ok(!lstrcmpA(val, "apple"),
10758        "Expected val to be unchanged, got \"%s\"\n", val);
10759     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10760
10761     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10762     lstrcatA(keypath, prod_squashed);
10763
10764     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10765     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10766
10767     /* local product key exists */
10768     size = MAX_PATH;
10769     lstrcpyA(val, "apple");
10770     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10771                             MSIINSTALLCONTEXT_MACHINE,
10772                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10773     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10774     ok(!lstrcmpA(val, "apple"),
10775        "Expected val to be unchanged, got \"%s\"\n", val);
10776     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10777
10778     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10780
10781     /* Patches key exists */
10782     size = MAX_PATH;
10783     lstrcpyA(val, "apple");
10784     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10785                             MSIINSTALLCONTEXT_MACHINE,
10786                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10787     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10788     ok(!lstrcmpA(val, "apple"),
10789        "Expected val to be unchanged, got \"%s\"\n", val);
10790     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10791
10792     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10793                          (const BYTE *)"transforms", 11);
10794     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10795
10796     /* specific patch value exists */
10797     size = MAX_PATH;
10798     lstrcpyA(val, "apple");
10799     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10800                             MSIINSTALLCONTEXT_MACHINE,
10801                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10802     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10803     ok(!lstrcmpA(val, "apple"),
10804        "Expected val to be unchanged, got \"%s\"\n", val);
10805     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10806
10807     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10808     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
10809     lstrcatA(keypath, patch_squashed);
10810
10811     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10812     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10813
10814     /* UserData Patches key exists */
10815     size = MAX_PATH;
10816     lstrcpyA(val, "apple");
10817     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10818                             MSIINSTALLCONTEXT_MACHINE,
10819                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10821     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10822     ok(size == 0, "Expected 0, got %d\n", size);
10823
10824     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10825                          (const BYTE *)"pack", 5);
10826     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10827
10828     /* LocalPatch value exists */
10829     size = MAX_PATH;
10830     lstrcpyA(val, "apple");
10831     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10832                             MSIINSTALLCONTEXT_MACHINE,
10833                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10834     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10835     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10836     ok(size == 4, "Expected 4, got %d\n", size);
10837
10838     size = MAX_PATH;
10839     lstrcpyA(val, "apple");
10840     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10841                             MSIINSTALLCONTEXT_MACHINE,
10842                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10843     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10844     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10845     ok(size == 10, "Expected 10, got %d\n", size);
10846
10847     RegDeleteValueA(prodpatches, patch_squashed);
10848     RegDeleteKeyA(prodpatches, "");
10849     RegCloseKey(prodpatches);
10850     RegDeleteKeyA(prodkey, "");
10851     RegCloseKey(prodkey);
10852
10853     /* UserData is sufficient for all properties
10854      * except INSTALLPROPERTY_TRANSFORMS
10855      */
10856     size = MAX_PATH;
10857     lstrcpyA(val, "apple");
10858     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10859                             MSIINSTALLCONTEXT_MACHINE,
10860                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10861     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10862     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10863     ok(size == 4, "Expected 4, got %d\n", size);
10864
10865     /* UserData is sufficient for all properties
10866      * except INSTALLPROPERTY_TRANSFORMS
10867      */
10868     size = MAX_PATH;
10869     lstrcpyA(val, "apple");
10870     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10871                             MSIINSTALLCONTEXT_MACHINE,
10872                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10873     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10874     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10875     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10876
10877     RegDeleteValueA(udpatch, "LocalPackage");
10878     RegDeleteKeyA(udpatch, "");
10879     RegCloseKey(udpatch);
10880     RegDeleteKeyA(hpatch, "");
10881     RegCloseKey(hpatch);
10882     RegDeleteKeyA(patches, "");
10883     RegCloseKey(patches);
10884     RegDeleteKeyA(props, "");
10885     RegCloseKey(props);
10886     RegDeleteKeyA(udprod, "");
10887     RegCloseKey(udprod);
10888     LocalFree(usersid);
10889 }
10890
10891 static void test_MsiGetPatchInfo(void)
10892 {
10893     UINT r;
10894     char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
10895     char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
10896     WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
10897     HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
10898     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
10899     DWORD size;
10900     LONG res;
10901
10902     create_test_guid(patch_code, patch_squashed);
10903     create_test_guid(prod_code, prod_squashed);
10904     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
10905
10906     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
10907     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
10908
10909     r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
10910     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
10911
10912     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
10913     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
10914
10915     size = 0;
10916     r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
10917     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
10918
10919     r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
10920     ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
10921
10922     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10923     lstrcatA(keypath, prod_squashed);
10924
10925     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_product);
10926     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
10927
10928     /* product key exists */
10929     size = MAX_PATH;
10930     lstrcpyA(val, "apple");
10931     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
10932     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
10933     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
10934     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
10935
10936     res = RegCreateKeyA(hkey_product, "Patches", &hkey_patches);
10937     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
10938
10939     /* patches key exists */
10940     size = MAX_PATH;
10941     lstrcpyA(val, "apple");
10942     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
10943     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
10944     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
10945     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
10946
10947     res = RegCreateKeyA(hkey_patches, patch_squashed, &hkey_patch);
10948     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
10949
10950     /* patch key exists */
10951     size = MAX_PATH;
10952     lstrcpyA(val, "apple");
10953     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
10954     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
10955     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
10956     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
10957
10958     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10959     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10960     lstrcatA(keypath, prod_squashed);
10961
10962     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udproduct);
10963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
10964
10965     /* UserData product key exists */
10966     size = MAX_PATH;
10967     lstrcpyA(val, "apple");
10968     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
10969     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
10970     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
10971     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
10972
10973     res = RegCreateKeyA(hkey_udproduct, "InstallProperties", &hkey_udprops);
10974     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
10975
10976     /* InstallProperties key exists */
10977     size = MAX_PATH;
10978     lstrcpyA(val, "apple");
10979     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
10980     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
10981     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
10982     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
10983
10984     res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udpatches);
10985     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
10986
10987     /* UserData Patches key exists */
10988     size = MAX_PATH;
10989     lstrcpyA(val, "apple");
10990     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
10991     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
10992     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
10993     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
10994
10995     res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udproductpatches);
10996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10997
10998     res = RegCreateKeyA(hkey_udproductpatches, patch_squashed, &hkey_udproductpatch);
10999     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11000
11001     /* UserData product patch key exists */
11002     size = MAX_PATH;
11003     lstrcpyA(val, "apple");
11004     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11005     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11006     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11007     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11008
11009     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11010     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11011     lstrcatA(keypath, patch_squashed);
11012
11013     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udpatch);
11014     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11015
11016     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11017     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11018
11019     /* UserData Patch key exists */
11020     size = 0;
11021     lstrcpyA(val, "apple");
11022     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11023     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11024     ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11025     ok(size == 11, "expected 11 got %u\n", size);
11026
11027     size = MAX_PATH;
11028     lstrcpyA(val, "apple");
11029     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11030     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11031     ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11032     ok(size == 11, "expected 11 got %u\n", size);
11033
11034     size = 0;
11035     valW[0] = 0;
11036     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11037     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11038     ok(!valW[0], "expected 0 got %u\n", valW[0]);
11039     ok(size == 11, "expected 11 got %u\n", size);
11040
11041     size = MAX_PATH;
11042     valW[0] = 0;
11043     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11044     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11045     ok(valW[0], "expected > 0 got %u\n", valW[0]);
11046     ok(size == 11, "expected 11 got %u\n", size);
11047
11048     RegDeleteKeyA(hkey_udproductpatch, "");
11049     RegCloseKey(hkey_udproductpatch);
11050     RegDeleteKeyA(hkey_udproductpatches, "");
11051     RegCloseKey(hkey_udproductpatches);
11052     RegDeleteKeyA(hkey_udpatch, "");
11053     RegCloseKey(hkey_udpatch);
11054     RegDeleteKeyA(hkey_patches, "");
11055     RegCloseKey(hkey_patches);
11056     RegDeleteKeyA(hkey_product, "");
11057     RegCloseKey(hkey_product);
11058     RegDeleteKeyA(hkey_patch, "");
11059     RegCloseKey(hkey_patch);
11060     RegDeleteKeyA(hkey_udpatches, "");
11061     RegCloseKey(hkey_udpatches);
11062     RegDeleteKeyA(hkey_udprops, "");
11063     RegCloseKey(hkey_udprops);
11064     RegDeleteKeyA(hkey_udproduct, "");
11065     RegCloseKey(hkey_udproduct);
11066 }
11067
11068 static void test_MsiEnumProducts(void)
11069 {
11070     UINT r;
11071     int found1, found2, found3;
11072     DWORD index;
11073     char product1[39], product2[39], product3[39], guid[39];
11074     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11075     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11076     char *usersid;
11077     HKEY key1, key2, key3;
11078
11079     create_test_guid(product1, product_squashed1);
11080     create_test_guid(product2, product_squashed2);
11081     create_test_guid(product3, product_squashed3);
11082     get_user_sid(&usersid);
11083
11084     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11085     strcat(keypath1, product_squashed1);
11086
11087     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath1, &key1);
11088     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11089
11090     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11091     strcat(keypath2, usersid);
11092     strcat(keypath2, "\\Installer\\Products\\");
11093     strcat(keypath2, product_squashed2);
11094
11095     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath2, &key2);
11096     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11097
11098     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
11099     strcat(keypath3, product_squashed3);
11100
11101     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
11102     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11103
11104     index = 0;
11105     r = MsiEnumProductsA(index, NULL);
11106     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11107
11108     index = 2;
11109     r = MsiEnumProductsA(index, guid);
11110     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11111
11112     index = 0;
11113     r = MsiEnumProductsA(index, guid);
11114     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11115
11116     found1 = found2 = found3 = 0;
11117     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
11118     {
11119         if (!strcmp(product1, guid)) found1 = 1;
11120         if (!strcmp(product2, guid)) found2 = 1;
11121         if (!strcmp(product3, guid)) found3 = 1;
11122         index++;
11123     }
11124     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
11125     ok(found1, "product1 not found\n");
11126     ok(found2, "product2 not found\n");
11127     ok(found3, "product3 not found\n");
11128
11129     RegDeleteKeyA(key1, "");
11130     RegDeleteKeyA(key2, "");
11131     RegDeleteKeyA(key3, "");
11132     RegCloseKey(key1);
11133     RegCloseKey(key2);
11134     RegCloseKey(key3);
11135     LocalFree(usersid);
11136 }
11137
11138 START_TEST(msi)
11139 {
11140     init_functionpointers();
11141
11142     test_usefeature();
11143     test_null();
11144     test_getcomponentpath();
11145     test_MsiGetFileHash();
11146
11147     if (!pConvertSidToStringSidA)
11148         win_skip("ConvertSidToStringSidA not implemented\n");
11149     else
11150     {
11151         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
11152         test_MsiQueryProductState();
11153         test_MsiQueryFeatureState();
11154         test_MsiQueryComponentState();
11155         test_MsiGetComponentPath();
11156         test_MsiGetProductCode();
11157         test_MsiEnumClients();
11158         test_MsiGetProductInfo();
11159         test_MsiGetProductInfoEx();
11160         test_MsiGetUserInfo();
11161         test_MsiOpenProduct();
11162         test_MsiEnumPatchesEx();
11163         test_MsiEnumPatches();
11164         test_MsiGetPatchInfoEx();
11165         test_MsiGetPatchInfo();
11166         test_MsiEnumProducts();
11167     }
11168
11169     test_MsiGetFileVersion();
11170 }