user32: Use the stored color and mask bitmaps instead of the raw bits in GetIconInfo.
[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-000000000001}", "foo", 0);
251     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
252
253     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "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((LPCOLESTR)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 ||
8225        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8226        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8227     ok(!lstrcmpA(patchcode, "apple"),
8228        "Expected patchcode to be unchanged, got %s\n", patchcode);
8229     ok(!lstrcmpA(targetprod, "banana"),
8230        "Expected targetprod to be unchanged, got %s\n", targetprod);
8231     ok(context == 0xdeadbeef,
8232        "Expected context to be unchanged, got %d\n", context);
8233     ok(!lstrcmpA(targetsid, "kiwi"),
8234        "Expected targetsid to be unchanged, got %s\n", targetsid);
8235     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8236
8237     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8238                          (const BYTE *)"whatever", 9);
8239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8240
8241     /* patch code value exists */
8242     lstrcpyA(patchcode, "apple");
8243     lstrcpyA(targetprod, "banana");
8244     context = 0xdeadbeef;
8245     lstrcpyA(targetsid, "kiwi");
8246     size = MAX_PATH;
8247     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8248                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8249                            &context, targetsid, &size);
8250     ok(r == ERROR_NO_MORE_ITEMS ||
8251        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8252        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8253     ok(!lstrcmpA(patchcode, "apple"),
8254        "Expected patchcode to be unchanged, got %s\n", patchcode);
8255     ok(!lstrcmpA(targetprod, "banana"),
8256        "Expected targetprod to be unchanged, got %s\n", targetprod);
8257     ok(context == 0xdeadbeef,
8258        "Expected context to be unchanged, got %d\n", context);
8259     ok(!lstrcmpA(targetsid, "kiwi"),
8260        "Expected targetsid to be unchanged, got %s\n", targetsid);
8261     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8262
8263     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8264     lstrcatA(keypath, expectedsid);
8265     lstrcatA(keypath, "\\Patches\\");
8266     lstrcatA(keypath, patch_squashed);
8267
8268     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
8269     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8270
8271     /* userdata patch key exists */
8272     lstrcpyA(patchcode, "apple");
8273     lstrcpyA(targetprod, "banana");
8274     context = 0xdeadbeef;
8275     lstrcpyA(targetsid, "kiwi");
8276     size = MAX_PATH;
8277     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8278                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8279                            &context, targetsid, &size);
8280     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8281     ok(!lstrcmpA(patchcode, patch),
8282        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8283     ok(!lstrcmpA(targetprod, prodcode),
8284        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8285     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8286        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8287     ok(!lstrcmpA(targetsid, expectedsid),
8288        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8289     ok(size == lstrlenA(expectedsid),
8290        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8291
8292     /* MSIPATCHSTATE_SUPERSEDED */
8293
8294     lstrcpyA(patchcode, "apple");
8295     lstrcpyA(targetprod, "banana");
8296     context = 0xdeadbeef;
8297     lstrcpyA(targetsid, "kiwi");
8298     size = MAX_PATH;
8299     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8300                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8301                            &context, targetsid, &size);
8302     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8303     ok(!lstrcmpA(patchcode, "apple"),
8304        "Expected patchcode to be unchanged, got %s\n", patchcode);
8305     ok(!lstrcmpA(targetprod, "banana"),
8306        "Expected targetprod to be unchanged, got %s\n", targetprod);
8307     ok(context == 0xdeadbeef,
8308        "Expected context to be unchanged, got %d\n", context);
8309     ok(!lstrcmpA(targetsid, "kiwi"),
8310        "Expected targetsid to be unchanged, got %s\n", targetsid);
8311     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8312
8313     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8314     lstrcatA(keypath, expectedsid);
8315     lstrcatA(keypath, "\\Products\\");
8316     lstrcatA(keypath, prod_squashed);
8317
8318     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8320
8321     /* UserData product key exists */
8322     lstrcpyA(patchcode, "apple");
8323     lstrcpyA(targetprod, "banana");
8324     context = 0xdeadbeef;
8325     lstrcpyA(targetsid, "kiwi");
8326     size = MAX_PATH;
8327     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8328                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8329                            &context, targetsid, &size);
8330     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8331     ok(!lstrcmpA(patchcode, "apple"),
8332        "Expected patchcode to be unchanged, got %s\n", patchcode);
8333     ok(!lstrcmpA(targetprod, "banana"),
8334        "Expected targetprod to be unchanged, got %s\n", targetprod);
8335     ok(context == 0xdeadbeef,
8336        "Expected context to be unchanged, got %d\n", context);
8337     ok(!lstrcmpA(targetsid, "kiwi"),
8338        "Expected targetsid to be unchanged, got %s\n", targetsid);
8339     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8340
8341     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8343
8344     /* UserData patches key exists */
8345     lstrcpyA(patchcode, "apple");
8346     lstrcpyA(targetprod, "banana");
8347     context = 0xdeadbeef;
8348     lstrcpyA(targetsid, "kiwi");
8349     size = MAX_PATH;
8350     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8351                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8352                            &context, targetsid, &size);
8353     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8354     ok(!lstrcmpA(patchcode, "apple"),
8355        "Expected patchcode to be unchanged, got %s\n", patchcode);
8356     ok(!lstrcmpA(targetprod, "banana"),
8357        "Expected targetprod to be unchanged, got %s\n", targetprod);
8358     ok(context == 0xdeadbeef,
8359        "Expected context to be unchanged, got %d\n", context);
8360     ok(!lstrcmpA(targetsid, "kiwi"),
8361        "Expected targetsid to be unchanged, got %s\n", targetsid);
8362     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8363
8364     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8366
8367     /* specific UserData patch key exists */
8368     lstrcpyA(patchcode, "apple");
8369     lstrcpyA(targetprod, "banana");
8370     context = 0xdeadbeef;
8371     lstrcpyA(targetsid, "kiwi");
8372     size = MAX_PATH;
8373     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8374                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8375                            &context, targetsid, &size);
8376     ok(r == ERROR_BAD_CONFIGURATION,
8377        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8378     ok(!lstrcmpA(patchcode, "apple"),
8379        "Expected patchcode to be unchanged, got %s\n", patchcode);
8380     ok(!lstrcmpA(targetprod, "banana"),
8381        "Expected targetprod to be unchanged, got %s\n", targetprod);
8382     ok(context == 0xdeadbeef,
8383        "Expected context to be unchanged, got %d\n", context);
8384     ok(!lstrcmpA(targetsid, "kiwi"),
8385        "Expected targetsid to be unchanged, got %s\n", targetsid);
8386     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8387
8388     data = MSIPATCHSTATE_SUPERSEDED;
8389     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8390                          (const BYTE *)&data, sizeof(DWORD));
8391     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8392
8393     /* State value exists */
8394     lstrcpyA(patchcode, "apple");
8395     lstrcpyA(targetprod, "banana");
8396     context = 0xdeadbeef;
8397     lstrcpyA(targetsid, "kiwi");
8398     size = MAX_PATH;
8399     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8400                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8401                            &context, targetsid, &size);
8402     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8403     ok(!lstrcmpA(patchcode, patch),
8404        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8405     ok(!lstrcmpA(targetprod, prodcode),
8406        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8407     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8408        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8409     ok(!lstrcmpA(targetsid, expectedsid),
8410        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8411     ok(size == lstrlenA(expectedsid),
8412        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8413
8414     /* MSIPATCHSTATE_OBSOLETED */
8415
8416     lstrcpyA(patchcode, "apple");
8417     lstrcpyA(targetprod, "banana");
8418     context = 0xdeadbeef;
8419     lstrcpyA(targetsid, "kiwi");
8420     size = MAX_PATH;
8421     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8422                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8423                            &context, targetsid, &size);
8424     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8425     ok(!lstrcmpA(patchcode, "apple"),
8426        "Expected patchcode to be unchanged, got %s\n", patchcode);
8427     ok(!lstrcmpA(targetprod, "banana"),
8428        "Expected targetprod to be unchanged, got %s\n", targetprod);
8429     ok(context == 0xdeadbeef,
8430        "Expected context to be unchanged, got %d\n", context);
8431     ok(!lstrcmpA(targetsid, "kiwi"),
8432        "Expected targetsid to be unchanged, got %s\n", targetsid);
8433     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8434
8435     data = MSIPATCHSTATE_OBSOLETED;
8436     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8437                          (const BYTE *)&data, sizeof(DWORD));
8438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8439
8440     /* State value is obsoleted */
8441     lstrcpyA(patchcode, "apple");
8442     lstrcpyA(targetprod, "banana");
8443     context = 0xdeadbeef;
8444     lstrcpyA(targetsid, "kiwi");
8445     size = MAX_PATH;
8446     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8447                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8448                            &context, targetsid, &size);
8449     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8450     ok(!lstrcmpA(patchcode, patch),
8451        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8452     ok(!lstrcmpA(targetprod, prodcode),
8453        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8454     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8455        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8456     ok(!lstrcmpA(targetsid, expectedsid),
8457        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8458     ok(size == lstrlenA(expectedsid),
8459        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8460
8461     /* MSIPATCHSTATE_REGISTERED */
8462     /* FIXME */
8463
8464     /* MSIPATCHSTATE_ALL */
8465
8466     /* 1st */
8467     lstrcpyA(patchcode, "apple");
8468     lstrcpyA(targetprod, "banana");
8469     context = 0xdeadbeef;
8470     lstrcpyA(targetsid, "kiwi");
8471     size = MAX_PATH;
8472     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8473                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8474                            &context, targetsid, &size);
8475     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8476     ok(!lstrcmpA(patchcode, patch),
8477        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8478     ok(!lstrcmpA(targetprod, prodcode),
8479        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8480     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8481        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8482     ok(!lstrcmpA(targetsid, expectedsid),
8483        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8484     ok(size == lstrlenA(expectedsid),
8485        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8486
8487     /* same patch in multiple places, only one is enumerated */
8488     lstrcpyA(patchcode, "apple");
8489     lstrcpyA(targetprod, "banana");
8490     context = 0xdeadbeef;
8491     lstrcpyA(targetsid, "kiwi");
8492     size = MAX_PATH;
8493     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8494                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8495                            &context, targetsid, &size);
8496     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8497     ok(!lstrcmpA(patchcode, "apple"),
8498        "Expected patchcode to be unchanged, got %s\n", patchcode);
8499     ok(!lstrcmpA(targetprod, "banana"),
8500        "Expected targetprod to be unchanged, got %s\n", targetprod);
8501     ok(context == 0xdeadbeef,
8502        "Expected context to be unchanged, got %d\n", context);
8503     ok(!lstrcmpA(targetsid, "kiwi"),
8504        "Expected targetsid to be unchanged, got %s\n", targetsid);
8505     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8506
8507     RegDeleteValueA(hpatch, "State");
8508     RegDeleteKeyA(hpatch, "");
8509     RegCloseKey(hpatch);
8510     RegDeleteKeyA(udpatch, "");
8511     RegCloseKey(udpatch);
8512     RegDeleteKeyA(udprod, "");
8513     RegCloseKey(udprod);
8514     RegDeleteKeyA(userkey, "");
8515     RegCloseKey(userkey);
8516     RegDeleteValueA(patches, patch_squashed);
8517     RegDeleteValueA(patches, "Patches");
8518     RegDeleteKeyA(patches, "");
8519     RegCloseKey(patches);
8520     RegDeleteKeyA(prodkey, "");
8521     RegCloseKey(prodkey);
8522 }
8523
8524 static void test_MsiEnumPatchesEx_machine(void)
8525 {
8526     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8527     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8528     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8529     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8530     HKEY prodkey, patches, udprod, udpatch;
8531     HKEY hpatch;
8532     MSIINSTALLCONTEXT context;
8533     DWORD size, data;
8534     LONG res;
8535     UINT r;
8536
8537     create_test_guid(prodcode, prod_squashed);
8538     create_test_guid(patch, patch_squashed);
8539
8540     /* MSIPATCHSTATE_APPLIED */
8541
8542     lstrcpyA(patchcode, "apple");
8543     lstrcpyA(targetprod, "banana");
8544     context = 0xdeadbeef;
8545     lstrcpyA(targetsid, "kiwi");
8546     size = MAX_PATH;
8547     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8548                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8549                            &context, targetsid, &size);
8550     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8551     ok(!lstrcmpA(patchcode, "apple"),
8552        "Expected patchcode to be unchanged, got %s\n", patchcode);
8553     ok(!lstrcmpA(targetprod, "banana"),
8554        "Expected targetprod to be unchanged, got %s\n", targetprod);
8555     ok(context == 0xdeadbeef,
8556        "Expected context to be unchanged, got %d\n", context);
8557     ok(!lstrcmpA(targetsid, "kiwi"),
8558        "Expected targetsid to be unchanged, got %s\n", targetsid);
8559     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8560
8561     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8562     lstrcatA(keypath, prod_squashed);
8563
8564     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
8565     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8566
8567     /* local product key exists */
8568     lstrcpyA(patchcode, "apple");
8569     lstrcpyA(targetprod, "banana");
8570     context = 0xdeadbeef;
8571     lstrcpyA(targetsid, "kiwi");
8572     size = MAX_PATH;
8573     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8574                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8575                            &context, targetsid, &size);
8576     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8577     ok(!lstrcmpA(patchcode, "apple"),
8578        "Expected patchcode to be unchanged, got %s\n", patchcode);
8579     ok(!lstrcmpA(targetprod, "banana"),
8580        "Expected targetprod to be unchanged, got %s\n", targetprod);
8581     ok(context == 0xdeadbeef,
8582        "Expected context to be unchanged, got %d\n", context);
8583     ok(!lstrcmpA(targetsid, "kiwi"),
8584        "Expected targetsid to be unchanged, got %s\n", targetsid);
8585     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8586
8587     res = RegCreateKeyA(prodkey, "Patches", &patches);
8588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8589
8590     /* Patches key exists */
8591     lstrcpyA(patchcode, "apple");
8592     lstrcpyA(targetprod, "banana");
8593     context = 0xdeadbeef;
8594     lstrcpyA(targetsid, "kiwi");
8595     size = MAX_PATH;
8596     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8597                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8598                            &context, targetsid, &size);
8599     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8600     ok(!lstrcmpA(patchcode, "apple"),
8601        "Expected patchcode to be unchanged, got %s\n", patchcode);
8602     ok(!lstrcmpA(targetprod, "banana"),
8603        "Expected targetprod to be unchanged, got %s\n", targetprod);
8604     ok(context == 0xdeadbeef,
8605        "Expected context to be unchanged, got %d\n", context);
8606     ok(!lstrcmpA(targetsid, "kiwi"),
8607        "Expected targetsid to be unchanged, got %s\n", targetsid);
8608     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8609
8610     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8611                          (const BYTE *)patch_squashed,
8612                          lstrlenA(patch_squashed) + 1);
8613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8614
8615     /* Patches value exists, is not REG_MULTI_SZ */
8616     lstrcpyA(patchcode, "apple");
8617     lstrcpyA(targetprod, "banana");
8618     context = 0xdeadbeef;
8619     lstrcpyA(targetsid, "kiwi");
8620     size = MAX_PATH;
8621     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8622                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8623                            &context, targetsid, &size);
8624     ok(r == ERROR_BAD_CONFIGURATION,
8625        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8626     ok(!lstrcmpA(patchcode, "apple"),
8627        "Expected patchcode to be unchanged, got %s\n", patchcode);
8628     ok(!lstrcmpA(targetprod, "banana"),
8629        "Expected targetprod to be unchanged, got %s\n", targetprod);
8630     ok(context == 0xdeadbeef,
8631        "Expected context to be unchanged, got %d\n", context);
8632     ok(!lstrcmpA(targetsid, "kiwi"),
8633        "Expected targetsid to be unchanged, got %s\n", targetsid);
8634     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8635
8636     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8637                          (const BYTE *)"a\0b\0c\0\0", 7);
8638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8639
8640     /* Patches value exists, is not a squashed guid */
8641     lstrcpyA(patchcode, "apple");
8642     lstrcpyA(targetprod, "banana");
8643     context = 0xdeadbeef;
8644     lstrcpyA(targetsid, "kiwi");
8645     size = MAX_PATH;
8646     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8647                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8648                            &context, targetsid, &size);
8649     ok(r == ERROR_BAD_CONFIGURATION,
8650        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8651     ok(!lstrcmpA(patchcode, "apple"),
8652        "Expected patchcode to be unchanged, got %s\n", patchcode);
8653     ok(!lstrcmpA(targetprod, "banana"),
8654        "Expected targetprod to be unchanged, got %s\n", targetprod);
8655     ok(context == 0xdeadbeef,
8656        "Expected context to be unchanged, got %d\n", context);
8657     ok(!lstrcmpA(targetsid, "kiwi"),
8658        "Expected targetsid to be unchanged, got %s\n", targetsid);
8659     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8660
8661     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8662     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8663                          (const BYTE *)patch_squashed,
8664                          lstrlenA(patch_squashed) + 2);
8665     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8666
8667     /* Patches value exists */
8668     lstrcpyA(patchcode, "apple");
8669     lstrcpyA(targetprod, "banana");
8670     context = 0xdeadbeef;
8671     lstrcpyA(targetsid, "kiwi");
8672     size = MAX_PATH;
8673     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8674                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8675                            &context, targetsid, &size);
8676     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8677     ok(!lstrcmpA(patchcode, "apple"),
8678        "Expected patchcode to be unchanged, got %s\n", patchcode);
8679     ok(!lstrcmpA(targetprod, "banana"),
8680        "Expected targetprod to be unchanged, got %s\n", targetprod);
8681     ok(context == 0xdeadbeef,
8682        "Expected context to be unchanged, got %d\n", context);
8683     ok(!lstrcmpA(targetsid, "kiwi"),
8684        "Expected targetsid to be unchanged, got %s\n", targetsid);
8685     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8686
8687     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8688                          (const BYTE *)"whatever", 9);
8689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8690
8691     /* patch code value exists */
8692     lstrcpyA(patchcode, "apple");
8693     lstrcpyA(targetprod, "banana");
8694     context = 0xdeadbeef;
8695     lstrcpyA(targetsid, "kiwi");
8696     size = MAX_PATH;
8697     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8698                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8699                            &context, targetsid, &size);
8700     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8701     ok(!lstrcmpA(patchcode, patch),
8702        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8703     ok(!lstrcmpA(targetprod, prodcode),
8704        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8705     ok(context == MSIINSTALLCONTEXT_MACHINE,
8706        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8707     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8708     ok(size == 0, "Expected 0, got %d\n", size);
8709
8710     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8711     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8712     lstrcatA(keypath, prod_squashed);
8713
8714     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8715     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8716
8717     /* local UserData product key exists */
8718     lstrcpyA(patchcode, "apple");
8719     lstrcpyA(targetprod, "banana");
8720     context = 0xdeadbeef;
8721     lstrcpyA(targetsid, "kiwi");
8722     size = MAX_PATH;
8723     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8724                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8725                            &context, targetsid, &size);
8726     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8727     ok(!lstrcmpA(patchcode, patch),
8728        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8729     ok(!lstrcmpA(targetprod, prodcode),
8730        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8731     ok(context == MSIINSTALLCONTEXT_MACHINE,
8732        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8733     ok(!lstrcmpA(targetsid, ""),
8734        "Expected \"\", got \"%s\"\n", targetsid);
8735     ok(size == 0, "Expected 0, got %d\n", size);
8736
8737     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8738     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8739
8740     /* local UserData Patches key exists */
8741     lstrcpyA(patchcode, "apple");
8742     lstrcpyA(targetprod, "banana");
8743     context = 0xdeadbeef;
8744     lstrcpyA(targetsid, "kiwi");
8745     size = MAX_PATH;
8746     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8747                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8748                            &context, targetsid, &size);
8749     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8750     ok(!lstrcmpA(patchcode, patch),
8751        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8752     ok(!lstrcmpA(targetprod, prodcode),
8753        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8754     ok(context == MSIINSTALLCONTEXT_MACHINE,
8755        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8756     ok(!lstrcmpA(targetsid, ""),
8757        "Expected \"\", got \"%s\"\n", targetsid);
8758     ok(size == 0, "Expected 0, got %d\n", size);
8759
8760     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8761     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8762
8763     /* local UserData Product patch key exists */
8764     lstrcpyA(patchcode, "apple");
8765     lstrcpyA(targetprod, "banana");
8766     context = 0xdeadbeef;
8767     lstrcpyA(targetsid, "kiwi");
8768     size = MAX_PATH;
8769     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8770                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8771                            &context, targetsid, &size);
8772     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8773     ok(!lstrcmpA(patchcode, "apple"),
8774        "Expected patchcode to be unchanged, got %s\n", patchcode);
8775     ok(!lstrcmpA(targetprod, "banana"),
8776        "Expected targetprod to be unchanged, got %s\n", targetprod);
8777     ok(context == 0xdeadbeef,
8778        "Expected context to be unchanged, got %d\n", context);
8779     ok(!lstrcmpA(targetsid, "kiwi"),
8780        "Expected targetsid to be unchanged, got %s\n", targetsid);
8781     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8782
8783     data = MSIPATCHSTATE_APPLIED;
8784     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8785                          (const BYTE *)&data, sizeof(DWORD));
8786     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8787
8788     /* State value exists */
8789     lstrcpyA(patchcode, "apple");
8790     lstrcpyA(targetprod, "banana");
8791     context = 0xdeadbeef;
8792     lstrcpyA(targetsid, "kiwi");
8793     size = MAX_PATH;
8794     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8795                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8796                            &context, targetsid, &size);
8797     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8798     ok(!lstrcmpA(patchcode, patch),
8799        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8800     ok(!lstrcmpA(targetprod, prodcode),
8801        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8802     ok(context == MSIINSTALLCONTEXT_MACHINE,
8803        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8804     ok(!lstrcmpA(targetsid, ""),
8805        "Expected \"\", got \"%s\"\n", targetsid);
8806     ok(size == 0, "Expected 0, got %d\n", size);
8807
8808     /* MSIPATCHSTATE_SUPERSEDED */
8809
8810     lstrcpyA(patchcode, "apple");
8811     lstrcpyA(targetprod, "banana");
8812     context = 0xdeadbeef;
8813     lstrcpyA(targetsid, "kiwi");
8814     size = MAX_PATH;
8815     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8816                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8817                            &context, targetsid, &size);
8818     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8819     ok(!lstrcmpA(patchcode, "apple"),
8820        "Expected patchcode to be unchanged, got %s\n", patchcode);
8821     ok(!lstrcmpA(targetprod, "banana"),
8822        "Expected targetprod to be unchanged, got %s\n", targetprod);
8823     ok(context == 0xdeadbeef,
8824        "Expected context to be unchanged, got %d\n", context);
8825     ok(!lstrcmpA(targetsid, "kiwi"),
8826        "Expected targetsid to be unchanged, got %s\n", targetsid);
8827     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8828
8829     data = MSIPATCHSTATE_SUPERSEDED;
8830     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8831                          (const BYTE *)&data, sizeof(DWORD));
8832     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8833
8834     /* State value is MSIPATCHSTATE_SUPERSEDED */
8835     lstrcpyA(patchcode, "apple");
8836     lstrcpyA(targetprod, "banana");
8837     context = 0xdeadbeef;
8838     lstrcpyA(targetsid, "kiwi");
8839     size = MAX_PATH;
8840     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8841                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8842                            &context, targetsid, &size);
8843     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8844     ok(!lstrcmpA(patchcode, patch),
8845        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8846     ok(!lstrcmpA(targetprod, prodcode),
8847        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8848     ok(context == MSIINSTALLCONTEXT_MACHINE,
8849        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8850     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8851     ok(size == 0, "Expected 0, got %d\n", size);
8852
8853     /* MSIPATCHSTATE_OBSOLETED */
8854
8855     lstrcpyA(patchcode, "apple");
8856     lstrcpyA(targetprod, "banana");
8857     context = 0xdeadbeef;
8858     lstrcpyA(targetsid, "kiwi");
8859     size = MAX_PATH;
8860     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8861                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8862                            &context, targetsid, &size);
8863     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8864     ok(!lstrcmpA(patchcode, "apple"),
8865        "Expected patchcode to be unchanged, got %s\n", patchcode);
8866     ok(!lstrcmpA(targetprod, "banana"),
8867        "Expected targetprod to be unchanged, got %s\n", targetprod);
8868     ok(context == 0xdeadbeef,
8869        "Expected context to be unchanged, got %d\n", context);
8870     ok(!lstrcmpA(targetsid, "kiwi"),
8871        "Expected targetsid to be unchanged, got %s\n", targetsid);
8872     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8873
8874     data = MSIPATCHSTATE_OBSOLETED;
8875     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8876                          (const BYTE *)&data, sizeof(DWORD));
8877     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8878
8879     /* State value is obsoleted */
8880     lstrcpyA(patchcode, "apple");
8881     lstrcpyA(targetprod, "banana");
8882     context = 0xdeadbeef;
8883     lstrcpyA(targetsid, "kiwi");
8884     size = MAX_PATH;
8885     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8886                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8887                            &context, targetsid, &size);
8888     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8889     ok(!lstrcmpA(patchcode, patch),
8890        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8891     ok(!lstrcmpA(targetprod, prodcode),
8892        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8893     ok(context == MSIINSTALLCONTEXT_MACHINE,
8894        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8895     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8896     ok(size == 0, "Expected 0, got %d\n", size);
8897
8898     /* MSIPATCHSTATE_REGISTERED */
8899     /* FIXME */
8900
8901     /* MSIPATCHSTATE_ALL */
8902
8903     /* 1st */
8904     lstrcpyA(patchcode, "apple");
8905     lstrcpyA(targetprod, "banana");
8906     context = 0xdeadbeef;
8907     lstrcpyA(targetsid, "kiwi");
8908     size = MAX_PATH;
8909     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8910                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8911                            &context, targetsid, &size);
8912     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8913     ok(!lstrcmpA(patchcode, patch),
8914        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8915     ok(!lstrcmpA(targetprod, prodcode),
8916        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8917     ok(context == MSIINSTALLCONTEXT_MACHINE,
8918        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8919     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8920     ok(size == 0, "Expected 0, got %d\n", size);
8921
8922     /* same patch in multiple places, only one is enumerated */
8923     lstrcpyA(patchcode, "apple");
8924     lstrcpyA(targetprod, "banana");
8925     context = 0xdeadbeef;
8926     lstrcpyA(targetsid, "kiwi");
8927     size = MAX_PATH;
8928     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8929                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8930                            &context, targetsid, &size);
8931     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8932     ok(!lstrcmpA(patchcode, "apple"),
8933        "Expected patchcode to be unchanged, got %s\n", patchcode);
8934     ok(!lstrcmpA(targetprod, "banana"),
8935        "Expected targetprod to be unchanged, got %s\n", targetprod);
8936     ok(context == 0xdeadbeef,
8937        "Expected context to be unchanged, got %d\n", context);
8938     ok(!lstrcmpA(targetsid, "kiwi"),
8939        "Expected targetsid to be unchanged, got %s\n", targetsid);
8940     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8941
8942     RegDeleteValueA(patches, patch_squashed);
8943     RegDeleteValueA(patches, "Patches");
8944     RegDeleteKeyA(patches, "");
8945     RegCloseKey(patches);
8946     RegDeleteValueA(hpatch, "State");
8947     RegDeleteKeyA(hpatch, "");
8948     RegCloseKey(hpatch);
8949     RegDeleteKeyA(udpatch, "");
8950     RegCloseKey(udpatch);
8951     RegDeleteKeyA(udprod, "");
8952     RegCloseKey(udprod);
8953     RegDeleteKeyA(prodkey, "");
8954     RegCloseKey(prodkey);
8955 }
8956
8957 static void test_MsiEnumPatchesEx(void)
8958 {
8959     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8960     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8961     CHAR patchcode[MAX_PATH];
8962     MSIINSTALLCONTEXT context;
8963     LPSTR usersid;
8964     DWORD size;
8965     UINT r;
8966
8967     if (!pMsiEnumPatchesExA)
8968     {
8969         win_skip("MsiEnumPatchesExA not implemented\n");
8970         return;
8971     }
8972
8973     create_test_guid(prodcode, prod_squashed);
8974     get_user_sid(&usersid);
8975
8976     /* empty szProductCode */
8977     lstrcpyA(patchcode, "apple");
8978     lstrcpyA(targetprod, "banana");
8979     context = 0xdeadbeef;
8980     lstrcpyA(targetsid, "kiwi");
8981     size = MAX_PATH;
8982     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8983                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
8984                            targetsid, &size);
8985     ok(r == ERROR_INVALID_PARAMETER,
8986        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
8987     ok(!lstrcmpA(patchcode, "apple"),
8988        "Expected patchcode to be unchanged, got %s\n", patchcode);
8989     ok(!lstrcmpA(targetprod, "banana"),
8990        "Expected targetprod to be unchanged, got %s\n", targetprod);
8991     ok(context == 0xdeadbeef,
8992        "Expected context to be unchanged, got %d\n", context);
8993     ok(!lstrcmpA(targetsid, "kiwi"),
8994        "Expected targetsid to be unchanged, got %s\n", targetsid);
8995     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8996
8997     /* garbage szProductCode */
8998     lstrcpyA(patchcode, "apple");
8999     lstrcpyA(targetprod, "banana");
9000     context = 0xdeadbeef;
9001     lstrcpyA(targetsid, "kiwi");
9002     size = MAX_PATH;
9003     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9004                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9005                            targetsid, &size);
9006     ok(r == ERROR_INVALID_PARAMETER,
9007        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9008     ok(!lstrcmpA(patchcode, "apple"),
9009        "Expected patchcode to be unchanged, got %s\n", patchcode);
9010     ok(!lstrcmpA(targetprod, "banana"),
9011        "Expected targetprod to be unchanged, got %s\n", targetprod);
9012     ok(context == 0xdeadbeef,
9013        "Expected context to be unchanged, got %d\n", context);
9014     ok(!lstrcmpA(targetsid, "kiwi"),
9015        "Expected targetsid to be unchanged, got %s\n", targetsid);
9016     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9017
9018     /* guid without brackets */
9019     lstrcpyA(patchcode, "apple");
9020     lstrcpyA(targetprod, "banana");
9021     context = 0xdeadbeef;
9022     lstrcpyA(targetsid, "kiwi");
9023     size = MAX_PATH;
9024     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9025                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9026                            0, patchcode, targetprod, &context,
9027                            targetsid, &size);
9028     ok(r == ERROR_INVALID_PARAMETER,
9029        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9030     ok(!lstrcmpA(patchcode, "apple"),
9031        "Expected patchcode to be unchanged, got %s\n", patchcode);
9032     ok(!lstrcmpA(targetprod, "banana"),
9033        "Expected targetprod to be unchanged, got %s\n", targetprod);
9034     ok(context == 0xdeadbeef,
9035        "Expected context to be unchanged, got %d\n", context);
9036     ok(!lstrcmpA(targetsid, "kiwi"),
9037        "Expected targetsid to be unchanged, got %s\n", targetsid);
9038     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9039
9040     /* guid with brackets */
9041     lstrcpyA(patchcode, "apple");
9042     lstrcpyA(targetprod, "banana");
9043     context = 0xdeadbeef;
9044     lstrcpyA(targetsid, "kiwi");
9045     size = MAX_PATH;
9046     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9047                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9048                            0, patchcode, targetprod, &context,
9049                            targetsid, &size);
9050     ok(r == ERROR_NO_MORE_ITEMS,
9051        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9052     ok(!lstrcmpA(patchcode, "apple"),
9053        "Expected patchcode to be unchanged, got %s\n", patchcode);
9054     ok(!lstrcmpA(targetprod, "banana"),
9055        "Expected targetprod to be unchanged, got %s\n", targetprod);
9056     ok(context == 0xdeadbeef,
9057        "Expected context to be unchanged, got %d\n", context);
9058     ok(!lstrcmpA(targetsid, "kiwi"),
9059        "Expected targetsid to be unchanged, got %s\n", targetsid);
9060     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9061
9062     /* szUserSid is S-1-5-18 */
9063     lstrcpyA(patchcode, "apple");
9064     lstrcpyA(targetprod, "banana");
9065     context = 0xdeadbeef;
9066     lstrcpyA(targetsid, "kiwi");
9067     size = MAX_PATH;
9068     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9069                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9070                            0, patchcode, targetprod, &context,
9071                            targetsid, &size);
9072     ok(r == ERROR_INVALID_PARAMETER,
9073        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9074     ok(!lstrcmpA(patchcode, "apple"),
9075        "Expected patchcode to be unchanged, got %s\n", patchcode);
9076     ok(!lstrcmpA(targetprod, "banana"),
9077        "Expected targetprod to be unchanged, got %s\n", targetprod);
9078     ok(context == 0xdeadbeef,
9079        "Expected context to be unchanged, got %d\n", context);
9080     ok(!lstrcmpA(targetsid, "kiwi"),
9081        "Expected targetsid to be unchanged, got %s\n", targetsid);
9082     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9083
9084     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9085     lstrcpyA(patchcode, "apple");
9086     lstrcpyA(targetprod, "banana");
9087     context = 0xdeadbeef;
9088     lstrcpyA(targetsid, "kiwi");
9089     size = MAX_PATH;
9090     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9091                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9092                            &context, targetsid, &size);
9093     ok(r == ERROR_INVALID_PARAMETER,
9094        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9095     ok(!lstrcmpA(patchcode, "apple"),
9096        "Expected patchcode to be unchanged, got %s\n", patchcode);
9097     ok(!lstrcmpA(targetprod, "banana"),
9098        "Expected targetprod to be unchanged, got %s\n", targetprod);
9099     ok(context == 0xdeadbeef,
9100        "Expected context to be unchanged, got %d\n", context);
9101     ok(!lstrcmpA(targetsid, "kiwi"),
9102        "Expected targetsid to be unchanged, got %s\n", targetsid);
9103     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9104
9105     /* dwContext is out of bounds */
9106     lstrcpyA(patchcode, "apple");
9107     lstrcpyA(targetprod, "banana");
9108     context = 0xdeadbeef;
9109     lstrcpyA(targetsid, "kiwi");
9110     size = MAX_PATH;
9111     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9112                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9113                            &context, targetsid, &size);
9114     ok(r == ERROR_INVALID_PARAMETER,
9115        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9116     ok(!lstrcmpA(patchcode, "apple"),
9117        "Expected patchcode to be unchanged, got %s\n", patchcode);
9118     ok(!lstrcmpA(targetprod, "banana"),
9119        "Expected targetprod to be unchanged, got %s\n", targetprod);
9120     ok(context == 0xdeadbeef,
9121        "Expected context to be unchanged, got %d\n", context);
9122     ok(!lstrcmpA(targetsid, "kiwi"),
9123        "Expected targetsid to be unchanged, got %s\n", targetsid);
9124     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9125
9126     /* dwContext is out of bounds */
9127     lstrcpyA(patchcode, "apple");
9128     lstrcpyA(targetprod, "banana");
9129     context = 0xdeadbeef;
9130     lstrcpyA(targetsid, "kiwi");
9131     size = MAX_PATH;
9132     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9133                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9134                            &context, targetsid, &size);
9135     ok(r == ERROR_INVALID_PARAMETER,
9136        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9137     ok(!lstrcmpA(patchcode, "apple"),
9138        "Expected patchcode to be unchanged, got %s\n", patchcode);
9139     ok(!lstrcmpA(targetprod, "banana"),
9140        "Expected targetprod to be unchanged, got %s\n", targetprod);
9141     ok(context == 0xdeadbeef,
9142        "Expected context to be unchanged, got %d\n", context);
9143     ok(!lstrcmpA(targetsid, "kiwi"),
9144        "Expected targetsid to be unchanged, got %s\n", targetsid);
9145     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9146
9147     /* dwFilter is out of bounds */
9148     lstrcpyA(patchcode, "apple");
9149     lstrcpyA(targetprod, "banana");
9150     context = 0xdeadbeef;
9151     lstrcpyA(targetsid, "kiwi");
9152     size = MAX_PATH;
9153     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9154                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9155                            &context, targetsid, &size);
9156     ok(r == ERROR_INVALID_PARAMETER,
9157        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9158     ok(!lstrcmpA(patchcode, "apple"),
9159        "Expected patchcode to be unchanged, got %s\n", patchcode);
9160     ok(!lstrcmpA(targetprod, "banana"),
9161        "Expected targetprod to be unchanged, got %s\n", targetprod);
9162     ok(context == 0xdeadbeef,
9163        "Expected context to be unchanged, got %d\n", context);
9164     ok(!lstrcmpA(targetsid, "kiwi"),
9165        "Expected targetsid to be unchanged, got %s\n", targetsid);
9166     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9167
9168     /* dwFilter is out of bounds */
9169     lstrcpyA(patchcode, "apple");
9170     lstrcpyA(targetprod, "banana");
9171     context = 0xdeadbeef;
9172     lstrcpyA(targetsid, "kiwi");
9173     size = MAX_PATH;
9174     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9175                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9176                            &context, targetsid, &size);
9177     ok(r == ERROR_INVALID_PARAMETER,
9178        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9179     ok(!lstrcmpA(patchcode, "apple"),
9180        "Expected patchcode to be unchanged, got %s\n", patchcode);
9181     ok(!lstrcmpA(targetprod, "banana"),
9182        "Expected targetprod to be unchanged, got %s\n", targetprod);
9183     ok(context == 0xdeadbeef,
9184        "Expected context to be unchanged, got %d\n", context);
9185     ok(!lstrcmpA(targetsid, "kiwi"),
9186        "Expected targetsid to be unchanged, got %s\n", targetsid);
9187     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9188
9189     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9190     lstrcpyA(patchcode, "apple");
9191     lstrcpyA(targetprod, "banana");
9192     context = 0xdeadbeef;
9193     lstrcpyA(targetsid, "kiwi");
9194     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9195                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9196                            &context, targetsid, NULL);
9197     ok(r == ERROR_INVALID_PARAMETER,
9198        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9199     ok(!lstrcmpA(patchcode, "apple"),
9200        "Expected patchcode to be unchanged, got %s\n", patchcode);
9201     ok(!lstrcmpA(targetprod, "banana"),
9202        "Expected targetprod to be unchanged, got %s\n", targetprod);
9203     ok(context == 0xdeadbeef,
9204        "Expected context to be unchanged, got %d\n", context);
9205     ok(!lstrcmpA(targetsid, "kiwi"),
9206        "Expected targetsid to be unchanged, got %s\n", targetsid);
9207
9208     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9209     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9210     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9211     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9212     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9213     /* FIXME: Successfully test userunmanaged with a different user */
9214     test_MsiEnumPatchesEx_machine();
9215     LocalFree(usersid);
9216 }
9217
9218 static void test_MsiEnumPatches(void)
9219 {
9220     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9221     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9222     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9223     CHAR transforms[MAX_PATH];
9224     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9225     HKEY prodkey, patches, udprod;
9226     HKEY userkey, hpatch, udpatch;
9227     DWORD size, data;
9228     LPSTR usersid;
9229     LONG res;
9230     UINT r;
9231
9232     create_test_guid(prodcode, prod_squashed);
9233     create_test_guid(patchcode, patch_squashed);
9234     get_user_sid(&usersid);
9235
9236     /* NULL szProduct */
9237     size = MAX_PATH;
9238     lstrcpyA(patch, "apple");
9239     lstrcpyA(transforms, "banana");
9240     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9241     ok(r == ERROR_INVALID_PARAMETER,
9242        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9243     ok(!lstrcmpA(patch, "apple"),
9244        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9245     ok(!lstrcmpA(transforms, "banana"),
9246        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9247     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9248
9249     /* empty szProduct */
9250     size = MAX_PATH;
9251     lstrcpyA(patch, "apple");
9252     lstrcpyA(transforms, "banana");
9253     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9254     ok(r == ERROR_INVALID_PARAMETER,
9255        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9256     ok(!lstrcmpA(patch, "apple"),
9257        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9258     ok(!lstrcmpA(transforms, "banana"),
9259        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9260     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9261
9262     /* garbage szProduct */
9263     size = MAX_PATH;
9264     lstrcpyA(patch, "apple");
9265     lstrcpyA(transforms, "banana");
9266     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9267     ok(r == ERROR_INVALID_PARAMETER,
9268        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9269     ok(!lstrcmpA(patch, "apple"),
9270        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9271     ok(!lstrcmpA(transforms, "banana"),
9272        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9273     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9274
9275     /* guid without brackets */
9276     size = MAX_PATH;
9277     lstrcpyA(patch, "apple");
9278     lstrcpyA(transforms, "banana");
9279     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9280                         transforms, &size);
9281     ok(r == ERROR_INVALID_PARAMETER,
9282        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9283     ok(!lstrcmpA(patch, "apple"),
9284        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9285     ok(!lstrcmpA(transforms, "banana"),
9286        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9287     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9288
9289     /* guid with brackets */
9290     size = MAX_PATH;
9291     lstrcpyA(patch, "apple");
9292     lstrcpyA(transforms, "banana");
9293     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9294                         transforms, &size);
9295     ok(r == ERROR_UNKNOWN_PRODUCT,
9296        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9297     ok(!lstrcmpA(patch, "apple"),
9298        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9299     ok(!lstrcmpA(transforms, "banana"),
9300        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9301     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9302
9303     /* same length as guid, but random */
9304     size = MAX_PATH;
9305     lstrcpyA(patch, "apple");
9306     lstrcpyA(transforms, "banana");
9307     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9308                         transforms, &size);
9309     ok(r == ERROR_INVALID_PARAMETER,
9310        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9311     ok(!lstrcmpA(patch, "apple"),
9312        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9313     ok(!lstrcmpA(transforms, "banana"),
9314        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9315     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9316
9317     /* MSIINSTALLCONTEXT_USERMANAGED */
9318
9319     size = MAX_PATH;
9320     lstrcpyA(patch, "apple");
9321     lstrcpyA(transforms, "banana");
9322     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9323     ok(r == ERROR_UNKNOWN_PRODUCT,
9324        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9325     ok(!lstrcmpA(patch, "apple"),
9326        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9327     ok(!lstrcmpA(transforms, "banana"),
9328        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9329     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9330
9331     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9332     lstrcatA(keypath, usersid);
9333     lstrcatA(keypath, "\\Installer\\Products\\");
9334     lstrcatA(keypath, prod_squashed);
9335
9336     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9337     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9338
9339     /* managed product key exists */
9340     size = MAX_PATH;
9341     lstrcpyA(patch, "apple");
9342     lstrcpyA(transforms, "banana");
9343     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9344     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9345     ok(!lstrcmpA(patch, "apple"),
9346        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9347     ok(!lstrcmpA(transforms, "banana"),
9348        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9349     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9350
9351     res = RegCreateKeyA(prodkey, "Patches", &patches);
9352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9353
9354     /* patches key exists */
9355     size = MAX_PATH;
9356     lstrcpyA(patch, "apple");
9357     lstrcpyA(transforms, "banana");
9358     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9359     ok(r == ERROR_NO_MORE_ITEMS ||
9360        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9361        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9362     ok(!lstrcmpA(patch, "apple"),
9363        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9364     ok(!lstrcmpA(transforms, "banana"),
9365        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9366     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9367
9368     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9369                          (const BYTE *)patch_squashed,
9370                          lstrlenA(patch_squashed) + 1);
9371     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9372
9373     /* Patches value exists, is not REG_MULTI_SZ */
9374     size = MAX_PATH;
9375     lstrcpyA(patch, "apple");
9376     lstrcpyA(transforms, "banana");
9377     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9378     ok(r == ERROR_BAD_CONFIGURATION ||
9379        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9380        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9381     ok(!lstrcmpA(patch, "apple"),
9382        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9383     ok(!lstrcmpA(transforms, "banana"),
9384        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9385     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9386
9387     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9388                          (const BYTE *)"a\0b\0c\0\0", 7);
9389     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9390
9391     /* Patches value exists, is not a squashed guid */
9392     size = MAX_PATH;
9393     lstrcpyA(patch, "apple");
9394     lstrcpyA(transforms, "banana");
9395     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9396     ok(r == ERROR_BAD_CONFIGURATION,
9397        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9398     ok(!lstrcmpA(patch, "apple"),
9399        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9400     ok(!lstrcmpA(transforms, "banana"),
9401        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9402     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9403
9404     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9405     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9406                          (const BYTE *)patch_squashed,
9407                          lstrlenA(patch_squashed) + 2);
9408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9409
9410     /* Patches value exists */
9411     size = MAX_PATH;
9412     lstrcpyA(patch, "apple");
9413     lstrcpyA(transforms, "banana");
9414     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9415     ok(r == ERROR_NO_MORE_ITEMS ||
9416        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9417        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9418     ok(!lstrcmpA(patch, "apple") ||
9419        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9420        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9421     ok(!lstrcmpA(transforms, "banana"),
9422        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9423     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9424
9425     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9426                          (const BYTE *)"whatever", 9);
9427     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9428
9429     /* patch squashed value exists */
9430     size = MAX_PATH;
9431     lstrcpyA(patch, "apple");
9432     lstrcpyA(transforms, "banana");
9433     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9434     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9435     ok(!lstrcmpA(patch, patchcode),
9436        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9437     ok(!lstrcmpA(transforms, "whatever"),
9438        "Expected \"whatever\", got \"%s\"\n", transforms);
9439     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9440
9441     /* lpPatchBuf is NULL */
9442     size = MAX_PATH;
9443     lstrcpyA(transforms, "banana");
9444     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9445     ok(r == ERROR_INVALID_PARAMETER,
9446        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9447     ok(!lstrcmpA(transforms, "banana"),
9448        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9449     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9450
9451     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9452     size = MAX_PATH;
9453     lstrcpyA(patch, "apple");
9454     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
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(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9460
9461     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9462     lstrcpyA(patch, "apple");
9463     lstrcpyA(transforms, "banana");
9464     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9465     ok(r == ERROR_INVALID_PARAMETER,
9466        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9467     ok(!lstrcmpA(patch, "apple"),
9468        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9469     ok(!lstrcmpA(transforms, "banana"),
9470        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9471
9472     /* pcchTransformsBuf is too small */
9473     size = 6;
9474     lstrcpyA(patch, "apple");
9475     lstrcpyA(transforms, "banana");
9476     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9477     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9478     ok(!lstrcmpA(patch, patchcode),
9479        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9480     ok(!lstrcmpA(transforms, "whate") ||
9481        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
9482        "Expected \"whate\", got \"%s\"\n", transforms);
9483     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
9484
9485     /* increase the index */
9486     size = MAX_PATH;
9487     lstrcpyA(patch, "apple");
9488     lstrcpyA(transforms, "banana");
9489     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9490     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9491     ok(!lstrcmpA(patch, "apple"),
9492        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9493     ok(!lstrcmpA(transforms, "banana"),
9494        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9495     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9496
9497     /* increase again */
9498     size = MAX_PATH;
9499     lstrcpyA(patch, "apple");
9500     lstrcpyA(transforms, "banana");
9501     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9502     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9503     ok(!lstrcmpA(patch, "apple"),
9504        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9505     ok(!lstrcmpA(transforms, "banana"),
9506        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9507     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9508
9509     RegDeleteValueA(patches, "Patches");
9510     RegDeleteKeyA(patches, "");
9511     RegCloseKey(patches);
9512     RegDeleteKeyA(prodkey, "");
9513     RegCloseKey(prodkey);
9514
9515     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9516
9517     size = MAX_PATH;
9518     lstrcpyA(patch, "apple");
9519     lstrcpyA(transforms, "banana");
9520     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9521     ok(r == ERROR_UNKNOWN_PRODUCT,
9522        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9523     ok(!lstrcmpA(patch, "apple"),
9524        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9525     ok(!lstrcmpA(transforms, "banana"),
9526        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9527     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9528
9529     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9530     lstrcatA(keypath, prod_squashed);
9531
9532     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9534
9535     /* current user product key exists */
9536     size = MAX_PATH;
9537     lstrcpyA(patch, "apple");
9538     lstrcpyA(transforms, "banana");
9539     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9540     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9541     ok(!lstrcmpA(patch, "apple"),
9542        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9543     ok(!lstrcmpA(transforms, "banana"),
9544        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9545     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9546
9547     res = RegCreateKeyA(prodkey, "Patches", &patches);
9548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9549
9550     /* Patches key exists */
9551     size = MAX_PATH;
9552     lstrcpyA(patch, "apple");
9553     lstrcpyA(transforms, "banana");
9554     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9555     ok(r == ERROR_NO_MORE_ITEMS ||
9556        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9557        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9558     ok(!lstrcmpA(patch, "apple"),
9559        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9560     ok(!lstrcmpA(transforms, "banana"),
9561        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9562     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9563
9564     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9565                          (const BYTE *)patch_squashed,
9566                          lstrlenA(patch_squashed) + 1);
9567     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9568
9569     /* Patches value exists, is not REG_MULTI_SZ */
9570     size = MAX_PATH;
9571     lstrcpyA(patch, "apple");
9572     lstrcpyA(transforms, "banana");
9573     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9574     ok(r == ERROR_BAD_CONFIGURATION ||
9575        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9576        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9577     ok(!lstrcmpA(patch, "apple"),
9578        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9579     ok(!lstrcmpA(transforms, "banana"),
9580        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9581     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9582
9583     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9584                          (const BYTE *)"a\0b\0c\0\0", 7);
9585     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9586
9587     /* Patches value exists, is not a squashed guid */
9588     size = MAX_PATH;
9589     lstrcpyA(patch, "apple");
9590     lstrcpyA(transforms, "banana");
9591     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9592     ok(r == ERROR_BAD_CONFIGURATION,
9593        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9594     ok(!lstrcmpA(patch, "apple"),
9595        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9596     ok(!lstrcmpA(transforms, "banana"),
9597        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9598     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9599
9600     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9601     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9602                          (const BYTE *)patch_squashed,
9603                          lstrlenA(patch_squashed) + 2);
9604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9605
9606     /* Patches value exists */
9607     size = MAX_PATH;
9608     lstrcpyA(patch, "apple");
9609     lstrcpyA(transforms, "banana");
9610     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9611     ok(r == ERROR_NO_MORE_ITEMS ||
9612        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9613        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9614     ok(!lstrcmpA(patch, "apple") ||
9615        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9616        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9617     ok(!lstrcmpA(transforms, "banana"),
9618        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9619     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9620
9621     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9622                          (const BYTE *)"whatever", 9);
9623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9624
9625     /* patch code value exists */
9626     size = MAX_PATH;
9627     lstrcpyA(patch, "apple");
9628     lstrcpyA(transforms, "banana");
9629     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9630     ok(r == ERROR_NO_MORE_ITEMS ||
9631        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9632        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9633     ok(!lstrcmpA(patch, "apple") ||
9634        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9635        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9636     ok(!lstrcmpA(transforms, "banana") ||
9637        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
9638        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9639     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9640
9641     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9642     lstrcatA(keypath, usersid);
9643     lstrcatA(keypath, "\\Patches\\");
9644     lstrcatA(keypath, patch_squashed);
9645
9646     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
9647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9648
9649     /* userdata patch key exists */
9650     size = MAX_PATH;
9651     lstrcpyA(patch, "apple");
9652     lstrcpyA(transforms, "banana");
9653     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9654     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9655     ok(!lstrcmpA(patch, patchcode),
9656        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9657     ok(!lstrcmpA(transforms, "whatever"),
9658        "Expected \"whatever\", got \"%s\"\n", transforms);
9659     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9660
9661     RegDeleteKeyA(userkey, "");
9662     RegCloseKey(userkey);
9663     RegDeleteValueA(patches, patch_squashed);
9664     RegDeleteValueA(patches, "Patches");
9665     RegDeleteKeyA(patches, "");
9666     RegCloseKey(patches);
9667     RegDeleteKeyA(prodkey, "");
9668     RegCloseKey(prodkey);
9669
9670     /* MSIINSTALLCONTEXT_MACHINE */
9671
9672     size = MAX_PATH;
9673     lstrcpyA(patch, "apple");
9674     lstrcpyA(transforms, "banana");
9675     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9676     ok(r == ERROR_UNKNOWN_PRODUCT,
9677        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9678     ok(!lstrcmpA(patch, "apple"),
9679        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9680     ok(!lstrcmpA(transforms, "banana"),
9681        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9682     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9683
9684     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9685     lstrcatA(keypath, prod_squashed);
9686
9687     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9688     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9689
9690     /* local product key exists */
9691     size = MAX_PATH;
9692     lstrcpyA(patch, "apple");
9693     lstrcpyA(transforms, "banana");
9694     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9695     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9696     ok(!lstrcmpA(patch, "apple"),
9697        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9698     ok(!lstrcmpA(transforms, "banana"),
9699        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9700     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9701
9702     res = RegCreateKeyA(prodkey, "Patches", &patches);
9703     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9704
9705     /* Patches key exists */
9706     size = MAX_PATH;
9707     lstrcpyA(patch, "apple");
9708     lstrcpyA(transforms, "banana");
9709     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9710     ok(r == ERROR_NO_MORE_ITEMS ||
9711        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9712        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9713     ok(!lstrcmpA(patch, "apple"),
9714        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9715     ok(!lstrcmpA(transforms, "banana"),
9716        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9717     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9718
9719     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9720                          (const BYTE *)patch_squashed,
9721                          lstrlenA(patch_squashed) + 1);
9722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9723
9724     /* Patches value exists, is not REG_MULTI_SZ */
9725     size = MAX_PATH;
9726     lstrcpyA(patch, "apple");
9727     lstrcpyA(transforms, "banana");
9728     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9729     ok(r == ERROR_BAD_CONFIGURATION ||
9730        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9731        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9732     ok(!lstrcmpA(patch, "apple"),
9733        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9734     ok(!lstrcmpA(transforms, "banana"),
9735        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9736     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9737
9738     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9739                          (const BYTE *)"a\0b\0c\0\0", 7);
9740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9741
9742     /* Patches value exists, is not a squashed guid */
9743     size = MAX_PATH;
9744     lstrcpyA(patch, "apple");
9745     lstrcpyA(transforms, "banana");
9746     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9747     ok(r == ERROR_BAD_CONFIGURATION,
9748        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9749     ok(!lstrcmpA(patch, "apple"),
9750        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9751     ok(!lstrcmpA(transforms, "banana"),
9752        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9753     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9754
9755     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9756     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9757                          (const BYTE *)patch_squashed,
9758                          lstrlenA(patch_squashed) + 2);
9759     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9760
9761     /* Patches value exists */
9762     size = MAX_PATH;
9763     lstrcpyA(patch, "apple");
9764     lstrcpyA(transforms, "banana");
9765     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9766     ok(r == ERROR_NO_MORE_ITEMS ||
9767        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9768        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9769     ok(!lstrcmpA(patch, "apple") ||
9770        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9771        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9772     ok(!lstrcmpA(transforms, "banana"),
9773        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9774     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9775
9776     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9777                          (const BYTE *)"whatever", 9);
9778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9779
9780     /* patch code value exists */
9781     size = MAX_PATH;
9782     lstrcpyA(patch, "apple");
9783     lstrcpyA(transforms, "banana");
9784     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9786     ok(!lstrcmpA(patch, patchcode),
9787        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9788     ok(!lstrcmpA(transforms, "whatever"),
9789        "Expected \"whatever\", got \"%s\"\n", transforms);
9790     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9791
9792     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9793     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9794     lstrcatA(keypath, prod_squashed);
9795
9796     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9798
9799     /* local UserData product key exists */
9800     size = MAX_PATH;
9801     lstrcpyA(patch, "apple");
9802     lstrcpyA(transforms, "banana");
9803     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9805     ok(!lstrcmpA(patch, patchcode),
9806        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9807     ok(!lstrcmpA(transforms, "whatever"),
9808        "Expected \"whatever\", got \"%s\"\n", transforms);
9809     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9810
9811     res = RegCreateKeyA(udprod, "Patches", &udpatch);
9812     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9813
9814     /* local UserData Patches key exists */
9815     size = MAX_PATH;
9816     lstrcpyA(patch, "apple");
9817     lstrcpyA(transforms, "banana");
9818     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9819     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9820     ok(!lstrcmpA(patch, patchcode),
9821        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9822     ok(!lstrcmpA(transforms, "whatever"),
9823        "Expected \"whatever\", got \"%s\"\n", transforms);
9824     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9825
9826     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
9827     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9828
9829     /* local UserData Product patch key exists */
9830     size = MAX_PATH;
9831     lstrcpyA(patch, "apple");
9832     lstrcpyA(transforms, "banana");
9833     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9834     ok(r == ERROR_NO_MORE_ITEMS ||
9835        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9836        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9837     ok(!lstrcmpA(patch, "apple") ||
9838        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9839        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9840     ok(!lstrcmpA(transforms, "banana") ||
9841        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
9842        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9843     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9844
9845     data = MSIPATCHSTATE_APPLIED;
9846     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9847                          (const BYTE *)&data, sizeof(DWORD));
9848     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9849
9850     /* State value exists */
9851     size = MAX_PATH;
9852     lstrcpyA(patch, "apple");
9853     lstrcpyA(transforms, "banana");
9854     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9855     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
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     /* now duplicate some of the tests for the W version */
9863
9864     /* pcchTransformsBuf is too small */
9865     size = 6;
9866     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
9867     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9868     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9869     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9870     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9871     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9872     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
9873     ok(!lstrcmpA(patch, patchcode),
9874        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9875     ok(!lstrcmpA(transforms, "whate") ||
9876        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
9877        "Expected \"whate\", got \"%s\"\n", transforms);
9878     ok(size == 8, "Expected 8, got %d\n", size);
9879
9880     /* patch code value exists */
9881     size = MAX_PATH;
9882     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
9883     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
9884     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
9885     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9886     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
9887     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
9888     ok(!lstrcmpA(patch, patchcode),
9889        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9890     ok(!lstrcmpA(transforms, "whatever"),
9891        "Expected \"whatever\", got \"%s\"\n", transforms);
9892     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9893
9894     RegDeleteValueA(patches, patch_squashed);
9895     RegDeleteValueA(patches, "Patches");
9896     RegDeleteKeyA(patches, "");
9897     RegCloseKey(patches);
9898     RegDeleteValueA(hpatch, "State");
9899     RegDeleteKeyA(hpatch, "");
9900     RegCloseKey(hpatch);
9901     RegDeleteKeyA(udpatch, "");
9902     RegCloseKey(udpatch);
9903     RegDeleteKeyA(udprod, "");
9904     RegCloseKey(udprod);
9905     RegDeleteKeyA(prodkey, "");
9906     RegCloseKey(prodkey);
9907     LocalFree(usersid);
9908 }
9909
9910 static void test_MsiGetPatchInfoEx(void)
9911 {
9912     CHAR keypath[MAX_PATH], val[MAX_PATH];
9913     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9914     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9915     HKEY prodkey, patches, udprod, props;
9916     HKEY hpatch, udpatch, prodpatches;
9917     LPSTR usersid;
9918     DWORD size;
9919     LONG res;
9920     UINT r;
9921
9922     if (!pMsiGetPatchInfoExA)
9923     {
9924         win_skip("MsiGetPatchInfoEx not implemented\n");
9925         return;
9926     }
9927
9928     create_test_guid(prodcode, prod_squashed);
9929     create_test_guid(patchcode, patch_squashed);
9930     get_user_sid(&usersid);
9931
9932     /* NULL szPatchCode */
9933     lstrcpyA(val, "apple");
9934     size = MAX_PATH;
9935     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9936                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9937     ok(r == ERROR_INVALID_PARAMETER,
9938        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9939     ok(!lstrcmpA(val, "apple"),
9940        "Expected val to be unchanged, got \"%s\"\n", val);
9941     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9942
9943     /* empty szPatchCode */
9944     size = MAX_PATH;
9945     lstrcpyA(val, "apple");
9946     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9947                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9948     ok(r == ERROR_INVALID_PARAMETER,
9949        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9950     ok(!lstrcmpA(val, "apple"),
9951        "Expected val to be unchanged, got \"%s\"\n", val);
9952     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9953
9954     /* garbage szPatchCode */
9955     size = MAX_PATH;
9956     lstrcpyA(val, "apple");
9957     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
9958                             MSIINSTALLCONTEXT_USERMANAGED,
9959                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9960     ok(r == ERROR_INVALID_PARAMETER,
9961        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9962     ok(!lstrcmpA(val, "apple"),
9963        "Expected val to be unchanged, got \"%s\"\n", val);
9964     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9965
9966     /* guid without brackets */
9967     size = MAX_PATH;
9968     lstrcpyA(val, "apple");
9969     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
9970                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9971                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9972     ok(r == ERROR_INVALID_PARAMETER,
9973        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9974     ok(!lstrcmpA(val, "apple"),
9975        "Expected val to be unchanged, got \"%s\"\n", val);
9976     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9977
9978     /* guid with brackets */
9979     size = MAX_PATH;
9980     lstrcpyA(val, "apple");
9981     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
9982                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9983                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9984     ok(r == ERROR_UNKNOWN_PRODUCT,
9985        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9986     ok(!lstrcmpA(val, "apple"),
9987        "Expected val to be unchanged, got \"%s\"\n", val);
9988     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9989
9990     /* same length as guid, but random */
9991     size = MAX_PATH;
9992     lstrcpyA(val, "apple");
9993     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
9994                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9995                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9996     ok(r == ERROR_INVALID_PARAMETER,
9997        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9998     ok(!lstrcmpA(val, "apple"),
9999        "Expected val to be unchanged, got \"%s\"\n", val);
10000     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10001
10002     /* NULL szProductCode */
10003     lstrcpyA(val, "apple");
10004     size = MAX_PATH;
10005     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10006                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10007     ok(r == ERROR_INVALID_PARAMETER,
10008        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10009     ok(!lstrcmpA(val, "apple"),
10010        "Expected val to be unchanged, got \"%s\"\n", val);
10011     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10012
10013     /* empty szProductCode */
10014     size = MAX_PATH;
10015     lstrcpyA(val, "apple");
10016     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10017                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10018     ok(r == ERROR_INVALID_PARAMETER,
10019        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10020     ok(!lstrcmpA(val, "apple"),
10021        "Expected val to be unchanged, got \"%s\"\n", val);
10022     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10023
10024     /* garbage szProductCode */
10025     size = MAX_PATH;
10026     lstrcpyA(val, "apple");
10027     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
10028                             MSIINSTALLCONTEXT_USERMANAGED,
10029                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10030     ok(r == ERROR_INVALID_PARAMETER,
10031        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10032     ok(!lstrcmpA(val, "apple"),
10033        "Expected val to be unchanged, got \"%s\"\n", val);
10034     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10035
10036     /* guid without brackets */
10037     size = MAX_PATH;
10038     lstrcpyA(val, "apple");
10039     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10040                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10041                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10042     ok(r == ERROR_INVALID_PARAMETER,
10043        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10044     ok(!lstrcmpA(val, "apple"),
10045        "Expected val to be unchanged, got \"%s\"\n", val);
10046     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10047
10048     /* guid with brackets */
10049     size = MAX_PATH;
10050     lstrcpyA(val, "apple");
10051     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10052                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10053                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10054     ok(r == ERROR_UNKNOWN_PRODUCT,
10055        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10056     ok(!lstrcmpA(val, "apple"),
10057        "Expected val to be unchanged, got \"%s\"\n", val);
10058     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10059
10060     /* same length as guid, but random */
10061     size = MAX_PATH;
10062     lstrcpyA(val, "apple");
10063     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10064                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10065                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10066     ok(r == ERROR_INVALID_PARAMETER,
10067        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10068     ok(!lstrcmpA(val, "apple"),
10069        "Expected val to be unchanged, got \"%s\"\n", val);
10070     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10071
10072     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10073     size = MAX_PATH;
10074     lstrcpyA(val, "apple");
10075     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10076                             MSIINSTALLCONTEXT_USERMANAGED,
10077                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10078     ok(r == ERROR_INVALID_PARAMETER,
10079        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10080     ok(!lstrcmpA(val, "apple"),
10081        "Expected val to be unchanged, got \"%s\"\n", val);
10082     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10083
10084     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10085     size = MAX_PATH;
10086     lstrcpyA(val, "apple");
10087     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10088                             MSIINSTALLCONTEXT_USERUNMANAGED,
10089                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10090     ok(r == ERROR_INVALID_PARAMETER,
10091        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10092     ok(!lstrcmpA(val, "apple"),
10093        "Expected val to be unchanged, got \"%s\"\n", val);
10094     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10095
10096     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10097     size = MAX_PATH;
10098     lstrcpyA(val, "apple");
10099     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10100                             MSIINSTALLCONTEXT_MACHINE,
10101                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10102     ok(r == ERROR_INVALID_PARAMETER,
10103        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10104     ok(!lstrcmpA(val, "apple"),
10105        "Expected val to be unchanged, got \"%s\"\n", val);
10106     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10107
10108     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10109     size = MAX_PATH;
10110     lstrcpyA(val, "apple");
10111     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10112                             MSIINSTALLCONTEXT_MACHINE,
10113                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10114     ok(r == ERROR_INVALID_PARAMETER,
10115        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10116     ok(!lstrcmpA(val, "apple"),
10117        "Expected val to be unchanged, got \"%s\"\n", val);
10118     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10119
10120     /* dwContext is out of range */
10121     size = MAX_PATH;
10122     lstrcpyA(val, "apple");
10123     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10124                             MSIINSTALLCONTEXT_NONE,
10125                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10126     ok(r == ERROR_INVALID_PARAMETER,
10127        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10128     ok(!lstrcmpA(val, "apple"),
10129        "Expected val to be unchanged, got \"%s\"\n", val);
10130     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10131
10132     /* dwContext is out of range */
10133     size = MAX_PATH;
10134     lstrcpyA(val, "apple");
10135     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10136                             MSIINSTALLCONTEXT_ALL,
10137                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10138     ok(r == ERROR_INVALID_PARAMETER,
10139        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10140     ok(!lstrcmpA(val, "apple"),
10141        "Expected val to be unchanged, got \"%s\"\n", val);
10142     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10143
10144     /* dwContext is invalid */
10145     size = MAX_PATH;
10146     lstrcpyA(val, "apple");
10147     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10148                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10149     ok(r == ERROR_INVALID_PARAMETER,
10150        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10151     ok(!lstrcmpA(val, "apple"),
10152        "Expected val to be unchanged, got \"%s\"\n", val);
10153     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10154
10155     /* MSIINSTALLCONTEXT_USERMANAGED */
10156
10157     size = MAX_PATH;
10158     lstrcpyA(val, "apple");
10159     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10160                             MSIINSTALLCONTEXT_USERMANAGED,
10161                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10162     ok(r == ERROR_UNKNOWN_PRODUCT,
10163        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10164     ok(!lstrcmpA(val, "apple"),
10165        "Expected val to be unchanged, got \"%s\"\n", val);
10166     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10167
10168     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10169     lstrcatA(keypath, usersid);
10170     lstrcatA(keypath, "\\Products\\");
10171     lstrcatA(keypath, prod_squashed);
10172
10173     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10174     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10175
10176     /* local UserData product key exists */
10177     size = MAX_PATH;
10178     lstrcpyA(val, "apple");
10179     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10180                             MSIINSTALLCONTEXT_USERMANAGED,
10181                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10182     ok(r == ERROR_UNKNOWN_PRODUCT,
10183        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10184     ok(!lstrcmpA(val, "apple"),
10185        "Expected val to be unchanged, got \"%s\"\n", val);
10186     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10187
10188     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10190
10191     /* InstallProperties key exists */
10192     size = MAX_PATH;
10193     lstrcpyA(val, "apple");
10194     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10195                             MSIINSTALLCONTEXT_USERMANAGED,
10196                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10197     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10198     ok(!lstrcmpA(val, "apple"),
10199        "Expected val to be unchanged, got \"%s\"\n", val);
10200     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10201
10202     res = RegCreateKeyA(udprod, "Patches", &patches);
10203     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10204
10205     /* Patches key exists */
10206     size = MAX_PATH;
10207     lstrcpyA(val, "apple");
10208     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10209                             MSIINSTALLCONTEXT_USERMANAGED,
10210                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10211     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10212     ok(!lstrcmpA(val, "apple"),
10213        "Expected val to be unchanged, got \"%s\"\n", val);
10214     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10215
10216     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10218
10219     /* Patches key exists */
10220     size = MAX_PATH;
10221     lstrcpyA(val, "apple");
10222     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10223                             MSIINSTALLCONTEXT_USERMANAGED,
10224                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10225     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10226     ok(!lstrcmpA(val, "apple"),
10227        "Expected val to be unchanged, got \"%s\"\n", val);
10228     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10229
10230     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10231     lstrcatA(keypath, usersid);
10232     lstrcatA(keypath, "\\Installer\\Products\\");
10233     lstrcatA(keypath, prod_squashed);
10234
10235     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10236     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10237
10238     /* managed product key exists */
10239     size = MAX_PATH;
10240     lstrcpyA(val, "apple");
10241     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10242                             MSIINSTALLCONTEXT_USERMANAGED,
10243                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10244     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10245     ok(!lstrcmpA(val, "apple"),
10246        "Expected val to be unchanged, got \"%s\"\n", val);
10247     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10248
10249     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10251
10252     /* Patches key exists */
10253     size = MAX_PATH;
10254     lstrcpyA(val, "apple");
10255     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10256                             MSIINSTALLCONTEXT_USERMANAGED,
10257                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10258     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10259     ok(!lstrcmpA(val, "apple"),
10260        "Expected val to be unchanged, got \"%s\"\n", val);
10261     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10262
10263     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10264                          (const BYTE *)"transforms", 11);
10265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10266
10267     /* specific patch value exists */
10268     size = MAX_PATH;
10269     lstrcpyA(val, "apple");
10270     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10271                             MSIINSTALLCONTEXT_USERMANAGED,
10272                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10273     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10274     ok(!lstrcmpA(val, "apple"),
10275        "Expected val to be unchanged, got \"%s\"\n", val);
10276     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10277
10278     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10279     lstrcatA(keypath, usersid);
10280     lstrcatA(keypath, "\\Patches\\");
10281     lstrcatA(keypath, patch_squashed);
10282
10283     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10285
10286     /* UserData Patches key exists */
10287     size = MAX_PATH;
10288     lstrcpyA(val, "apple");
10289     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10290                             MSIINSTALLCONTEXT_USERMANAGED,
10291                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10292     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10293     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10294     ok(size == 0, "Expected 0, got %d\n", size);
10295
10296     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10297                          (const BYTE *)"pack", 5);
10298     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10299
10300     /* ManagedLocalPatch value exists */
10301     size = MAX_PATH;
10302     lstrcpyA(val, "apple");
10303     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10304                             MSIINSTALLCONTEXT_USERMANAGED,
10305                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10306     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10307     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10308     ok(size == 4, "Expected 4, got %d\n", size);
10309
10310     size = MAX_PATH;
10311     lstrcpyA(val, "apple");
10312     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10313                             MSIINSTALLCONTEXT_USERMANAGED,
10314                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10315     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10316     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10317     ok(size == 10, "Expected 10, got %d\n", size);
10318
10319     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10320                          (const BYTE *)"mydate", 7);
10321     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10322
10323     /* Installed value exists */
10324     size = MAX_PATH;
10325     lstrcpyA(val, "apple");
10326     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10327                             MSIINSTALLCONTEXT_USERMANAGED,
10328                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10329     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10330     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10331     ok(size == 6, "Expected 6, got %d\n", size);
10332
10333     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10334                          (const BYTE *)"yes", 4);
10335     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10336
10337     /* Uninstallable value exists */
10338     size = MAX_PATH;
10339     lstrcpyA(val, "apple");
10340     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10341                             MSIINSTALLCONTEXT_USERMANAGED,
10342                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10343     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10344     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10345     ok(size == 3, "Expected 3, got %d\n", size);
10346
10347     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10348                          (const BYTE *)"good", 5);
10349     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10350
10351     /* State value exists */
10352     size = MAX_PATH;
10353     lstrcpyA(val, "apple");
10354     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10355                             MSIINSTALLCONTEXT_USERMANAGED,
10356                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10357     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10358     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10359     ok(size == 4, "Expected 4, got %d\n", size);
10360
10361     size = 1;
10362     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10363                          (const BYTE *)&size, sizeof(DWORD));
10364     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10365
10366     /* State value exists */
10367     size = MAX_PATH;
10368     lstrcpyA(val, "apple");
10369     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10370                             MSIINSTALLCONTEXT_USERMANAGED,
10371                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10372     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10373     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10374     ok(size == 1, "Expected 1, got %d\n", size);
10375
10376     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10377                          (const BYTE *)"display", 8);
10378     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10379
10380     /* DisplayName value exists */
10381     size = MAX_PATH;
10382     lstrcpyA(val, "apple");
10383     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10384                             MSIINSTALLCONTEXT_USERMANAGED,
10385                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10386     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10387     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10388     ok(size == 7, "Expected 7, got %d\n", size);
10389
10390     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10391                          (const BYTE *)"moreinfo", 9);
10392     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10393
10394     /* MoreInfoURL value exists */
10395     size = MAX_PATH;
10396     lstrcpyA(val, "apple");
10397     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10398                             MSIINSTALLCONTEXT_USERMANAGED,
10399                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10401     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10402     ok(size == 8, "Expected 8, got %d\n", size);
10403
10404     /* szProperty is invalid */
10405     size = MAX_PATH;
10406     lstrcpyA(val, "apple");
10407     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10408                             MSIINSTALLCONTEXT_USERMANAGED,
10409                             "IDontExist", val, &size);
10410     ok(r == ERROR_UNKNOWN_PROPERTY,
10411        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10412     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10413     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10414
10415     /* lpValue is NULL, while pcchValue is non-NULL */
10416     size = MAX_PATH;
10417     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10418                             MSIINSTALLCONTEXT_USERMANAGED,
10419                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10420     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10421     ok(size == 16, "Expected 16, got %d\n", size);
10422
10423     /* pcchValue is NULL, while lpValue is non-NULL */
10424     lstrcpyA(val, "apple");
10425     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10426                             MSIINSTALLCONTEXT_USERMANAGED,
10427                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10428     ok(r == ERROR_INVALID_PARAMETER,
10429        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10430     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10431
10432     /* both lpValue and pcchValue are NULL */
10433     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10434                             MSIINSTALLCONTEXT_USERMANAGED,
10435                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10436     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10437
10438     /* pcchValue doesn't have enough room for NULL terminator */
10439     size = 8;
10440     lstrcpyA(val, "apple");
10441     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10442                             MSIINSTALLCONTEXT_USERMANAGED,
10443                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10444     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10445     ok(!lstrcmpA(val, "moreinf"),
10446        "Expected \"moreinf\", got \"%s\"\n", val);
10447     ok(size == 16, "Expected 16, got %d\n", size);
10448
10449     /* pcchValue has exactly enough room for NULL terminator */
10450     size = 9;
10451     lstrcpyA(val, "apple");
10452     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10453                             MSIINSTALLCONTEXT_USERMANAGED,
10454                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10455     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10456     ok(!lstrcmpA(val, "moreinfo"),
10457        "Expected \"moreinfo\", got \"%s\"\n", val);
10458     ok(size == 8, "Expected 8, got %d\n", size);
10459
10460     /* pcchValue is too small, lpValue is NULL */
10461     size = 0;
10462     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10463                             MSIINSTALLCONTEXT_USERMANAGED,
10464                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10465     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10466     ok(size == 16, "Expected 16, got %d\n", size);
10467
10468     RegDeleteValueA(prodpatches, patch_squashed);
10469     RegDeleteKeyA(prodpatches, "");
10470     RegCloseKey(prodpatches);
10471     RegDeleteKeyA(prodkey, "");
10472     RegCloseKey(prodkey);
10473
10474     /* UserData is sufficient for all properties
10475      * except INSTALLPROPERTY_TRANSFORMS
10476      */
10477     size = MAX_PATH;
10478     lstrcpyA(val, "apple");
10479     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10480                             MSIINSTALLCONTEXT_USERMANAGED,
10481                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10483     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10484     ok(size == 4, "Expected 4, got %d\n", size);
10485
10486     /* UserData is sufficient for all properties
10487      * except INSTALLPROPERTY_TRANSFORMS
10488      */
10489     size = MAX_PATH;
10490     lstrcpyA(val, "apple");
10491     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10492                             MSIINSTALLCONTEXT_USERMANAGED,
10493                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10494     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10495     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10496     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10497
10498     RegDeleteValueA(hpatch, "MoreInfoURL");
10499     RegDeleteValueA(hpatch, "Display");
10500     RegDeleteValueA(hpatch, "State");
10501     RegDeleteValueA(hpatch, "Uninstallable");
10502     RegDeleteValueA(hpatch, "Installed");
10503     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10504     RegDeleteKeyA(udpatch, "");
10505     RegCloseKey(udpatch);
10506     RegDeleteKeyA(hpatch, "");
10507     RegCloseKey(hpatch);
10508     RegDeleteKeyA(patches, "");
10509     RegCloseKey(patches);
10510     RegDeleteKeyA(props, "");
10511     RegCloseKey(props);
10512     RegDeleteKeyA(udprod, "");
10513     RegCloseKey(udprod);
10514
10515     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10516
10517     size = MAX_PATH;
10518     lstrcpyA(val, "apple");
10519     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10520                             MSIINSTALLCONTEXT_USERUNMANAGED,
10521                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10522     ok(r == ERROR_UNKNOWN_PRODUCT,
10523        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10524     ok(!lstrcmpA(val, "apple"),
10525        "Expected val to be unchanged, got \"%s\"\n", val);
10526     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10527
10528     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10529     lstrcatA(keypath, usersid);
10530     lstrcatA(keypath, "\\Products\\");
10531     lstrcatA(keypath, prod_squashed);
10532
10533     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10534     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10535
10536     /* local UserData product key exists */
10537     size = MAX_PATH;
10538     lstrcpyA(val, "apple");
10539     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10540                             MSIINSTALLCONTEXT_USERUNMANAGED,
10541                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10542     ok(r == ERROR_UNKNOWN_PRODUCT,
10543        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10544     ok(!lstrcmpA(val, "apple"),
10545        "Expected val to be unchanged, got \"%s\"\n", val);
10546     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10547
10548     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10549     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10550
10551     /* InstallProperties key exists */
10552     size = MAX_PATH;
10553     lstrcpyA(val, "apple");
10554     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10555                             MSIINSTALLCONTEXT_USERUNMANAGED,
10556                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10557     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10558     ok(!lstrcmpA(val, "apple"),
10559        "Expected val to be unchanged, got \"%s\"\n", val);
10560     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10561
10562     res = RegCreateKeyA(udprod, "Patches", &patches);
10563     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10564
10565     /* Patches key exists */
10566     size = MAX_PATH;
10567     lstrcpyA(val, "apple");
10568     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10569                             MSIINSTALLCONTEXT_USERUNMANAGED,
10570                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10571     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10572     ok(!lstrcmpA(val, "apple"),
10573        "Expected val to be unchanged, got \"%s\"\n", val);
10574     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10575
10576     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10577     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10578
10579     /* Patches key exists */
10580     size = MAX_PATH;
10581     lstrcpyA(val, "apple");
10582     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10583                             MSIINSTALLCONTEXT_USERUNMANAGED,
10584                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10585     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10586     ok(!lstrcmpA(val, "apple"),
10587        "Expected val to be unchanged, got \"%s\"\n", val);
10588     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10589
10590     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10591     lstrcatA(keypath, prod_squashed);
10592
10593     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10594     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10595
10596     /* current user product key exists */
10597     size = MAX_PATH;
10598     lstrcpyA(val, "apple");
10599     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10600                             MSIINSTALLCONTEXT_USERUNMANAGED,
10601                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10602     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10603     ok(!lstrcmpA(val, "apple"),
10604        "Expected val to be unchanged, got \"%s\"\n", val);
10605     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10606
10607     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10608     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10609
10610     /* Patches key exists */
10611     size = MAX_PATH;
10612     lstrcpyA(val, "apple");
10613     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10614                             MSIINSTALLCONTEXT_USERUNMANAGED,
10615                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10616     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10617     ok(!lstrcmpA(val, "apple"),
10618        "Expected val to be unchanged, got \"%s\"\n", val);
10619     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10620
10621     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10622                          (const BYTE *)"transforms", 11);
10623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10624
10625     /* specific patch value exists */
10626     size = MAX_PATH;
10627     lstrcpyA(val, "apple");
10628     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10629                             MSIINSTALLCONTEXT_USERUNMANAGED,
10630                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10631     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10632     ok(!lstrcmpA(val, "apple"),
10633        "Expected val to be unchanged, got \"%s\"\n", val);
10634     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10635
10636     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10637     lstrcatA(keypath, usersid);
10638     lstrcatA(keypath, "\\Patches\\");
10639     lstrcatA(keypath, patch_squashed);
10640
10641     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10643
10644     /* UserData Patches key exists */
10645     size = MAX_PATH;
10646     lstrcpyA(val, "apple");
10647     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10648                             MSIINSTALLCONTEXT_USERUNMANAGED,
10649                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10650     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10651     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10652     ok(size == 0, "Expected 0, got %d\n", size);
10653
10654     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10655                          (const BYTE *)"pack", 5);
10656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10657
10658     /* LocalPatch value exists */
10659     size = MAX_PATH;
10660     lstrcpyA(val, "apple");
10661     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10662                             MSIINSTALLCONTEXT_USERUNMANAGED,
10663                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10665     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10666     ok(size == 4, "Expected 4, got %d\n", size);
10667
10668     size = MAX_PATH;
10669     lstrcpyA(val, "apple");
10670     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10671                             MSIINSTALLCONTEXT_USERUNMANAGED,
10672                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10673     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10674     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10675     ok(size == 10, "Expected 10, got %d\n", size);
10676
10677     RegDeleteValueA(prodpatches, patch_squashed);
10678     RegDeleteKeyA(prodpatches, "");
10679     RegCloseKey(prodpatches);
10680     RegDeleteKeyA(prodkey, "");
10681     RegCloseKey(prodkey);
10682
10683     /* UserData is sufficient for all properties
10684      * except INSTALLPROPERTY_TRANSFORMS
10685      */
10686     size = MAX_PATH;
10687     lstrcpyA(val, "apple");
10688     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10689                             MSIINSTALLCONTEXT_USERUNMANAGED,
10690                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10691     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10692     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10693     ok(size == 4, "Expected 4, got %d\n", size);
10694
10695     /* UserData is sufficient for all properties
10696      * except INSTALLPROPERTY_TRANSFORMS
10697      */
10698     size = MAX_PATH;
10699     lstrcpyA(val, "apple");
10700     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10701                             MSIINSTALLCONTEXT_USERUNMANAGED,
10702                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10703     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10704     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10705     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10706
10707     RegDeleteValueA(udpatch, "LocalPackage");
10708     RegDeleteKeyA(udpatch, "");
10709     RegCloseKey(udpatch);
10710     RegDeleteKeyA(hpatch, "");
10711     RegCloseKey(hpatch);
10712     RegDeleteKeyA(patches, "");
10713     RegCloseKey(patches);
10714     RegDeleteKeyA(props, "");
10715     RegCloseKey(props);
10716     RegDeleteKeyA(udprod, "");
10717     RegCloseKey(udprod);
10718
10719     /* MSIINSTALLCONTEXT_MACHINE */
10720
10721     size = MAX_PATH;
10722     lstrcpyA(val, "apple");
10723     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10724                             MSIINSTALLCONTEXT_MACHINE,
10725                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10726     ok(r == ERROR_UNKNOWN_PRODUCT,
10727        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10728     ok(!lstrcmpA(val, "apple"),
10729        "Expected val to be unchanged, got \"%s\"\n", val);
10730     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10731
10732     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10733     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10734     lstrcatA(keypath, prod_squashed);
10735
10736     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10737     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10738
10739     /* local UserData product key exists */
10740     size = MAX_PATH;
10741     lstrcpyA(val, "apple");
10742     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10743                             MSIINSTALLCONTEXT_MACHINE,
10744                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10745     ok(r == ERROR_UNKNOWN_PRODUCT,
10746        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10747     ok(!lstrcmpA(val, "apple"),
10748        "Expected val to be unchanged, got \"%s\"\n", val);
10749     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10750
10751     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10752     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10753
10754     /* InstallProperties key exists */
10755     size = MAX_PATH;
10756     lstrcpyA(val, "apple");
10757     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10758                             MSIINSTALLCONTEXT_MACHINE,
10759                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10760     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10761     ok(!lstrcmpA(val, "apple"),
10762        "Expected val to be unchanged, got \"%s\"\n", val);
10763     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10764
10765     res = RegCreateKeyA(udprod, "Patches", &patches);
10766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10767
10768     /* Patches key exists */
10769     size = MAX_PATH;
10770     lstrcpyA(val, "apple");
10771     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10772                             MSIINSTALLCONTEXT_MACHINE,
10773                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10774     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10775     ok(!lstrcmpA(val, "apple"),
10776        "Expected val to be unchanged, got \"%s\"\n", val);
10777     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10778
10779     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10780     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10781
10782     /* Patches key exists */
10783     size = MAX_PATH;
10784     lstrcpyA(val, "apple");
10785     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10786                             MSIINSTALLCONTEXT_MACHINE,
10787                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10788     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10789     ok(!lstrcmpA(val, "apple"),
10790        "Expected val to be unchanged, got \"%s\"\n", val);
10791     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10792
10793     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10794     lstrcatA(keypath, prod_squashed);
10795
10796     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10797     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10798
10799     /* local product key exists */
10800     size = MAX_PATH;
10801     lstrcpyA(val, "apple");
10802     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10803                             MSIINSTALLCONTEXT_MACHINE,
10804                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10805     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10806     ok(!lstrcmpA(val, "apple"),
10807        "Expected val to be unchanged, got \"%s\"\n", val);
10808     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10809
10810     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10811     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10812
10813     /* Patches key exists */
10814     size = MAX_PATH;
10815     lstrcpyA(val, "apple");
10816     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10817                             MSIINSTALLCONTEXT_MACHINE,
10818                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10819     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10820     ok(!lstrcmpA(val, "apple"),
10821        "Expected val to be unchanged, got \"%s\"\n", val);
10822     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10823
10824     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10825                          (const BYTE *)"transforms", 11);
10826     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10827
10828     /* specific patch 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_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10835     ok(!lstrcmpA(val, "apple"),
10836        "Expected val to be unchanged, got \"%s\"\n", val);
10837     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10838
10839     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10840     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
10841     lstrcatA(keypath, patch_squashed);
10842
10843     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10845
10846     /* UserData Patches key exists */
10847     size = MAX_PATH;
10848     lstrcpyA(val, "apple");
10849     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10850                             MSIINSTALLCONTEXT_MACHINE,
10851                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10852     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10853     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10854     ok(size == 0, "Expected 0, got %d\n", size);
10855
10856     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10857                          (const BYTE *)"pack", 5);
10858     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10859
10860     /* LocalPatch value exists */
10861     size = MAX_PATH;
10862     lstrcpyA(val, "apple");
10863     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10864                             MSIINSTALLCONTEXT_MACHINE,
10865                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10866     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10867     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10868     ok(size == 4, "Expected 4, got %d\n", size);
10869
10870     size = MAX_PATH;
10871     lstrcpyA(val, "apple");
10872     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10873                             MSIINSTALLCONTEXT_MACHINE,
10874                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10875     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10876     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10877     ok(size == 10, "Expected 10, got %d\n", size);
10878
10879     RegDeleteValueA(prodpatches, patch_squashed);
10880     RegDeleteKeyA(prodpatches, "");
10881     RegCloseKey(prodpatches);
10882     RegDeleteKeyA(prodkey, "");
10883     RegCloseKey(prodkey);
10884
10885     /* UserData is sufficient for all properties
10886      * except INSTALLPROPERTY_TRANSFORMS
10887      */
10888     size = MAX_PATH;
10889     lstrcpyA(val, "apple");
10890     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10891                             MSIINSTALLCONTEXT_MACHINE,
10892                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10893     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10894     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10895     ok(size == 4, "Expected 4, got %d\n", size);
10896
10897     /* UserData is sufficient for all properties
10898      * except INSTALLPROPERTY_TRANSFORMS
10899      */
10900     size = MAX_PATH;
10901     lstrcpyA(val, "apple");
10902     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10903                             MSIINSTALLCONTEXT_MACHINE,
10904                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10905     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10906     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10907     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10908
10909     RegDeleteValueA(udpatch, "LocalPackage");
10910     RegDeleteKeyA(udpatch, "");
10911     RegCloseKey(udpatch);
10912     RegDeleteKeyA(hpatch, "");
10913     RegCloseKey(hpatch);
10914     RegDeleteKeyA(patches, "");
10915     RegCloseKey(patches);
10916     RegDeleteKeyA(props, "");
10917     RegCloseKey(props);
10918     RegDeleteKeyA(udprod, "");
10919     RegCloseKey(udprod);
10920     LocalFree(usersid);
10921 }
10922
10923 static void test_MsiGetPatchInfo(void)
10924 {
10925     UINT r;
10926     char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
10927     char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
10928     WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
10929     HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
10930     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
10931     DWORD size;
10932     LONG res;
10933
10934     create_test_guid(patch_code, patch_squashed);
10935     create_test_guid(prod_code, prod_squashed);
10936     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
10937
10938     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
10939     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
10940
10941     r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
10942     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
10943
10944     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
10945     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
10946
10947     size = 0;
10948     r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
10949     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
10950
10951     r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
10952     ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
10953
10954     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10955     lstrcatA(keypath, prod_squashed);
10956
10957     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_product);
10958     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
10959
10960     /* product key exists */
10961     size = MAX_PATH;
10962     lstrcpyA(val, "apple");
10963     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
10964     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
10965     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
10966     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
10967
10968     res = RegCreateKeyA(hkey_product, "Patches", &hkey_patches);
10969     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
10970
10971     /* patches key exists */
10972     size = MAX_PATH;
10973     lstrcpyA(val, "apple");
10974     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
10975     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
10976     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
10977     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
10978
10979     res = RegCreateKeyA(hkey_patches, patch_squashed, &hkey_patch);
10980     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
10981
10982     /* patch key exists */
10983     size = MAX_PATH;
10984     lstrcpyA(val, "apple");
10985     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
10986     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
10987     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
10988     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
10989
10990     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10991     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10992     lstrcatA(keypath, prod_squashed);
10993
10994     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udproduct);
10995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
10996
10997     /* UserData product key exists */
10998     size = MAX_PATH;
10999     lstrcpyA(val, "apple");
11000     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11001     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11002     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11003     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11004
11005     res = RegCreateKeyA(hkey_udproduct, "InstallProperties", &hkey_udprops);
11006     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11007
11008     /* InstallProperties key exists */
11009     size = MAX_PATH;
11010     lstrcpyA(val, "apple");
11011     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11012     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11013     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11014     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11015
11016     res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udpatches);
11017     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11018
11019     /* UserData Patches key exists */
11020     size = MAX_PATH;
11021     lstrcpyA(val, "apple");
11022     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11023     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11024     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11025     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11026
11027     res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udproductpatches);
11028     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11029
11030     res = RegCreateKeyA(hkey_udproductpatches, patch_squashed, &hkey_udproductpatch);
11031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11032
11033     /* UserData product patch key exists */
11034     size = MAX_PATH;
11035     lstrcpyA(val, "apple");
11036     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11037     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11038     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11039     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11040
11041     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11042     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11043     lstrcatA(keypath, patch_squashed);
11044
11045     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udpatch);
11046     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11047
11048     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11049     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11050
11051     /* UserData Patch key exists */
11052     size = 0;
11053     lstrcpyA(val, "apple");
11054     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11055     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11056     ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11057     ok(size == 11, "expected 11 got %u\n", size);
11058
11059     size = MAX_PATH;
11060     lstrcpyA(val, "apple");
11061     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11062     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11063     ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11064     ok(size == 11, "expected 11 got %u\n", size);
11065
11066     size = 0;
11067     valW[0] = 0;
11068     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11069     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11070     ok(!valW[0], "expected 0 got %u\n", valW[0]);
11071     ok(size == 11, "expected 11 got %u\n", size);
11072
11073     size = MAX_PATH;
11074     valW[0] = 0;
11075     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11076     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11077     ok(valW[0], "expected > 0 got %u\n", valW[0]);
11078     ok(size == 11, "expected 11 got %u\n", size);
11079
11080     RegDeleteKeyA(hkey_udproductpatch, "");
11081     RegCloseKey(hkey_udproductpatch);
11082     RegDeleteKeyA(hkey_udproductpatches, "");
11083     RegCloseKey(hkey_udproductpatches);
11084     RegDeleteKeyA(hkey_udpatch, "");
11085     RegCloseKey(hkey_udpatch);
11086     RegDeleteKeyA(hkey_patches, "");
11087     RegCloseKey(hkey_patches);
11088     RegDeleteKeyA(hkey_product, "");
11089     RegCloseKey(hkey_product);
11090     RegDeleteKeyA(hkey_patch, "");
11091     RegCloseKey(hkey_patch);
11092     RegDeleteKeyA(hkey_udpatches, "");
11093     RegCloseKey(hkey_udpatches);
11094     RegDeleteKeyA(hkey_udprops, "");
11095     RegCloseKey(hkey_udprops);
11096     RegDeleteKeyA(hkey_udproduct, "");
11097     RegCloseKey(hkey_udproduct);
11098 }
11099
11100 static void test_MsiEnumProducts(void)
11101 {
11102     UINT r;
11103     int found1, found2, found3;
11104     DWORD index;
11105     char product1[39], product2[39], product3[39], guid[39];
11106     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11107     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11108     char *usersid;
11109     HKEY key1, key2, key3;
11110
11111     create_test_guid(product1, product_squashed1);
11112     create_test_guid(product2, product_squashed2);
11113     create_test_guid(product3, product_squashed3);
11114     get_user_sid(&usersid);
11115
11116     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11117     strcat(keypath1, product_squashed1);
11118
11119     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath1, &key1);
11120     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11121
11122     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11123     strcat(keypath2, usersid);
11124     strcat(keypath2, "\\Installer\\Products\\");
11125     strcat(keypath2, product_squashed2);
11126
11127     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath2, &key2);
11128     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11129
11130     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
11131     strcat(keypath3, product_squashed3);
11132
11133     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
11134     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11135
11136     index = 0;
11137     r = MsiEnumProductsA(index, NULL);
11138     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11139
11140     index = 2;
11141     r = MsiEnumProductsA(index, guid);
11142     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11143
11144     index = 0;
11145     r = MsiEnumProductsA(index, guid);
11146     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11147
11148     found1 = found2 = found3 = 0;
11149     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
11150     {
11151         if (!strcmp(product1, guid)) found1 = 1;
11152         if (!strcmp(product2, guid)) found2 = 1;
11153         if (!strcmp(product3, guid)) found3 = 1;
11154         index++;
11155     }
11156     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
11157     ok(found1, "product1 not found\n");
11158     ok(found2, "product2 not found\n");
11159     ok(found3, "product3 not found\n");
11160
11161     RegDeleteKeyA(key1, "");
11162     RegDeleteKeyA(key2, "");
11163     RegDeleteKeyA(key3, "");
11164     RegCloseKey(key1);
11165     RegCloseKey(key2);
11166     RegCloseKey(key3);
11167     LocalFree(usersid);
11168 }
11169
11170 START_TEST(msi)
11171 {
11172     init_functionpointers();
11173
11174     test_usefeature();
11175     test_null();
11176     test_getcomponentpath();
11177     test_MsiGetFileHash();
11178
11179     if (!pConvertSidToStringSidA)
11180         win_skip("ConvertSidToStringSidA not implemented\n");
11181     else
11182     {
11183         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
11184         test_MsiQueryProductState();
11185         test_MsiQueryFeatureState();
11186         test_MsiQueryComponentState();
11187         test_MsiGetComponentPath();
11188         test_MsiGetProductCode();
11189         test_MsiEnumClients();
11190         test_MsiGetProductInfo();
11191         test_MsiGetProductInfoEx();
11192         test_MsiGetUserInfo();
11193         test_MsiOpenProduct();
11194         test_MsiEnumPatchesEx();
11195         test_MsiEnumPatches();
11196         test_MsiGetPatchInfoEx();
11197         test_MsiGetPatchInfo();
11198         test_MsiEnumProducts();
11199     }
11200
11201     test_MsiGetFileVersion();
11202 }