msi/tests: Skip some source tests if a required product key cannot be created.
[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     size = MAX_PATH;
1559     state = MsiLocateComponentA(NULL, path, &size);
1560     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1561     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1562
1563     /* NULL lpPathBuf */
1564     size = MAX_PATH;
1565     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1566     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1567     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1568
1569     size = MAX_PATH;
1570     state = MsiLocateComponentA(component, NULL, &size);
1571     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1572     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1573
1574     /* NULL pcchBuf */
1575     size = MAX_PATH;
1576     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1577     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1578     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1579
1580     size = MAX_PATH;
1581     state = MsiLocateComponentA(component, path, NULL);
1582     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1583     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1584
1585     /* all params valid */
1586     size = MAX_PATH;
1587     state = MsiGetComponentPathA(prodcode, component, path, &size);
1588     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1589     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1590
1591     size = MAX_PATH;
1592     state = MsiLocateComponentA(component, path, &size);
1593     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1594     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1595
1596     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1597     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1598     lstrcatA(keypath, comp_squashed);
1599
1600     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1602
1603     /* local system component key exists */
1604     size = MAX_PATH;
1605     state = MsiGetComponentPathA(prodcode, component, path, &size);
1606     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1607     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1608
1609     size = MAX_PATH;
1610     state = MsiLocateComponentA(component, path, &size);
1611     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1612     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1613
1614     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1615     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1616
1617     /* product value exists */
1618     path[0] = 0;
1619     size = MAX_PATH;
1620     state = MsiGetComponentPathA(prodcode, component, path, &size);
1621     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1622     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1623     ok(size == 10, "Expected 10, got %d\n", size);
1624
1625     path[0] = 0;
1626     size = MAX_PATH;
1627     state = MsiLocateComponentA(component, path, &size);
1628     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1629     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1630     ok(size == 10, "Expected 10, got %d\n", size);
1631
1632     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1633     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1634     lstrcatA(keypath, prod_squashed);
1635     lstrcatA(keypath, "\\InstallProperties");
1636
1637     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1639
1640     val = 1;
1641     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1643
1644     /* install properties key exists */
1645     path[0] = 0;
1646     size = MAX_PATH;
1647     state = MsiGetComponentPathA(prodcode, component, path, &size);
1648     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1649     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1650     ok(size == 10, "Expected 10, got %d\n", size);
1651
1652     path[0] = 0;
1653     size = MAX_PATH;
1654     state = MsiLocateComponentA(component, path, &size);
1655     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1656     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1657     ok(size == 10, "Expected 10, got %d\n", size);
1658
1659     create_file("C:\\imapath", "C:\\imapath", 11);
1660
1661     /* file exists */
1662     path[0] = 0;
1663     size = MAX_PATH;
1664     state = MsiGetComponentPathA(prodcode, component, path, &size);
1665     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1666     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1667     ok(size == 10, "Expected 10, got %d\n", size);
1668
1669     path[0] = 0;
1670     size = MAX_PATH;
1671     state = MsiLocateComponentA(component, path, &size);
1672     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1673     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1674     ok(size == 10, "Expected 10, got %d\n", size);
1675
1676     RegDeleteValueA(compkey, prod_squashed);
1677     RegDeleteKeyA(compkey, "");
1678     RegDeleteValueA(installprop, "WindowsInstaller");
1679     RegDeleteKeyA(installprop, "");
1680     RegCloseKey(compkey);
1681     RegCloseKey(installprop);
1682     DeleteFileA("C:\\imapath");
1683
1684     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1685     lstrcatA(keypath, "Installer\\UserData\\");
1686     lstrcatA(keypath, usersid);
1687     lstrcatA(keypath, "\\Components\\");
1688     lstrcatA(keypath, comp_squashed);
1689
1690     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1691     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1692
1693     /* user managed component key exists */
1694     size = MAX_PATH;
1695     state = MsiGetComponentPathA(prodcode, component, path, &size);
1696     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1697     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1698
1699     size = MAX_PATH;
1700     state = MsiLocateComponentA(component, path, &size);
1701     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1702     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1703
1704     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1705     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1706
1707     /* product value exists */
1708     path[0] = 0;
1709     size = MAX_PATH;
1710     state = MsiGetComponentPathA(prodcode, component, path, &size);
1711     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1712     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1713     ok(size == 10, "Expected 10, got %d\n", size);
1714
1715     path[0] = 0;
1716     size = MAX_PATH;
1717     state = MsiLocateComponentA(component, path, &size);
1718     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1719     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1720     ok(size == 10, "Expected 10, got %d\n", size);
1721
1722     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1723     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1724     lstrcatA(keypath, prod_squashed);
1725     lstrcatA(keypath, "\\InstallProperties");
1726
1727     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1729
1730     val = 1;
1731     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1732     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1733
1734     /* install properties key exists */
1735     path[0] = 0;
1736     size = MAX_PATH;
1737     state = MsiGetComponentPathA(prodcode, component, path, &size);
1738     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1739     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1740     ok(size == 10, "Expected 10, got %d\n", size);
1741
1742     path[0] = 0;
1743     size = MAX_PATH;
1744     state = MsiLocateComponentA(component, path, &size);
1745     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1746     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1747     ok(size == 10, "Expected 10, got %d\n", size);
1748
1749     create_file("C:\\imapath", "C:\\imapath", 11);
1750
1751     /* file exists */
1752     path[0] = 0;
1753     size = MAX_PATH;
1754     state = MsiGetComponentPathA(prodcode, component, path, &size);
1755     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1756     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1757     ok(size == 10, "Expected 10, got %d\n", size);
1758
1759     path[0] = 0;
1760     size = MAX_PATH;
1761     state = MsiLocateComponentA(component, path, &size);
1762     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1763     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1764     ok(size == 10, "Expected 10, got %d\n", size);
1765
1766     RegDeleteValueA(compkey, prod_squashed);
1767     RegDeleteKeyA(compkey, "");
1768     RegDeleteValueA(installprop, "WindowsInstaller");
1769     RegDeleteKeyA(installprop, "");
1770     RegCloseKey(compkey);
1771     RegCloseKey(installprop);
1772     DeleteFileA("C:\\imapath");
1773
1774     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1775     lstrcatA(keypath, "Installer\\Managed\\");
1776     lstrcatA(keypath, usersid);
1777     lstrcatA(keypath, "\\Installer\\Products\\");
1778     lstrcatA(keypath, prod_squashed);
1779
1780     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1781     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1782
1783     /* user managed product key exists */
1784     size = MAX_PATH;
1785     state = MsiGetComponentPathA(prodcode, component, path, &size);
1786     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1787     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1788
1789     size = MAX_PATH;
1790     state = MsiLocateComponentA(component, path, &size);
1791     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1792     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1793
1794     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1795     lstrcatA(keypath, "Installer\\UserData\\");
1796     lstrcatA(keypath, usersid);
1797     lstrcatA(keypath, "\\Components\\");
1798     lstrcatA(keypath, comp_squashed);
1799
1800     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1801     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1802
1803     /* user managed component key exists */
1804     size = MAX_PATH;
1805     state = MsiGetComponentPathA(prodcode, component, path, &size);
1806     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1807     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1808
1809     size = MAX_PATH;
1810     state = MsiLocateComponentA(component, path, &size);
1811     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1812     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1813
1814     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1815     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1816
1817     /* product value exists */
1818     path[0] = 0;
1819     size = MAX_PATH;
1820     state = MsiGetComponentPathA(prodcode, component, path, &size);
1821     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1822     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1823     ok(size == 10, "Expected 10, got %d\n", size);
1824
1825     path[0] = 0;
1826     size = MAX_PATH;
1827     state = MsiLocateComponentA(component, path, &size);
1828     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1829     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1830     ok(size == 10, "Expected 10, got %d\n", size);
1831
1832     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1833     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1834     lstrcatA(keypath, prod_squashed);
1835     lstrcatA(keypath, "\\InstallProperties");
1836
1837     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1838     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1839
1840     val = 1;
1841     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1842     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1843
1844     /* install properties key exists */
1845     path[0] = 0;
1846     size = MAX_PATH;
1847     state = MsiGetComponentPathA(prodcode, component, path, &size);
1848     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1849     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1850     ok(size == 10, "Expected 10, got %d\n", size);
1851
1852     path[0] = 0;
1853     size = MAX_PATH;
1854     state = MsiLocateComponentA(component, path, &size);
1855     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1856     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1857     ok(size == 10, "Expected 10, got %d\n", size);
1858
1859     create_file("C:\\imapath", "C:\\imapath", 11);
1860
1861     /* file exists */
1862     path[0] = 0;
1863     size = MAX_PATH;
1864     state = MsiGetComponentPathA(prodcode, component, path, &size);
1865     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1866     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1867     ok(size == 10, "Expected 10, got %d\n", size);
1868
1869     path[0] = 0;
1870     size = MAX_PATH;
1871     state = MsiLocateComponentA(component, path, &size);
1872     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1873     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1874     ok(size == 10, "Expected 10, got %d\n", size);
1875
1876     RegDeleteValueA(compkey, prod_squashed);
1877     RegDeleteKeyA(prodkey, "");
1878     RegDeleteKeyA(compkey, "");
1879     RegDeleteValueA(installprop, "WindowsInstaller");
1880     RegDeleteKeyA(installprop, "");
1881     RegCloseKey(prodkey);
1882     RegCloseKey(compkey);
1883     RegCloseKey(installprop);
1884     DeleteFileA("C:\\imapath");
1885
1886     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1887     lstrcatA(keypath, prod_squashed);
1888
1889     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1891
1892     /* user unmanaged product key exists */
1893     size = MAX_PATH;
1894     state = MsiGetComponentPathA(prodcode, component, path, &size);
1895     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1896     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1897
1898     size = MAX_PATH;
1899     state = MsiLocateComponentA(component, path, &size);
1900     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1901     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1902
1903     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1904     lstrcatA(keypath, "Installer\\UserData\\");
1905     lstrcatA(keypath, usersid);
1906     lstrcatA(keypath, "\\Components\\");
1907     lstrcatA(keypath, comp_squashed);
1908
1909     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1910     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1911
1912     /* user unmanaged component key exists */
1913     size = MAX_PATH;
1914     state = MsiGetComponentPathA(prodcode, component, path, &size);
1915     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1916     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1917
1918     size = MAX_PATH;
1919     state = MsiLocateComponentA(component, path, &size);
1920     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1921     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1922
1923     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1924     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1925
1926     /* product value exists */
1927     path[0] = 0;
1928     size = MAX_PATH;
1929     state = MsiGetComponentPathA(prodcode, component, path, &size);
1930     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1931     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1932     ok(size == 10, "Expected 10, got %d\n", size);
1933
1934     path[0] = 0;
1935     size = MAX_PATH;
1936     state = MsiLocateComponentA(component, path, &size);
1937     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1938     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1939     ok(size == 10, "Expected 10, got %d\n", size);
1940
1941     create_file("C:\\imapath", "C:\\imapath", 11);
1942
1943     /* file exists */
1944     path[0] = 0;
1945     size = MAX_PATH;
1946     state = MsiGetComponentPathA(prodcode, component, path, &size);
1947     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1948     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1949     ok(size == 10, "Expected 10, got %d\n", size);
1950
1951     path[0] = 0;
1952     size = MAX_PATH;
1953     state = MsiLocateComponentA(component, path, &size);
1954     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1955     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1956     ok(size == 10, "Expected 10, got %d\n", size);
1957
1958     RegDeleteValueA(compkey, prod_squashed);
1959     RegDeleteKeyA(prodkey, "");
1960     RegDeleteKeyA(compkey, "");
1961     RegCloseKey(prodkey);
1962     RegCloseKey(compkey);
1963     DeleteFileA("C:\\imapath");
1964
1965     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1966     lstrcatA(keypath, prod_squashed);
1967
1968     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1970
1971     /* local classes product key exists */
1972     size = MAX_PATH;
1973     state = MsiGetComponentPathA(prodcode, component, path, &size);
1974     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1975     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1976
1977     size = MAX_PATH;
1978     state = MsiLocateComponentA(component, path, &size);
1979     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1980     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1981
1982     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1983     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1984     lstrcatA(keypath, comp_squashed);
1985
1986     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1987     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1988
1989     /* local user component key exists */
1990     size = MAX_PATH;
1991     state = MsiGetComponentPathA(prodcode, component, path, &size);
1992     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1993     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1994
1995     size = MAX_PATH;
1996     state = MsiLocateComponentA(component, path, &size);
1997     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1998     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1999
2000     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2001     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2002
2003     /* product value exists */
2004     path[0] = 0;
2005     size = MAX_PATH;
2006     state = MsiGetComponentPathA(prodcode, component, path, &size);
2007     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2008     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2009     ok(size == 10, "Expected 10, got %d\n", size);
2010
2011     path[0] = 0;
2012     size = MAX_PATH;
2013     state = MsiLocateComponentA(component, path, &size);
2014     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2015     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2016     ok(size == 10, "Expected 10, got %d\n", size);
2017
2018     create_file("C:\\imapath", "C:\\imapath", 11);
2019
2020     /* file exists */
2021     path[0] = 0;
2022     size = MAX_PATH;
2023     state = MsiGetComponentPathA(prodcode, component, path, &size);
2024     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2025     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2026     ok(size == 10, "Expected 10, got %d\n", size);
2027
2028     path[0] = 0;
2029     size = MAX_PATH;
2030     state = MsiLocateComponentA(component, path, &size);
2031     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
2032     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
2033     ok(size == 10, "Expected 10, got %d\n", size);
2034
2035     RegDeleteValueA(compkey, prod_squashed);
2036     RegDeleteKeyA(prodkey, "");
2037     RegDeleteKeyA(compkey, "");
2038     RegCloseKey(prodkey);
2039     RegCloseKey(compkey);
2040     DeleteFileA("C:\\imapath");
2041     LocalFree(usersid);
2042 }
2043
2044 static void test_MsiGetProductCode(void)
2045 {
2046     HKEY compkey, prodkey;
2047     CHAR prodcode[MAX_PATH];
2048     CHAR prod_squashed[MAX_PATH];
2049     CHAR prodcode2[MAX_PATH];
2050     CHAR prod2_squashed[MAX_PATH];
2051     CHAR component[MAX_PATH];
2052     CHAR comp_base85[MAX_PATH];
2053     CHAR comp_squashed[MAX_PATH];
2054     CHAR keypath[MAX_PATH];
2055     CHAR product[MAX_PATH];
2056     LPSTR usersid;
2057     LONG res;
2058     UINT r;
2059
2060     create_test_guid(prodcode, prod_squashed);
2061     create_test_guid(prodcode2, prod2_squashed);
2062     compose_base85_guid(component, comp_base85, comp_squashed);
2063     get_user_sid(&usersid);
2064
2065     /* szComponent is NULL */
2066     lstrcpyA(product, "prod");
2067     r = MsiGetProductCodeA(NULL, product);
2068     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2069     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2070
2071     /* szComponent is empty */
2072     lstrcpyA(product, "prod");
2073     r = MsiGetProductCodeA("", product);
2074     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2075     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2076
2077     /* garbage szComponent */
2078     lstrcpyA(product, "prod");
2079     r = MsiGetProductCodeA("garbage", product);
2080     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2081     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2082
2083     /* guid without brackets */
2084     lstrcpyA(product, "prod");
2085     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
2086     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2087     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2088
2089     /* guid with brackets */
2090     lstrcpyA(product, "prod");
2091     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
2092     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2093     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2094
2095     /* same length as guid, but random */
2096     lstrcpyA(product, "prod");
2097     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
2098     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2099     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2100
2101     /* all params correct, szComponent not published */
2102     lstrcpyA(product, "prod");
2103     r = MsiGetProductCodeA(component, product);
2104     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2105     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2106
2107     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2108     lstrcatA(keypath, "Installer\\UserData\\");
2109     lstrcatA(keypath, usersid);
2110     lstrcatA(keypath, "\\Components\\");
2111     lstrcatA(keypath, comp_squashed);
2112
2113     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2114     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2115
2116     /* user unmanaged component key exists */
2117     lstrcpyA(product, "prod");
2118     r = MsiGetProductCodeA(component, product);
2119     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2120     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2121
2122     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2124
2125     /* product value exists */
2126     lstrcpyA(product, "prod");
2127     r = MsiGetProductCodeA(component, product);
2128     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2129     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2130
2131     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2133
2134     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2135     lstrcatA(keypath, "Installer\\Managed\\");
2136     lstrcatA(keypath, usersid);
2137     lstrcatA(keypath, "\\Installer\\Products\\");
2138     lstrcatA(keypath, prod_squashed);
2139
2140     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2142
2143     /* user managed product key of first product exists */
2144     lstrcpyA(product, "prod");
2145     r = MsiGetProductCodeA(component, product);
2146     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2147     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2148
2149     RegDeleteKeyA(prodkey, "");
2150     RegCloseKey(prodkey);
2151
2152     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2153     lstrcatA(keypath, prod_squashed);
2154
2155     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2156     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2157
2158     /* user unmanaged product key exists */
2159     lstrcpyA(product, "prod");
2160     r = MsiGetProductCodeA(component, product);
2161     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2162     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2163
2164     RegDeleteKeyA(prodkey, "");
2165     RegCloseKey(prodkey);
2166
2167     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2168     lstrcatA(keypath, prod_squashed);
2169
2170     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2171     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2172
2173     /* local classes product key exists */
2174     lstrcpyA(product, "prod");
2175     r = MsiGetProductCodeA(component, product);
2176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2177     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2178
2179     RegDeleteKeyA(prodkey, "");
2180     RegCloseKey(prodkey);
2181
2182     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2183     lstrcatA(keypath, "Installer\\Managed\\");
2184     lstrcatA(keypath, usersid);
2185     lstrcatA(keypath, "\\Installer\\Products\\");
2186     lstrcatA(keypath, prod2_squashed);
2187
2188     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2190
2191     /* user managed product key of second product exists */
2192     lstrcpyA(product, "prod");
2193     r = MsiGetProductCodeA(component, product);
2194     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2195     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2196
2197     RegDeleteKeyA(prodkey, "");
2198     RegCloseKey(prodkey);
2199     RegDeleteValueA(compkey, prod_squashed);
2200     RegDeleteValueA(compkey, prod2_squashed);
2201     RegDeleteKeyA(compkey, "");
2202     RegCloseKey(compkey);
2203
2204     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2205     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2206     lstrcatA(keypath, comp_squashed);
2207
2208     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2209     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2210
2211     /* local user component key exists */
2212     lstrcpyA(product, "prod");
2213     r = MsiGetProductCodeA(component, product);
2214     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2215     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
2216
2217     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2218     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2219
2220     /* product value exists */
2221     lstrcpyA(product, "prod");
2222     r = MsiGetProductCodeA(component, product);
2223     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2224     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2225
2226     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2228
2229     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2230     lstrcatA(keypath, "Installer\\Managed\\");
2231     lstrcatA(keypath, usersid);
2232     lstrcatA(keypath, "\\Installer\\Products\\");
2233     lstrcatA(keypath, prod_squashed);
2234
2235     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2236     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2237
2238     /* user managed product key of first product exists */
2239     lstrcpyA(product, "prod");
2240     r = MsiGetProductCodeA(component, product);
2241     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2242     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2243
2244     RegDeleteKeyA(prodkey, "");
2245     RegCloseKey(prodkey);
2246
2247     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2248     lstrcatA(keypath, prod_squashed);
2249
2250     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2251     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2252
2253     /* user unmanaged product key exists */
2254     lstrcpyA(product, "prod");
2255     r = MsiGetProductCodeA(component, product);
2256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2257     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2258
2259     RegDeleteKeyA(prodkey, "");
2260     RegCloseKey(prodkey);
2261
2262     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2263     lstrcatA(keypath, prod_squashed);
2264
2265     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2267
2268     /* local classes product key exists */
2269     lstrcpyA(product, "prod");
2270     r = MsiGetProductCodeA(component, product);
2271     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2272     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2273
2274     RegDeleteKeyA(prodkey, "");
2275     RegCloseKey(prodkey);
2276
2277     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2278     lstrcatA(keypath, "Installer\\Managed\\");
2279     lstrcatA(keypath, usersid);
2280     lstrcatA(keypath, "\\Installer\\Products\\");
2281     lstrcatA(keypath, prod2_squashed);
2282
2283     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2285
2286     /* user managed product key of second product exists */
2287     lstrcpyA(product, "prod");
2288     r = MsiGetProductCodeA(component, product);
2289     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2290     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2291
2292     RegDeleteKeyA(prodkey, "");
2293     RegCloseKey(prodkey);
2294     RegDeleteValueA(compkey, prod_squashed);
2295     RegDeleteValueA(compkey, prod2_squashed);
2296     RegDeleteKeyA(compkey, "");
2297     RegCloseKey(compkey);
2298     LocalFree(usersid);
2299 }
2300
2301 static void test_MsiEnumClients(void)
2302 {
2303     HKEY compkey;
2304     CHAR prodcode[MAX_PATH];
2305     CHAR prod_squashed[MAX_PATH];
2306     CHAR prodcode2[MAX_PATH];
2307     CHAR prod2_squashed[MAX_PATH];
2308     CHAR component[MAX_PATH];
2309     CHAR comp_base85[MAX_PATH];
2310     CHAR comp_squashed[MAX_PATH];
2311     CHAR product[MAX_PATH];
2312     CHAR keypath[MAX_PATH];
2313     LPSTR usersid;
2314     LONG res;
2315     UINT r;
2316
2317     create_test_guid(prodcode, prod_squashed);
2318     create_test_guid(prodcode2, prod2_squashed);
2319     compose_base85_guid(component, comp_base85, comp_squashed);
2320     get_user_sid(&usersid);
2321
2322     /* NULL szComponent */
2323     product[0] = '\0';
2324     r = MsiEnumClientsA(NULL, 0, product);
2325     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2326     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2327
2328     /* empty szComponent */
2329     product[0] = '\0';
2330     r = MsiEnumClientsA("", 0, product);
2331     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2332     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2333
2334     /* NULL lpProductBuf */
2335     r = MsiEnumClientsA(component, 0, NULL);
2336     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2337
2338     /* all params correct, component missing */
2339     product[0] = '\0';
2340     r = MsiEnumClientsA(component, 0, product);
2341     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2342     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2343
2344     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2345     lstrcatA(keypath, "Installer\\UserData\\");
2346     lstrcatA(keypath, usersid);
2347     lstrcatA(keypath, "\\Components\\");
2348     lstrcatA(keypath, comp_squashed);
2349
2350     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2352
2353     /* user unmanaged component key exists */
2354     product[0] = '\0';
2355     r = MsiEnumClientsA(component, 0, product);
2356     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2357     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2358
2359     /* index > 0, no products exist */
2360     product[0] = '\0';
2361     r = MsiEnumClientsA(component, 1, product);
2362     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2363     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2364
2365     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2366     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2367
2368     /* product value exists */
2369     r = MsiEnumClientsA(component, 0, product);
2370     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2371     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2372
2373     /* try index 0 again */
2374     product[0] = '\0';
2375     r = MsiEnumClientsA(component, 0, product);
2376     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2377     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2378
2379     /* try index 1, second product value does not exist */
2380     product[0] = '\0';
2381     r = MsiEnumClientsA(component, 1, product);
2382     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2383     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2384
2385     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2386     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2387
2388     /* try index 1, second product value does exist */
2389     product[0] = '\0';
2390     r = MsiEnumClientsA(component, 1, product);
2391     todo_wine
2392     {
2393         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2394         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2395     }
2396
2397     /* start the enumeration over */
2398     product[0] = '\0';
2399     r = MsiEnumClientsA(component, 0, product);
2400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2401     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2402        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2403
2404     /* correctly query second product */
2405     product[0] = '\0';
2406     r = MsiEnumClientsA(component, 1, product);
2407     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2408     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2409        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2410
2411     RegDeleteValueA(compkey, prod_squashed);
2412     RegDeleteValueA(compkey, prod2_squashed);
2413     RegDeleteKeyA(compkey, "");
2414     RegCloseKey(compkey);
2415
2416     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2417     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2418     lstrcatA(keypath, comp_squashed);
2419
2420     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2421     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2422
2423     /* user local component key exists */
2424     product[0] = '\0';
2425     r = MsiEnumClientsA(component, 0, product);
2426     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2427     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2428
2429     /* index > 0, no products exist */
2430     product[0] = '\0';
2431     r = MsiEnumClientsA(component, 1, product);
2432     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2433     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2434
2435     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2436     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2437
2438     /* product value exists */
2439     product[0] = '\0';
2440     r = MsiEnumClientsA(component, 0, product);
2441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2442     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2443
2444     /* try index 0 again */
2445     product[0] = '\0';
2446     r = MsiEnumClientsA(component, 0, product);
2447     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2448
2449     /* try index 1, second product value does not exist */
2450     product[0] = '\0';
2451     r = MsiEnumClientsA(component, 1, product);
2452     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2453     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2454
2455     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2457
2458     /* try index 1, second product value does exist */
2459     product[0] = '\0';
2460     r = MsiEnumClientsA(component, 1, product);
2461     todo_wine
2462     {
2463         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2464         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2465     }
2466
2467     /* start the enumeration over */
2468     product[0] = '\0';
2469     r = MsiEnumClientsA(component, 0, product);
2470     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2471     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2472        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2473
2474     /* correctly query second product */
2475     product[0] = '\0';
2476     r = MsiEnumClientsA(component, 1, product);
2477     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2478     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2479        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2480
2481     RegDeleteValueA(compkey, prod_squashed);
2482     RegDeleteValueA(compkey, prod2_squashed);
2483     RegDeleteKeyA(compkey, "");
2484     RegCloseKey(compkey);
2485     LocalFree(usersid);
2486 }
2487
2488 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2489                              LPSTR *langcheck, LPDWORD langchecksz)
2490 {
2491     LPSTR version;
2492     VS_FIXEDFILEINFO *ffi;
2493     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2494     USHORT *lang;
2495
2496     version = HeapAlloc(GetProcessHeap(), 0, size);
2497     GetFileVersionInfoA(path, 0, size, version);
2498
2499     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2500     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2501     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2502             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2503             LOWORD(ffi->dwFileVersionLS));
2504     *verchecksz = lstrlenA(*vercheck);
2505
2506     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2507     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2508     sprintf(*langcheck, "%d", *lang);
2509     *langchecksz = lstrlenA(*langcheck);
2510
2511     HeapFree(GetProcessHeap(), 0, version);
2512 }
2513
2514 static void test_MsiGetFileVersion(void)
2515 {
2516     UINT r;
2517     DWORD versz, langsz;
2518     char version[MAX_PATH];
2519     char lang[MAX_PATH];
2520     char path[MAX_PATH];
2521     LPSTR vercheck, langcheck;
2522     DWORD verchecksz, langchecksz;
2523
2524     /* NULL szFilePath */
2525     versz = MAX_PATH;
2526     langsz = MAX_PATH;
2527     lstrcpyA(version, "version");
2528     lstrcpyA(lang, "lang");
2529     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2530     ok(r == ERROR_INVALID_PARAMETER,
2531        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2532     ok(!lstrcmpA(version, "version"),
2533        "Expected version to be unchanged, got %s\n", version);
2534     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2535     ok(!lstrcmpA(lang, "lang"),
2536        "Expected lang to be unchanged, got %s\n", lang);
2537     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2538
2539     /* empty szFilePath */
2540     versz = MAX_PATH;
2541     langsz = MAX_PATH;
2542     lstrcpyA(version, "version");
2543     lstrcpyA(lang, "lang");
2544     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2545     ok(r == ERROR_FILE_NOT_FOUND,
2546        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2547     ok(!lstrcmpA(version, "version"),
2548        "Expected version to be unchanged, got %s\n", version);
2549     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2550     ok(!lstrcmpA(lang, "lang"),
2551        "Expected lang to be unchanged, got %s\n", lang);
2552     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2553
2554     /* nonexistent szFilePath */
2555     versz = MAX_PATH;
2556     langsz = MAX_PATH;
2557     lstrcpyA(version, "version");
2558     lstrcpyA(lang, "lang");
2559     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2560     ok(r == ERROR_FILE_NOT_FOUND,
2561        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2562     ok(!lstrcmpA(version, "version"),
2563        "Expected version to be unchanged, got %s\n", version);
2564     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2565     ok(!lstrcmpA(lang, "lang"),
2566        "Expected lang to be unchanged, got %s\n", lang);
2567     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2568
2569     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2570     versz = MAX_PATH;
2571     langsz = MAX_PATH;
2572     lstrcpyA(version, "version");
2573     lstrcpyA(lang, "lang");
2574     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2575     ok(r == ERROR_INVALID_PARAMETER,
2576        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2577     ok(!lstrcmpA(version, "version"),
2578        "Expected version to be unchanged, got %s\n", version);
2579     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2580     ok(!lstrcmpA(lang, "lang"),
2581        "Expected lang to be unchanged, got %s\n", lang);
2582     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2583
2584     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2585     versz = MAX_PATH;
2586     langsz = MAX_PATH;
2587     lstrcpyA(version, "version");
2588     lstrcpyA(lang, "lang");
2589     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2590     ok(r == ERROR_INVALID_PARAMETER,
2591        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2592     ok(!lstrcmpA(version, "version"),
2593        "Expected version to be unchanged, got %s\n", version);
2594     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2595     ok(!lstrcmpA(lang, "lang"),
2596        "Expected lang to be unchanged, got %s\n", lang);
2597     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2598
2599     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2600     versz = 0;
2601     langsz = MAX_PATH;
2602     lstrcpyA(version, "version");
2603     lstrcpyA(lang, "lang");
2604     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2605     ok(r == ERROR_FILE_NOT_FOUND,
2606        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2607     ok(!lstrcmpA(version, "version"),
2608        "Expected version to be unchanged, got %s\n", version);
2609     ok(versz == 0, "Expected 0, got %d\n", versz);
2610     ok(!lstrcmpA(lang, "lang"),
2611        "Expected lang to be unchanged, got %s\n", lang);
2612     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2613
2614     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2615     versz = MAX_PATH;
2616     langsz = 0;
2617     lstrcpyA(version, "version");
2618     lstrcpyA(lang, "lang");
2619     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2620     ok(r == ERROR_FILE_NOT_FOUND,
2621        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2622     ok(!lstrcmpA(version, "version"),
2623        "Expected version to be unchanged, got %s\n", version);
2624     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2625     ok(!lstrcmpA(lang, "lang"),
2626        "Expected lang to be unchanged, got %s\n", lang);
2627     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2628
2629     /* nonexistent szFilePath, rest NULL */
2630     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2631     ok(r == ERROR_FILE_NOT_FOUND,
2632        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2633
2634     create_file("ver.txt", "ver.txt", 20);
2635
2636     /* file exists, no version information */
2637     versz = MAX_PATH;
2638     langsz = MAX_PATH;
2639     lstrcpyA(version, "version");
2640     lstrcpyA(lang, "lang");
2641     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2642     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2643     ok(!lstrcmpA(version, "version"),
2644        "Expected version to be unchanged, got %s\n", version);
2645     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2646     ok(!lstrcmpA(lang, "lang"),
2647        "Expected lang to be unchanged, got %s\n", lang);
2648     ok(r == ERROR_FILE_INVALID,
2649        "Expected ERROR_FILE_INVALID, got %d\n", r);
2650
2651     DeleteFileA("ver.txt");
2652
2653     /* relative path, has version information */
2654     versz = MAX_PATH;
2655     langsz = MAX_PATH;
2656     lstrcpyA(version, "version");
2657     lstrcpyA(lang, "lang");
2658     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2659     todo_wine
2660     {
2661         ok(r == ERROR_FILE_NOT_FOUND,
2662            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2663         ok(!lstrcmpA(version, "version"),
2664            "Expected version to be unchanged, got %s\n", version);
2665         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2666         ok(!lstrcmpA(lang, "lang"),
2667            "Expected lang to be unchanged, got %s\n", lang);
2668         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2669     }
2670
2671     GetSystemDirectoryA(path, MAX_PATH);
2672     lstrcatA(path, "\\kernel32.dll");
2673
2674     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2675
2676     /* absolute path, has version information */
2677     versz = MAX_PATH;
2678     langsz = MAX_PATH;
2679     lstrcpyA(version, "version");
2680     lstrcpyA(lang, "lang");
2681     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2682     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2683     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2684     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2685     ok(!lstrcmpA(version, vercheck),
2686         "Expected %s, got %s\n", vercheck, version);
2687
2688     /* only check version */
2689     versz = MAX_PATH;
2690     lstrcpyA(version, "version");
2691     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2692     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2693     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2694     ok(!lstrcmpA(version, vercheck),
2695        "Expected %s, got %s\n", vercheck, version);
2696
2697     /* only check language */
2698     langsz = MAX_PATH;
2699     lstrcpyA(lang, "lang");
2700     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2702     ok(strstr(lang, langcheck) != NULL, "Expected %s in %s\n", langcheck, lang);
2703
2704     /* check neither version nor language */
2705     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2706     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2707
2708     /* get pcchVersionBuf */
2709     versz = MAX_PATH;
2710     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2711     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2712     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2713
2714     /* get pcchLangBuf */
2715     langsz = MAX_PATH;
2716     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2717     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2718     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
2719
2720     /* pcchVersionBuf not big enough */
2721     versz = 5;
2722     lstrcpyA(version, "version");
2723     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2724     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2725     ok(!strncmp(version, vercheck, 4),
2726        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2727     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2728
2729     /* pcchLangBuf not big enough */
2730     langsz = 3;
2731     lstrcpyA(lang, "lang");
2732     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2733     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2734     ok(!strncmp(lang, langcheck, 2),
2735        "Expected first character of %s, got %s\n", langcheck, lang);
2736     ok(langsz >= langchecksz, "Expected %d >= %d\n", langsz, langchecksz);
2737
2738     HeapFree(GetProcessHeap(), 0, vercheck);
2739     HeapFree(GetProcessHeap(), 0, langcheck);
2740 }
2741
2742 static void test_MsiGetProductInfo(void)
2743 {
2744     UINT r;
2745     LONG res;
2746     HKEY propkey, source;
2747     HKEY prodkey, localkey;
2748     CHAR prodcode[MAX_PATH];
2749     CHAR prod_squashed[MAX_PATH];
2750     CHAR packcode[MAX_PATH];
2751     CHAR pack_squashed[MAX_PATH];
2752     CHAR buf[MAX_PATH];
2753     CHAR keypath[MAX_PATH];
2754     LPSTR usersid;
2755     DWORD sz, val = 42;
2756
2757     create_test_guid(prodcode, prod_squashed);
2758     create_test_guid(packcode, pack_squashed);
2759     get_user_sid(&usersid);
2760
2761     /* NULL szProduct */
2762     sz = MAX_PATH;
2763     lstrcpyA(buf, "apple");
2764     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2765     ok(r == ERROR_INVALID_PARAMETER,
2766        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2767     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2768     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2769
2770     /* empty szProduct */
2771     sz = MAX_PATH;
2772     lstrcpyA(buf, "apple");
2773     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2774     ok(r == ERROR_INVALID_PARAMETER,
2775        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2776     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2777     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2778
2779     /* garbage szProduct */
2780     sz = MAX_PATH;
2781     lstrcpyA(buf, "apple");
2782     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2783     ok(r == ERROR_INVALID_PARAMETER,
2784        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2785     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2786     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2787
2788     /* guid without brackets */
2789     sz = MAX_PATH;
2790     lstrcpyA(buf, "apple");
2791     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2792                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2793     ok(r == ERROR_INVALID_PARAMETER,
2794        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2795     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2796     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2797
2798     /* guid with brackets */
2799     sz = MAX_PATH;
2800     lstrcpyA(buf, "apple");
2801     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2802                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2803     ok(r == ERROR_UNKNOWN_PRODUCT,
2804        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2805     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2806     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2807
2808     /* same length as guid, but random */
2809     sz = MAX_PATH;
2810     lstrcpyA(buf, "apple");
2811     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2812                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2813     ok(r == ERROR_INVALID_PARAMETER,
2814        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2815     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2816     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2817
2818     /* not installed, NULL szAttribute */
2819     sz = MAX_PATH;
2820     lstrcpyA(buf, "apple");
2821     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2822     ok(r == ERROR_INVALID_PARAMETER,
2823        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2824     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2825     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2826
2827     /* not installed, NULL lpValueBuf */
2828     sz = MAX_PATH;
2829     lstrcpyA(buf, "apple");
2830     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2831     ok(r == ERROR_UNKNOWN_PRODUCT,
2832        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2833     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2834     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2835
2836     /* not installed, NULL pcchValueBuf */
2837     sz = MAX_PATH;
2838     lstrcpyA(buf, "apple");
2839     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2840     ok(r == ERROR_INVALID_PARAMETER,
2841        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2842     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2843     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2844
2845     /* created guid cannot possibly be an installed product code */
2846     sz = MAX_PATH;
2847     lstrcpyA(buf, "apple");
2848     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2849     ok(r == ERROR_UNKNOWN_PRODUCT,
2850        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2851     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2852     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2853
2854     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2855     lstrcatA(keypath, usersid);
2856     lstrcatA(keypath, "\\Installer\\Products\\");
2857     lstrcatA(keypath, prod_squashed);
2858
2859     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2860     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2861
2862     /* managed product code exists */
2863     sz = MAX_PATH;
2864     lstrcpyA(buf, "apple");
2865     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2866     ok(r == ERROR_UNKNOWN_PROPERTY,
2867        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2868     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2869     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2870
2871     RegDeleteKeyA(prodkey, "");
2872     RegCloseKey(prodkey);
2873
2874     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2875     lstrcatA(keypath, usersid);
2876     lstrcatA(keypath, "\\Products\\");
2877     lstrcatA(keypath, prod_squashed);
2878
2879     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2880     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2881
2882     /* local user product code exists */
2883     sz = MAX_PATH;
2884     lstrcpyA(buf, "apple");
2885     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2886     ok(r == ERROR_UNKNOWN_PRODUCT,
2887        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2888     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2889     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2890
2891     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2892     lstrcatA(keypath, usersid);
2893     lstrcatA(keypath, "\\Installer\\Products\\");
2894     lstrcatA(keypath, prod_squashed);
2895
2896     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2897     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2898
2899     /* both local and managed product code exist */
2900     sz = MAX_PATH;
2901     lstrcpyA(buf, "apple");
2902     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2903     ok(r == ERROR_UNKNOWN_PROPERTY,
2904        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2905     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2906     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2907
2908     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2909     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2910
2911     /* InstallProperties key exists */
2912     sz = MAX_PATH;
2913     lstrcpyA(buf, "apple");
2914     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2915     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2916     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2917     ok(sz == 0, "Expected 0, got %d\n", sz);
2918
2919     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2920     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2921
2922     /* HelpLink value exists */
2923     sz = MAX_PATH;
2924     lstrcpyA(buf, "apple");
2925     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2926     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2927     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2928     ok(sz == 4, "Expected 4, got %d\n", sz);
2929
2930     /* pcchBuf is NULL */
2931     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
2932     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2933
2934     /* lpValueBuf is NULL */
2935     sz = MAX_PATH;
2936     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2937     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2938     ok(sz == 4, "Expected 4, got %d\n", sz);
2939
2940     /* lpValueBuf is NULL, pcchValueBuf is too small */
2941     sz = 2;
2942     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2943     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2944     ok(sz == 4, "Expected 4, got %d\n", sz);
2945
2946     /* lpValueBuf is non-NULL, pcchValueBuf is too small */
2947     sz = 2;
2948     lstrcpyA(buf, "apple");
2949     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2950     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
2951     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2952     ok(sz == 4, "Expected 4, got %d\n", sz);
2953
2954     /* lpValueBuf is non-NULL, pcchValueBuf is exactly 4 */
2955     sz = 4;
2956     lstrcpyA(buf, "apple");
2957     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2958     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2959     ok(!lstrcmpA(buf, "apple"),
2960        "Expected buf to remain unchanged, got \"%s\"\n", buf);
2961     ok(sz == 4, "Expected 4, got %d\n", sz);
2962
2963     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
2964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2965
2966     /* random property not supported by MSI, value exists */
2967     sz = MAX_PATH;
2968     lstrcpyA(buf, "apple");
2969     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
2970     ok(r == ERROR_UNKNOWN_PROPERTY,
2971        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2972     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2973     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2974
2975     RegDeleteValueA(propkey, "IMadeThis");
2976     RegDeleteValueA(propkey, "HelpLink");
2977     RegDeleteKeyA(propkey, "");
2978     RegDeleteKeyA(localkey, "");
2979     RegDeleteKeyA(prodkey, "");
2980     RegCloseKey(propkey);
2981     RegCloseKey(localkey);
2982     RegCloseKey(prodkey);
2983
2984     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2985     lstrcatA(keypath, prod_squashed);
2986
2987     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2988     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2989
2990     /* user product key exists */
2991     sz = MAX_PATH;
2992     lstrcpyA(buf, "apple");
2993     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2994     ok(r == ERROR_UNKNOWN_PROPERTY,
2995        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2996     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2997     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2998
2999     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3000     lstrcatA(keypath, usersid);
3001     lstrcatA(keypath, "\\Products\\");
3002     lstrcatA(keypath, prod_squashed);
3003
3004     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
3005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3006
3007     /* local user product key exists */
3008     sz = MAX_PATH;
3009     lstrcpyA(buf, "apple");
3010     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3011     ok(r == ERROR_UNKNOWN_PROPERTY,
3012        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3013     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3014     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3015
3016     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
3017     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3018
3019     /* InstallProperties key exists */
3020     sz = MAX_PATH;
3021     lstrcpyA(buf, "apple");
3022     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3023     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3024     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3025     ok(sz == 0, "Expected 0, got %d\n", sz);
3026
3027     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3028     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3029
3030     /* HelpLink value exists */
3031     sz = MAX_PATH;
3032     lstrcpyA(buf, "apple");
3033     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3034     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3035     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3036     ok(sz == 4, "Expected 4, got %d\n", sz);
3037
3038     RegDeleteValueA(propkey, "HelpLink");
3039     RegDeleteKeyA(propkey, "");
3040     RegDeleteKeyA(localkey, "");
3041     RegDeleteKeyA(prodkey, "");
3042     RegCloseKey(propkey);
3043     RegCloseKey(localkey);
3044     RegCloseKey(prodkey);
3045
3046     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
3047     lstrcatA(keypath, prod_squashed);
3048
3049     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
3050     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3051
3052     /* classes product key exists */
3053     sz = MAX_PATH;
3054     lstrcpyA(buf, "apple");
3055     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3056     ok(r == ERROR_UNKNOWN_PROPERTY,
3057        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3058     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3059     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3060
3061     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3062     lstrcatA(keypath, usersid);
3063     lstrcatA(keypath, "\\Products\\");
3064     lstrcatA(keypath, prod_squashed);
3065
3066     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
3067     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3068
3069     /* local user product key exists */
3070     sz = MAX_PATH;
3071     lstrcpyA(buf, "apple");
3072     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3073     ok(r == ERROR_UNKNOWN_PROPERTY,
3074        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3075     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3076     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3077
3078     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
3079     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3080
3081     /* InstallProperties key exists */
3082     sz = MAX_PATH;
3083     lstrcpyA(buf, "apple");
3084     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3085     ok(r == ERROR_UNKNOWN_PROPERTY,
3086        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3087     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3088     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3089
3090     RegDeleteKeyA(propkey, "");
3091     RegDeleteKeyA(localkey, "");
3092     RegCloseKey(propkey);
3093     RegCloseKey(localkey);
3094
3095     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3096     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
3097     lstrcatA(keypath, prod_squashed);
3098
3099     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
3100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3101
3102     /* Local System product key exists */
3103     sz = MAX_PATH;
3104     lstrcpyA(buf, "apple");
3105     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3106     ok(r == ERROR_UNKNOWN_PROPERTY,
3107         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
3108     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
3109     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3110
3111     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
3112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3113
3114     /* InstallProperties key exists */
3115     sz = MAX_PATH;
3116     lstrcpyA(buf, "apple");
3117     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3118     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3119     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3120     ok(sz == 0, "Expected 0, got %d\n", sz);
3121
3122     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3124
3125     /* HelpLink value exists */
3126     sz = MAX_PATH;
3127     lstrcpyA(buf, "apple");
3128     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3129     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3130     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3131     ok(sz == 4, "Expected 4, got %d\n", sz);
3132
3133     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
3134                          (const BYTE *)&val, sizeof(DWORD));
3135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3136
3137     /* HelpLink type is REG_DWORD */
3138     sz = MAX_PATH;
3139     lstrcpyA(buf, "apple");
3140     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
3141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3142     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3143     ok(sz == 2, "Expected 2, got %d\n", sz);
3144
3145     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
3146     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3147
3148     /* DisplayName value exists */
3149     sz = MAX_PATH;
3150     lstrcpyA(buf, "apple");
3151     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3152     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3153     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3154     ok(sz == 4, "Expected 4, got %d\n", sz);
3155
3156     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
3157                          (const BYTE *)&val, sizeof(DWORD));
3158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3159
3160     /* DisplayName type is REG_DWORD */
3161     sz = MAX_PATH;
3162     lstrcpyA(buf, "apple");
3163     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
3164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3165     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3166     ok(sz == 2, "Expected 2, got %d\n", sz);
3167
3168     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
3169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3170
3171     /* DisplayVersion value exists */
3172     sz = MAX_PATH;
3173     lstrcpyA(buf, "apple");
3174     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3175     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3176     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
3177     ok(sz == 5, "Expected 5, got %d\n", sz);
3178
3179     res = RegSetValueExA(propkey, "DisplayVersion", 0,
3180                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
3181     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3182
3183     /* DisplayVersion type is REG_DWORD */
3184     sz = MAX_PATH;
3185     lstrcpyA(buf, "apple");
3186     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
3187     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3188     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3189     ok(sz == 2, "Expected 2, got %d\n", sz);
3190
3191     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
3192     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3193
3194     /* HelpTelephone value exists */
3195     sz = MAX_PATH;
3196     lstrcpyA(buf, "apple");
3197     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3198     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3199     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
3200     ok(sz == 4, "Expected 4, got %d\n", sz);
3201
3202     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
3203                          (const BYTE *)&val, sizeof(DWORD));
3204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3205
3206     /* HelpTelephone type is REG_DWORD */
3207     sz = MAX_PATH;
3208     lstrcpyA(buf, "apple");
3209     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
3210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3211     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3212     ok(sz == 2, "Expected 2, got %d\n", sz);
3213
3214     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
3215     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3216
3217     /* InstallLocation value exists */
3218     sz = MAX_PATH;
3219     lstrcpyA(buf, "apple");
3220     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3221     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3222     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3223     ok(sz == 3, "Expected 3, got %d\n", sz);
3224
3225     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3226                          (const BYTE *)&val, sizeof(DWORD));
3227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3228
3229     /* InstallLocation type is REG_DWORD */
3230     sz = MAX_PATH;
3231     lstrcpyA(buf, "apple");
3232     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3234     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3235     ok(sz == 2, "Expected 2, got %d\n", sz);
3236
3237     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3238     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3239
3240     /* InstallSource value exists */
3241     sz = MAX_PATH;
3242     lstrcpyA(buf, "apple");
3243     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3244     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3245     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3246     ok(sz == 6, "Expected 6, got %d\n", sz);
3247
3248     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3249                          (const BYTE *)&val, sizeof(DWORD));
3250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3251
3252     /* InstallSource type is REG_DWORD */
3253     sz = MAX_PATH;
3254     lstrcpyA(buf, "apple");
3255     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3257     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3258     ok(sz == 2, "Expected 2, got %d\n", sz);
3259
3260     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3261     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3262
3263     /* InstallDate value exists */
3264     sz = MAX_PATH;
3265     lstrcpyA(buf, "apple");
3266     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3267     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3268     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3269     ok(sz == 4, "Expected 4, got %d\n", sz);
3270
3271     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3272                          (const BYTE *)&val, sizeof(DWORD));
3273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3274
3275     /* InstallDate type is REG_DWORD */
3276     sz = MAX_PATH;
3277     lstrcpyA(buf, "apple");
3278     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3280     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3281     ok(sz == 2, "Expected 2, got %d\n", sz);
3282
3283     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3285
3286     /* Publisher value exists */
3287     sz = MAX_PATH;
3288     lstrcpyA(buf, "apple");
3289     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3290     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3291     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3292     ok(sz == 3, "Expected 3, got %d\n", sz);
3293
3294     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3295                          (const BYTE *)&val, sizeof(DWORD));
3296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3297
3298     /* Publisher type is REG_DWORD */
3299     sz = MAX_PATH;
3300     lstrcpyA(buf, "apple");
3301     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3303     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3304     ok(sz == 2, "Expected 2, got %d\n", sz);
3305
3306     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3308
3309     /* LocalPackage value exists */
3310     sz = MAX_PATH;
3311     lstrcpyA(buf, "apple");
3312     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3314     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3315     ok(sz == 4, "Expected 4, got %d\n", sz);
3316
3317     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3318                          (const BYTE *)&val, sizeof(DWORD));
3319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3320
3321     /* LocalPackage type is REG_DWORD */
3322     sz = MAX_PATH;
3323     lstrcpyA(buf, "apple");
3324     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3326     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3327     ok(sz == 2, "Expected 2, got %d\n", sz);
3328
3329     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3330     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3331
3332     /* UrlInfoAbout value exists */
3333     sz = MAX_PATH;
3334     lstrcpyA(buf, "apple");
3335     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3336     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3337     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3338     ok(sz == 5, "Expected 5, got %d\n", sz);
3339
3340     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3341                          (const BYTE *)&val, sizeof(DWORD));
3342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3343
3344     /* UrlInfoAbout type is REG_DWORD */
3345     sz = MAX_PATH;
3346     lstrcpyA(buf, "apple");
3347     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3349     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3350     ok(sz == 2, "Expected 2, got %d\n", sz);
3351
3352     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3353     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3354
3355     /* UrlUpdateInfo value exists */
3356     sz = MAX_PATH;
3357     lstrcpyA(buf, "apple");
3358     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3359     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3360     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3361     ok(sz == 4, "Expected 4, got %d\n", sz);
3362
3363     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3364                          (const BYTE *)&val, sizeof(DWORD));
3365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3366
3367     /* UrlUpdateInfo type is REG_DWORD */
3368     sz = MAX_PATH;
3369     lstrcpyA(buf, "apple");
3370     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3372     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3373     ok(sz == 2, "Expected 2, got %d\n", sz);
3374
3375     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3376     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3377
3378     /* VersionMinor value exists */
3379     sz = MAX_PATH;
3380     lstrcpyA(buf, "apple");
3381     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3382     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3383     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3384     ok(sz == 1, "Expected 1, got %d\n", sz);
3385
3386     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3387                          (const BYTE *)&val, sizeof(DWORD));
3388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3389
3390     /* VersionMinor type is REG_DWORD */
3391     sz = MAX_PATH;
3392     lstrcpyA(buf, "apple");
3393     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3394     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3395     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3396     ok(sz == 2, "Expected 2, got %d\n", sz);
3397
3398     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3399     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3400
3401     /* VersionMajor value exists */
3402     sz = MAX_PATH;
3403     lstrcpyA(buf, "apple");
3404     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3405     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3406     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3407     ok(sz == 1, "Expected 1, got %d\n", sz);
3408
3409     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3410                          (const BYTE *)&val, sizeof(DWORD));
3411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3412
3413     /* VersionMajor type is REG_DWORD */
3414     sz = MAX_PATH;
3415     lstrcpyA(buf, "apple");
3416     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3417     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3418     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3419     ok(sz == 2, "Expected 2, got %d\n", sz);
3420
3421     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3423
3424     /* ProductID value exists */
3425     sz = MAX_PATH;
3426     lstrcpyA(buf, "apple");
3427     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3428     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3429     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3430     ok(sz == 2, "Expected 2, got %d\n", sz);
3431
3432     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3433                          (const BYTE *)&val, sizeof(DWORD));
3434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3435
3436     /* ProductID type is REG_DWORD */
3437     sz = MAX_PATH;
3438     lstrcpyA(buf, "apple");
3439     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3441     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3442     ok(sz == 2, "Expected 2, got %d\n", sz);
3443
3444     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3445     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3446
3447     /* RegCompany value exists */
3448     sz = MAX_PATH;
3449     lstrcpyA(buf, "apple");
3450     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3452     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3453     ok(sz == 4, "Expected 4, got %d\n", sz);
3454
3455     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3456                          (const BYTE *)&val, sizeof(DWORD));
3457     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3458
3459     /* RegCompany type is REG_DWORD */
3460     sz = MAX_PATH;
3461     lstrcpyA(buf, "apple");
3462     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3464     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3465     ok(sz == 2, "Expected 2, got %d\n", sz);
3466
3467     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3468     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3469
3470     /* RegOwner value exists */
3471     sz = MAX_PATH;
3472     lstrcpyA(buf, "apple");
3473     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3474     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3475     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3476     ok(sz == 3, "Expected 3, got %d\n", sz);
3477
3478     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3479                          (const BYTE *)&val, sizeof(DWORD));
3480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3481
3482     /* RegOwner type is REG_DWORD */
3483     sz = MAX_PATH;
3484     lstrcpyA(buf, "apple");
3485     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3486     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3487     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3488     ok(sz == 2, "Expected 2, got %d\n", sz);
3489
3490     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3491     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3492
3493     /* InstanceType value exists */
3494     sz = MAX_PATH;
3495     lstrcpyA(buf, "apple");
3496     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3497     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3498     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3499     ok(sz == 0, "Expected 0, got %d\n", sz);
3500
3501     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3502                          (const BYTE *)&val, sizeof(DWORD));
3503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3504
3505     /* InstanceType type is REG_DWORD */
3506     sz = MAX_PATH;
3507     lstrcpyA(buf, "apple");
3508     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3510     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3511     ok(sz == 0, "Expected 0, got %d\n", sz);
3512
3513     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3514     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3515
3516     /* InstanceType value exists */
3517     sz = MAX_PATH;
3518     lstrcpyA(buf, "apple");
3519     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3520     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3521     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3522     ok(sz == 4, "Expected 4, got %d\n", sz);
3523
3524     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3525                          (const BYTE *)&val, sizeof(DWORD));
3526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3527
3528     /* InstanceType type is REG_DWORD */
3529     sz = MAX_PATH;
3530     lstrcpyA(buf, "apple");
3531     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3532     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3533     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3534     ok(sz == 2, "Expected 2, got %d\n", sz);
3535
3536     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3537     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3538
3539     /* Transforms value exists */
3540     sz = MAX_PATH;
3541     lstrcpyA(buf, "apple");
3542     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3543     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3544     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3545     ok(sz == 0, "Expected 0, got %d\n", sz);
3546
3547     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3548                          (const BYTE *)&val, sizeof(DWORD));
3549     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3550
3551     /* Transforms type is REG_DWORD */
3552     sz = MAX_PATH;
3553     lstrcpyA(buf, "apple");
3554     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3555     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3556     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3557     ok(sz == 0, "Expected 0, got %d\n", sz);
3558
3559     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3560     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3561
3562     /* Transforms value exists */
3563     sz = MAX_PATH;
3564     lstrcpyA(buf, "apple");
3565     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3566     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3567     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3568     ok(sz == 6, "Expected 6, got %d\n", sz);
3569
3570     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3571                          (const BYTE *)&val, sizeof(DWORD));
3572     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3573
3574     /* Transforms type is REG_DWORD */
3575     sz = MAX_PATH;
3576     lstrcpyA(buf, "apple");
3577     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3578     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3579     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3580     ok(sz == 2, "Expected 2, got %d\n", sz);
3581
3582     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3583     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3584
3585     /* Language value exists */
3586     sz = MAX_PATH;
3587     lstrcpyA(buf, "apple");
3588     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3589     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3590     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3591     ok(sz == 0, "Expected 0, got %d\n", sz);
3592
3593     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3594                          (const BYTE *)&val, sizeof(DWORD));
3595     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3596
3597     /* Language type is REG_DWORD */
3598     sz = MAX_PATH;
3599     lstrcpyA(buf, "apple");
3600     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3601     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3602     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3603     ok(sz == 0, "Expected 0, got %d\n", sz);
3604
3605     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3606     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3607
3608     /* Language value exists */
3609     sz = MAX_PATH;
3610     lstrcpyA(buf, "apple");
3611     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3612     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3613     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3614     ok(sz == 4, "Expected 4, got %d\n", sz);
3615
3616     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3617                          (const BYTE *)&val, sizeof(DWORD));
3618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3619
3620     /* Language type is REG_DWORD */
3621     sz = MAX_PATH;
3622     lstrcpyA(buf, "apple");
3623     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3624     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3625     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3626     ok(sz == 2, "Expected 2, got %d\n", sz);
3627
3628     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3629     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3630
3631     /* ProductName value exists */
3632     sz = MAX_PATH;
3633     lstrcpyA(buf, "apple");
3634     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3635     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3636     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3637     ok(sz == 0, "Expected 0, got %d\n", sz);
3638
3639     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3640                          (const BYTE *)&val, sizeof(DWORD));
3641     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3642
3643     /* ProductName type is REG_DWORD */
3644     sz = MAX_PATH;
3645     lstrcpyA(buf, "apple");
3646     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3647     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3648     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3649     ok(sz == 0, "Expected 0, got %d\n", sz);
3650
3651     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3653
3654     /* ProductName value exists */
3655     sz = MAX_PATH;
3656     lstrcpyA(buf, "apple");
3657     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3658     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3659     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3660     ok(sz == 4, "Expected 4, got %d\n", sz);
3661
3662     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3663                          (const BYTE *)&val, sizeof(DWORD));
3664     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3665
3666     /* ProductName type is REG_DWORD */
3667     sz = MAX_PATH;
3668     lstrcpyA(buf, "apple");
3669     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3670     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3671     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3672     ok(sz == 2, "Expected 2, got %d\n", sz);
3673
3674     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3675     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3676
3677     /* Assignment value exists */
3678     sz = MAX_PATH;
3679     lstrcpyA(buf, "apple");
3680     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3681     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3682     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3683     ok(sz == 0, "Expected 0, got %d\n", sz);
3684
3685     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3686                          (const BYTE *)&val, sizeof(DWORD));
3687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3688
3689     /* Assignment type is REG_DWORD */
3690     sz = MAX_PATH;
3691     lstrcpyA(buf, "apple");
3692     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3693     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3694     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3695     ok(sz == 0, "Expected 0, got %d\n", sz);
3696
3697     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3698     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3699
3700     /* Assignment value exists */
3701     sz = MAX_PATH;
3702     lstrcpyA(buf, "apple");
3703     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3704     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3705     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3706     ok(sz == 2, "Expected 2, got %d\n", sz);
3707
3708     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3709                          (const BYTE *)&val, sizeof(DWORD));
3710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3711
3712     /* Assignment type is REG_DWORD */
3713     sz = MAX_PATH;
3714     lstrcpyA(buf, "apple");
3715     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3716     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3717     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3718     ok(sz == 2, "Expected 2, got %d\n", sz);
3719
3720     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3721     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3722
3723     /* PackageCode value exists */
3724     sz = MAX_PATH;
3725     lstrcpyA(buf, "apple");
3726     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3727     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3728     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3729     ok(sz == 0, "Expected 0, got %d\n", sz);
3730
3731     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3732                          (const BYTE *)&val, sizeof(DWORD));
3733     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3734
3735     /* PackageCode type is REG_DWORD */
3736     sz = MAX_PATH;
3737     lstrcpyA(buf, "apple");
3738     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3739     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3740     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3741     ok(sz == 0, "Expected 0, got %d\n", sz);
3742
3743     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3744     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3745
3746     /* PackageCode value exists */
3747     sz = MAX_PATH;
3748     lstrcpyA(buf, "apple");
3749     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3750     ok(r == ERROR_BAD_CONFIGURATION,
3751        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3752     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3753     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3754
3755     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3756                          (const BYTE *)&val, sizeof(DWORD));
3757     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3758
3759     /* PackageCode type is REG_DWORD */
3760     sz = MAX_PATH;
3761     lstrcpyA(buf, "apple");
3762     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3763     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3764     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3765     ok(sz == 2, "Expected 2, got %d\n", sz);
3766
3767     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3768     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3769
3770     /* PackageCode value exists */
3771     sz = MAX_PATH;
3772     lstrcpyA(buf, "apple");
3773     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3774     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3775     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3776     ok(sz == 38, "Expected 38, got %d\n", sz);
3777
3778     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3780
3781     /* Version value exists */
3782     sz = MAX_PATH;
3783     lstrcpyA(buf, "apple");
3784     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3786     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3787     ok(sz == 0, "Expected 0, got %d\n", sz);
3788
3789     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3790                          (const BYTE *)&val, sizeof(DWORD));
3791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3792
3793     /* Version type is REG_DWORD */
3794     sz = MAX_PATH;
3795     lstrcpyA(buf, "apple");
3796     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3797     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3798     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3799     ok(sz == 0, "Expected 0, got %d\n", sz);
3800
3801     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3803
3804     /* Version value exists */
3805     sz = MAX_PATH;
3806     lstrcpyA(buf, "apple");
3807     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3808     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3809     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3810     ok(sz == 3, "Expected 3, got %d\n", sz);
3811
3812     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3813                          (const BYTE *)&val, sizeof(DWORD));
3814     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3815
3816     /* Version type is REG_DWORD */
3817     sz = MAX_PATH;
3818     lstrcpyA(buf, "apple");
3819     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3821     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3822     ok(sz == 2, "Expected 2, got %d\n", sz);
3823
3824     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3825     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3826
3827     /* ProductIcon value exists */
3828     sz = MAX_PATH;
3829     lstrcpyA(buf, "apple");
3830     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3831     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3832     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3833     ok(sz == 0, "Expected 0, got %d\n", sz);
3834
3835     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3836                          (const BYTE *)&val, sizeof(DWORD));
3837     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3838
3839     /* ProductIcon type is REG_DWORD */
3840     sz = MAX_PATH;
3841     lstrcpyA(buf, "apple");
3842     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3843     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3844     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3845     ok(sz == 0, "Expected 0, got %d\n", sz);
3846
3847     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3848     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3849
3850     /* ProductIcon value exists */
3851     sz = MAX_PATH;
3852     lstrcpyA(buf, "apple");
3853     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3854     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3855     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3856     ok(sz == 3, "Expected 3, got %d\n", sz);
3857
3858     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3859                          (const BYTE *)&val, sizeof(DWORD));
3860     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3861
3862     /* ProductIcon type is REG_DWORD */
3863     sz = MAX_PATH;
3864     lstrcpyA(buf, "apple");
3865     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3866     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3867     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3868     ok(sz == 2, "Expected 2, got %d\n", sz);
3869
3870     /* SourceList key does not exist */
3871     sz = MAX_PATH;
3872     lstrcpyA(buf, "apple");
3873     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3874     ok(r == ERROR_UNKNOWN_PRODUCT,
3875        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3876     ok(!lstrcmpA(buf, "apple"),
3877        "Expected buf to be unchanged, got \"%s\"\n", buf);
3878     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
3879
3880     res = RegCreateKeyA(prodkey, "SourceList", &source);
3881     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3882
3883     /* SourceList key exists, but PackageName val does not exist */
3884     sz = MAX_PATH;
3885     lstrcpyA(buf, "apple");
3886     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3887     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3888     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3889     ok(sz == 0, "Expected 0, got %d\n", sz);
3890
3891     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3892     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3893
3894     /* PackageName val exists */
3895     sz = MAX_PATH;
3896     lstrcpyA(buf, "apple");
3897     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3898     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3899     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
3900     ok(sz == 8, "Expected 8, got %d\n", sz);
3901
3902     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
3903                          (const BYTE *)&val, sizeof(DWORD));
3904     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3905
3906     /* PackageName type is REG_DWORD */
3907     sz = MAX_PATH;
3908     lstrcpyA(buf, "apple");
3909     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3910     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3911     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3912     ok(sz == 2, "Expected 2, got %d\n", sz);
3913
3914     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3915     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3916
3917     /* Authorized value exists */
3918     sz = MAX_PATH;
3919     lstrcpyA(buf, "apple");
3920     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3921     if (r != ERROR_UNKNOWN_PROPERTY)
3922     {
3923         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3924         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3925         ok(sz == 0, "Expected 0, got %d\n", sz);
3926     }
3927
3928     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
3929                          (const BYTE *)&val, sizeof(DWORD));
3930     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3931
3932     /* AuthorizedLUAApp type is REG_DWORD */
3933     sz = MAX_PATH;
3934     lstrcpyA(buf, "apple");
3935     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3936     if (r != ERROR_UNKNOWN_PROPERTY)
3937     {
3938         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3939         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3940         ok(sz == 0, "Expected 0, got %d\n", sz);
3941     }
3942
3943     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3945
3946     /* Authorized value exists */
3947     sz = MAX_PATH;
3948     lstrcpyA(buf, "apple");
3949     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3950     if (r != ERROR_UNKNOWN_PROPERTY)
3951     {
3952         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3953         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
3954         ok(sz == 4, "Expected 4, got %d\n", sz);
3955     }
3956
3957     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
3958                          (const BYTE *)&val, sizeof(DWORD));
3959     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3960
3961     /* AuthorizedLUAApp type is REG_DWORD */
3962     sz = MAX_PATH;
3963     lstrcpyA(buf, "apple");
3964     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3965     if (r != ERROR_UNKNOWN_PROPERTY)
3966     {
3967         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3968         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3969         ok(sz == 2, "Expected 2, got %d\n", sz);
3970     }
3971
3972     RegDeleteValueA(propkey, "HelpLink");
3973     RegDeleteValueA(propkey, "DisplayName");
3974     RegDeleteValueA(propkey, "DisplayVersion");
3975     RegDeleteValueA(propkey, "HelpTelephone");
3976     RegDeleteValueA(propkey, "InstallLocation");
3977     RegDeleteValueA(propkey, "InstallSource");
3978     RegDeleteValueA(propkey, "InstallDate");
3979     RegDeleteValueA(propkey, "Publisher");
3980     RegDeleteValueA(propkey, "LocalPackage");
3981     RegDeleteValueA(propkey, "UrlInfoAbout");
3982     RegDeleteValueA(propkey, "UrlUpdateInfo");
3983     RegDeleteValueA(propkey, "VersionMinor");
3984     RegDeleteValueA(propkey, "VersionMajor");
3985     RegDeleteValueA(propkey, "ProductID");
3986     RegDeleteValueA(propkey, "RegCompany");
3987     RegDeleteValueA(propkey, "RegOwner");
3988     RegDeleteValueA(propkey, "InstanceType");
3989     RegDeleteValueA(propkey, "Transforms");
3990     RegDeleteValueA(propkey, "Language");
3991     RegDeleteValueA(propkey, "ProductName");
3992     RegDeleteValueA(propkey, "Assignment");
3993     RegDeleteValueA(propkey, "PackageCode");
3994     RegDeleteValueA(propkey, "Version");
3995     RegDeleteValueA(propkey, "ProductIcon");
3996     RegDeleteValueA(propkey, "AuthorizedLUAApp");
3997     RegDeleteKeyA(propkey, "");
3998     RegDeleteKeyA(localkey, "");
3999     RegDeleteValueA(prodkey, "InstanceType");
4000     RegDeleteValueA(prodkey, "Transforms");
4001     RegDeleteValueA(prodkey, "Language");
4002     RegDeleteValueA(prodkey, "ProductName");
4003     RegDeleteValueA(prodkey, "Assignment");
4004     RegDeleteValueA(prodkey, "PackageCode");
4005     RegDeleteValueA(prodkey, "Version");
4006     RegDeleteValueA(prodkey, "ProductIcon");
4007     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4008     RegDeleteValueA(source, "PackageName");
4009     RegDeleteKeyA(source, "");
4010     RegDeleteKeyA(prodkey, "");
4011     RegCloseKey(propkey);
4012     RegCloseKey(localkey);
4013     RegCloseKey(source);
4014     RegCloseKey(prodkey);
4015     LocalFree(usersid);
4016 }
4017
4018 static void test_MsiGetProductInfoEx(void)
4019 {
4020     UINT r;
4021     LONG res;
4022     HKEY propkey, userkey;
4023     HKEY prodkey, localkey;
4024     CHAR prodcode[MAX_PATH];
4025     CHAR prod_squashed[MAX_PATH];
4026     CHAR packcode[MAX_PATH];
4027     CHAR pack_squashed[MAX_PATH];
4028     CHAR buf[MAX_PATH];
4029     CHAR keypath[MAX_PATH];
4030     LPSTR usersid;
4031     DWORD sz;
4032
4033     if (!pMsiGetProductInfoExA)
4034     {
4035         win_skip("MsiGetProductInfoExA is not available\n");
4036         return;
4037     }
4038
4039     create_test_guid(prodcode, prod_squashed);
4040     create_test_guid(packcode, pack_squashed);
4041     get_user_sid(&usersid);
4042
4043     /* NULL szProductCode */
4044     sz = MAX_PATH;
4045     lstrcpyA(buf, "apple");
4046     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4047                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4048     ok(r == ERROR_INVALID_PARAMETER,
4049        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4050     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4051     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4052
4053     /* empty szProductCode */
4054     sz = MAX_PATH;
4055     lstrcpyA(buf, "apple");
4056     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4057                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4058     ok(r == ERROR_INVALID_PARAMETER,
4059        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4060     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4061     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4062
4063     /* garbage szProductCode */
4064     sz = MAX_PATH;
4065     lstrcpyA(buf, "apple");
4066     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
4067                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4068     ok(r == ERROR_INVALID_PARAMETER,
4069        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4070     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4071     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4072
4073     /* guid without brackets */
4074     sz = MAX_PATH;
4075     lstrcpyA(buf, "apple");
4076     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
4077                               MSIINSTALLCONTEXT_USERUNMANAGED,
4078                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4079     ok(r == ERROR_INVALID_PARAMETER,
4080        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4081     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4082     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4083
4084     /* guid with brackets */
4085     sz = MAX_PATH;
4086     lstrcpyA(buf, "apple");
4087     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
4088                               MSIINSTALLCONTEXT_USERUNMANAGED,
4089                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4090     ok(r == ERROR_UNKNOWN_PRODUCT,
4091        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4092     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4093     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4094
4095     /* szValue is non-NULL while pcchValue is NULL */
4096     lstrcpyA(buf, "apple");
4097     r = pMsiGetProductInfoExA(prodcode, usersid,
4098                               MSIINSTALLCONTEXT_USERUNMANAGED,
4099                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
4100     ok(r == ERROR_INVALID_PARAMETER,
4101        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4102     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4103
4104     /* dwContext is out of range */
4105     sz = MAX_PATH;
4106     lstrcpyA(buf, "apple");
4107     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
4108                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4109     ok(r == ERROR_INVALID_PARAMETER,
4110        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4111     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4112     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4113
4114     /* szProperty is NULL */
4115     sz = MAX_PATH;
4116     lstrcpyA(buf, "apple");
4117     r = pMsiGetProductInfoExA(prodcode, usersid,
4118                               MSIINSTALLCONTEXT_USERUNMANAGED,
4119                               NULL, buf, &sz);
4120     ok(r == ERROR_INVALID_PARAMETER,
4121        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4122     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4123     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4124
4125     /* szProperty is empty */
4126     sz = MAX_PATH;
4127     lstrcpyA(buf, "apple");
4128     r = pMsiGetProductInfoExA(prodcode, usersid,
4129                               MSIINSTALLCONTEXT_USERUNMANAGED,
4130                               "", buf, &sz);
4131     ok(r == ERROR_INVALID_PARAMETER,
4132        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4133     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4134     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4135
4136     /* szProperty is not a valid property */
4137     sz = MAX_PATH;
4138     lstrcpyA(buf, "apple");
4139     r = pMsiGetProductInfoExA(prodcode, usersid,
4140                               MSIINSTALLCONTEXT_USERUNMANAGED,
4141                               "notvalid", buf, &sz);
4142     ok(r == ERROR_UNKNOWN_PRODUCT,
4143        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4144     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4145     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4146
4147     /* same length as guid, but random */
4148     sz = MAX_PATH;
4149     lstrcpyA(buf, "apple");
4150     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
4151                               MSIINSTALLCONTEXT_USERUNMANAGED,
4152                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4153     ok(r == ERROR_INVALID_PARAMETER,
4154        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4155     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4156     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4157
4158     /* MSIINSTALLCONTEXT_USERUNMANAGED */
4159
4160     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4161     lstrcatA(keypath, usersid);
4162     lstrcatA(keypath, "\\Products\\");
4163     lstrcatA(keypath, prod_squashed);
4164
4165     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4166     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4167
4168     /* local user product key exists */
4169     sz = MAX_PATH;
4170     lstrcpyA(buf, "apple");
4171     r = pMsiGetProductInfoExA(prodcode, usersid,
4172                               MSIINSTALLCONTEXT_USERUNMANAGED,
4173                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4174     ok(r == ERROR_UNKNOWN_PRODUCT,
4175        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4176     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4177     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4178
4179     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4180     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4181
4182     /* InstallProperties key exists */
4183     sz = MAX_PATH;
4184     lstrcpyA(buf, "apple");
4185     r = pMsiGetProductInfoExA(prodcode, usersid,
4186                               MSIINSTALLCONTEXT_USERUNMANAGED,
4187                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4188     ok(r == ERROR_UNKNOWN_PRODUCT,
4189        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4190     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4191     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4192
4193     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4194     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4195
4196     /* LocalPackage value exists */
4197     sz = MAX_PATH;
4198     lstrcpyA(buf, "apple");
4199     r = pMsiGetProductInfoExA(prodcode, usersid,
4200                               MSIINSTALLCONTEXT_USERUNMANAGED,
4201                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4202     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4203     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4204     ok(sz == 1, "Expected 1, got %d\n", sz);
4205
4206     RegDeleteValueA(propkey, "LocalPackage");
4207
4208     /* LocalPackage value must exist */
4209     sz = MAX_PATH;
4210     lstrcpyA(buf, "apple");
4211     r = pMsiGetProductInfoExA(prodcode, usersid,
4212                               MSIINSTALLCONTEXT_USERUNMANAGED,
4213                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4214     ok(r == ERROR_UNKNOWN_PRODUCT,
4215        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4216     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4217     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4218
4219     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4220     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4221
4222     /* LocalPackage exists, but HelpLink does not exist */
4223     sz = MAX_PATH;
4224     lstrcpyA(buf, "apple");
4225     r = pMsiGetProductInfoExA(prodcode, usersid,
4226                               MSIINSTALLCONTEXT_USERUNMANAGED,
4227                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4229     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4230     ok(sz == 0, "Expected 0, got %d\n", sz);
4231
4232     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4233     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4234
4235     /* HelpLink value exists */
4236     sz = MAX_PATH;
4237     lstrcpyA(buf, "apple");
4238     r = pMsiGetProductInfoExA(prodcode, usersid,
4239                               MSIINSTALLCONTEXT_USERUNMANAGED,
4240                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4241     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4242     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4243     ok(sz == 4, "Expected 4, got %d\n", sz);
4244
4245     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4246     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4247
4248     /* HelpTelephone value exists */
4249     sz = MAX_PATH;
4250     lstrcpyA(buf, "apple");
4251     r = pMsiGetProductInfoExA(prodcode, usersid,
4252                               MSIINSTALLCONTEXT_USERUNMANAGED,
4253                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4254     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4255     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4256     ok(sz == 5, "Expected 5, got %d\n", sz);
4257
4258     /* szValue and pcchValue are NULL */
4259     r = pMsiGetProductInfoExA(prodcode, usersid,
4260                               MSIINSTALLCONTEXT_USERUNMANAGED,
4261                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4262     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4263
4264     /* pcchValue is exactly 5 */
4265     sz = 5;
4266     lstrcpyA(buf, "apple");
4267     r = pMsiGetProductInfoExA(prodcode, usersid,
4268                               MSIINSTALLCONTEXT_USERUNMANAGED,
4269                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4270     ok(r == ERROR_MORE_DATA,
4271        "Expected ERROR_MORE_DATA, got %d\n", r);
4272     ok(sz == 10, "Expected 10, got %d\n", sz);
4273
4274     /* szValue is NULL, pcchValue is exactly 5 */
4275     sz = 5;
4276     r = pMsiGetProductInfoExA(prodcode, usersid,
4277                               MSIINSTALLCONTEXT_USERUNMANAGED,
4278                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4280     ok(sz == 10, "Expected 10, got %d\n", sz);
4281
4282     /* szValue is NULL, pcchValue is MAX_PATH */
4283     sz = MAX_PATH;
4284     r = pMsiGetProductInfoExA(prodcode, usersid,
4285                               MSIINSTALLCONTEXT_USERUNMANAGED,
4286                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4287     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4288     ok(sz == 10, "Expected 10, got %d\n", sz);
4289
4290     /* pcchValue is exactly 0 */
4291     sz = 0;
4292     lstrcpyA(buf, "apple");
4293     r = pMsiGetProductInfoExA(prodcode, usersid,
4294                               MSIINSTALLCONTEXT_USERUNMANAGED,
4295                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4296     ok(r == ERROR_MORE_DATA,
4297        "Expected ERROR_MORE_DATA, got %d\n", r);
4298     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4299     ok(sz == 10, "Expected 10, got %d\n", sz);
4300
4301     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4303
4304     /* szProperty is not a valid property */
4305     sz = MAX_PATH;
4306     lstrcpyA(buf, "apple");
4307     r = pMsiGetProductInfoExA(prodcode, usersid,
4308                               MSIINSTALLCONTEXT_USERUNMANAGED,
4309                               "notvalid", buf, &sz);
4310     ok(r == ERROR_UNKNOWN_PROPERTY,
4311        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4312     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4313     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4314
4315     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4316     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4317
4318     /* InstallDate value exists */
4319     sz = MAX_PATH;
4320     lstrcpyA(buf, "apple");
4321     r = pMsiGetProductInfoExA(prodcode, usersid,
4322                               MSIINSTALLCONTEXT_USERUNMANAGED,
4323                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4324     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4325     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4326     ok(sz == 4, "Expected 4, got %d\n", sz);
4327
4328     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4330
4331     /* DisplayName value exists */
4332     sz = MAX_PATH;
4333     lstrcpyA(buf, "apple");
4334     r = pMsiGetProductInfoExA(prodcode, usersid,
4335                               MSIINSTALLCONTEXT_USERUNMANAGED,
4336                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4338     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4339     ok(sz == 4, "Expected 4, got %d\n", sz);
4340
4341     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4343
4344     /* InstallLocation value exists */
4345     sz = MAX_PATH;
4346     lstrcpyA(buf, "apple");
4347     r = pMsiGetProductInfoExA(prodcode, usersid,
4348                               MSIINSTALLCONTEXT_USERUNMANAGED,
4349                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4350     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4351     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4352     ok(sz == 3, "Expected 3, got %d\n", sz);
4353
4354     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4356
4357     /* InstallSource value exists */
4358     sz = MAX_PATH;
4359     lstrcpyA(buf, "apple");
4360     r = pMsiGetProductInfoExA(prodcode, usersid,
4361                               MSIINSTALLCONTEXT_USERUNMANAGED,
4362                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4363     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4364     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4365     ok(sz == 6, "Expected 6, got %d\n", sz);
4366
4367     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4369
4370     /* LocalPackage value exists */
4371     sz = MAX_PATH;
4372     lstrcpyA(buf, "apple");
4373     r = pMsiGetProductInfoExA(prodcode, usersid,
4374                               MSIINSTALLCONTEXT_USERUNMANAGED,
4375                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4376     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4377     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4378     ok(sz == 5, "Expected 5, got %d\n", sz);
4379
4380     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4381     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4382
4383     /* Publisher value exists */
4384     sz = MAX_PATH;
4385     lstrcpyA(buf, "apple");
4386     r = pMsiGetProductInfoExA(prodcode, usersid,
4387                               MSIINSTALLCONTEXT_USERUNMANAGED,
4388                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4389     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4390     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4391     ok(sz == 3, "Expected 3, got %d\n", sz);
4392
4393     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4395
4396     /* URLInfoAbout value exists */
4397     sz = MAX_PATH;
4398     lstrcpyA(buf, "apple");
4399     r = pMsiGetProductInfoExA(prodcode, usersid,
4400                               MSIINSTALLCONTEXT_USERUNMANAGED,
4401                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4402     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4403     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4404     ok(sz == 5, "Expected 5, got %d\n", sz);
4405
4406     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4407     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4408
4409     /* URLUpdateInfo value exists */
4410     sz = MAX_PATH;
4411     lstrcpyA(buf, "apple");
4412     r = pMsiGetProductInfoExA(prodcode, usersid,
4413                               MSIINSTALLCONTEXT_USERUNMANAGED,
4414                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4415     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4416     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4417     ok(sz == 6, "Expected 6, got %d\n", sz);
4418
4419     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4420     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4421
4422     /* VersionMinor value exists */
4423     sz = MAX_PATH;
4424     lstrcpyA(buf, "apple");
4425     r = pMsiGetProductInfoExA(prodcode, usersid,
4426                               MSIINSTALLCONTEXT_USERUNMANAGED,
4427                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4428     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4429     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4430     ok(sz == 1, "Expected 1, got %d\n", sz);
4431
4432     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4434
4435     /* VersionMajor value exists */
4436     sz = MAX_PATH;
4437     lstrcpyA(buf, "apple");
4438     r = pMsiGetProductInfoExA(prodcode, usersid,
4439                               MSIINSTALLCONTEXT_USERUNMANAGED,
4440                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4442     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4443     ok(sz == 1, "Expected 1, got %d\n", sz);
4444
4445     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4447
4448     /* DisplayVersion value exists */
4449     sz = MAX_PATH;
4450     lstrcpyA(buf, "apple");
4451     r = pMsiGetProductInfoExA(prodcode, usersid,
4452                               MSIINSTALLCONTEXT_USERUNMANAGED,
4453                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4455     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4456     ok(sz == 5, "Expected 5, got %d\n", sz);
4457
4458     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4460
4461     /* ProductID value exists */
4462     sz = MAX_PATH;
4463     lstrcpyA(buf, "apple");
4464     r = pMsiGetProductInfoExA(prodcode, usersid,
4465                               MSIINSTALLCONTEXT_USERUNMANAGED,
4466                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4467     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4468     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4469     ok(sz == 2, "Expected 2, got %d\n", sz);
4470
4471     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4472     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4473
4474     /* RegCompany value exists */
4475     sz = MAX_PATH;
4476     lstrcpyA(buf, "apple");
4477     r = pMsiGetProductInfoExA(prodcode, usersid,
4478                               MSIINSTALLCONTEXT_USERUNMANAGED,
4479                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4480     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4481     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4482     ok(sz == 4, "Expected 4, got %d\n", sz);
4483
4484     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4485     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4486
4487     /* RegOwner value exists */
4488     sz = MAX_PATH;
4489     lstrcpyA(buf, "apple");
4490     r = pMsiGetProductInfoExA(prodcode, usersid,
4491                               MSIINSTALLCONTEXT_USERUNMANAGED,
4492                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4494     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4495     ok(sz == 5, "Expected 5, got %d\n", sz);
4496
4497     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4499
4500     /* Transforms value exists */
4501     sz = MAX_PATH;
4502     lstrcpyA(buf, "apple");
4503     r = pMsiGetProductInfoExA(prodcode, usersid,
4504                               MSIINSTALLCONTEXT_USERUNMANAGED,
4505                               INSTALLPROPERTY_TRANSFORMS, 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     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4513
4514     /* Language value exists */
4515     sz = MAX_PATH;
4516     lstrcpyA(buf, "apple");
4517     r = pMsiGetProductInfoExA(prodcode, usersid,
4518                               MSIINSTALLCONTEXT_USERUNMANAGED,
4519                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4520     ok(r == ERROR_UNKNOWN_PRODUCT,
4521        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4522     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4523     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4524
4525     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4527
4528     /* ProductName value exists */
4529     sz = MAX_PATH;
4530     lstrcpyA(buf, "apple");
4531     r = pMsiGetProductInfoExA(prodcode, usersid,
4532                               MSIINSTALLCONTEXT_USERUNMANAGED,
4533                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4534     ok(r == ERROR_UNKNOWN_PRODUCT,
4535        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4536     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4537     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4538
4539     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4541
4542     /* FIXME */
4543
4544     /* AssignmentType value exists */
4545     sz = MAX_PATH;
4546     lstrcpyA(buf, "apple");
4547     r = pMsiGetProductInfoExA(prodcode, usersid,
4548                               MSIINSTALLCONTEXT_USERUNMANAGED,
4549                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4550     ok(r == ERROR_UNKNOWN_PRODUCT,
4551        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4552     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4553     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4554
4555     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4557
4558     /* PackageCode value exists */
4559     sz = MAX_PATH;
4560     lstrcpyA(buf, "apple");
4561     r = pMsiGetProductInfoExA(prodcode, usersid,
4562                               MSIINSTALLCONTEXT_USERUNMANAGED,
4563                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4564     ok(r == ERROR_UNKNOWN_PRODUCT,
4565        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4566     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4567     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4568
4569     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4570     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4571
4572     /* Version value exists */
4573     sz = MAX_PATH;
4574     lstrcpyA(buf, "apple");
4575     r = pMsiGetProductInfoExA(prodcode, usersid,
4576                               MSIINSTALLCONTEXT_USERUNMANAGED,
4577                               INSTALLPROPERTY_VERSION, buf, &sz);
4578     ok(r == ERROR_UNKNOWN_PRODUCT,
4579        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4580     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4581     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4582
4583     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4584     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4585
4586     /* ProductIcon value exists */
4587     sz = MAX_PATH;
4588     lstrcpyA(buf, "apple");
4589     r = pMsiGetProductInfoExA(prodcode, usersid,
4590                               MSIINSTALLCONTEXT_USERUNMANAGED,
4591                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4592     ok(r == ERROR_UNKNOWN_PRODUCT,
4593        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4594     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4595     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4596
4597     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4598     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4599
4600     /* PackageName value exists */
4601     sz = MAX_PATH;
4602     lstrcpyA(buf, "apple");
4603     r = pMsiGetProductInfoExA(prodcode, usersid,
4604                               MSIINSTALLCONTEXT_USERUNMANAGED,
4605                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4606     ok(r == ERROR_UNKNOWN_PRODUCT,
4607        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4608     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4609     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4610
4611     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4612     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4613
4614     /* AuthorizedLUAApp value exists */
4615     sz = MAX_PATH;
4616     lstrcpyA(buf, "apple");
4617     r = pMsiGetProductInfoExA(prodcode, usersid,
4618                               MSIINSTALLCONTEXT_USERUNMANAGED,
4619                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4620     ok(r == ERROR_UNKNOWN_PRODUCT,
4621        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4622     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4623     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4624
4625     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4626     RegDeleteValueA(propkey, "PackageName");
4627     RegDeleteValueA(propkey, "ProductIcon");
4628     RegDeleteValueA(propkey, "Version");
4629     RegDeleteValueA(propkey, "PackageCode");
4630     RegDeleteValueA(propkey, "AssignmentType");
4631     RegDeleteValueA(propkey, "ProductName");
4632     RegDeleteValueA(propkey, "Language");
4633     RegDeleteValueA(propkey, "Transforms");
4634     RegDeleteValueA(propkey, "RegOwner");
4635     RegDeleteValueA(propkey, "RegCompany");
4636     RegDeleteValueA(propkey, "ProductID");
4637     RegDeleteValueA(propkey, "DisplayVersion");
4638     RegDeleteValueA(propkey, "VersionMajor");
4639     RegDeleteValueA(propkey, "VersionMinor");
4640     RegDeleteValueA(propkey, "URLUpdateInfo");
4641     RegDeleteValueA(propkey, "URLInfoAbout");
4642     RegDeleteValueA(propkey, "Publisher");
4643     RegDeleteValueA(propkey, "LocalPackage");
4644     RegDeleteValueA(propkey, "InstallSource");
4645     RegDeleteValueA(propkey, "InstallLocation");
4646     RegDeleteValueA(propkey, "DisplayName");
4647     RegDeleteValueA(propkey, "InstallDate");
4648     RegDeleteValueA(propkey, "HelpTelephone");
4649     RegDeleteValueA(propkey, "HelpLink");
4650     RegDeleteValueA(propkey, "LocalPackage");
4651     RegDeleteKeyA(propkey, "");
4652     RegCloseKey(propkey);
4653     RegDeleteKeyA(localkey, "");
4654     RegCloseKey(localkey);
4655
4656     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4657     lstrcatA(keypath, usersid);
4658     lstrcatA(keypath, "\\Installer\\Products\\");
4659     lstrcatA(keypath, prod_squashed);
4660
4661     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
4662     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4663
4664     /* user product key exists */
4665     sz = MAX_PATH;
4666     lstrcpyA(buf, "apple");
4667     r = pMsiGetProductInfoExA(prodcode, usersid,
4668                               MSIINSTALLCONTEXT_USERUNMANAGED,
4669                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4670     ok(r == ERROR_UNKNOWN_PRODUCT,
4671        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4672     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4673     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4674
4675     RegDeleteKeyA(userkey, "");
4676     RegCloseKey(userkey);
4677
4678     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4679     lstrcatA(keypath, prod_squashed);
4680
4681     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4683
4684     sz = MAX_PATH;
4685     lstrcpyA(buf, "apple");
4686     r = pMsiGetProductInfoExA(prodcode, usersid,
4687                               MSIINSTALLCONTEXT_USERUNMANAGED,
4688                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4689     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4690     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4691     ok(sz == 1, "Expected 1, got %d\n", sz);
4692
4693     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4694     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4695
4696     /* HelpLink value exists */
4697     sz = MAX_PATH;
4698     lstrcpyA(buf, "apple");
4699     r = pMsiGetProductInfoExA(prodcode, usersid,
4700                               MSIINSTALLCONTEXT_USERUNMANAGED,
4701                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4702     ok(r == ERROR_UNKNOWN_PROPERTY,
4703        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4704     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4705     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4706
4707     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4708     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4709
4710     /* HelpTelephone value exists */
4711     sz = MAX_PATH;
4712     lstrcpyA(buf, "apple");
4713     r = pMsiGetProductInfoExA(prodcode, usersid,
4714                               MSIINSTALLCONTEXT_USERUNMANAGED,
4715                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4716     ok(r == ERROR_UNKNOWN_PROPERTY,
4717        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4718     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4719     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4720
4721     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4723
4724     /* InstallDate value exists */
4725     sz = MAX_PATH;
4726     lstrcpyA(buf, "apple");
4727     r = pMsiGetProductInfoExA(prodcode, usersid,
4728                               MSIINSTALLCONTEXT_USERUNMANAGED,
4729                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4730     ok(r == ERROR_UNKNOWN_PROPERTY,
4731        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4732     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4733     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4734
4735     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4736     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4737
4738     /* DisplayName value exists */
4739     sz = MAX_PATH;
4740     lstrcpyA(buf, "apple");
4741     r = pMsiGetProductInfoExA(prodcode, usersid,
4742                               MSIINSTALLCONTEXT_USERUNMANAGED,
4743                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4744     ok(r == ERROR_UNKNOWN_PROPERTY,
4745        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4746     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4747     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4748
4749     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4750     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4751
4752     /* InstallLocation value exists */
4753     sz = MAX_PATH;
4754     lstrcpyA(buf, "apple");
4755     r = pMsiGetProductInfoExA(prodcode, usersid,
4756                               MSIINSTALLCONTEXT_USERUNMANAGED,
4757                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4758     ok(r == ERROR_UNKNOWN_PROPERTY,
4759        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4760     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4761     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4762
4763     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4764     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4765
4766     /* InstallSource value exists */
4767     sz = MAX_PATH;
4768     lstrcpyA(buf, "apple");
4769     r = pMsiGetProductInfoExA(prodcode, usersid,
4770                               MSIINSTALLCONTEXT_USERUNMANAGED,
4771                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4772     ok(r == ERROR_UNKNOWN_PROPERTY,
4773        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4774     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4775     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4776
4777     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4779
4780     /* LocalPackage value exists */
4781     sz = MAX_PATH;
4782     lstrcpyA(buf, "apple");
4783     r = pMsiGetProductInfoExA(prodcode, usersid,
4784                               MSIINSTALLCONTEXT_USERUNMANAGED,
4785                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4786     ok(r == ERROR_UNKNOWN_PROPERTY,
4787        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4788     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4789     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4790
4791     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4792     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4793
4794     /* Publisher value exists */
4795     sz = MAX_PATH;
4796     lstrcpyA(buf, "apple");
4797     r = pMsiGetProductInfoExA(prodcode, usersid,
4798                               MSIINSTALLCONTEXT_USERUNMANAGED,
4799                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4800     ok(r == ERROR_UNKNOWN_PROPERTY,
4801        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4802     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4803     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4804
4805     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4806     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4807
4808     /* URLInfoAbout value exists */
4809     sz = MAX_PATH;
4810     lstrcpyA(buf, "apple");
4811     r = pMsiGetProductInfoExA(prodcode, usersid,
4812                               MSIINSTALLCONTEXT_USERUNMANAGED,
4813                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4814     ok(r == ERROR_UNKNOWN_PROPERTY,
4815        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4816     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4817     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4818
4819     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4820     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4821
4822     /* URLUpdateInfo value exists */
4823     sz = MAX_PATH;
4824     lstrcpyA(buf, "apple");
4825     r = pMsiGetProductInfoExA(prodcode, usersid,
4826                               MSIINSTALLCONTEXT_USERUNMANAGED,
4827                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4828     ok(r == ERROR_UNKNOWN_PROPERTY,
4829        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4830     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4831     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4832
4833     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4834     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4835
4836     /* VersionMinor value exists */
4837     sz = MAX_PATH;
4838     lstrcpyA(buf, "apple");
4839     r = pMsiGetProductInfoExA(prodcode, usersid,
4840                               MSIINSTALLCONTEXT_USERUNMANAGED,
4841                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4842     ok(r == ERROR_UNKNOWN_PROPERTY,
4843        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4844     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4845     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4846
4847     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4848     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4849
4850     /* VersionMajor value exists */
4851     sz = MAX_PATH;
4852     lstrcpyA(buf, "apple");
4853     r = pMsiGetProductInfoExA(prodcode, usersid,
4854                               MSIINSTALLCONTEXT_USERUNMANAGED,
4855                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4856     ok(r == ERROR_UNKNOWN_PROPERTY,
4857        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4858     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4859     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4860
4861     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4863
4864     /* DisplayVersion value exists */
4865     sz = MAX_PATH;
4866     lstrcpyA(buf, "apple");
4867     r = pMsiGetProductInfoExA(prodcode, usersid,
4868                               MSIINSTALLCONTEXT_USERUNMANAGED,
4869                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4870     ok(r == ERROR_UNKNOWN_PROPERTY,
4871        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4872     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4873     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4874
4875     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4876     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4877
4878     /* ProductID value exists */
4879     sz = MAX_PATH;
4880     lstrcpyA(buf, "apple");
4881     r = pMsiGetProductInfoExA(prodcode, usersid,
4882                               MSIINSTALLCONTEXT_USERUNMANAGED,
4883                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4884     ok(r == ERROR_UNKNOWN_PROPERTY,
4885        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4886     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4887     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4888
4889     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4891
4892     /* RegCompany value exists */
4893     sz = MAX_PATH;
4894     lstrcpyA(buf, "apple");
4895     r = pMsiGetProductInfoExA(prodcode, usersid,
4896                               MSIINSTALLCONTEXT_USERUNMANAGED,
4897                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4898     ok(r == ERROR_UNKNOWN_PROPERTY,
4899        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4900     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4901     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4902
4903     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4904     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4905
4906     /* RegOwner value exists */
4907     sz = MAX_PATH;
4908     lstrcpyA(buf, "apple");
4909     r = pMsiGetProductInfoExA(prodcode, usersid,
4910                               MSIINSTALLCONTEXT_USERUNMANAGED,
4911                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4912     ok(r == ERROR_UNKNOWN_PROPERTY,
4913        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4914     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4915     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4916
4917     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4918     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4919
4920     /* Transforms value exists */
4921     sz = MAX_PATH;
4922     lstrcpyA(buf, "apple");
4923     r = pMsiGetProductInfoExA(prodcode, usersid,
4924                               MSIINSTALLCONTEXT_USERUNMANAGED,
4925                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4926     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4927     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
4928     ok(sz == 5, "Expected 5, got %d\n", sz);
4929
4930     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4931     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4932
4933     /* Language value exists */
4934     sz = MAX_PATH;
4935     lstrcpyA(buf, "apple");
4936     r = pMsiGetProductInfoExA(prodcode, usersid,
4937                               MSIINSTALLCONTEXT_USERUNMANAGED,
4938                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4939     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4940     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4941     ok(sz == 4, "Expected 4, got %d\n", sz);
4942
4943     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4945
4946     /* ProductName value exists */
4947     sz = MAX_PATH;
4948     lstrcpyA(buf, "apple");
4949     r = pMsiGetProductInfoExA(prodcode, usersid,
4950                               MSIINSTALLCONTEXT_USERUNMANAGED,
4951                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4953     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4954     ok(sz == 4, "Expected 4, got %d\n", sz);
4955
4956     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4958
4959     /* FIXME */
4960
4961     /* AssignmentType value exists */
4962     sz = MAX_PATH;
4963     lstrcpyA(buf, "apple");
4964     r = pMsiGetProductInfoExA(prodcode, usersid,
4965                               MSIINSTALLCONTEXT_USERUNMANAGED,
4966                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4967     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4968     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4969     ok(sz == 0, "Expected 0, got %d\n", sz);
4970
4971     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4972     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4973
4974     /* FIXME */
4975
4976     /* PackageCode value exists */
4977     sz = MAX_PATH;
4978     lstrcpyA(buf, "apple");
4979     r = pMsiGetProductInfoExA(prodcode, usersid,
4980                               MSIINSTALLCONTEXT_USERUNMANAGED,
4981                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4982     todo_wine
4983     {
4984         ok(r == ERROR_BAD_CONFIGURATION,
4985            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4986         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4987         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4988     }
4989
4990     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4992
4993     /* Version value exists */
4994     sz = MAX_PATH;
4995     lstrcpyA(buf, "apple");
4996     r = pMsiGetProductInfoExA(prodcode, usersid,
4997                               MSIINSTALLCONTEXT_USERUNMANAGED,
4998                               INSTALLPROPERTY_VERSION, buf, &sz);
4999     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5000     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5001     ok(sz == 3, "Expected 3, got %d\n", sz);
5002
5003     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5005
5006     /* ProductIcon value exists */
5007     sz = MAX_PATH;
5008     lstrcpyA(buf, "apple");
5009     r = pMsiGetProductInfoExA(prodcode, usersid,
5010                               MSIINSTALLCONTEXT_USERUNMANAGED,
5011                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5012     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5013     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5014     ok(sz == 4, "Expected 4, got %d\n", sz);
5015
5016     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5017     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5018
5019     /* PackageName value exists */
5020     sz = MAX_PATH;
5021     lstrcpyA(buf, "apple");
5022     r = pMsiGetProductInfoExA(prodcode, usersid,
5023                               MSIINSTALLCONTEXT_USERUNMANAGED,
5024                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5025     todo_wine
5026     {
5027         ok(r == ERROR_UNKNOWN_PRODUCT,
5028            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5029         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5030         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5031     }
5032
5033     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5034     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5035
5036     /* AuthorizedLUAApp value exists */
5037     sz = MAX_PATH;
5038     lstrcpyA(buf, "apple");
5039     r = pMsiGetProductInfoExA(prodcode, usersid,
5040                               MSIINSTALLCONTEXT_USERUNMANAGED,
5041                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5042     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5043     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5044     ok(sz == 4, "Expected 4, got %d\n", sz);
5045
5046     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
5047     RegDeleteValueA(prodkey, "PackageName");
5048     RegDeleteValueA(prodkey, "ProductIcon");
5049     RegDeleteValueA(prodkey, "Version");
5050     RegDeleteValueA(prodkey, "PackageCode");
5051     RegDeleteValueA(prodkey, "AssignmentType");
5052     RegDeleteValueA(prodkey, "ProductName");
5053     RegDeleteValueA(prodkey, "Language");
5054     RegDeleteValueA(prodkey, "Transforms");
5055     RegDeleteValueA(prodkey, "RegOwner");
5056     RegDeleteValueA(prodkey, "RegCompany");
5057     RegDeleteValueA(prodkey, "ProductID");
5058     RegDeleteValueA(prodkey, "DisplayVersion");
5059     RegDeleteValueA(prodkey, "VersionMajor");
5060     RegDeleteValueA(prodkey, "VersionMinor");
5061     RegDeleteValueA(prodkey, "URLUpdateInfo");
5062     RegDeleteValueA(prodkey, "URLInfoAbout");
5063     RegDeleteValueA(prodkey, "Publisher");
5064     RegDeleteValueA(prodkey, "LocalPackage");
5065     RegDeleteValueA(prodkey, "InstallSource");
5066     RegDeleteValueA(prodkey, "InstallLocation");
5067     RegDeleteValueA(prodkey, "DisplayName");
5068     RegDeleteValueA(prodkey, "InstallDate");
5069     RegDeleteValueA(prodkey, "HelpTelephone");
5070     RegDeleteValueA(prodkey, "HelpLink");
5071     RegDeleteValueA(prodkey, "LocalPackage");
5072     RegDeleteKeyA(prodkey, "");
5073     RegCloseKey(prodkey);
5074
5075     /* MSIINSTALLCONTEXT_USERMANAGED */
5076
5077     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
5078     lstrcatA(keypath, usersid);
5079     lstrcatA(keypath, "\\Products\\");
5080     lstrcatA(keypath, prod_squashed);
5081
5082     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5084
5085     /* local user product key exists */
5086     sz = MAX_PATH;
5087     lstrcpyA(buf, "apple");
5088     r = pMsiGetProductInfoExA(prodcode, usersid,
5089                               MSIINSTALLCONTEXT_USERMANAGED,
5090                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5091     ok(r == ERROR_UNKNOWN_PRODUCT,
5092        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5093     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5094     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5095
5096     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5097     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5098
5099     /* InstallProperties key exists */
5100     sz = MAX_PATH;
5101     lstrcpyA(buf, "apple");
5102     r = pMsiGetProductInfoExA(prodcode, usersid,
5103                               MSIINSTALLCONTEXT_USERMANAGED,
5104                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5105     ok(r == ERROR_UNKNOWN_PRODUCT,
5106        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5107     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5108     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5109
5110     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5111     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5112
5113     /* ManagedLocalPackage value exists */
5114     sz = MAX_PATH;
5115     lstrcpyA(buf, "apple");
5116     r = pMsiGetProductInfoExA(prodcode, usersid,
5117                               MSIINSTALLCONTEXT_USERMANAGED,
5118                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5119     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5120     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5121     ok(sz == 1, "Expected 1, got %d\n", sz);
5122
5123     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5124     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5125
5126     /* HelpLink value exists */
5127     sz = MAX_PATH;
5128     lstrcpyA(buf, "apple");
5129     r = pMsiGetProductInfoExA(prodcode, usersid,
5130                               MSIINSTALLCONTEXT_USERMANAGED,
5131                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5132     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5133     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5134     ok(sz == 4, "Expected 4, got %d\n", sz);
5135
5136     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5137     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5138
5139     /* HelpTelephone value exists */
5140     sz = MAX_PATH;
5141     lstrcpyA(buf, "apple");
5142     r = pMsiGetProductInfoExA(prodcode, usersid,
5143                               MSIINSTALLCONTEXT_USERMANAGED,
5144                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5146     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5147     ok(sz == 5, "Expected 5, got %d\n", sz);
5148
5149     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5151
5152     /* InstallDate value exists */
5153     sz = MAX_PATH;
5154     lstrcpyA(buf, "apple");
5155     r = pMsiGetProductInfoExA(prodcode, usersid,
5156                               MSIINSTALLCONTEXT_USERMANAGED,
5157                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5158     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5159     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5160     ok(sz == 4, "Expected 4, got %d\n", sz);
5161
5162     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5163     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5164
5165     /* DisplayName value exists */
5166     sz = MAX_PATH;
5167     lstrcpyA(buf, "apple");
5168     r = pMsiGetProductInfoExA(prodcode, usersid,
5169                               MSIINSTALLCONTEXT_USERMANAGED,
5170                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5171     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5172     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5173     ok(sz == 4, "Expected 4, got %d\n", sz);
5174
5175     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5176     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5177
5178     /* InstallLocation value exists */
5179     sz = MAX_PATH;
5180     lstrcpyA(buf, "apple");
5181     r = pMsiGetProductInfoExA(prodcode, usersid,
5182                               MSIINSTALLCONTEXT_USERMANAGED,
5183                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5184     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5185     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5186     ok(sz == 3, "Expected 3, got %d\n", sz);
5187
5188     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5190
5191     /* InstallSource value exists */
5192     sz = MAX_PATH;
5193     lstrcpyA(buf, "apple");
5194     r = pMsiGetProductInfoExA(prodcode, usersid,
5195                               MSIINSTALLCONTEXT_USERMANAGED,
5196                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5197     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5198     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5199     ok(sz == 6, "Expected 6, got %d\n", sz);
5200
5201     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5203
5204     /* LocalPackage value exists */
5205     sz = MAX_PATH;
5206     lstrcpyA(buf, "apple");
5207     r = pMsiGetProductInfoExA(prodcode, usersid,
5208                               MSIINSTALLCONTEXT_USERMANAGED,
5209                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5211     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5212     ok(sz == 5, "Expected 5, got %d\n", sz);
5213
5214     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5215     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5216
5217     /* Publisher value exists */
5218     sz = MAX_PATH;
5219     lstrcpyA(buf, "apple");
5220     r = pMsiGetProductInfoExA(prodcode, usersid,
5221                               MSIINSTALLCONTEXT_USERMANAGED,
5222                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5223     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5224     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5225     ok(sz == 3, "Expected 3, got %d\n", sz);
5226
5227     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5228     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5229
5230     /* URLInfoAbout value exists */
5231     sz = MAX_PATH;
5232     lstrcpyA(buf, "apple");
5233     r = pMsiGetProductInfoExA(prodcode, usersid,
5234                               MSIINSTALLCONTEXT_USERMANAGED,
5235                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5236     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5237     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5238     ok(sz == 5, "Expected 5, got %d\n", sz);
5239
5240     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5242
5243     /* URLUpdateInfo value exists */
5244     sz = MAX_PATH;
5245     lstrcpyA(buf, "apple");
5246     r = pMsiGetProductInfoExA(prodcode, usersid,
5247                               MSIINSTALLCONTEXT_USERMANAGED,
5248                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5249     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5250     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5251     ok(sz == 6, "Expected 6, got %d\n", sz);
5252
5253     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5255
5256     /* VersionMinor value exists */
5257     sz = MAX_PATH;
5258     lstrcpyA(buf, "apple");
5259     r = pMsiGetProductInfoExA(prodcode, usersid,
5260                               MSIINSTALLCONTEXT_USERMANAGED,
5261                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5262     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5263     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5264     ok(sz == 1, "Expected 1, got %d\n", sz);
5265
5266     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5267     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5268
5269     /* VersionMajor value exists */
5270     sz = MAX_PATH;
5271     lstrcpyA(buf, "apple");
5272     r = pMsiGetProductInfoExA(prodcode, usersid,
5273                               MSIINSTALLCONTEXT_USERMANAGED,
5274                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5275     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5276     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5277     ok(sz == 1, "Expected 1, got %d\n", sz);
5278
5279     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5281
5282     /* DisplayVersion value exists */
5283     sz = MAX_PATH;
5284     lstrcpyA(buf, "apple");
5285     r = pMsiGetProductInfoExA(prodcode, usersid,
5286                               MSIINSTALLCONTEXT_USERMANAGED,
5287                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5288     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5289     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5290     ok(sz == 5, "Expected 5, got %d\n", sz);
5291
5292     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5293     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5294
5295     /* ProductID value exists */
5296     sz = MAX_PATH;
5297     lstrcpyA(buf, "apple");
5298     r = pMsiGetProductInfoExA(prodcode, usersid,
5299                               MSIINSTALLCONTEXT_USERMANAGED,
5300                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5301     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5302     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5303     ok(sz == 2, "Expected 2, got %d\n", sz);
5304
5305     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5306     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5307
5308     /* RegCompany value exists */
5309     sz = MAX_PATH;
5310     lstrcpyA(buf, "apple");
5311     r = pMsiGetProductInfoExA(prodcode, usersid,
5312                               MSIINSTALLCONTEXT_USERMANAGED,
5313                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5315     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5316     ok(sz == 4, "Expected 4, got %d\n", sz);
5317
5318     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5320
5321     /* RegOwner value exists */
5322     sz = MAX_PATH;
5323     lstrcpyA(buf, "apple");
5324     r = pMsiGetProductInfoExA(prodcode, usersid,
5325                               MSIINSTALLCONTEXT_USERMANAGED,
5326                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5327     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5328     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5329     ok(sz == 5, "Expected 5, got %d\n", sz);
5330
5331     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5333
5334     /* Transforms value exists */
5335     sz = MAX_PATH;
5336     lstrcpyA(buf, "apple");
5337     r = pMsiGetProductInfoExA(prodcode, usersid,
5338                               MSIINSTALLCONTEXT_USERMANAGED,
5339                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5340     ok(r == ERROR_UNKNOWN_PRODUCT,
5341        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5342     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5343     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5344
5345     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5347
5348     /* Language value exists */
5349     sz = MAX_PATH;
5350     lstrcpyA(buf, "apple");
5351     r = pMsiGetProductInfoExA(prodcode, usersid,
5352                               MSIINSTALLCONTEXT_USERMANAGED,
5353                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5354     ok(r == ERROR_UNKNOWN_PRODUCT,
5355        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5356     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5357     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5358
5359     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5361
5362     /* ProductName value exists */
5363     sz = MAX_PATH;
5364     lstrcpyA(buf, "apple");
5365     r = pMsiGetProductInfoExA(prodcode, usersid,
5366                               MSIINSTALLCONTEXT_USERMANAGED,
5367                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5368     ok(r == ERROR_UNKNOWN_PRODUCT,
5369        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5370     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5371     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5372
5373     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5374     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5375
5376     /* FIXME */
5377
5378     /* AssignmentType value exists */
5379     sz = MAX_PATH;
5380     lstrcpyA(buf, "apple");
5381     r = pMsiGetProductInfoExA(prodcode, usersid,
5382                               MSIINSTALLCONTEXT_USERMANAGED,
5383                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5384     ok(r == ERROR_UNKNOWN_PRODUCT,
5385        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5386     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5387     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5388
5389     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5390     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5391
5392     /* PackageCode value exists */
5393     sz = MAX_PATH;
5394     lstrcpyA(buf, "apple");
5395     r = pMsiGetProductInfoExA(prodcode, usersid,
5396                               MSIINSTALLCONTEXT_USERMANAGED,
5397                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5398     ok(r == ERROR_UNKNOWN_PRODUCT,
5399        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5400     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5401     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5402
5403     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5404     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5405
5406     /* Version value exists */
5407     sz = MAX_PATH;
5408     lstrcpyA(buf, "apple");
5409     r = pMsiGetProductInfoExA(prodcode, usersid,
5410                               MSIINSTALLCONTEXT_USERMANAGED,
5411                               INSTALLPROPERTY_VERSION, buf, &sz);
5412     ok(r == ERROR_UNKNOWN_PRODUCT,
5413        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5414     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5415     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5416
5417     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5418     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5419
5420     /* ProductIcon value exists */
5421     sz = MAX_PATH;
5422     lstrcpyA(buf, "apple");
5423     r = pMsiGetProductInfoExA(prodcode, usersid,
5424                               MSIINSTALLCONTEXT_USERMANAGED,
5425                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5426     ok(r == ERROR_UNKNOWN_PRODUCT,
5427        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5428     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5429     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5430
5431     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5432     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5433
5434     /* PackageName value exists */
5435     sz = MAX_PATH;
5436     lstrcpyA(buf, "apple");
5437     r = pMsiGetProductInfoExA(prodcode, usersid,
5438                               MSIINSTALLCONTEXT_USERMANAGED,
5439                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5440     ok(r == ERROR_UNKNOWN_PRODUCT,
5441        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5442     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5443     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5444
5445     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5447
5448     /* AuthorizedLUAApp value exists */
5449     sz = MAX_PATH;
5450     lstrcpyA(buf, "apple");
5451     r = pMsiGetProductInfoExA(prodcode, usersid,
5452                               MSIINSTALLCONTEXT_USERMANAGED,
5453                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5454     ok(r == ERROR_UNKNOWN_PRODUCT,
5455        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5456     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5457     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5458
5459     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5460     RegDeleteValueA(propkey, "PackageName");
5461     RegDeleteValueA(propkey, "ProductIcon");
5462     RegDeleteValueA(propkey, "Version");
5463     RegDeleteValueA(propkey, "PackageCode");
5464     RegDeleteValueA(propkey, "AssignmentType");
5465     RegDeleteValueA(propkey, "ProductName");
5466     RegDeleteValueA(propkey, "Language");
5467     RegDeleteValueA(propkey, "Transforms");
5468     RegDeleteValueA(propkey, "RegOwner");
5469     RegDeleteValueA(propkey, "RegCompany");
5470     RegDeleteValueA(propkey, "ProductID");
5471     RegDeleteValueA(propkey, "DisplayVersion");
5472     RegDeleteValueA(propkey, "VersionMajor");
5473     RegDeleteValueA(propkey, "VersionMinor");
5474     RegDeleteValueA(propkey, "URLUpdateInfo");
5475     RegDeleteValueA(propkey, "URLInfoAbout");
5476     RegDeleteValueA(propkey, "Publisher");
5477     RegDeleteValueA(propkey, "LocalPackage");
5478     RegDeleteValueA(propkey, "InstallSource");
5479     RegDeleteValueA(propkey, "InstallLocation");
5480     RegDeleteValueA(propkey, "DisplayName");
5481     RegDeleteValueA(propkey, "InstallDate");
5482     RegDeleteValueA(propkey, "HelpTelephone");
5483     RegDeleteValueA(propkey, "HelpLink");
5484     RegDeleteValueA(propkey, "ManagedLocalPackage");
5485     RegDeleteKeyA(propkey, "");
5486     RegCloseKey(propkey);
5487     RegDeleteKeyA(localkey, "");
5488     RegCloseKey(localkey);
5489
5490     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5491     lstrcatA(keypath, usersid);
5492     lstrcatA(keypath, "\\Installer\\Products\\");
5493     lstrcatA(keypath, prod_squashed);
5494
5495     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5496     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5497
5498     /* user product key exists */
5499     sz = MAX_PATH;
5500     lstrcpyA(buf, "apple");
5501     r = pMsiGetProductInfoExA(prodcode, usersid,
5502                               MSIINSTALLCONTEXT_USERMANAGED,
5503                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5504     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5505     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5506     ok(sz == 1, "Expected 1, got %d\n", sz);
5507
5508     RegDeleteKeyA(userkey, "");
5509     RegCloseKey(userkey);
5510
5511     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5512     lstrcatA(keypath, prod_squashed);
5513
5514     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5516
5517     /* current user product key exists */
5518     sz = MAX_PATH;
5519     lstrcpyA(buf, "apple");
5520     r = pMsiGetProductInfoExA(prodcode, usersid,
5521                               MSIINSTALLCONTEXT_USERMANAGED,
5522                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5523     ok(r == ERROR_UNKNOWN_PRODUCT,
5524        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5525     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5526     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5527
5528     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5530
5531     /* HelpLink value exists, user product key does not exist */
5532     sz = MAX_PATH;
5533     lstrcpyA(buf, "apple");
5534     r = pMsiGetProductInfoExA(prodcode, usersid,
5535                               MSIINSTALLCONTEXT_USERMANAGED,
5536                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5537     ok(r == ERROR_UNKNOWN_PRODUCT,
5538        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5539     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5540     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5541
5542     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5543     lstrcatA(keypath, usersid);
5544     lstrcatA(keypath, "\\Installer\\Products\\");
5545     lstrcatA(keypath, prod_squashed);
5546
5547     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5549
5550     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5551     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5552
5553     /* HelpLink value exists, user product key does exist */
5554     sz = MAX_PATH;
5555     lstrcpyA(buf, "apple");
5556     r = pMsiGetProductInfoExA(prodcode, usersid,
5557                               MSIINSTALLCONTEXT_USERMANAGED,
5558                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5559     ok(r == ERROR_UNKNOWN_PROPERTY,
5560        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5561     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5562     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5563
5564     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5565     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5566
5567     /* HelpTelephone value exists */
5568     sz = MAX_PATH;
5569     lstrcpyA(buf, "apple");
5570     r = pMsiGetProductInfoExA(prodcode, usersid,
5571                               MSIINSTALLCONTEXT_USERMANAGED,
5572                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5573     ok(r == ERROR_UNKNOWN_PROPERTY,
5574        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5575     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5576     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5577
5578     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5580
5581     /* InstallDate value exists */
5582     sz = MAX_PATH;
5583     lstrcpyA(buf, "apple");
5584     r = pMsiGetProductInfoExA(prodcode, usersid,
5585                               MSIINSTALLCONTEXT_USERMANAGED,
5586                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5587     ok(r == ERROR_UNKNOWN_PROPERTY,
5588        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5589     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5590     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5591
5592     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5593     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5594
5595     /* DisplayName value exists */
5596     sz = MAX_PATH;
5597     lstrcpyA(buf, "apple");
5598     r = pMsiGetProductInfoExA(prodcode, usersid,
5599                               MSIINSTALLCONTEXT_USERMANAGED,
5600                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5601     ok(r == ERROR_UNKNOWN_PROPERTY,
5602        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5603     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5604     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5605
5606     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5608
5609     /* InstallLocation value exists */
5610     sz = MAX_PATH;
5611     lstrcpyA(buf, "apple");
5612     r = pMsiGetProductInfoExA(prodcode, usersid,
5613                               MSIINSTALLCONTEXT_USERMANAGED,
5614                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5615     ok(r == ERROR_UNKNOWN_PROPERTY,
5616        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5617     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5618     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5619
5620     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5621     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5622
5623     /* InstallSource value exists */
5624     sz = MAX_PATH;
5625     lstrcpyA(buf, "apple");
5626     r = pMsiGetProductInfoExA(prodcode, usersid,
5627                               MSIINSTALLCONTEXT_USERMANAGED,
5628                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5629     ok(r == ERROR_UNKNOWN_PROPERTY,
5630        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5631     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5632     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5633
5634     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5635     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5636
5637     /* LocalPackage value exists */
5638     sz = MAX_PATH;
5639     lstrcpyA(buf, "apple");
5640     r = pMsiGetProductInfoExA(prodcode, usersid,
5641                               MSIINSTALLCONTEXT_USERMANAGED,
5642                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5643     ok(r == ERROR_UNKNOWN_PROPERTY,
5644        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5645     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5646     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5647
5648     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5649     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5650
5651     /* Publisher value exists */
5652     sz = MAX_PATH;
5653     lstrcpyA(buf, "apple");
5654     r = pMsiGetProductInfoExA(prodcode, usersid,
5655                               MSIINSTALLCONTEXT_USERMANAGED,
5656                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5657     ok(r == ERROR_UNKNOWN_PROPERTY,
5658        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5659     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5660     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5661
5662     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5663     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5664
5665     /* URLInfoAbout value exists */
5666     sz = MAX_PATH;
5667     lstrcpyA(buf, "apple");
5668     r = pMsiGetProductInfoExA(prodcode, usersid,
5669                               MSIINSTALLCONTEXT_USERMANAGED,
5670                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5671     ok(r == ERROR_UNKNOWN_PROPERTY,
5672        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5673     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5674     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5675
5676     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5677     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5678
5679     /* URLUpdateInfo value exists */
5680     sz = MAX_PATH;
5681     lstrcpyA(buf, "apple");
5682     r = pMsiGetProductInfoExA(prodcode, usersid,
5683                               MSIINSTALLCONTEXT_USERMANAGED,
5684                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5685     ok(r == ERROR_UNKNOWN_PROPERTY,
5686        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5687     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5688     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5689
5690     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5691     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5692
5693     /* VersionMinor value exists */
5694     sz = MAX_PATH;
5695     lstrcpyA(buf, "apple");
5696     r = pMsiGetProductInfoExA(prodcode, usersid,
5697                               MSIINSTALLCONTEXT_USERMANAGED,
5698                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5699     ok(r == ERROR_UNKNOWN_PROPERTY,
5700        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5701     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5702     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5703
5704     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5705     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5706
5707     /* VersionMajor value exists */
5708     sz = MAX_PATH;
5709     lstrcpyA(buf, "apple");
5710     r = pMsiGetProductInfoExA(prodcode, usersid,
5711                               MSIINSTALLCONTEXT_USERMANAGED,
5712                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5713     ok(r == ERROR_UNKNOWN_PROPERTY,
5714        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5715     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5716     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5717
5718     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5720
5721     /* DisplayVersion value exists */
5722     sz = MAX_PATH;
5723     lstrcpyA(buf, "apple");
5724     r = pMsiGetProductInfoExA(prodcode, usersid,
5725                               MSIINSTALLCONTEXT_USERMANAGED,
5726                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5727     ok(r == ERROR_UNKNOWN_PROPERTY,
5728        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5729     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5730     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5731
5732     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5733     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5734
5735     /* ProductID value exists */
5736     sz = MAX_PATH;
5737     lstrcpyA(buf, "apple");
5738     r = pMsiGetProductInfoExA(prodcode, usersid,
5739                               MSIINSTALLCONTEXT_USERMANAGED,
5740                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5741     ok(r == ERROR_UNKNOWN_PROPERTY,
5742        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5743     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5744     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5745
5746     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5748
5749     /* RegCompany value exists */
5750     sz = MAX_PATH;
5751     lstrcpyA(buf, "apple");
5752     r = pMsiGetProductInfoExA(prodcode, usersid,
5753                               MSIINSTALLCONTEXT_USERMANAGED,
5754                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5755     ok(r == ERROR_UNKNOWN_PROPERTY,
5756        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5757     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5758     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5759
5760     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5761     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5762
5763     /* RegOwner value exists */
5764     sz = MAX_PATH;
5765     lstrcpyA(buf, "apple");
5766     r = pMsiGetProductInfoExA(prodcode, usersid,
5767                               MSIINSTALLCONTEXT_USERMANAGED,
5768                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5769     ok(r == ERROR_UNKNOWN_PROPERTY,
5770        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5771     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5772     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5773
5774     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5775     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5776
5777     /* Transforms value exists */
5778     sz = MAX_PATH;
5779     lstrcpyA(buf, "apple");
5780     r = pMsiGetProductInfoExA(prodcode, usersid,
5781                               MSIINSTALLCONTEXT_USERMANAGED,
5782                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5783     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5784     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5785     ok(sz == 5, "Expected 5, got %d\n", sz);
5786
5787     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5788     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5789
5790     /* Language value exists */
5791     sz = MAX_PATH;
5792     lstrcpyA(buf, "apple");
5793     r = pMsiGetProductInfoExA(prodcode, usersid,
5794                               MSIINSTALLCONTEXT_USERMANAGED,
5795                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5796     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5797     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5798     ok(sz == 4, "Expected 4, got %d\n", sz);
5799
5800     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5801     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5802
5803     /* ProductName value exists */
5804     sz = MAX_PATH;
5805     lstrcpyA(buf, "apple");
5806     r = pMsiGetProductInfoExA(prodcode, usersid,
5807                               MSIINSTALLCONTEXT_USERMANAGED,
5808                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5809     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5810     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5811     ok(sz == 4, "Expected 4, got %d\n", sz);
5812
5813     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5814     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5815
5816     /* FIXME */
5817
5818     /* AssignmentType value exists */
5819     sz = MAX_PATH;
5820     lstrcpyA(buf, "apple");
5821     r = pMsiGetProductInfoExA(prodcode, usersid,
5822                               MSIINSTALLCONTEXT_USERMANAGED,
5823                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5824     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5825     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5826     ok(sz == 0, "Expected 0, got %d\n", sz);
5827
5828     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5829     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5830
5831     /* FIXME */
5832
5833     /* PackageCode value exists */
5834     sz = MAX_PATH;
5835     lstrcpyA(buf, "apple");
5836     r = pMsiGetProductInfoExA(prodcode, usersid,
5837                               MSIINSTALLCONTEXT_USERMANAGED,
5838                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5839     todo_wine
5840     {
5841         ok(r == ERROR_BAD_CONFIGURATION,
5842            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5843         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5844         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5845     }
5846
5847     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5848     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5849
5850     /* Version value exists */
5851     sz = MAX_PATH;
5852     lstrcpyA(buf, "apple");
5853     r = pMsiGetProductInfoExA(prodcode, usersid,
5854                               MSIINSTALLCONTEXT_USERMANAGED,
5855                               INSTALLPROPERTY_VERSION, buf, &sz);
5856     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5857     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5858     ok(sz == 3, "Expected 3, got %d\n", sz);
5859
5860     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5861     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5862
5863     /* ProductIcon value exists */
5864     sz = MAX_PATH;
5865     lstrcpyA(buf, "apple");
5866     r = pMsiGetProductInfoExA(prodcode, usersid,
5867                               MSIINSTALLCONTEXT_USERMANAGED,
5868                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5869     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5870     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5871     ok(sz == 4, "Expected 4, got %d\n", sz);
5872
5873     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5874     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5875
5876     /* PackageName value exists */
5877     sz = MAX_PATH;
5878     lstrcpyA(buf, "apple");
5879     r = pMsiGetProductInfoExA(prodcode, usersid,
5880                               MSIINSTALLCONTEXT_USERMANAGED,
5881                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5882     todo_wine
5883     {
5884         ok(r == ERROR_UNKNOWN_PRODUCT,
5885            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5886         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5887         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5888     }
5889
5890     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5892
5893     /* AuthorizedLUAApp value exists */
5894     sz = MAX_PATH;
5895     lstrcpyA(buf, "apple");
5896     r = pMsiGetProductInfoExA(prodcode, usersid,
5897                               MSIINSTALLCONTEXT_USERMANAGED,
5898                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5899     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5900     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5901     ok(sz == 4, "Expected 4, got %d\n", sz);
5902
5903     RegDeleteValueA(userkey, "AuthorizedLUAApp");
5904     RegDeleteValueA(userkey, "PackageName");
5905     RegDeleteValueA(userkey, "ProductIcon");
5906     RegDeleteValueA(userkey, "Version");
5907     RegDeleteValueA(userkey, "PackageCode");
5908     RegDeleteValueA(userkey, "AssignmentType");
5909     RegDeleteValueA(userkey, "ProductName");
5910     RegDeleteValueA(userkey, "Language");
5911     RegDeleteValueA(userkey, "Transforms");
5912     RegDeleteValueA(userkey, "RegOwner");
5913     RegDeleteValueA(userkey, "RegCompany");
5914     RegDeleteValueA(userkey, "ProductID");
5915     RegDeleteValueA(userkey, "DisplayVersion");
5916     RegDeleteValueA(userkey, "VersionMajor");
5917     RegDeleteValueA(userkey, "VersionMinor");
5918     RegDeleteValueA(userkey, "URLUpdateInfo");
5919     RegDeleteValueA(userkey, "URLInfoAbout");
5920     RegDeleteValueA(userkey, "Publisher");
5921     RegDeleteValueA(userkey, "LocalPackage");
5922     RegDeleteValueA(userkey, "InstallSource");
5923     RegDeleteValueA(userkey, "InstallLocation");
5924     RegDeleteValueA(userkey, "DisplayName");
5925     RegDeleteValueA(userkey, "InstallDate");
5926     RegDeleteValueA(userkey, "HelpTelephone");
5927     RegDeleteValueA(userkey, "HelpLink");
5928     RegDeleteKeyA(userkey, "");
5929     RegCloseKey(userkey);
5930     RegDeleteKeyA(prodkey, "");
5931     RegCloseKey(prodkey);
5932
5933     /* MSIINSTALLCONTEXT_MACHINE */
5934
5935     /* szUserSid is non-NULL */
5936     sz = MAX_PATH;
5937     lstrcpyA(buf, "apple");
5938     r = pMsiGetProductInfoExA(prodcode, usersid,
5939                               MSIINSTALLCONTEXT_MACHINE,
5940                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5941     ok(r == ERROR_INVALID_PARAMETER,
5942        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5943     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5944     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5945
5946     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
5947     lstrcatA(keypath, prod_squashed);
5948
5949     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5951
5952     /* local system product key exists */
5953     sz = MAX_PATH;
5954     lstrcpyA(buf, "apple");
5955     r = pMsiGetProductInfoExA(prodcode, NULL,
5956                               MSIINSTALLCONTEXT_MACHINE,
5957                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5958     ok(r == ERROR_UNKNOWN_PRODUCT,
5959        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5960     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5961     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5962
5963     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5965
5966     /* InstallProperties key exists */
5967     sz = MAX_PATH;
5968     lstrcpyA(buf, "apple");
5969     r = pMsiGetProductInfoExA(prodcode, NULL,
5970                               MSIINSTALLCONTEXT_MACHINE,
5971                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5972     ok(r == ERROR_UNKNOWN_PRODUCT,
5973        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5974     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5975     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5976
5977     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5978     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5979
5980     /* LocalPackage value exists */
5981     sz = MAX_PATH;
5982     lstrcpyA(buf, "apple");
5983     r = pMsiGetProductInfoExA(prodcode, NULL,
5984                               MSIINSTALLCONTEXT_MACHINE,
5985                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5986     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5987     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5988     ok(sz == 1, "Expected 1, got %d\n", sz);
5989
5990     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5992
5993     /* HelpLink value exists */
5994     sz = MAX_PATH;
5995     lstrcpyA(buf, "apple");
5996     r = pMsiGetProductInfoExA(prodcode, NULL,
5997                               MSIINSTALLCONTEXT_MACHINE,
5998                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5999     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6000     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
6001     ok(sz == 4, "Expected 4, got %d\n", sz);
6002
6003     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6004     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6005
6006     /* HelpTelephone value exists */
6007     sz = MAX_PATH;
6008     lstrcpyA(buf, "apple");
6009     r = pMsiGetProductInfoExA(prodcode, NULL,
6010                               MSIINSTALLCONTEXT_MACHINE,
6011                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6012     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6013     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
6014     ok(sz == 5, "Expected 5, got %d\n", sz);
6015
6016     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6017     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6018
6019     /* InstallDate value exists */
6020     sz = MAX_PATH;
6021     lstrcpyA(buf, "apple");
6022     r = pMsiGetProductInfoExA(prodcode, NULL,
6023                               MSIINSTALLCONTEXT_MACHINE,
6024                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6025     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6026     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
6027     ok(sz == 4, "Expected 4, got %d\n", sz);
6028
6029     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6030     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6031
6032     /* DisplayName value exists */
6033     sz = MAX_PATH;
6034     lstrcpyA(buf, "apple");
6035     r = pMsiGetProductInfoExA(prodcode, NULL,
6036                               MSIINSTALLCONTEXT_MACHINE,
6037                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6038     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6039     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6040     ok(sz == 4, "Expected 4, got %d\n", sz);
6041
6042     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6044
6045     /* InstallLocation value exists */
6046     sz = MAX_PATH;
6047     lstrcpyA(buf, "apple");
6048     r = pMsiGetProductInfoExA(prodcode, NULL,
6049                               MSIINSTALLCONTEXT_MACHINE,
6050                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6051     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6052     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
6053     ok(sz == 3, "Expected 3, got %d\n", sz);
6054
6055     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6056     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6057
6058     /* InstallSource value exists */
6059     sz = MAX_PATH;
6060     lstrcpyA(buf, "apple");
6061     r = pMsiGetProductInfoExA(prodcode, NULL,
6062                               MSIINSTALLCONTEXT_MACHINE,
6063                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6064     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6065     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
6066     ok(sz == 6, "Expected 6, got %d\n", sz);
6067
6068     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6069     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6070
6071     /* LocalPackage value exists */
6072     sz = MAX_PATH;
6073     lstrcpyA(buf, "apple");
6074     r = pMsiGetProductInfoExA(prodcode, NULL,
6075                               MSIINSTALLCONTEXT_MACHINE,
6076                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6077     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6078     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
6079     ok(sz == 5, "Expected 5, got %d\n", sz);
6080
6081     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6082     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6083
6084     /* Publisher value exists */
6085     sz = MAX_PATH;
6086     lstrcpyA(buf, "apple");
6087     r = pMsiGetProductInfoExA(prodcode, NULL,
6088                               MSIINSTALLCONTEXT_MACHINE,
6089                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6090     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6091     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
6092     ok(sz == 3, "Expected 3, got %d\n", sz);
6093
6094     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6095     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6096
6097     /* URLInfoAbout value exists */
6098     sz = MAX_PATH;
6099     lstrcpyA(buf, "apple");
6100     r = pMsiGetProductInfoExA(prodcode, NULL,
6101                               MSIINSTALLCONTEXT_MACHINE,
6102                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6103     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6104     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
6105     ok(sz == 5, "Expected 5, got %d\n", sz);
6106
6107     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6108     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6109
6110     /* URLUpdateInfo value exists */
6111     sz = MAX_PATH;
6112     lstrcpyA(buf, "apple");
6113     r = pMsiGetProductInfoExA(prodcode, NULL,
6114                               MSIINSTALLCONTEXT_MACHINE,
6115                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6116     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6117     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
6118     ok(sz == 6, "Expected 6, got %d\n", sz);
6119
6120     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6121     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6122
6123     /* VersionMinor value exists */
6124     sz = MAX_PATH;
6125     lstrcpyA(buf, "apple");
6126     r = pMsiGetProductInfoExA(prodcode, NULL,
6127                               MSIINSTALLCONTEXT_MACHINE,
6128                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6129     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6130     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
6131     ok(sz == 1, "Expected 1, got %d\n", sz);
6132
6133     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6135
6136     /* VersionMajor value exists */
6137     sz = MAX_PATH;
6138     lstrcpyA(buf, "apple");
6139     r = pMsiGetProductInfoExA(prodcode, NULL,
6140                               MSIINSTALLCONTEXT_MACHINE,
6141                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6142     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6143     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
6144     ok(sz == 1, "Expected 1, got %d\n", sz);
6145
6146     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6148
6149     /* DisplayVersion value exists */
6150     sz = MAX_PATH;
6151     lstrcpyA(buf, "apple");
6152     r = pMsiGetProductInfoExA(prodcode, NULL,
6153                               MSIINSTALLCONTEXT_MACHINE,
6154                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6155     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6156     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
6157     ok(sz == 5, "Expected 5, got %d\n", sz);
6158
6159     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6160     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6161
6162     /* ProductID value exists */
6163     sz = MAX_PATH;
6164     lstrcpyA(buf, "apple");
6165     r = pMsiGetProductInfoExA(prodcode, NULL,
6166                               MSIINSTALLCONTEXT_MACHINE,
6167                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6168     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6169     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
6170     ok(sz == 2, "Expected 2, got %d\n", sz);
6171
6172     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6173     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6174
6175     /* RegCompany value exists */
6176     sz = MAX_PATH;
6177     lstrcpyA(buf, "apple");
6178     r = pMsiGetProductInfoExA(prodcode, NULL,
6179                               MSIINSTALLCONTEXT_MACHINE,
6180                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6182     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
6183     ok(sz == 4, "Expected 4, got %d\n", sz);
6184
6185     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6186     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6187
6188     /* RegOwner value exists */
6189     sz = MAX_PATH;
6190     lstrcpyA(buf, "apple");
6191     r = pMsiGetProductInfoExA(prodcode, NULL,
6192                               MSIINSTALLCONTEXT_MACHINE,
6193                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6194     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6195     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
6196     ok(sz == 5, "Expected 5, got %d\n", sz);
6197
6198     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6199     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6200
6201     /* Transforms value exists */
6202     sz = MAX_PATH;
6203     lstrcpyA(buf, "apple");
6204     r = pMsiGetProductInfoExA(prodcode, NULL,
6205                               MSIINSTALLCONTEXT_MACHINE,
6206                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6207     ok(r == ERROR_UNKNOWN_PRODUCT,
6208        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6209     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6210     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6211
6212     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6213     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6214
6215     /* Language value exists */
6216     sz = MAX_PATH;
6217     lstrcpyA(buf, "apple");
6218     r = pMsiGetProductInfoExA(prodcode, NULL,
6219                               MSIINSTALLCONTEXT_MACHINE,
6220                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6221     ok(r == ERROR_UNKNOWN_PRODUCT,
6222        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6223     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6224     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6225
6226     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6228
6229     /* ProductName value exists */
6230     sz = MAX_PATH;
6231     lstrcpyA(buf, "apple");
6232     r = pMsiGetProductInfoExA(prodcode, NULL,
6233                               MSIINSTALLCONTEXT_MACHINE,
6234                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6235     ok(r == ERROR_UNKNOWN_PRODUCT,
6236        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6237     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6238     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6239
6240     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6242
6243     /* FIXME */
6244
6245     /* AssignmentType value exists */
6246     sz = MAX_PATH;
6247     lstrcpyA(buf, "apple");
6248     r = pMsiGetProductInfoExA(prodcode, NULL,
6249                               MSIINSTALLCONTEXT_MACHINE,
6250                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6251     ok(r == ERROR_UNKNOWN_PRODUCT,
6252        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6253     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6254     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6255
6256     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6257     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6258
6259     /* PackageCode value exists */
6260     sz = MAX_PATH;
6261     lstrcpyA(buf, "apple");
6262     r = pMsiGetProductInfoExA(prodcode, NULL,
6263                               MSIINSTALLCONTEXT_MACHINE,
6264                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6265     ok(r == ERROR_UNKNOWN_PRODUCT,
6266        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6267     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6268     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6269
6270     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6271     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6272
6273     /* Version value exists */
6274     sz = MAX_PATH;
6275     lstrcpyA(buf, "apple");
6276     r = pMsiGetProductInfoExA(prodcode, NULL,
6277                               MSIINSTALLCONTEXT_MACHINE,
6278                               INSTALLPROPERTY_VERSION, buf, &sz);
6279     ok(r == ERROR_UNKNOWN_PRODUCT,
6280        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6281     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6282     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6283
6284     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6286
6287     /* ProductIcon value exists */
6288     sz = MAX_PATH;
6289     lstrcpyA(buf, "apple");
6290     r = pMsiGetProductInfoExA(prodcode, NULL,
6291                               MSIINSTALLCONTEXT_MACHINE,
6292                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6293     ok(r == ERROR_UNKNOWN_PRODUCT,
6294        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6295     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6296     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6297
6298     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6299     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6300
6301     /* PackageName value exists */
6302     sz = MAX_PATH;
6303     lstrcpyA(buf, "apple");
6304     r = pMsiGetProductInfoExA(prodcode, NULL,
6305                               MSIINSTALLCONTEXT_MACHINE,
6306                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6307     ok(r == ERROR_UNKNOWN_PRODUCT,
6308        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6309     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6310     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6311
6312     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6313     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6314
6315     /* AuthorizedLUAApp value exists */
6316     sz = MAX_PATH;
6317     lstrcpyA(buf, "apple");
6318     r = pMsiGetProductInfoExA(prodcode, NULL,
6319                               MSIINSTALLCONTEXT_MACHINE,
6320                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6321     ok(r == ERROR_UNKNOWN_PRODUCT,
6322        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6323     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6324     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6325
6326     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6327     RegDeleteValueA(propkey, "PackageName");
6328     RegDeleteValueA(propkey, "ProductIcon");
6329     RegDeleteValueA(propkey, "Version");
6330     RegDeleteValueA(propkey, "PackageCode");
6331     RegDeleteValueA(propkey, "AssignmentType");
6332     RegDeleteValueA(propkey, "ProductName");
6333     RegDeleteValueA(propkey, "Language");
6334     RegDeleteValueA(propkey, "Transforms");
6335     RegDeleteValueA(propkey, "RegOwner");
6336     RegDeleteValueA(propkey, "RegCompany");
6337     RegDeleteValueA(propkey, "ProductID");
6338     RegDeleteValueA(propkey, "DisplayVersion");
6339     RegDeleteValueA(propkey, "VersionMajor");
6340     RegDeleteValueA(propkey, "VersionMinor");
6341     RegDeleteValueA(propkey, "URLUpdateInfo");
6342     RegDeleteValueA(propkey, "URLInfoAbout");
6343     RegDeleteValueA(propkey, "Publisher");
6344     RegDeleteValueA(propkey, "LocalPackage");
6345     RegDeleteValueA(propkey, "InstallSource");
6346     RegDeleteValueA(propkey, "InstallLocation");
6347     RegDeleteValueA(propkey, "DisplayName");
6348     RegDeleteValueA(propkey, "InstallDate");
6349     RegDeleteValueA(propkey, "HelpTelephone");
6350     RegDeleteValueA(propkey, "HelpLink");
6351     RegDeleteValueA(propkey, "LocalPackage");
6352     RegDeleteKeyA(propkey, "");
6353     RegCloseKey(propkey);
6354     RegDeleteKeyA(localkey, "");
6355     RegCloseKey(localkey);
6356
6357     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6358     lstrcatA(keypath, prod_squashed);
6359
6360     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6362
6363     /* local classes product key exists */
6364     sz = MAX_PATH;
6365     lstrcpyA(buf, "apple");
6366     r = pMsiGetProductInfoExA(prodcode, NULL,
6367                               MSIINSTALLCONTEXT_MACHINE,
6368                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6369     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6370     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6371     ok(sz == 1, "Expected 1, got %d\n", sz);
6372
6373     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6374     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6375
6376     /* HelpLink value exists */
6377     sz = MAX_PATH;
6378     lstrcpyA(buf, "apple");
6379     r = pMsiGetProductInfoExA(prodcode, NULL,
6380                               MSIINSTALLCONTEXT_MACHINE,
6381                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6382     ok(r == ERROR_UNKNOWN_PROPERTY,
6383        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6384     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6385     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6386
6387     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6389
6390     /* HelpTelephone value exists */
6391     sz = MAX_PATH;
6392     lstrcpyA(buf, "apple");
6393     r = pMsiGetProductInfoExA(prodcode, NULL,
6394                               MSIINSTALLCONTEXT_MACHINE,
6395                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6396     ok(r == ERROR_UNKNOWN_PROPERTY,
6397        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6398     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6399     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6400
6401     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6403
6404     /* InstallDate value exists */
6405     sz = MAX_PATH;
6406     lstrcpyA(buf, "apple");
6407     r = pMsiGetProductInfoExA(prodcode, NULL,
6408                               MSIINSTALLCONTEXT_MACHINE,
6409                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6410     ok(r == ERROR_UNKNOWN_PROPERTY,
6411        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6412     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6413     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6414
6415     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6417
6418     /* DisplayName value exists */
6419     sz = MAX_PATH;
6420     lstrcpyA(buf, "apple");
6421     r = pMsiGetProductInfoExA(prodcode, NULL,
6422                               MSIINSTALLCONTEXT_MACHINE,
6423                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6424     ok(r == ERROR_UNKNOWN_PROPERTY,
6425        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6426     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6427     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6428
6429     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6430     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6431
6432     /* InstallLocation value exists */
6433     sz = MAX_PATH;
6434     lstrcpyA(buf, "apple");
6435     r = pMsiGetProductInfoExA(prodcode, NULL,
6436                               MSIINSTALLCONTEXT_MACHINE,
6437                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6438     ok(r == ERROR_UNKNOWN_PROPERTY,
6439        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6440     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6441     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6442
6443     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6445
6446     /* InstallSource value exists */
6447     sz = MAX_PATH;
6448     lstrcpyA(buf, "apple");
6449     r = pMsiGetProductInfoExA(prodcode, NULL,
6450                               MSIINSTALLCONTEXT_MACHINE,
6451                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6452     ok(r == ERROR_UNKNOWN_PROPERTY,
6453        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6454     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6455     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6456
6457     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6459
6460     /* LocalPackage value exists */
6461     sz = MAX_PATH;
6462     lstrcpyA(buf, "apple");
6463     r = pMsiGetProductInfoExA(prodcode, NULL,
6464                               MSIINSTALLCONTEXT_MACHINE,
6465                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6466     ok(r == ERROR_UNKNOWN_PROPERTY,
6467        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6468     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6469     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6470
6471     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6472     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6473
6474     /* Publisher value exists */
6475     sz = MAX_PATH;
6476     lstrcpyA(buf, "apple");
6477     r = pMsiGetProductInfoExA(prodcode, NULL,
6478                               MSIINSTALLCONTEXT_MACHINE,
6479                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6480     ok(r == ERROR_UNKNOWN_PROPERTY,
6481        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6482     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6483     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6484
6485     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6486     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6487
6488     /* URLInfoAbout value exists */
6489     sz = MAX_PATH;
6490     lstrcpyA(buf, "apple");
6491     r = pMsiGetProductInfoExA(prodcode, NULL,
6492                               MSIINSTALLCONTEXT_MACHINE,
6493                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6494     ok(r == ERROR_UNKNOWN_PROPERTY,
6495        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6496     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6497     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6498
6499     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6500     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6501
6502     /* URLUpdateInfo value exists */
6503     sz = MAX_PATH;
6504     lstrcpyA(buf, "apple");
6505     r = pMsiGetProductInfoExA(prodcode, NULL,
6506                               MSIINSTALLCONTEXT_MACHINE,
6507                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6508     ok(r == ERROR_UNKNOWN_PROPERTY,
6509        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6510     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6511     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6512
6513     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6514     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6515
6516     /* VersionMinor value exists */
6517     sz = MAX_PATH;
6518     lstrcpyA(buf, "apple");
6519     r = pMsiGetProductInfoExA(prodcode, NULL,
6520                               MSIINSTALLCONTEXT_MACHINE,
6521                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6522     ok(r == ERROR_UNKNOWN_PROPERTY,
6523        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6524     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6525     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6526
6527     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6528     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6529
6530     /* VersionMajor value exists */
6531     sz = MAX_PATH;
6532     lstrcpyA(buf, "apple");
6533     r = pMsiGetProductInfoExA(prodcode, NULL,
6534                               MSIINSTALLCONTEXT_MACHINE,
6535                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6536     ok(r == ERROR_UNKNOWN_PROPERTY,
6537        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6538     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6539     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6540
6541     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6543
6544     /* DisplayVersion value exists */
6545     sz = MAX_PATH;
6546     lstrcpyA(buf, "apple");
6547     r = pMsiGetProductInfoExA(prodcode, NULL,
6548                               MSIINSTALLCONTEXT_MACHINE,
6549                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6550     ok(r == ERROR_UNKNOWN_PROPERTY,
6551        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6552     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6553     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6554
6555     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6557
6558     /* ProductID value exists */
6559     sz = MAX_PATH;
6560     lstrcpyA(buf, "apple");
6561     r = pMsiGetProductInfoExA(prodcode, NULL,
6562                               MSIINSTALLCONTEXT_MACHINE,
6563                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6564     ok(r == ERROR_UNKNOWN_PROPERTY,
6565        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6566     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6567     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6568
6569     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6570     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6571
6572     /* RegCompany value exists */
6573     sz = MAX_PATH;
6574     lstrcpyA(buf, "apple");
6575     r = pMsiGetProductInfoExA(prodcode, NULL,
6576                               MSIINSTALLCONTEXT_MACHINE,
6577                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6578     ok(r == ERROR_UNKNOWN_PROPERTY,
6579        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6580     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6581     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6582
6583     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6584     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6585
6586     /* RegOwner value exists */
6587     sz = MAX_PATH;
6588     lstrcpyA(buf, "apple");
6589     r = pMsiGetProductInfoExA(prodcode, NULL,
6590                               MSIINSTALLCONTEXT_MACHINE,
6591                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6592     ok(r == ERROR_UNKNOWN_PROPERTY,
6593        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6594     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6595     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6596
6597     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6598     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6599
6600     /* Transforms value exists */
6601     sz = MAX_PATH;
6602     lstrcpyA(buf, "apple");
6603     r = pMsiGetProductInfoExA(prodcode, NULL,
6604                               MSIINSTALLCONTEXT_MACHINE,
6605                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6606     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6607     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6608     ok(sz == 5, "Expected 5, got %d\n", sz);
6609
6610     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6612
6613     /* Language value exists */
6614     sz = MAX_PATH;
6615     lstrcpyA(buf, "apple");
6616     r = pMsiGetProductInfoExA(prodcode, NULL,
6617                               MSIINSTALLCONTEXT_MACHINE,
6618                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6619     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6620     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6621     ok(sz == 4, "Expected 4, got %d\n", sz);
6622
6623     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6625
6626     /* ProductName value exists */
6627     sz = MAX_PATH;
6628     lstrcpyA(buf, "apple");
6629     r = pMsiGetProductInfoExA(prodcode, NULL,
6630                               MSIINSTALLCONTEXT_MACHINE,
6631                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6632     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6633     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6634     ok(sz == 4, "Expected 4, got %d\n", sz);
6635
6636     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6637     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6638
6639     /* FIXME */
6640
6641     /* AssignmentType value exists */
6642     sz = MAX_PATH;
6643     lstrcpyA(buf, "apple");
6644     r = pMsiGetProductInfoExA(prodcode, NULL,
6645                               MSIINSTALLCONTEXT_MACHINE,
6646                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6647     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6648     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6649     ok(sz == 0, "Expected 0, got %d\n", sz);
6650
6651     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6653
6654     /* FIXME */
6655
6656     /* PackageCode value exists */
6657     sz = MAX_PATH;
6658     lstrcpyA(buf, "apple");
6659     r = pMsiGetProductInfoExA(prodcode, NULL,
6660                               MSIINSTALLCONTEXT_MACHINE,
6661                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6662     todo_wine
6663     {
6664         ok(r == ERROR_BAD_CONFIGURATION,
6665            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6666         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6667         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6668     }
6669
6670     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6671     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6672
6673     /* Version value exists */
6674     sz = MAX_PATH;
6675     lstrcpyA(buf, "apple");
6676     r = pMsiGetProductInfoExA(prodcode, NULL,
6677                               MSIINSTALLCONTEXT_MACHINE,
6678                               INSTALLPROPERTY_VERSION, buf, &sz);
6679     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6680     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6681     ok(sz == 3, "Expected 3, got %d\n", sz);
6682
6683     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6684     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6685
6686     /* ProductIcon value exists */
6687     sz = MAX_PATH;
6688     lstrcpyA(buf, "apple");
6689     r = pMsiGetProductInfoExA(prodcode, NULL,
6690                               MSIINSTALLCONTEXT_MACHINE,
6691                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6692     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6693     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6694     ok(sz == 4, "Expected 4, got %d\n", sz);
6695
6696     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6697     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6698
6699     /* PackageName value exists */
6700     sz = MAX_PATH;
6701     lstrcpyA(buf, "apple");
6702     r = pMsiGetProductInfoExA(prodcode, NULL,
6703                               MSIINSTALLCONTEXT_MACHINE,
6704                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6705     todo_wine
6706     {
6707         ok(r == ERROR_UNKNOWN_PRODUCT,
6708            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6709         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6710         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6711     }
6712
6713     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6714     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6715
6716     /* AuthorizedLUAApp value exists */
6717     sz = MAX_PATH;
6718     lstrcpyA(buf, "apple");
6719     r = pMsiGetProductInfoExA(prodcode, NULL,
6720                               MSIINSTALLCONTEXT_MACHINE,
6721                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6722     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6723     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6724     ok(sz == 4, "Expected 4, got %d\n", sz);
6725
6726     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6727     RegDeleteValueA(prodkey, "PackageName");
6728     RegDeleteValueA(prodkey, "ProductIcon");
6729     RegDeleteValueA(prodkey, "Version");
6730     RegDeleteValueA(prodkey, "PackageCode");
6731     RegDeleteValueA(prodkey, "AssignmentType");
6732     RegDeleteValueA(prodkey, "ProductName");
6733     RegDeleteValueA(prodkey, "Language");
6734     RegDeleteValueA(prodkey, "Transforms");
6735     RegDeleteValueA(prodkey, "RegOwner");
6736     RegDeleteValueA(prodkey, "RegCompany");
6737     RegDeleteValueA(prodkey, "ProductID");
6738     RegDeleteValueA(prodkey, "DisplayVersion");
6739     RegDeleteValueA(prodkey, "VersionMajor");
6740     RegDeleteValueA(prodkey, "VersionMinor");
6741     RegDeleteValueA(prodkey, "URLUpdateInfo");
6742     RegDeleteValueA(prodkey, "URLInfoAbout");
6743     RegDeleteValueA(prodkey, "Publisher");
6744     RegDeleteValueA(prodkey, "LocalPackage");
6745     RegDeleteValueA(prodkey, "InstallSource");
6746     RegDeleteValueA(prodkey, "InstallLocation");
6747     RegDeleteValueA(prodkey, "DisplayName");
6748     RegDeleteValueA(prodkey, "InstallDate");
6749     RegDeleteValueA(prodkey, "HelpTelephone");
6750     RegDeleteValueA(prodkey, "HelpLink");
6751     RegDeleteKeyA(prodkey, "");
6752     RegCloseKey(prodkey);
6753     LocalFree(usersid);
6754 }
6755
6756 #define INIT_USERINFO() \
6757     lstrcpyA(user, "apple"); \
6758     lstrcpyA(org, "orange"); \
6759     lstrcpyA(serial, "banana"); \
6760     usersz = orgsz = serialsz = MAX_PATH;
6761
6762 static void test_MsiGetUserInfo(void)
6763 {
6764     USERINFOSTATE state;
6765     CHAR user[MAX_PATH];
6766     CHAR org[MAX_PATH];
6767     CHAR serial[MAX_PATH];
6768     DWORD usersz, orgsz, serialsz;
6769     CHAR keypath[MAX_PATH * 2];
6770     CHAR prodcode[MAX_PATH];
6771     CHAR prod_squashed[MAX_PATH];
6772     HKEY prodkey, userprod, props;
6773     LPSTR usersid;
6774     LONG res;
6775
6776     create_test_guid(prodcode, prod_squashed);
6777     get_user_sid(&usersid);
6778
6779     /* NULL szProduct */
6780     INIT_USERINFO();
6781     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6782     ok(state == USERINFOSTATE_INVALIDARG,
6783        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6784     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6785     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6786     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6787     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6788     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6789     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6790
6791     /* empty szProductCode */
6792     INIT_USERINFO();
6793     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6794     ok(state == USERINFOSTATE_INVALIDARG,
6795        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6796     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6797     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6798     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6799     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6800     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6801     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6802
6803     /* garbage szProductCode */
6804     INIT_USERINFO();
6805     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6806     ok(state == USERINFOSTATE_INVALIDARG,
6807        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6808     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6809     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6810     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6811     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6812     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6813     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6814
6815     /* guid without brackets */
6816     INIT_USERINFO();
6817     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6818                             user, &usersz, org, &orgsz, serial, &serialsz);
6819     ok(state == USERINFOSTATE_INVALIDARG,
6820        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6821     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6822     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6823     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6824     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6825     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6826     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6827
6828     /* guid with brackets */
6829     INIT_USERINFO();
6830     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6831                             user, &usersz, org, &orgsz, serial, &serialsz);
6832     ok(state == USERINFOSTATE_UNKNOWN,
6833        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6834     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6835     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6836     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6837     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6838     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6839     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6840
6841     /* NULL lpUserNameBuf */
6842     INIT_USERINFO();
6843     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6844     ok(state == USERINFOSTATE_UNKNOWN,
6845        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6846     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6847     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6848     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6849     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6850     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6851
6852     /* NULL pcchUserNameBuf */
6853     INIT_USERINFO();
6854     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6855     ok(state == USERINFOSTATE_INVALIDARG,
6856        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6857     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6858     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6859     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6860     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6861     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6862
6863     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6864     INIT_USERINFO();
6865     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6866     ok(state == USERINFOSTATE_UNKNOWN,
6867        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6868     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6869     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6870     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6871     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6872
6873     /* NULL lpOrgNameBuf */
6874     INIT_USERINFO();
6875     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6876     ok(state == USERINFOSTATE_UNKNOWN,
6877        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6878     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6879     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6880     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6881     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6882     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6883
6884     /* NULL pcchOrgNameBuf */
6885     INIT_USERINFO();
6886     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
6887     ok(state == USERINFOSTATE_INVALIDARG,
6888        "Expected USERINFOSTATE_INVALIDARG, 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 == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6893     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6894
6895     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
6896     INIT_USERINFO();
6897     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
6898     ok(state == USERINFOSTATE_UNKNOWN,
6899        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6900     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6901     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6902     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6903     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6904
6905     /* NULL lpSerialBuf */
6906     INIT_USERINFO();
6907     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
6908     ok(state == USERINFOSTATE_UNKNOWN,
6909        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6910     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6911     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6912     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6913     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6914     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6915
6916     /* NULL pcchSerialBuf */
6917     INIT_USERINFO();
6918     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
6919     ok(state == USERINFOSTATE_INVALIDARG,
6920        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6921     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6922     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6923     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6924     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6925     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6926
6927     /* both lpSerialBuf and pcchSerialBuf NULL */
6928     INIT_USERINFO();
6929     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
6930     ok(state == USERINFOSTATE_UNKNOWN,
6931        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6932     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6933     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6934     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6935     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6936
6937     /* MSIINSTALLCONTEXT_USERMANAGED */
6938
6939     /* create local system product key */
6940     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6941     lstrcatA(keypath, usersid);
6942     lstrcatA(keypath, "\\Installer\\Products\\");
6943     lstrcatA(keypath, prod_squashed);
6944
6945     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6946     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6947
6948     /* managed product key exists */
6949     INIT_USERINFO();
6950     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6951     ok(state == USERINFOSTATE_ABSENT,
6952        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6953     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6954     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6955     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6956     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6957     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6958     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6959
6960     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6961     lstrcatA(keypath, "Installer\\UserData\\");
6962     lstrcatA(keypath, usersid);
6963     lstrcatA(keypath, "\\Products\\");
6964     lstrcatA(keypath, prod_squashed);
6965
6966     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6967     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6968
6969     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6970     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6971
6972     /* InstallProperties key exists */
6973     INIT_USERINFO();
6974     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6975     ok(state == USERINFOSTATE_ABSENT,
6976        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6977     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6978     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6979     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6980     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6981     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6982     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6983
6984     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6985     INIT_USERINFO();
6986     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6987     ok(state == USERINFOSTATE_ABSENT,
6988        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6989     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6990     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6991     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6992     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6993
6994     /* RegOwner, RegCompany don't exist, out params are NULL */
6995     INIT_USERINFO();
6996     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6997     ok(state == USERINFOSTATE_ABSENT,
6998        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6999     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7000     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7001
7002     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7003     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7004
7005     /* RegOwner value exists */
7006     INIT_USERINFO();
7007     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7008     ok(state == USERINFOSTATE_ABSENT,
7009        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7010     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7011     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7012     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7013     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7014     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7015     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7016
7017     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7019
7020     /* RegCompany value exists */
7021     INIT_USERINFO();
7022     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7023     ok(state == USERINFOSTATE_ABSENT,
7024        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7025     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7026     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7027     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7028     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7029     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7030     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7031
7032     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7033     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7034
7035     /* ProductID value exists */
7036     INIT_USERINFO();
7037     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7038     ok(state == USERINFOSTATE_PRESENT,
7039        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7040     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7041     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7042     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7043     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7044     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7045     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7046
7047     /* pcchUserNameBuf is too small */
7048     INIT_USERINFO();
7049     usersz = 0;
7050     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7051     ok(state == USERINFOSTATE_MOREDATA,
7052        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7053     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7054     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7055     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7056     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7057     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7058     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7059
7060     /* pcchUserNameBuf has no room for NULL terminator */
7061     INIT_USERINFO();
7062     usersz = 5;
7063     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7064     ok(state == USERINFOSTATE_MOREDATA,
7065        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
7066     todo_wine
7067     {
7068         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7069     }
7070     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7071     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7072     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7073     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7074     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7075
7076     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
7077     INIT_USERINFO();
7078     usersz = 0;
7079     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
7080     ok(state == USERINFOSTATE_PRESENT,
7081        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7082     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7083     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7084     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7085     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7086     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7087     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7088
7089     RegDeleteValueA(props, "ProductID");
7090     RegDeleteValueA(props, "RegCompany");
7091     RegDeleteValueA(props, "RegOwner");
7092     RegDeleteKeyA(props, "");
7093     RegCloseKey(props);
7094     RegDeleteKeyA(userprod, "");
7095     RegCloseKey(userprod);
7096     RegDeleteKeyA(prodkey, "");
7097     RegCloseKey(prodkey);
7098
7099     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7100
7101     /* create local system product key */
7102     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7103     lstrcatA(keypath, prod_squashed);
7104
7105     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7107
7108     /* product key exists */
7109     INIT_USERINFO();
7110     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7111     ok(state == USERINFOSTATE_ABSENT,
7112        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7113     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7114     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7115     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7116     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7117     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7118     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7119
7120     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7121     lstrcatA(keypath, "Installer\\UserData\\");
7122     lstrcatA(keypath, usersid);
7123     lstrcatA(keypath, "\\Products\\");
7124     lstrcatA(keypath, prod_squashed);
7125
7126     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
7127     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7128
7129     res = RegCreateKeyA(userprod, "InstallProperties", &props);
7130     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7131
7132     /* InstallProperties key exists */
7133     INIT_USERINFO();
7134     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7135     ok(state == USERINFOSTATE_ABSENT,
7136        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7137     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7138     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7139     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7140     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7141     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7142     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7143
7144     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7145     INIT_USERINFO();
7146     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7147     ok(state == USERINFOSTATE_ABSENT,
7148        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7149     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7150     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7151     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7152     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7153
7154     /* RegOwner, RegCompany don't exist, out params are NULL */
7155     INIT_USERINFO();
7156     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7157     ok(state == USERINFOSTATE_ABSENT,
7158        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7159     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7160     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7161
7162     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7163     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7164
7165     /* RegOwner value exists */
7166     INIT_USERINFO();
7167     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7168     ok(state == USERINFOSTATE_ABSENT,
7169        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7170     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7171     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7172     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7173     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7174     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7175     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7176
7177     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7179
7180     /* RegCompany value exists */
7181     INIT_USERINFO();
7182     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7183     ok(state == USERINFOSTATE_ABSENT,
7184        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7185     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7186     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7187     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7188     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7189     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7190     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7191
7192     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7194
7195     /* ProductID value exists */
7196     INIT_USERINFO();
7197     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7198     ok(state == USERINFOSTATE_PRESENT,
7199        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7200     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7201     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7202     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7203     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7204     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7205     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7206
7207     RegDeleteValueA(props, "ProductID");
7208     RegDeleteValueA(props, "RegCompany");
7209     RegDeleteValueA(props, "RegOwner");
7210     RegDeleteKeyA(props, "");
7211     RegCloseKey(props);
7212     RegDeleteKeyA(userprod, "");
7213     RegCloseKey(userprod);
7214     RegDeleteKeyA(prodkey, "");
7215     RegCloseKey(prodkey);
7216
7217     /* MSIINSTALLCONTEXT_MACHINE */
7218
7219     /* create local system product key */
7220     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7221     lstrcatA(keypath, prod_squashed);
7222
7223     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7224     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7225
7226     /* product key exists */
7227     INIT_USERINFO();
7228     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7229     ok(state == USERINFOSTATE_ABSENT,
7230        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7231     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7232     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7233     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7234     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
7235     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7236     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7237
7238     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7239     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7240     lstrcatA(keypath, "\\Products\\");
7241     lstrcatA(keypath, prod_squashed);
7242
7243     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
7244     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7245
7246     res = RegCreateKeyA(userprod, "InstallProperties", &props);
7247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7248
7249     /* InstallProperties key exists */
7250     INIT_USERINFO();
7251     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7252     ok(state == USERINFOSTATE_ABSENT,
7253        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7254     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7255     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7256     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7257     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7258     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7259     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7260
7261     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7262     INIT_USERINFO();
7263     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7264     ok(state == USERINFOSTATE_ABSENT,
7265        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7266     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7267     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7268     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7269     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7270
7271     /* RegOwner, RegCompany don't exist, out params are NULL */
7272     INIT_USERINFO();
7273     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7274     ok(state == USERINFOSTATE_ABSENT,
7275        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7276     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7277     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7278
7279     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7280     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7281
7282     /* RegOwner value exists */
7283     INIT_USERINFO();
7284     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7285     ok(state == USERINFOSTATE_ABSENT,
7286        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7287     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7288     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7289     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7290     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7291     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7292     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7293
7294     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7295     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7296
7297     /* RegCompany value exists */
7298     INIT_USERINFO();
7299     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7300     ok(state == USERINFOSTATE_ABSENT,
7301        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7302     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7303     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7304     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7305     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7306     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7307     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7308
7309     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7311
7312     /* ProductID value exists */
7313     INIT_USERINFO();
7314     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7315     ok(state == USERINFOSTATE_PRESENT,
7316        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7317     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7318     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7319     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7320     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7321     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7322     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7323
7324     RegDeleteValueA(props, "ProductID");
7325     RegDeleteValueA(props, "RegCompany");
7326     RegDeleteValueA(props, "RegOwner");
7327     RegDeleteKeyA(props, "");
7328     RegCloseKey(props);
7329     RegDeleteKeyA(userprod, "");
7330     RegCloseKey(userprod);
7331     RegDeleteKeyA(prodkey, "");
7332     RegCloseKey(prodkey);
7333     LocalFree(usersid);
7334 }
7335
7336 static void test_MsiOpenProduct(void)
7337 {
7338     MSIHANDLE hprod, hdb;
7339     CHAR val[MAX_PATH];
7340     CHAR path[MAX_PATH];
7341     CHAR keypath[MAX_PATH*2];
7342     CHAR prodcode[MAX_PATH];
7343     CHAR prod_squashed[MAX_PATH];
7344     HKEY prodkey, userkey, props;
7345     LPSTR usersid;
7346     DWORD size;
7347     LONG res;
7348     UINT r;
7349
7350     GetCurrentDirectoryA(MAX_PATH, path);
7351     lstrcatA(path, "\\");
7352
7353     create_test_guid(prodcode, prod_squashed);
7354     get_user_sid(&usersid);
7355
7356     hdb = create_package_db(prodcode);
7357     MsiCloseHandle(hdb);
7358
7359     /* NULL szProduct */
7360     hprod = 0xdeadbeef;
7361     r = MsiOpenProductA(NULL, &hprod);
7362     ok(r == ERROR_INVALID_PARAMETER,
7363        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7364     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7365
7366     /* empty szProduct */
7367     hprod = 0xdeadbeef;
7368     r = MsiOpenProductA("", &hprod);
7369     ok(r == ERROR_INVALID_PARAMETER,
7370        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7371     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7372
7373     /* garbage szProduct */
7374     hprod = 0xdeadbeef;
7375     r = MsiOpenProductA("garbage", &hprod);
7376     ok(r == ERROR_INVALID_PARAMETER,
7377        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7378     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7379
7380     /* guid without brackets */
7381     hprod = 0xdeadbeef;
7382     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7383     ok(r == ERROR_INVALID_PARAMETER,
7384        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7385     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7386
7387     /* guid with brackets */
7388     hprod = 0xdeadbeef;
7389     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7390     ok(r == ERROR_UNKNOWN_PRODUCT,
7391        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7392     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7393
7394     /* same length as guid, but random */
7395     hprod = 0xdeadbeef;
7396     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7397     ok(r == ERROR_INVALID_PARAMETER,
7398        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7399     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7400
7401     /* hProduct is NULL */
7402     hprod = 0xdeadbeef;
7403     r = MsiOpenProductA(prodcode, NULL);
7404     ok(r == ERROR_INVALID_PARAMETER,
7405        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7406     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7407
7408     /* MSIINSTALLCONTEXT_USERMANAGED */
7409
7410     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7411     lstrcatA(keypath, "Installer\\Managed\\");
7412     lstrcatA(keypath, usersid);
7413     lstrcatA(keypath, "\\Installer\\Products\\");
7414     lstrcatA(keypath, prod_squashed);
7415
7416     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7418
7419     /* managed product key exists */
7420     hprod = 0xdeadbeef;
7421     r = MsiOpenProductA(prodcode, &hprod);
7422     ok(r == ERROR_UNKNOWN_PRODUCT,
7423        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7424     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7425
7426     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7427     lstrcatA(keypath, "Installer\\UserData\\");
7428     lstrcatA(keypath, usersid);
7429     lstrcatA(keypath, "\\Products\\");
7430     lstrcatA(keypath, prod_squashed);
7431
7432     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7434
7435     /* user product key exists */
7436     hprod = 0xdeadbeef;
7437     r = MsiOpenProductA(prodcode, &hprod);
7438     ok(r == ERROR_UNKNOWN_PRODUCT,
7439        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7440     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7441
7442     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7443     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7444
7445     /* InstallProperties key exists */
7446     hprod = 0xdeadbeef;
7447     r = MsiOpenProductA(prodcode, &hprod);
7448     ok(r == ERROR_UNKNOWN_PRODUCT,
7449        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7450     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7451
7452     lstrcpyA(val, path);
7453     lstrcatA(val, "\\winetest.msi");
7454     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7455                          (const BYTE *)val, lstrlenA(val) + 1);
7456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7457
7458     /* ManagedLocalPackage value exists */
7459     hprod = 0xdeadbeef;
7460     r = MsiOpenProductA(prodcode, &hprod);
7461     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7462     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7463
7464     size = MAX_PATH;
7465     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7466     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7467     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7468     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7469
7470     MsiCloseHandle(hprod);
7471
7472     RegDeleteValueA(props, "ManagedLocalPackage");
7473     RegDeleteKeyA(props, "");
7474     RegCloseKey(props);
7475     RegDeleteKeyA(userkey, "");
7476     RegCloseKey(userkey);
7477     RegDeleteKeyA(prodkey, "");
7478     RegCloseKey(prodkey);
7479
7480     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7481
7482     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7483     lstrcatA(keypath, prod_squashed);
7484
7485     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7486     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7487
7488     /* unmanaged product key exists */
7489     hprod = 0xdeadbeef;
7490     r = MsiOpenProductA(prodcode, &hprod);
7491     ok(r == ERROR_UNKNOWN_PRODUCT,
7492        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7493     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7494
7495     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7496     lstrcatA(keypath, "Installer\\UserData\\");
7497     lstrcatA(keypath, usersid);
7498     lstrcatA(keypath, "\\Products\\");
7499     lstrcatA(keypath, prod_squashed);
7500
7501     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7502     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7503
7504     /* user product key exists */
7505     hprod = 0xdeadbeef;
7506     r = MsiOpenProductA(prodcode, &hprod);
7507     ok(r == ERROR_UNKNOWN_PRODUCT,
7508        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7509     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7510
7511     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7513
7514     /* InstallProperties key exists */
7515     hprod = 0xdeadbeef;
7516     r = MsiOpenProductA(prodcode, &hprod);
7517     ok(r == ERROR_UNKNOWN_PRODUCT,
7518        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7519     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7520
7521     lstrcpyA(val, path);
7522     lstrcatA(val, "\\winetest.msi");
7523     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7524                          (const BYTE *)val, lstrlenA(val) + 1);
7525     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7526
7527     /* LocalPackage value exists */
7528     hprod = 0xdeadbeef;
7529     r = MsiOpenProductA(prodcode, &hprod);
7530     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7531     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7532
7533     size = MAX_PATH;
7534     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7535     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7536     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7537     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7538
7539     MsiCloseHandle(hprod);
7540
7541     RegDeleteValueA(props, "LocalPackage");
7542     RegDeleteKeyA(props, "");
7543     RegCloseKey(props);
7544     RegDeleteKeyA(userkey, "");
7545     RegCloseKey(userkey);
7546     RegDeleteKeyA(prodkey, "");
7547     RegCloseKey(prodkey);
7548
7549     /* MSIINSTALLCONTEXT_MACHINE */
7550
7551     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7552     lstrcatA(keypath, prod_squashed);
7553
7554     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7555     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7556
7557     /* managed product key exists */
7558     hprod = 0xdeadbeef;
7559     r = MsiOpenProductA(prodcode, &hprod);
7560     ok(r == ERROR_UNKNOWN_PRODUCT,
7561        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7562     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7563
7564     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7565     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7566     lstrcatA(keypath, prod_squashed);
7567
7568     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7569     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7570
7571     /* user product key exists */
7572     hprod = 0xdeadbeef;
7573     r = MsiOpenProductA(prodcode, &hprod);
7574     ok(r == ERROR_UNKNOWN_PRODUCT,
7575        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7576     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7577
7578     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7580
7581     /* InstallProperties key exists */
7582     hprod = 0xdeadbeef;
7583     r = MsiOpenProductA(prodcode, &hprod);
7584     ok(r == ERROR_UNKNOWN_PRODUCT,
7585        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7586     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7587
7588     lstrcpyA(val, path);
7589     lstrcatA(val, "\\winetest.msi");
7590     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7591                          (const BYTE *)val, lstrlenA(val) + 1);
7592     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7593
7594     /* LocalPackage value exists */
7595     hprod = 0xdeadbeef;
7596     r = MsiOpenProductA(prodcode, &hprod);
7597     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7598     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7599
7600     size = MAX_PATH;
7601     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7602     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7603     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7604     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7605
7606     MsiCloseHandle(hprod);
7607
7608     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7609                          (const BYTE *)"winetest.msi", 13);
7610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7611
7612     /* LocalPackage has just the package name */
7613     hprod = 0xdeadbeef;
7614     r = MsiOpenProductA(prodcode, &hprod);
7615     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7616        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7617     if (r == ERROR_SUCCESS)
7618         MsiCloseHandle(hprod);
7619     else
7620         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7621
7622     lstrcpyA(val, path);
7623     lstrcatA(val, "\\winetest.msi");
7624     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7625                          (const BYTE *)val, lstrlenA(val) + 1);
7626     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7627
7628     DeleteFileA(msifile);
7629
7630     /* local package does not exist */
7631     hprod = 0xdeadbeef;
7632     r = MsiOpenProductA(prodcode, &hprod);
7633     ok(r == ERROR_UNKNOWN_PRODUCT,
7634        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7635     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7636
7637     RegDeleteValueA(props, "LocalPackage");
7638     RegDeleteKeyA(props, "");
7639     RegCloseKey(props);
7640     RegDeleteKeyA(userkey, "");
7641     RegCloseKey(userkey);
7642     RegDeleteKeyA(prodkey, "");
7643     RegCloseKey(prodkey);
7644
7645     DeleteFileA(msifile);
7646     LocalFree(usersid);
7647 }
7648
7649 static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
7650 {
7651     MSIINSTALLCONTEXT context;
7652     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7653     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7654     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7655     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7656     HKEY prodkey, patches, udprod, udpatch, hpatch;
7657     DWORD size, data;
7658     LONG res;
7659     UINT r;
7660
7661     create_test_guid(prodcode, prod_squashed);
7662     create_test_guid(patch, patch_squashed);
7663
7664     /* MSIPATCHSTATE_APPLIED */
7665
7666     lstrcpyA(patchcode, "apple");
7667     lstrcpyA(targetprod, "banana");
7668     context = 0xdeadbeef;
7669     lstrcpyA(targetsid, "kiwi");
7670     size = MAX_PATH;
7671     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7672                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7673                            &context, targetsid, &size);
7674     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7675     ok(!lstrcmpA(patchcode, "apple"),
7676        "Expected patchcode to be unchanged, got %s\n", patchcode);
7677     ok(!lstrcmpA(targetprod, "banana"),
7678        "Expected targetprod to be unchanged, got %s\n", targetprod);
7679     ok(context == 0xdeadbeef,
7680        "Expected context to be unchanged, got %d\n", context);
7681     ok(!lstrcmpA(targetsid, "kiwi"),
7682        "Expected targetsid to be unchanged, got %s\n", targetsid);
7683     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7684
7685     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7686     lstrcatA(keypath, expectedsid);
7687     lstrcatA(keypath, "\\Installer\\Products\\");
7688     lstrcatA(keypath, prod_squashed);
7689
7690     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7691     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7692
7693     /* managed product key exists */
7694     lstrcpyA(patchcode, "apple");
7695     lstrcpyA(targetprod, "banana");
7696     context = 0xdeadbeef;
7697     lstrcpyA(targetsid, "kiwi");
7698     size = MAX_PATH;
7699     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7700                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7701                            &context, targetsid, &size);
7702     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7703     ok(!lstrcmpA(patchcode, "apple"),
7704        "Expected patchcode to be unchanged, got %s\n", patchcode);
7705     ok(!lstrcmpA(targetprod, "banana"),
7706        "Expected targetprod to be unchanged, got %s\n", targetprod);
7707     ok(context == 0xdeadbeef,
7708        "Expected context to be unchanged, got %d\n", context);
7709     ok(!lstrcmpA(targetsid, "kiwi"),
7710        "Expected targetsid to be unchanged, got %s\n", targetsid);
7711     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7712
7713     res = RegCreateKeyA(prodkey, "Patches", &patches);
7714     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7715
7716     /* patches key exists */
7717     lstrcpyA(patchcode, "apple");
7718     lstrcpyA(targetprod, "banana");
7719     context = 0xdeadbeef;
7720     lstrcpyA(targetsid, "kiwi");
7721     size = MAX_PATH;
7722     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7723                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7724                            &context, targetsid, &size);
7725     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7726     ok(!lstrcmpA(patchcode, "apple"),
7727        "Expected patchcode to be unchanged, got %s\n", patchcode);
7728     ok(!lstrcmpA(targetprod, "banana"),
7729        "Expected targetprod to be unchanged, got %s\n", targetprod);
7730     ok(context == 0xdeadbeef,
7731        "Expected context to be unchanged, got %d\n", context);
7732     ok(!lstrcmpA(targetsid, "kiwi"),
7733        "Expected targetsid to be unchanged, got %s\n", targetsid);
7734     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7735
7736     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7737                          (const BYTE *)patch_squashed,
7738                          lstrlenA(patch_squashed) + 1);
7739     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7740
7741     /* Patches value exists, is not REG_MULTI_SZ */
7742     lstrcpyA(patchcode, "apple");
7743     lstrcpyA(targetprod, "banana");
7744     context = 0xdeadbeef;
7745     lstrcpyA(targetsid, "kiwi");
7746     size = MAX_PATH;
7747     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7748                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7749                            &context, targetsid, &size);
7750     ok(r == ERROR_BAD_CONFIGURATION,
7751        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7752     ok(!lstrcmpA(patchcode, "apple"),
7753        "Expected patchcode to be unchanged, got %s\n", patchcode);
7754     ok(!lstrcmpA(targetprod, "banana"),
7755        "Expected targetprod to be unchanged, got %s\n", targetprod);
7756     ok(context == 0xdeadbeef,
7757        "Expected context to be unchanged, got %d\n", context);
7758     ok(!lstrcmpA(targetsid, "kiwi"),
7759        "Expected targetsid to be unchanged, got %s\n", targetsid);
7760     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7761
7762     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7763                          (const BYTE *)"a\0b\0c\0\0", 7);
7764     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7765
7766     /* Patches value exists, is not a squashed guid */
7767     lstrcpyA(patchcode, "apple");
7768     lstrcpyA(targetprod, "banana");
7769     context = 0xdeadbeef;
7770     lstrcpyA(targetsid, "kiwi");
7771     size = MAX_PATH;
7772     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7773                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7774                            &context, targetsid, &size);
7775     ok(r == ERROR_BAD_CONFIGURATION,
7776        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7777     ok(!lstrcmpA(patchcode, "apple"),
7778        "Expected patchcode to be unchanged, got %s\n", patchcode);
7779     ok(!lstrcmpA(targetprod, "banana"),
7780        "Expected targetprod to be unchanged, got %s\n", targetprod);
7781     ok(context == 0xdeadbeef,
7782        "Expected context to be unchanged, got %d\n", context);
7783     ok(!lstrcmpA(targetsid, "kiwi"),
7784        "Expected targetsid to be unchanged, got %s\n", targetsid);
7785     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7786
7787     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
7788     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7789                          (const BYTE *)patch_squashed,
7790                          lstrlenA(patch_squashed) + 2);
7791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7792
7793     /* Patches value exists */
7794     lstrcpyA(patchcode, "apple");
7795     lstrcpyA(targetprod, "banana");
7796     context = 0xdeadbeef;
7797     lstrcpyA(targetsid, "kiwi");
7798     size = MAX_PATH;
7799     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7800                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7801                            &context, targetsid, &size);
7802     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7803     ok(!lstrcmpA(patchcode, "apple"),
7804        "Expected patchcode to be unchanged, got %s\n", patchcode);
7805     ok(!lstrcmpA(targetprod, "banana"),
7806        "Expected targetprod to be unchanged, got %s\n", targetprod);
7807     ok(context == 0xdeadbeef,
7808        "Expected context to be unchanged, got %d\n", context);
7809     ok(!lstrcmpA(targetsid, "kiwi"),
7810        "Expected targetsid to be unchanged, got %s\n", targetsid);
7811     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7812
7813     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7814                          (const BYTE *)"whatever", 9);
7815     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7816
7817     /* patch squashed value exists */
7818     lstrcpyA(patchcode, "apple");
7819     lstrcpyA(targetprod, "banana");
7820     context = 0xdeadbeef;
7821     lstrcpyA(targetsid, "kiwi");
7822     size = MAX_PATH;
7823     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7824                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7825                            &context, targetsid, &size);
7826     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7827     ok(!lstrcmpA(patchcode, patch),
7828        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7829     ok(!lstrcmpA(targetprod, prodcode),
7830        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7831     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7832        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7833     ok(!lstrcmpA(targetsid, expectedsid),
7834        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7835     ok(size == lstrlenA(expectedsid),
7836        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7837
7838     /* increase the index */
7839     lstrcpyA(patchcode, "apple");
7840     lstrcpyA(targetprod, "banana");
7841     context = 0xdeadbeef;
7842     lstrcpyA(targetsid, "kiwi");
7843     size = MAX_PATH;
7844     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7845                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7846                            &context, targetsid, &size);
7847     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7848     ok(!lstrcmpA(patchcode, "apple"),
7849        "Expected patchcode to be unchanged, got %s\n", patchcode);
7850     ok(!lstrcmpA(targetprod, "banana"),
7851        "Expected targetprod to be unchanged, got %s\n", targetprod);
7852     ok(context == 0xdeadbeef,
7853        "Expected context to be unchanged, got %d\n", context);
7854     ok(!lstrcmpA(targetsid, "kiwi"),
7855        "Expected targetsid to be unchanged, got %s\n", targetsid);
7856     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7857
7858     /* increase again */
7859     lstrcpyA(patchcode, "apple");
7860     lstrcpyA(targetprod, "banana");
7861     context = 0xdeadbeef;
7862     lstrcpyA(targetsid, "kiwi");
7863     size = MAX_PATH;
7864     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7865                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
7866                            &context, targetsid, &size);
7867     ok(r == ERROR_INVALID_PARAMETER,
7868        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7869     ok(!lstrcmpA(patchcode, "apple"),
7870        "Expected patchcode to be unchanged, got %s\n", patchcode);
7871     ok(!lstrcmpA(targetprod, "banana"),
7872        "Expected targetprod to be unchanged, got %s\n", targetprod);
7873     ok(context == 0xdeadbeef,
7874        "Expected context to be unchanged, got %d\n", context);
7875     ok(!lstrcmpA(targetsid, "kiwi"),
7876        "Expected targetsid to be unchanged, got %s\n", targetsid);
7877     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7878
7879     /* szPatchCode is NULL */
7880     lstrcpyA(targetprod, "banana");
7881     context = 0xdeadbeef;
7882     lstrcpyA(targetsid, "kiwi");
7883     size = MAX_PATH;
7884     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7885                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
7886                            &context, targetsid, &size);
7887     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7888     ok(!lstrcmpA(targetprod, prodcode),
7889        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7890     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7891        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7892     ok(!lstrcmpA(targetsid, expectedsid),
7893        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7894     ok(size == lstrlenA(expectedsid),
7895        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7896
7897     /* szTargetProductCode is NULL */
7898     lstrcpyA(patchcode, "apple");
7899     context = 0xdeadbeef;
7900     lstrcpyA(targetsid, "kiwi");
7901     size = MAX_PATH;
7902     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7903                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
7904                            &context, targetsid, &size);
7905     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7906     ok(!lstrcmpA(patchcode, patch),
7907        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7908     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7909        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7910     ok(!lstrcmpA(targetsid, expectedsid),
7911        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7912     ok(size == lstrlenA(expectedsid),
7913        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7914
7915     /* pdwTargetProductContext is NULL */
7916     lstrcpyA(patchcode, "apple");
7917     lstrcpyA(targetprod, "banana");
7918     lstrcpyA(targetsid, "kiwi");
7919     size = MAX_PATH;
7920     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7921                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7922                            NULL, targetsid, &size);
7923     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7924     ok(!lstrcmpA(patchcode, patch),
7925        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7926     ok(!lstrcmpA(targetprod, prodcode),
7927        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7928     ok(!lstrcmpA(targetsid, expectedsid),
7929        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7930     ok(size == lstrlenA(expectedsid),
7931        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7932
7933     /* szTargetUserSid is NULL */
7934     lstrcpyA(patchcode, "apple");
7935     lstrcpyA(targetprod, "banana");
7936     context = 0xdeadbeef;
7937     size = MAX_PATH;
7938     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7939                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7940                            &context, NULL, &size);
7941     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7942     ok(!lstrcmpA(patchcode, patch),
7943        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7944     ok(!lstrcmpA(targetprod, prodcode),
7945        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7946     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7947        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7948     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7949        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
7950
7951     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
7952     lstrcpyA(patchcode, "apple");
7953     lstrcpyA(targetprod, "banana");
7954     context = 0xdeadbeef;
7955     lstrcpyA(targetsid, "kiwi");
7956     size = lstrlenA(expectedsid);
7957     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7958                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7959                            &context, targetsid, &size);
7960     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
7961     ok(!lstrcmpA(patchcode, patch),
7962        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7963     ok(!lstrcmpA(targetprod, prodcode),
7964        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7965     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7966        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7967     ok(!strncmp(targetsid, expectedsid, lstrlenA(expectedsid) - 1),
7968        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7969     ok(size == lstrlenA(expectedsid) * sizeof(WCHAR),
7970        "Expected %d*sizeof(WCHAR), got %d\n", lstrlenA(expectedsid), size);
7971
7972     /* pcchTargetUserSid has enough room for NULL terminator */
7973     lstrcpyA(patchcode, "apple");
7974     lstrcpyA(targetprod, "banana");
7975     context = 0xdeadbeef;
7976     lstrcpyA(targetsid, "kiwi");
7977     size = lstrlenA(expectedsid) + 1;
7978     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7979                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7980                            &context, targetsid, &size);
7981     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7982     ok(!lstrcmpA(patchcode, patch),
7983        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7984     ok(!lstrcmpA(targetprod, prodcode),
7985        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7986     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7987        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7988     ok(!lstrcmpA(targetsid, expectedsid),
7989        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
7990     ok(size == lstrlenA(expectedsid),
7991        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
7992
7993     /* both szTargetuserSid and pcchTargetUserSid are NULL */
7994     lstrcpyA(patchcode, "apple");
7995     lstrcpyA(targetprod, "banana");
7996     context = 0xdeadbeef;
7997     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7998                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7999                            &context, NULL, NULL);
8000     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8001     ok(!lstrcmpA(patchcode, patch),
8002        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8003     ok(!lstrcmpA(targetprod, prodcode),
8004        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8005     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8006        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8007
8008     /* MSIPATCHSTATE_SUPERSEDED */
8009
8010     lstrcpyA(patchcode, "apple");
8011     lstrcpyA(targetprod, "banana");
8012     context = 0xdeadbeef;
8013     lstrcpyA(targetsid, "kiwi");
8014     size = MAX_PATH;
8015     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8016                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8017                            &context, targetsid, &size);
8018     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8019     ok(!lstrcmpA(patchcode, "apple"),
8020        "Expected patchcode to be unchanged, got %s\n", patchcode);
8021     ok(!lstrcmpA(targetprod, "banana"),
8022        "Expected targetprod to be unchanged, got %s\n", targetprod);
8023     ok(context == 0xdeadbeef,
8024        "Expected context to be unchanged, got %d\n", context);
8025     ok(!lstrcmpA(targetsid, "kiwi"),
8026        "Expected targetsid to be unchanged, got %s\n", targetsid);
8027     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8028
8029     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8030     lstrcatA(keypath, expectedsid);
8031     lstrcatA(keypath, "\\Products\\");
8032     lstrcatA(keypath, prod_squashed);
8033
8034     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8035     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8036
8037     /* UserData product key exists */
8038     lstrcpyA(patchcode, "apple");
8039     lstrcpyA(targetprod, "banana");
8040     context = 0xdeadbeef;
8041     lstrcpyA(targetsid, "kiwi");
8042     size = MAX_PATH;
8043     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8044                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8045                            &context, targetsid, &size);
8046     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8047     ok(!lstrcmpA(patchcode, "apple"),
8048        "Expected patchcode to be unchanged, got %s\n", patchcode);
8049     ok(!lstrcmpA(targetprod, "banana"),
8050        "Expected targetprod to be unchanged, got %s\n", targetprod);
8051     ok(context == 0xdeadbeef,
8052        "Expected context to be unchanged, got %d\n", context);
8053     ok(!lstrcmpA(targetsid, "kiwi"),
8054        "Expected targetsid to be unchanged, got %s\n", targetsid);
8055     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8056
8057     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8058     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8059
8060     /* UserData patches key exists */
8061     lstrcpyA(patchcode, "apple");
8062     lstrcpyA(targetprod, "banana");
8063     context = 0xdeadbeef;
8064     lstrcpyA(targetsid, "kiwi");
8065     size = MAX_PATH;
8066     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8067                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8068                            &context, targetsid, &size);
8069     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8070     ok(!lstrcmpA(patchcode, "apple"),
8071        "Expected patchcode to be unchanged, got %s\n", patchcode);
8072     ok(!lstrcmpA(targetprod, "banana"),
8073        "Expected targetprod to be unchanged, got %s\n", targetprod);
8074     ok(context == 0xdeadbeef,
8075        "Expected context to be unchanged, got %d\n", context);
8076     ok(!lstrcmpA(targetsid, "kiwi"),
8077        "Expected targetsid to be unchanged, got %s\n", targetsid);
8078     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8079
8080     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8081     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8082
8083     /* specific UserData patch key exists */
8084     lstrcpyA(patchcode, "apple");
8085     lstrcpyA(targetprod, "banana");
8086     context = 0xdeadbeef;
8087     lstrcpyA(targetsid, "kiwi");
8088     size = MAX_PATH;
8089     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8090                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8091                            &context, targetsid, &size);
8092     ok(r == ERROR_BAD_CONFIGURATION,
8093        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8094     ok(!lstrcmpA(patchcode, "apple"),
8095        "Expected patchcode to be unchanged, got %s\n", patchcode);
8096     ok(!lstrcmpA(targetprod, "banana"),
8097        "Expected targetprod to be unchanged, got %s\n", targetprod);
8098     ok(context == 0xdeadbeef,
8099        "Expected context to be unchanged, got %d\n", context);
8100     ok(!lstrcmpA(targetsid, "kiwi"),
8101        "Expected targetsid to be unchanged, got %s\n", targetsid);
8102     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8103
8104     data = MSIPATCHSTATE_SUPERSEDED;
8105     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8106                          (const BYTE *)&data, sizeof(DWORD));
8107     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8108
8109     /* State value exists */
8110     lstrcpyA(patchcode, "apple");
8111     lstrcpyA(targetprod, "banana");
8112     context = 0xdeadbeef;
8113     lstrcpyA(targetsid, "kiwi");
8114     size = MAX_PATH;
8115     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8116                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8117                            &context, targetsid, &size);
8118     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8119     ok(!lstrcmpA(patchcode, patch),
8120        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8121     ok(!lstrcmpA(targetprod, prodcode),
8122        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8123     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8124        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8125     ok(!lstrcmpA(targetsid, expectedsid),
8126        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8127     ok(size == lstrlenA(expectedsid),
8128        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8129
8130     /* MSIPATCHSTATE_OBSOLETED */
8131
8132     lstrcpyA(patchcode, "apple");
8133     lstrcpyA(targetprod, "banana");
8134     context = 0xdeadbeef;
8135     lstrcpyA(targetsid, "kiwi");
8136     size = MAX_PATH;
8137     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8138                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8139                            &context, targetsid, &size);
8140     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8141     ok(!lstrcmpA(patchcode, "apple"),
8142        "Expected patchcode to be unchanged, got %s\n", patchcode);
8143     ok(!lstrcmpA(targetprod, "banana"),
8144        "Expected targetprod to be unchanged, got %s\n", targetprod);
8145     ok(context == 0xdeadbeef,
8146        "Expected context to be unchanged, got %d\n", context);
8147     ok(!lstrcmpA(targetsid, "kiwi"),
8148        "Expected targetsid to be unchanged, got %s\n", targetsid);
8149     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8150
8151     data = MSIPATCHSTATE_OBSOLETED;
8152     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8153                          (const BYTE *)&data, sizeof(DWORD));
8154     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8155
8156     /* State value is obsoleted */
8157     lstrcpyA(patchcode, "apple");
8158     lstrcpyA(targetprod, "banana");
8159     context = 0xdeadbeef;
8160     lstrcpyA(targetsid, "kiwi");
8161     size = MAX_PATH;
8162     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8163                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8164                            &context, targetsid, &size);
8165     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8166     ok(!lstrcmpA(patchcode, patch),
8167        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8168     ok(!lstrcmpA(targetprod, prodcode),
8169        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8170     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8171        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8172     ok(!lstrcmpA(targetsid, expectedsid),
8173        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8174     ok(size == lstrlenA(expectedsid),
8175        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8176
8177     /* MSIPATCHSTATE_REGISTERED */
8178     /* FIXME */
8179
8180     /* MSIPATCHSTATE_ALL */
8181
8182     /* 1st */
8183     lstrcpyA(patchcode, "apple");
8184     lstrcpyA(targetprod, "banana");
8185     context = 0xdeadbeef;
8186     lstrcpyA(targetsid, "kiwi");
8187     size = MAX_PATH;
8188     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8189                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8190                            &context, targetsid, &size);
8191     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8192     ok(!lstrcmpA(patchcode, patch),
8193        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8194     ok(!lstrcmpA(targetprod, prodcode),
8195        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8196     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8197        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8198     ok(!lstrcmpA(targetsid, expectedsid),
8199        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8200     ok(size == lstrlenA(expectedsid),
8201        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8202
8203     /* same patch in multiple places, only one is enumerated */
8204     lstrcpyA(patchcode, "apple");
8205     lstrcpyA(targetprod, "banana");
8206     context = 0xdeadbeef;
8207     lstrcpyA(targetsid, "kiwi");
8208     size = MAX_PATH;
8209     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8210                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8211                            &context, targetsid, &size);
8212     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8213     ok(!lstrcmpA(patchcode, "apple"),
8214        "Expected patchcode to be unchanged, got %s\n", patchcode);
8215     ok(!lstrcmpA(targetprod, "banana"),
8216        "Expected targetprod to be unchanged, got %s\n", targetprod);
8217     ok(context == 0xdeadbeef,
8218        "Expected context to be unchanged, got %d\n", context);
8219     ok(!lstrcmpA(targetsid, "kiwi"),
8220        "Expected targetsid to be unchanged, got %s\n", targetsid);
8221     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8222
8223     RegDeleteValueA(hpatch, "State");
8224     RegDeleteKeyA(hpatch, "");
8225     RegCloseKey(hpatch);
8226     RegDeleteKeyA(udpatch, "");
8227     RegCloseKey(udpatch);
8228     RegDeleteKeyA(udprod, "");
8229     RegCloseKey(udprod);
8230     RegDeleteValueA(patches, "Patches");
8231     RegDeleteKeyA(patches, "");
8232     RegCloseKey(patches);
8233     RegDeleteKeyA(prodkey, "");
8234     RegCloseKey(prodkey);
8235 }
8236
8237 static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
8238 {
8239     MSIINSTALLCONTEXT context;
8240     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8241     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8242     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8243     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8244     HKEY prodkey, patches, udprod, udpatch;
8245     HKEY userkey, hpatch;
8246     DWORD size, data;
8247     LONG res;
8248     UINT r;
8249
8250     create_test_guid(prodcode, prod_squashed);
8251     create_test_guid(patch, patch_squashed);
8252
8253     /* MSIPATCHSTATE_APPLIED */
8254
8255     lstrcpyA(patchcode, "apple");
8256     lstrcpyA(targetprod, "banana");
8257     context = 0xdeadbeef;
8258     lstrcpyA(targetsid, "kiwi");
8259     size = MAX_PATH;
8260     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8261                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8262                            &context, targetsid, &size);
8263     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8264     ok(!lstrcmpA(patchcode, "apple"),
8265        "Expected patchcode to be unchanged, got %s\n", patchcode);
8266     ok(!lstrcmpA(targetprod, "banana"),
8267        "Expected targetprod to be unchanged, got %s\n", targetprod);
8268     ok(context == 0xdeadbeef,
8269        "Expected context to be unchanged, got %d\n", context);
8270     ok(!lstrcmpA(targetsid, "kiwi"),
8271        "Expected targetsid to be unchanged, got %s\n", targetsid);
8272     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8273
8274     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8275     lstrcatA(keypath, prod_squashed);
8276
8277     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8278     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8279
8280     /* current user product key exists */
8281     lstrcpyA(patchcode, "apple");
8282     lstrcpyA(targetprod, "banana");
8283     context = 0xdeadbeef;
8284     lstrcpyA(targetsid, "kiwi");
8285     size = MAX_PATH;
8286     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8287                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8288                            &context, targetsid, &size);
8289     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8290     ok(!lstrcmpA(patchcode, "apple"),
8291        "Expected patchcode to be unchanged, got %s\n", patchcode);
8292     ok(!lstrcmpA(targetprod, "banana"),
8293        "Expected targetprod to be unchanged, got %s\n", targetprod);
8294     ok(context == 0xdeadbeef,
8295        "Expected context to be unchanged, got %d\n", context);
8296     ok(!lstrcmpA(targetsid, "kiwi"),
8297        "Expected targetsid to be unchanged, got %s\n", targetsid);
8298     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8299
8300     res = RegCreateKeyA(prodkey, "Patches", &patches);
8301     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8302
8303     /* Patches key exists */
8304     lstrcpyA(patchcode, "apple");
8305     lstrcpyA(targetprod, "banana");
8306     context = 0xdeadbeef;
8307     lstrcpyA(targetsid, "kiwi");
8308     size = MAX_PATH;
8309     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8310                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8311                            &context, targetsid, &size);
8312     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8313     ok(!lstrcmpA(patchcode, "apple"),
8314        "Expected patchcode to be unchanged, got %s\n", patchcode);
8315     ok(!lstrcmpA(targetprod, "banana"),
8316        "Expected targetprod to be unchanged, got %s\n", targetprod);
8317     ok(context == 0xdeadbeef,
8318        "Expected context to be unchanged, got %d\n", context);
8319     ok(!lstrcmpA(targetsid, "kiwi"),
8320        "Expected targetsid to be unchanged, got %s\n", targetsid);
8321     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8322
8323     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8324                          (const BYTE *)patch_squashed,
8325                          lstrlenA(patch_squashed) + 1);
8326     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8327
8328     /* Patches value exists, is not REG_MULTI_SZ */
8329     lstrcpyA(patchcode, "apple");
8330     lstrcpyA(targetprod, "banana");
8331     context = 0xdeadbeef;
8332     lstrcpyA(targetsid, "kiwi");
8333     size = MAX_PATH;
8334     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8335                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8336                            &context, targetsid, &size);
8337     ok(r == ERROR_BAD_CONFIGURATION,
8338        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8339     ok(!lstrcmpA(patchcode, "apple"),
8340        "Expected patchcode to be unchanged, got %s\n", patchcode);
8341     ok(!lstrcmpA(targetprod, "banana"),
8342        "Expected targetprod to be unchanged, got %s\n", targetprod);
8343     ok(context == 0xdeadbeef,
8344        "Expected context to be unchanged, got %d\n", context);
8345     ok(!lstrcmpA(targetsid, "kiwi"),
8346        "Expected targetsid to be unchanged, got %s\n", targetsid);
8347     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8348
8349     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8350                          (const BYTE *)"a\0b\0c\0\0", 7);
8351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8352
8353     /* Patches value exists, is not a squashed guid */
8354     lstrcpyA(patchcode, "apple");
8355     lstrcpyA(targetprod, "banana");
8356     context = 0xdeadbeef;
8357     lstrcpyA(targetsid, "kiwi");
8358     size = MAX_PATH;
8359     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8360                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8361                            &context, targetsid, &size);
8362     ok(r == ERROR_BAD_CONFIGURATION,
8363        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8364     ok(!lstrcmpA(patchcode, "apple"),
8365        "Expected patchcode to be unchanged, got %s\n", patchcode);
8366     ok(!lstrcmpA(targetprod, "banana"),
8367        "Expected targetprod to be unchanged, got %s\n", targetprod);
8368     ok(context == 0xdeadbeef,
8369        "Expected context to be unchanged, got %d\n", context);
8370     ok(!lstrcmpA(targetsid, "kiwi"),
8371        "Expected targetsid to be unchanged, got %s\n", targetsid);
8372     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8373
8374     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8375                          (const BYTE *)patch_squashed,
8376                          lstrlenA(patch_squashed) + 1);
8377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8378
8379     /* Patches value exists */
8380     lstrcpyA(patchcode, "apple");
8381     lstrcpyA(targetprod, "banana");
8382     context = 0xdeadbeef;
8383     lstrcpyA(targetsid, "kiwi");
8384     size = MAX_PATH;
8385     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8386                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8387                            &context, targetsid, &size);
8388     ok(r == ERROR_NO_MORE_ITEMS ||
8389        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8390        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8391     ok(!lstrcmpA(patchcode, "apple"),
8392        "Expected patchcode to be unchanged, got %s\n", patchcode);
8393     ok(!lstrcmpA(targetprod, "banana"),
8394        "Expected targetprod to be unchanged, got %s\n", targetprod);
8395     ok(context == 0xdeadbeef,
8396        "Expected context to be unchanged, got %d\n", context);
8397     ok(!lstrcmpA(targetsid, "kiwi"),
8398        "Expected targetsid to be unchanged, got %s\n", targetsid);
8399     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8400
8401     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8402                          (const BYTE *)"whatever", 9);
8403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8404
8405     /* patch code value exists */
8406     lstrcpyA(patchcode, "apple");
8407     lstrcpyA(targetprod, "banana");
8408     context = 0xdeadbeef;
8409     lstrcpyA(targetsid, "kiwi");
8410     size = MAX_PATH;
8411     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8412                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8413                            &context, targetsid, &size);
8414     ok(r == ERROR_NO_MORE_ITEMS ||
8415        broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
8416        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8417     ok(!lstrcmpA(patchcode, "apple"),
8418        "Expected patchcode to be unchanged, got %s\n", patchcode);
8419     ok(!lstrcmpA(targetprod, "banana"),
8420        "Expected targetprod to be unchanged, got %s\n", targetprod);
8421     ok(context == 0xdeadbeef,
8422        "Expected context to be unchanged, got %d\n", context);
8423     ok(!lstrcmpA(targetsid, "kiwi"),
8424        "Expected targetsid to be unchanged, got %s\n", targetsid);
8425     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8426
8427     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8428     lstrcatA(keypath, expectedsid);
8429     lstrcatA(keypath, "\\Patches\\");
8430     lstrcatA(keypath, patch_squashed);
8431
8432     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
8433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8434
8435     /* userdata patch key exists */
8436     lstrcpyA(patchcode, "apple");
8437     lstrcpyA(targetprod, "banana");
8438     context = 0xdeadbeef;
8439     lstrcpyA(targetsid, "kiwi");
8440     size = MAX_PATH;
8441     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8442                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8443                            &context, targetsid, &size);
8444     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8445     ok(!lstrcmpA(patchcode, patch),
8446        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8447     ok(!lstrcmpA(targetprod, prodcode),
8448        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8449     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8450        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8451     ok(!lstrcmpA(targetsid, expectedsid),
8452        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8453     ok(size == lstrlenA(expectedsid),
8454        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8455
8456     /* MSIPATCHSTATE_SUPERSEDED */
8457
8458     lstrcpyA(patchcode, "apple");
8459     lstrcpyA(targetprod, "banana");
8460     context = 0xdeadbeef;
8461     lstrcpyA(targetsid, "kiwi");
8462     size = MAX_PATH;
8463     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8464                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8465                            &context, targetsid, &size);
8466     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8467     ok(!lstrcmpA(patchcode, "apple"),
8468        "Expected patchcode to be unchanged, got %s\n", patchcode);
8469     ok(!lstrcmpA(targetprod, "banana"),
8470        "Expected targetprod to be unchanged, got %s\n", targetprod);
8471     ok(context == 0xdeadbeef,
8472        "Expected context to be unchanged, got %d\n", context);
8473     ok(!lstrcmpA(targetsid, "kiwi"),
8474        "Expected targetsid to be unchanged, got %s\n", targetsid);
8475     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8476
8477     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8478     lstrcatA(keypath, expectedsid);
8479     lstrcatA(keypath, "\\Products\\");
8480     lstrcatA(keypath, prod_squashed);
8481
8482     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8483     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8484
8485     /* UserData product key exists */
8486     lstrcpyA(patchcode, "apple");
8487     lstrcpyA(targetprod, "banana");
8488     context = 0xdeadbeef;
8489     lstrcpyA(targetsid, "kiwi");
8490     size = MAX_PATH;
8491     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8492                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8493                            &context, targetsid, &size);
8494     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8495     ok(!lstrcmpA(patchcode, "apple"),
8496        "Expected patchcode to be unchanged, got %s\n", patchcode);
8497     ok(!lstrcmpA(targetprod, "banana"),
8498        "Expected targetprod to be unchanged, got %s\n", targetprod);
8499     ok(context == 0xdeadbeef,
8500        "Expected context to be unchanged, got %d\n", context);
8501     ok(!lstrcmpA(targetsid, "kiwi"),
8502        "Expected targetsid to be unchanged, got %s\n", targetsid);
8503     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8504
8505     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8506     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8507
8508     /* UserData patches key exists */
8509     lstrcpyA(patchcode, "apple");
8510     lstrcpyA(targetprod, "banana");
8511     context = 0xdeadbeef;
8512     lstrcpyA(targetsid, "kiwi");
8513     size = MAX_PATH;
8514     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8515                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8516                            &context, targetsid, &size);
8517     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8518     ok(!lstrcmpA(patchcode, "apple"),
8519        "Expected patchcode to be unchanged, got %s\n", patchcode);
8520     ok(!lstrcmpA(targetprod, "banana"),
8521        "Expected targetprod to be unchanged, got %s\n", targetprod);
8522     ok(context == 0xdeadbeef,
8523        "Expected context to be unchanged, got %d\n", context);
8524     ok(!lstrcmpA(targetsid, "kiwi"),
8525        "Expected targetsid to be unchanged, got %s\n", targetsid);
8526     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8527
8528     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8529     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8530
8531     /* specific UserData patch key exists */
8532     lstrcpyA(patchcode, "apple");
8533     lstrcpyA(targetprod, "banana");
8534     context = 0xdeadbeef;
8535     lstrcpyA(targetsid, "kiwi");
8536     size = MAX_PATH;
8537     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8538                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8539                            &context, targetsid, &size);
8540     ok(r == ERROR_BAD_CONFIGURATION,
8541        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8542     ok(!lstrcmpA(patchcode, "apple"),
8543        "Expected patchcode to be unchanged, got %s\n", patchcode);
8544     ok(!lstrcmpA(targetprod, "banana"),
8545        "Expected targetprod to be unchanged, got %s\n", targetprod);
8546     ok(context == 0xdeadbeef,
8547        "Expected context to be unchanged, got %d\n", context);
8548     ok(!lstrcmpA(targetsid, "kiwi"),
8549        "Expected targetsid to be unchanged, got %s\n", targetsid);
8550     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8551
8552     data = MSIPATCHSTATE_SUPERSEDED;
8553     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8554                          (const BYTE *)&data, sizeof(DWORD));
8555     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8556
8557     /* State value exists */
8558     lstrcpyA(patchcode, "apple");
8559     lstrcpyA(targetprod, "banana");
8560     context = 0xdeadbeef;
8561     lstrcpyA(targetsid, "kiwi");
8562     size = MAX_PATH;
8563     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8564                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8565                            &context, targetsid, &size);
8566     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8567     ok(!lstrcmpA(patchcode, patch),
8568        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8569     ok(!lstrcmpA(targetprod, prodcode),
8570        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8571     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8572        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8573     ok(!lstrcmpA(targetsid, expectedsid),
8574        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8575     ok(size == lstrlenA(expectedsid),
8576        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8577
8578     /* MSIPATCHSTATE_OBSOLETED */
8579
8580     lstrcpyA(patchcode, "apple");
8581     lstrcpyA(targetprod, "banana");
8582     context = 0xdeadbeef;
8583     lstrcpyA(targetsid, "kiwi");
8584     size = MAX_PATH;
8585     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8586                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8587                            &context, targetsid, &size);
8588     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8589     ok(!lstrcmpA(patchcode, "apple"),
8590        "Expected patchcode to be unchanged, got %s\n", patchcode);
8591     ok(!lstrcmpA(targetprod, "banana"),
8592        "Expected targetprod to be unchanged, got %s\n", targetprod);
8593     ok(context == 0xdeadbeef,
8594        "Expected context to be unchanged, got %d\n", context);
8595     ok(!lstrcmpA(targetsid, "kiwi"),
8596        "Expected targetsid to be unchanged, got %s\n", targetsid);
8597     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8598
8599     data = MSIPATCHSTATE_OBSOLETED;
8600     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8601                          (const BYTE *)&data, sizeof(DWORD));
8602     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8603
8604     /* State value is obsoleted */
8605     lstrcpyA(patchcode, "apple");
8606     lstrcpyA(targetprod, "banana");
8607     context = 0xdeadbeef;
8608     lstrcpyA(targetsid, "kiwi");
8609     size = MAX_PATH;
8610     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8611                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8612                            &context, targetsid, &size);
8613     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8614     ok(!lstrcmpA(patchcode, patch),
8615        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8616     ok(!lstrcmpA(targetprod, prodcode),
8617        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8618     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8619        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8620     ok(!lstrcmpA(targetsid, expectedsid),
8621        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8622     ok(size == lstrlenA(expectedsid),
8623        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8624
8625     /* MSIPATCHSTATE_REGISTERED */
8626     /* FIXME */
8627
8628     /* MSIPATCHSTATE_ALL */
8629
8630     /* 1st */
8631     lstrcpyA(patchcode, "apple");
8632     lstrcpyA(targetprod, "banana");
8633     context = 0xdeadbeef;
8634     lstrcpyA(targetsid, "kiwi");
8635     size = MAX_PATH;
8636     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8637                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8638                            &context, targetsid, &size);
8639     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8640     ok(!lstrcmpA(patchcode, patch),
8641        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8642     ok(!lstrcmpA(targetprod, prodcode),
8643        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8644     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8645        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8646     ok(!lstrcmpA(targetsid, expectedsid),
8647        "Expected \"%s\", got \"%s\"\n", expectedsid, targetsid);
8648     ok(size == lstrlenA(expectedsid),
8649        "Expected %d, got %d\n", lstrlenA(expectedsid), size);
8650
8651     /* same patch in multiple places, only one is enumerated */
8652     lstrcpyA(patchcode, "apple");
8653     lstrcpyA(targetprod, "banana");
8654     context = 0xdeadbeef;
8655     lstrcpyA(targetsid, "kiwi");
8656     size = MAX_PATH;
8657     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8658                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8659                            &context, targetsid, &size);
8660     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8661     ok(!lstrcmpA(patchcode, "apple"),
8662        "Expected patchcode to be unchanged, got %s\n", patchcode);
8663     ok(!lstrcmpA(targetprod, "banana"),
8664        "Expected targetprod to be unchanged, got %s\n", targetprod);
8665     ok(context == 0xdeadbeef,
8666        "Expected context to be unchanged, got %d\n", context);
8667     ok(!lstrcmpA(targetsid, "kiwi"),
8668        "Expected targetsid to be unchanged, got %s\n", targetsid);
8669     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8670
8671     RegDeleteValueA(hpatch, "State");
8672     RegDeleteKeyA(hpatch, "");
8673     RegCloseKey(hpatch);
8674     RegDeleteKeyA(udpatch, "");
8675     RegCloseKey(udpatch);
8676     RegDeleteKeyA(udprod, "");
8677     RegCloseKey(udprod);
8678     RegDeleteKeyA(userkey, "");
8679     RegCloseKey(userkey);
8680     RegDeleteValueA(patches, patch_squashed);
8681     RegDeleteValueA(patches, "Patches");
8682     RegDeleteKeyA(patches, "");
8683     RegCloseKey(patches);
8684     RegDeleteKeyA(prodkey, "");
8685     RegCloseKey(prodkey);
8686 }
8687
8688 static void test_MsiEnumPatchesEx_machine(void)
8689 {
8690     CHAR keypath[MAX_PATH], patch[MAX_PATH];
8691     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
8692     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
8693     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
8694     HKEY prodkey, patches, udprod, udpatch;
8695     HKEY hpatch;
8696     MSIINSTALLCONTEXT context;
8697     DWORD size, data;
8698     LONG res;
8699     UINT r;
8700
8701     create_test_guid(prodcode, prod_squashed);
8702     create_test_guid(patch, patch_squashed);
8703
8704     /* MSIPATCHSTATE_APPLIED */
8705
8706     lstrcpyA(patchcode, "apple");
8707     lstrcpyA(targetprod, "banana");
8708     context = 0xdeadbeef;
8709     lstrcpyA(targetsid, "kiwi");
8710     size = MAX_PATH;
8711     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8712                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8713                            &context, targetsid, &size);
8714     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8715     ok(!lstrcmpA(patchcode, "apple"),
8716        "Expected patchcode to be unchanged, got %s\n", patchcode);
8717     ok(!lstrcmpA(targetprod, "banana"),
8718        "Expected targetprod to be unchanged, got %s\n", targetprod);
8719     ok(context == 0xdeadbeef,
8720        "Expected context to be unchanged, got %d\n", context);
8721     ok(!lstrcmpA(targetsid, "kiwi"),
8722        "Expected targetsid to be unchanged, got %s\n", targetsid);
8723     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8724
8725     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8726     lstrcatA(keypath, prod_squashed);
8727
8728     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
8729     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8730
8731     /* local product key exists */
8732     lstrcpyA(patchcode, "apple");
8733     lstrcpyA(targetprod, "banana");
8734     context = 0xdeadbeef;
8735     lstrcpyA(targetsid, "kiwi");
8736     size = MAX_PATH;
8737     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8738                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8739                            &context, targetsid, &size);
8740     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8741     ok(!lstrcmpA(patchcode, "apple"),
8742        "Expected patchcode to be unchanged, got %s\n", patchcode);
8743     ok(!lstrcmpA(targetprod, "banana"),
8744        "Expected targetprod to be unchanged, got %s\n", targetprod);
8745     ok(context == 0xdeadbeef,
8746        "Expected context to be unchanged, got %d\n", context);
8747     ok(!lstrcmpA(targetsid, "kiwi"),
8748        "Expected targetsid to be unchanged, got %s\n", targetsid);
8749     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8750
8751     res = RegCreateKeyA(prodkey, "Patches", &patches);
8752     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8753
8754     /* Patches key exists */
8755     lstrcpyA(patchcode, "apple");
8756     lstrcpyA(targetprod, "banana");
8757     context = 0xdeadbeef;
8758     lstrcpyA(targetsid, "kiwi");
8759     size = MAX_PATH;
8760     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8761                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8762                            &context, targetsid, &size);
8763     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8764     ok(!lstrcmpA(patchcode, "apple"),
8765        "Expected patchcode to be unchanged, got %s\n", patchcode);
8766     ok(!lstrcmpA(targetprod, "banana"),
8767        "Expected targetprod to be unchanged, got %s\n", targetprod);
8768     ok(context == 0xdeadbeef,
8769        "Expected context to be unchanged, got %d\n", context);
8770     ok(!lstrcmpA(targetsid, "kiwi"),
8771        "Expected targetsid to be unchanged, got %s\n", targetsid);
8772     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8773
8774     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8775                          (const BYTE *)patch_squashed,
8776                          lstrlenA(patch_squashed) + 1);
8777     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8778
8779     /* Patches value exists, is not REG_MULTI_SZ */
8780     lstrcpyA(patchcode, "apple");
8781     lstrcpyA(targetprod, "banana");
8782     context = 0xdeadbeef;
8783     lstrcpyA(targetsid, "kiwi");
8784     size = MAX_PATH;
8785     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8786                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8787                            &context, targetsid, &size);
8788     ok(r == ERROR_BAD_CONFIGURATION,
8789        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8790     ok(!lstrcmpA(patchcode, "apple"),
8791        "Expected patchcode to be unchanged, got %s\n", patchcode);
8792     ok(!lstrcmpA(targetprod, "banana"),
8793        "Expected targetprod to be unchanged, got %s\n", targetprod);
8794     ok(context == 0xdeadbeef,
8795        "Expected context to be unchanged, got %d\n", context);
8796     ok(!lstrcmpA(targetsid, "kiwi"),
8797        "Expected targetsid to be unchanged, got %s\n", targetsid);
8798     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8799
8800     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8801                          (const BYTE *)"a\0b\0c\0\0", 7);
8802     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8803
8804     /* Patches value exists, is not a squashed guid */
8805     lstrcpyA(patchcode, "apple");
8806     lstrcpyA(targetprod, "banana");
8807     context = 0xdeadbeef;
8808     lstrcpyA(targetsid, "kiwi");
8809     size = MAX_PATH;
8810     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8811                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8812                            &context, targetsid, &size);
8813     ok(r == ERROR_BAD_CONFIGURATION,
8814        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8815     ok(!lstrcmpA(patchcode, "apple"),
8816        "Expected patchcode to be unchanged, got %s\n", patchcode);
8817     ok(!lstrcmpA(targetprod, "banana"),
8818        "Expected targetprod to be unchanged, got %s\n", targetprod);
8819     ok(context == 0xdeadbeef,
8820        "Expected context to be unchanged, got %d\n", context);
8821     ok(!lstrcmpA(targetsid, "kiwi"),
8822        "Expected targetsid to be unchanged, got %s\n", targetsid);
8823     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8824
8825     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8826     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8827                          (const BYTE *)patch_squashed,
8828                          lstrlenA(patch_squashed) + 2);
8829     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8830
8831     /* Patches value exists */
8832     lstrcpyA(patchcode, "apple");
8833     lstrcpyA(targetprod, "banana");
8834     context = 0xdeadbeef;
8835     lstrcpyA(targetsid, "kiwi");
8836     size = MAX_PATH;
8837     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8838                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8839                            &context, targetsid, &size);
8840     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8841     ok(!lstrcmpA(patchcode, "apple"),
8842        "Expected patchcode to be unchanged, got %s\n", patchcode);
8843     ok(!lstrcmpA(targetprod, "banana"),
8844        "Expected targetprod to be unchanged, got %s\n", targetprod);
8845     ok(context == 0xdeadbeef,
8846        "Expected context to be unchanged, got %d\n", context);
8847     ok(!lstrcmpA(targetsid, "kiwi"),
8848        "Expected targetsid to be unchanged, got %s\n", targetsid);
8849     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8850
8851     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8852                          (const BYTE *)"whatever", 9);
8853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8854
8855     /* patch code value exists */
8856     lstrcpyA(patchcode, "apple");
8857     lstrcpyA(targetprod, "banana");
8858     context = 0xdeadbeef;
8859     lstrcpyA(targetsid, "kiwi");
8860     size = MAX_PATH;
8861     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8862                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8863                            &context, targetsid, &size);
8864     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8865     ok(!lstrcmpA(patchcode, patch),
8866        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8867     ok(!lstrcmpA(targetprod, prodcode),
8868        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8869     ok(context == MSIINSTALLCONTEXT_MACHINE,
8870        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8871     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8872     ok(size == 0, "Expected 0, got %d\n", size);
8873
8874     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8875     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8876     lstrcatA(keypath, prod_squashed);
8877
8878     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8879     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8880
8881     /* local UserData product key exists */
8882     lstrcpyA(patchcode, "apple");
8883     lstrcpyA(targetprod, "banana");
8884     context = 0xdeadbeef;
8885     lstrcpyA(targetsid, "kiwi");
8886     size = MAX_PATH;
8887     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8888                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8889                            &context, targetsid, &size);
8890     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8891     ok(!lstrcmpA(patchcode, patch),
8892        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8893     ok(!lstrcmpA(targetprod, prodcode),
8894        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8895     ok(context == MSIINSTALLCONTEXT_MACHINE,
8896        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8897     ok(!lstrcmpA(targetsid, ""),
8898        "Expected \"\", got \"%s\"\n", targetsid);
8899     ok(size == 0, "Expected 0, got %d\n", size);
8900
8901     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8902     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8903
8904     /* local UserData Patches key exists */
8905     lstrcpyA(patchcode, "apple");
8906     lstrcpyA(targetprod, "banana");
8907     context = 0xdeadbeef;
8908     lstrcpyA(targetsid, "kiwi");
8909     size = MAX_PATH;
8910     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8911                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8912                            &context, targetsid, &size);
8913     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8914     ok(!lstrcmpA(patchcode, patch),
8915        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8916     ok(!lstrcmpA(targetprod, prodcode),
8917        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8918     ok(context == MSIINSTALLCONTEXT_MACHINE,
8919        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8920     ok(!lstrcmpA(targetsid, ""),
8921        "Expected \"\", got \"%s\"\n", targetsid);
8922     ok(size == 0, "Expected 0, got %d\n", size);
8923
8924     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8925     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8926
8927     /* local UserData Product patch key exists */
8928     lstrcpyA(patchcode, "apple");
8929     lstrcpyA(targetprod, "banana");
8930     context = 0xdeadbeef;
8931     lstrcpyA(targetsid, "kiwi");
8932     size = MAX_PATH;
8933     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8934                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8935                            &context, targetsid, &size);
8936     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8937     ok(!lstrcmpA(patchcode, "apple"),
8938        "Expected patchcode to be unchanged, got %s\n", patchcode);
8939     ok(!lstrcmpA(targetprod, "banana"),
8940        "Expected targetprod to be unchanged, got %s\n", targetprod);
8941     ok(context == 0xdeadbeef,
8942        "Expected context to be unchanged, got %d\n", context);
8943     ok(!lstrcmpA(targetsid, "kiwi"),
8944        "Expected targetsid to be unchanged, got %s\n", targetsid);
8945     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8946
8947     data = MSIPATCHSTATE_APPLIED;
8948     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8949                          (const BYTE *)&data, sizeof(DWORD));
8950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8951
8952     /* State value exists */
8953     lstrcpyA(patchcode, "apple");
8954     lstrcpyA(targetprod, "banana");
8955     context = 0xdeadbeef;
8956     lstrcpyA(targetsid, "kiwi");
8957     size = MAX_PATH;
8958     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8959                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8960                            &context, targetsid, &size);
8961     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8962     ok(!lstrcmpA(patchcode, patch),
8963        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8964     ok(!lstrcmpA(targetprod, prodcode),
8965        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8966     ok(context == MSIINSTALLCONTEXT_MACHINE,
8967        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8968     ok(!lstrcmpA(targetsid, ""),
8969        "Expected \"\", got \"%s\"\n", targetsid);
8970     ok(size == 0, "Expected 0, got %d\n", size);
8971
8972     /* MSIPATCHSTATE_SUPERSEDED */
8973
8974     lstrcpyA(patchcode, "apple");
8975     lstrcpyA(targetprod, "banana");
8976     context = 0xdeadbeef;
8977     lstrcpyA(targetsid, "kiwi");
8978     size = MAX_PATH;
8979     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8980                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8981                            &context, targetsid, &size);
8982     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8983     ok(!lstrcmpA(patchcode, "apple"),
8984        "Expected patchcode to be unchanged, got %s\n", patchcode);
8985     ok(!lstrcmpA(targetprod, "banana"),
8986        "Expected targetprod to be unchanged, got %s\n", targetprod);
8987     ok(context == 0xdeadbeef,
8988        "Expected context to be unchanged, got %d\n", context);
8989     ok(!lstrcmpA(targetsid, "kiwi"),
8990        "Expected targetsid to be unchanged, got %s\n", targetsid);
8991     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8992
8993     data = MSIPATCHSTATE_SUPERSEDED;
8994     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8995                          (const BYTE *)&data, sizeof(DWORD));
8996     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8997
8998     /* State value is MSIPATCHSTATE_SUPERSEDED */
8999     lstrcpyA(patchcode, "apple");
9000     lstrcpyA(targetprod, "banana");
9001     context = 0xdeadbeef;
9002     lstrcpyA(targetsid, "kiwi");
9003     size = MAX_PATH;
9004     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9005                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
9006                            &context, targetsid, &size);
9007     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9008     ok(!lstrcmpA(patchcode, patch),
9009        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9010     ok(!lstrcmpA(targetprod, prodcode),
9011        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9012     ok(context == MSIINSTALLCONTEXT_MACHINE,
9013        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9014     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9015     ok(size == 0, "Expected 0, got %d\n", size);
9016
9017     /* MSIPATCHSTATE_OBSOLETED */
9018
9019     lstrcpyA(patchcode, "apple");
9020     lstrcpyA(targetprod, "banana");
9021     context = 0xdeadbeef;
9022     lstrcpyA(targetsid, "kiwi");
9023     size = MAX_PATH;
9024     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9025                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9026                            &context, targetsid, &size);
9027     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9028     ok(!lstrcmpA(patchcode, "apple"),
9029        "Expected patchcode to be unchanged, got %s\n", patchcode);
9030     ok(!lstrcmpA(targetprod, "banana"),
9031        "Expected targetprod to be unchanged, got %s\n", targetprod);
9032     ok(context == 0xdeadbeef,
9033        "Expected context to be unchanged, got %d\n", context);
9034     ok(!lstrcmpA(targetsid, "kiwi"),
9035        "Expected targetsid to be unchanged, got %s\n", targetsid);
9036     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9037
9038     data = MSIPATCHSTATE_OBSOLETED;
9039     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9040                          (const BYTE *)&data, sizeof(DWORD));
9041     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9042
9043     /* State value is obsoleted */
9044     lstrcpyA(patchcode, "apple");
9045     lstrcpyA(targetprod, "banana");
9046     context = 0xdeadbeef;
9047     lstrcpyA(targetsid, "kiwi");
9048     size = MAX_PATH;
9049     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9050                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9051                            &context, targetsid, &size);
9052     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9053     ok(!lstrcmpA(patchcode, patch),
9054        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9055     ok(!lstrcmpA(targetprod, prodcode),
9056        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9057     ok(context == MSIINSTALLCONTEXT_MACHINE,
9058        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9059     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9060     ok(size == 0, "Expected 0, got %d\n", size);
9061
9062     /* MSIPATCHSTATE_REGISTERED */
9063     /* FIXME */
9064
9065     /* MSIPATCHSTATE_ALL */
9066
9067     /* 1st */
9068     lstrcpyA(patchcode, "apple");
9069     lstrcpyA(targetprod, "banana");
9070     context = 0xdeadbeef;
9071     lstrcpyA(targetsid, "kiwi");
9072     size = MAX_PATH;
9073     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9074                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9075                            &context, targetsid, &size);
9076     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9077     ok(!lstrcmpA(patchcode, patch),
9078        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9079     ok(!lstrcmpA(targetprod, prodcode),
9080        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9081     ok(context == MSIINSTALLCONTEXT_MACHINE,
9082        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9083     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9084     ok(size == 0, "Expected 0, got %d\n", size);
9085
9086     /* same patch in multiple places, only one is enumerated */
9087     lstrcpyA(patchcode, "apple");
9088     lstrcpyA(targetprod, "banana");
9089     context = 0xdeadbeef;
9090     lstrcpyA(targetsid, "kiwi");
9091     size = MAX_PATH;
9092     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9093                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9094                            &context, targetsid, &size);
9095     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9096     ok(!lstrcmpA(patchcode, "apple"),
9097        "Expected patchcode to be unchanged, got %s\n", patchcode);
9098     ok(!lstrcmpA(targetprod, "banana"),
9099        "Expected targetprod to be unchanged, got %s\n", targetprod);
9100     ok(context == 0xdeadbeef,
9101        "Expected context to be unchanged, got %d\n", context);
9102     ok(!lstrcmpA(targetsid, "kiwi"),
9103        "Expected targetsid to be unchanged, got %s\n", targetsid);
9104     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9105
9106     RegDeleteValueA(patches, patch_squashed);
9107     RegDeleteValueA(patches, "Patches");
9108     RegDeleteKeyA(patches, "");
9109     RegCloseKey(patches);
9110     RegDeleteValueA(hpatch, "State");
9111     RegDeleteKeyA(hpatch, "");
9112     RegCloseKey(hpatch);
9113     RegDeleteKeyA(udpatch, "");
9114     RegCloseKey(udpatch);
9115     RegDeleteKeyA(udprod, "");
9116     RegCloseKey(udprod);
9117     RegDeleteKeyA(prodkey, "");
9118     RegCloseKey(prodkey);
9119 }
9120
9121 static void test_MsiEnumPatchesEx(void)
9122 {
9123     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
9124     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9125     CHAR patchcode[MAX_PATH];
9126     MSIINSTALLCONTEXT context;
9127     LPSTR usersid;
9128     DWORD size;
9129     UINT r;
9130
9131     if (!pMsiEnumPatchesExA)
9132     {
9133         win_skip("MsiEnumPatchesExA not implemented\n");
9134         return;
9135     }
9136
9137     create_test_guid(prodcode, prod_squashed);
9138     get_user_sid(&usersid);
9139
9140     /* empty szProductCode */
9141     lstrcpyA(patchcode, "apple");
9142     lstrcpyA(targetprod, "banana");
9143     context = 0xdeadbeef;
9144     lstrcpyA(targetsid, "kiwi");
9145     size = MAX_PATH;
9146     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9147                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9148                            targetsid, &size);
9149     ok(r == ERROR_INVALID_PARAMETER,
9150        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9151     ok(!lstrcmpA(patchcode, "apple"),
9152        "Expected patchcode to be unchanged, got %s\n", patchcode);
9153     ok(!lstrcmpA(targetprod, "banana"),
9154        "Expected targetprod to be unchanged, got %s\n", targetprod);
9155     ok(context == 0xdeadbeef,
9156        "Expected context to be unchanged, got %d\n", context);
9157     ok(!lstrcmpA(targetsid, "kiwi"),
9158        "Expected targetsid to be unchanged, got %s\n", targetsid);
9159     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9160
9161     /* garbage szProductCode */
9162     lstrcpyA(patchcode, "apple");
9163     lstrcpyA(targetprod, "banana");
9164     context = 0xdeadbeef;
9165     lstrcpyA(targetsid, "kiwi");
9166     size = MAX_PATH;
9167     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9168                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
9169                            targetsid, &size);
9170     ok(r == ERROR_INVALID_PARAMETER,
9171        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9172     ok(!lstrcmpA(patchcode, "apple"),
9173        "Expected patchcode to be unchanged, got %s\n", patchcode);
9174     ok(!lstrcmpA(targetprod, "banana"),
9175        "Expected targetprod to be unchanged, got %s\n", targetprod);
9176     ok(context == 0xdeadbeef,
9177        "Expected context to be unchanged, got %d\n", context);
9178     ok(!lstrcmpA(targetsid, "kiwi"),
9179        "Expected targetsid to be unchanged, got %s\n", targetsid);
9180     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9181
9182     /* guid without brackets */
9183     lstrcpyA(patchcode, "apple");
9184     lstrcpyA(targetprod, "banana");
9185     context = 0xdeadbeef;
9186     lstrcpyA(targetsid, "kiwi");
9187     size = MAX_PATH;
9188     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
9189                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9190                            0, patchcode, targetprod, &context,
9191                            targetsid, &size);
9192     ok(r == ERROR_INVALID_PARAMETER,
9193        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9194     ok(!lstrcmpA(patchcode, "apple"),
9195        "Expected patchcode to be unchanged, got %s\n", patchcode);
9196     ok(!lstrcmpA(targetprod, "banana"),
9197        "Expected targetprod to be unchanged, got %s\n", targetprod);
9198     ok(context == 0xdeadbeef,
9199        "Expected context to be unchanged, got %d\n", context);
9200     ok(!lstrcmpA(targetsid, "kiwi"),
9201        "Expected targetsid to be unchanged, got %s\n", targetsid);
9202     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9203
9204     /* guid with brackets */
9205     lstrcpyA(patchcode, "apple");
9206     lstrcpyA(targetprod, "banana");
9207     context = 0xdeadbeef;
9208     lstrcpyA(targetsid, "kiwi");
9209     size = MAX_PATH;
9210     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
9211                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9212                            0, patchcode, targetprod, &context,
9213                            targetsid, &size);
9214     ok(r == ERROR_NO_MORE_ITEMS,
9215        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9216     ok(!lstrcmpA(patchcode, "apple"),
9217        "Expected patchcode to be unchanged, got %s\n", patchcode);
9218     ok(!lstrcmpA(targetprod, "banana"),
9219        "Expected targetprod to be unchanged, got %s\n", targetprod);
9220     ok(context == 0xdeadbeef,
9221        "Expected context to be unchanged, got %d\n", context);
9222     ok(!lstrcmpA(targetsid, "kiwi"),
9223        "Expected targetsid to be unchanged, got %s\n", targetsid);
9224     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9225
9226     /* szUserSid is S-1-5-18 */
9227     lstrcpyA(patchcode, "apple");
9228     lstrcpyA(targetprod, "banana");
9229     context = 0xdeadbeef;
9230     lstrcpyA(targetsid, "kiwi");
9231     size = MAX_PATH;
9232     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
9233                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
9234                            0, patchcode, targetprod, &context,
9235                            targetsid, &size);
9236     ok(r == ERROR_INVALID_PARAMETER,
9237        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9238     ok(!lstrcmpA(patchcode, "apple"),
9239        "Expected patchcode to be unchanged, got %s\n", patchcode);
9240     ok(!lstrcmpA(targetprod, "banana"),
9241        "Expected targetprod to be unchanged, got %s\n", targetprod);
9242     ok(context == 0xdeadbeef,
9243        "Expected context to be unchanged, got %d\n", context);
9244     ok(!lstrcmpA(targetsid, "kiwi"),
9245        "Expected targetsid to be unchanged, got %s\n", targetsid);
9246     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9247
9248     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
9249     lstrcpyA(patchcode, "apple");
9250     lstrcpyA(targetprod, "banana");
9251     context = 0xdeadbeef;
9252     lstrcpyA(targetsid, "kiwi");
9253     size = MAX_PATH;
9254     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
9255                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9256                            &context, targetsid, &size);
9257     ok(r == ERROR_INVALID_PARAMETER,
9258        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9259     ok(!lstrcmpA(patchcode, "apple"),
9260        "Expected patchcode to be unchanged, got %s\n", patchcode);
9261     ok(!lstrcmpA(targetprod, "banana"),
9262        "Expected targetprod to be unchanged, got %s\n", targetprod);
9263     ok(context == 0xdeadbeef,
9264        "Expected context to be unchanged, got %d\n", context);
9265     ok(!lstrcmpA(targetsid, "kiwi"),
9266        "Expected targetsid to be unchanged, got %s\n", targetsid);
9267     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9268
9269     /* dwContext is out of bounds */
9270     lstrcpyA(patchcode, "apple");
9271     lstrcpyA(targetprod, "banana");
9272     context = 0xdeadbeef;
9273     lstrcpyA(targetsid, "kiwi");
9274     size = MAX_PATH;
9275     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
9276                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9277                            &context, targetsid, &size);
9278     ok(r == ERROR_INVALID_PARAMETER,
9279        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9280     ok(!lstrcmpA(patchcode, "apple"),
9281        "Expected patchcode to be unchanged, got %s\n", patchcode);
9282     ok(!lstrcmpA(targetprod, "banana"),
9283        "Expected targetprod to be unchanged, got %s\n", targetprod);
9284     ok(context == 0xdeadbeef,
9285        "Expected context to be unchanged, got %d\n", context);
9286     ok(!lstrcmpA(targetsid, "kiwi"),
9287        "Expected targetsid to be unchanged, got %s\n", targetsid);
9288     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9289
9290     /* dwContext is out of bounds */
9291     lstrcpyA(patchcode, "apple");
9292     lstrcpyA(targetprod, "banana");
9293     context = 0xdeadbeef;
9294     lstrcpyA(targetsid, "kiwi");
9295     size = MAX_PATH;
9296     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
9297                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9298                            &context, targetsid, &size);
9299     ok(r == ERROR_INVALID_PARAMETER,
9300        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9301     ok(!lstrcmpA(patchcode, "apple"),
9302        "Expected patchcode to be unchanged, got %s\n", patchcode);
9303     ok(!lstrcmpA(targetprod, "banana"),
9304        "Expected targetprod to be unchanged, got %s\n", targetprod);
9305     ok(context == 0xdeadbeef,
9306        "Expected context to be unchanged, got %d\n", context);
9307     ok(!lstrcmpA(targetsid, "kiwi"),
9308        "Expected targetsid to be unchanged, got %s\n", targetsid);
9309     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9310
9311     /* dwFilter is out of bounds */
9312     lstrcpyA(patchcode, "apple");
9313     lstrcpyA(targetprod, "banana");
9314     context = 0xdeadbeef;
9315     lstrcpyA(targetsid, "kiwi");
9316     size = MAX_PATH;
9317     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9318                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
9319                            &context, targetsid, &size);
9320     ok(r == ERROR_INVALID_PARAMETER,
9321        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9322     ok(!lstrcmpA(patchcode, "apple"),
9323        "Expected patchcode to be unchanged, got %s\n", patchcode);
9324     ok(!lstrcmpA(targetprod, "banana"),
9325        "Expected targetprod to be unchanged, got %s\n", targetprod);
9326     ok(context == 0xdeadbeef,
9327        "Expected context to be unchanged, got %d\n", context);
9328     ok(!lstrcmpA(targetsid, "kiwi"),
9329        "Expected targetsid to be unchanged, got %s\n", targetsid);
9330     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9331
9332     /* dwFilter is out of bounds */
9333     lstrcpyA(patchcode, "apple");
9334     lstrcpyA(targetprod, "banana");
9335     context = 0xdeadbeef;
9336     lstrcpyA(targetsid, "kiwi");
9337     size = MAX_PATH;
9338     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9339                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
9340                            &context, targetsid, &size);
9341     ok(r == ERROR_INVALID_PARAMETER,
9342        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9343     ok(!lstrcmpA(patchcode, "apple"),
9344        "Expected patchcode to be unchanged, got %s\n", patchcode);
9345     ok(!lstrcmpA(targetprod, "banana"),
9346        "Expected targetprod to be unchanged, got %s\n", targetprod);
9347     ok(context == 0xdeadbeef,
9348        "Expected context to be unchanged, got %d\n", context);
9349     ok(!lstrcmpA(targetsid, "kiwi"),
9350        "Expected targetsid to be unchanged, got %s\n", targetsid);
9351     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9352
9353     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
9354     lstrcpyA(patchcode, "apple");
9355     lstrcpyA(targetprod, "banana");
9356     context = 0xdeadbeef;
9357     lstrcpyA(targetsid, "kiwi");
9358     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
9359                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9360                            &context, targetsid, NULL);
9361     ok(r == ERROR_INVALID_PARAMETER,
9362        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9363     ok(!lstrcmpA(patchcode, "apple"),
9364        "Expected patchcode to be unchanged, got %s\n", patchcode);
9365     ok(!lstrcmpA(targetprod, "banana"),
9366        "Expected targetprod to be unchanged, got %s\n", targetprod);
9367     ok(context == 0xdeadbeef,
9368        "Expected context to be unchanged, got %d\n", context);
9369     ok(!lstrcmpA(targetsid, "kiwi"),
9370        "Expected targetsid to be unchanged, got %s\n", targetsid);
9371
9372     test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
9373     test_MsiEnumPatchesEx_usermanaged(NULL, usersid);
9374     test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
9375     test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
9376     test_MsiEnumPatchesEx_userunmanaged(NULL, usersid);
9377     /* FIXME: Successfully test userunmanaged with a different user */
9378     test_MsiEnumPatchesEx_machine();
9379     LocalFree(usersid);
9380 }
9381
9382 static void test_MsiEnumPatches(void)
9383 {
9384     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9385     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9386     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9387     CHAR transforms[MAX_PATH];
9388     WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
9389     HKEY prodkey, patches, udprod;
9390     HKEY userkey, hpatch, udpatch;
9391     DWORD size, data;
9392     LPSTR usersid;
9393     LONG res;
9394     UINT r;
9395
9396     create_test_guid(prodcode, prod_squashed);
9397     create_test_guid(patchcode, patch_squashed);
9398     get_user_sid(&usersid);
9399
9400     /* NULL szProduct */
9401     size = MAX_PATH;
9402     lstrcpyA(patch, "apple");
9403     lstrcpyA(transforms, "banana");
9404     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9405     ok(r == ERROR_INVALID_PARAMETER,
9406        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9407     ok(!lstrcmpA(patch, "apple"),
9408        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9409     ok(!lstrcmpA(transforms, "banana"),
9410        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9411     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9412
9413     /* empty szProduct */
9414     size = MAX_PATH;
9415     lstrcpyA(patch, "apple");
9416     lstrcpyA(transforms, "banana");
9417     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9418     ok(r == ERROR_INVALID_PARAMETER,
9419        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9420     ok(!lstrcmpA(patch, "apple"),
9421        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9422     ok(!lstrcmpA(transforms, "banana"),
9423        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9424     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9425
9426     /* garbage szProduct */
9427     size = MAX_PATH;
9428     lstrcpyA(patch, "apple");
9429     lstrcpyA(transforms, "banana");
9430     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9431     ok(r == ERROR_INVALID_PARAMETER,
9432        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9433     ok(!lstrcmpA(patch, "apple"),
9434        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9435     ok(!lstrcmpA(transforms, "banana"),
9436        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9437     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9438
9439     /* guid without brackets */
9440     size = MAX_PATH;
9441     lstrcpyA(patch, "apple");
9442     lstrcpyA(transforms, "banana");
9443     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9444                         transforms, &size);
9445     ok(r == ERROR_INVALID_PARAMETER,
9446        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9447     ok(!lstrcmpA(patch, "apple"),
9448        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9449     ok(!lstrcmpA(transforms, "banana"),
9450        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9451     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9452
9453     /* guid with brackets */
9454     size = MAX_PATH;
9455     lstrcpyA(patch, "apple");
9456     lstrcpyA(transforms, "banana");
9457     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9458                         transforms, &size);
9459     ok(r == ERROR_UNKNOWN_PRODUCT,
9460        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9461     ok(!lstrcmpA(patch, "apple"),
9462        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9463     ok(!lstrcmpA(transforms, "banana"),
9464        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9465     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9466
9467     /* same length as guid, but random */
9468     size = MAX_PATH;
9469     lstrcpyA(patch, "apple");
9470     lstrcpyA(transforms, "banana");
9471     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9472                         transforms, &size);
9473     ok(r == ERROR_INVALID_PARAMETER,
9474        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9475     ok(!lstrcmpA(patch, "apple"),
9476        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9477     ok(!lstrcmpA(transforms, "banana"),
9478        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9479     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9480
9481     /* MSIINSTALLCONTEXT_USERMANAGED */
9482
9483     size = MAX_PATH;
9484     lstrcpyA(patch, "apple");
9485     lstrcpyA(transforms, "banana");
9486     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9487     ok(r == ERROR_UNKNOWN_PRODUCT,
9488        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9489     ok(!lstrcmpA(patch, "apple"),
9490        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9491     ok(!lstrcmpA(transforms, "banana"),
9492        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9493     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9494
9495     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9496     lstrcatA(keypath, usersid);
9497     lstrcatA(keypath, "\\Installer\\Products\\");
9498     lstrcatA(keypath, prod_squashed);
9499
9500     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9501     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9502
9503     /* managed product key exists */
9504     size = MAX_PATH;
9505     lstrcpyA(patch, "apple");
9506     lstrcpyA(transforms, "banana");
9507     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9508     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9509     ok(!lstrcmpA(patch, "apple"),
9510        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9511     ok(!lstrcmpA(transforms, "banana"),
9512        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9513     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9514
9515     res = RegCreateKeyA(prodkey, "Patches", &patches);
9516     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9517
9518     /* patches key exists */
9519     size = MAX_PATH;
9520     lstrcpyA(patch, "apple");
9521     lstrcpyA(transforms, "banana");
9522     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9523     ok(r == ERROR_NO_MORE_ITEMS ||
9524        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9525        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9526     ok(!lstrcmpA(patch, "apple"),
9527        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9528     ok(!lstrcmpA(transforms, "banana"),
9529        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9530     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9531
9532     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9533                          (const BYTE *)patch_squashed,
9534                          lstrlenA(patch_squashed) + 1);
9535     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9536
9537     /* Patches value exists, is not REG_MULTI_SZ */
9538     size = MAX_PATH;
9539     lstrcpyA(patch, "apple");
9540     lstrcpyA(transforms, "banana");
9541     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9542     ok(r == ERROR_BAD_CONFIGURATION ||
9543        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9544        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9545     ok(!lstrcmpA(patch, "apple"),
9546        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9547     ok(!lstrcmpA(transforms, "banana"),
9548        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9549     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9550
9551     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9552                          (const BYTE *)"a\0b\0c\0\0", 7);
9553     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9554
9555     /* Patches value exists, is not a squashed guid */
9556     size = MAX_PATH;
9557     lstrcpyA(patch, "apple");
9558     lstrcpyA(transforms, "banana");
9559     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9560     ok(r == ERROR_BAD_CONFIGURATION,
9561        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9562     ok(!lstrcmpA(patch, "apple"),
9563        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9564     ok(!lstrcmpA(transforms, "banana"),
9565        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9566     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9567
9568     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9569     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9570                          (const BYTE *)patch_squashed,
9571                          lstrlenA(patch_squashed) + 2);
9572     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9573
9574     /* Patches value exists */
9575     size = MAX_PATH;
9576     lstrcpyA(patch, "apple");
9577     lstrcpyA(transforms, "banana");
9578     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9579     ok(r == ERROR_NO_MORE_ITEMS ||
9580        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9581        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9582     ok(!lstrcmpA(patch, "apple") ||
9583        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9584        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9585     ok(!lstrcmpA(transforms, "banana"),
9586        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9587     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9588
9589     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9590                          (const BYTE *)"whatever", 9);
9591     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9592
9593     /* patch squashed value exists */
9594     size = MAX_PATH;
9595     lstrcpyA(patch, "apple");
9596     lstrcpyA(transforms, "banana");
9597     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9598     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9599     ok(!lstrcmpA(patch, patchcode),
9600        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9601     ok(!lstrcmpA(transforms, "whatever"),
9602        "Expected \"whatever\", got \"%s\"\n", transforms);
9603     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9604
9605     /* lpPatchBuf is NULL */
9606     size = MAX_PATH;
9607     lstrcpyA(transforms, "banana");
9608     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9609     ok(r == ERROR_INVALID_PARAMETER,
9610        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9611     ok(!lstrcmpA(transforms, "banana"),
9612        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9613     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9614
9615     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9616     size = MAX_PATH;
9617     lstrcpyA(patch, "apple");
9618     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9619     ok(r == ERROR_INVALID_PARAMETER,
9620        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9621     ok(!lstrcmpA(patch, "apple"),
9622        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9623     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9624
9625     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9626     lstrcpyA(patch, "apple");
9627     lstrcpyA(transforms, "banana");
9628     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9629     ok(r == ERROR_INVALID_PARAMETER,
9630        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9631     ok(!lstrcmpA(patch, "apple"),
9632        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9633     ok(!lstrcmpA(transforms, "banana"),
9634        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9635
9636     /* pcchTransformsBuf is too small */
9637     size = 6;
9638     lstrcpyA(patch, "apple");
9639     lstrcpyA(transforms, "banana");
9640     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9641     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9642     ok(!lstrcmpA(patch, patchcode),
9643        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9644     ok(!lstrcmpA(transforms, "whate") ||
9645        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
9646        "Expected \"whate\", got \"%s\"\n", transforms);
9647     ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
9648
9649     /* increase the index */
9650     size = MAX_PATH;
9651     lstrcpyA(patch, "apple");
9652     lstrcpyA(transforms, "banana");
9653     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9654     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9655     ok(!lstrcmpA(patch, "apple"),
9656        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9657     ok(!lstrcmpA(transforms, "banana"),
9658        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9659     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9660
9661     /* increase again */
9662     size = MAX_PATH;
9663     lstrcpyA(patch, "apple");
9664     lstrcpyA(transforms, "banana");
9665     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9666     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9667     ok(!lstrcmpA(patch, "apple"),
9668        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9669     ok(!lstrcmpA(transforms, "banana"),
9670        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9671     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9672
9673     RegDeleteValueA(patches, "Patches");
9674     RegDeleteKeyA(patches, "");
9675     RegCloseKey(patches);
9676     RegDeleteKeyA(prodkey, "");
9677     RegCloseKey(prodkey);
9678
9679     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9680
9681     size = MAX_PATH;
9682     lstrcpyA(patch, "apple");
9683     lstrcpyA(transforms, "banana");
9684     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9685     ok(r == ERROR_UNKNOWN_PRODUCT,
9686        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9687     ok(!lstrcmpA(patch, "apple"),
9688        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9689     ok(!lstrcmpA(transforms, "banana"),
9690        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9691     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9692
9693     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9694     lstrcatA(keypath, prod_squashed);
9695
9696     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9697     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9698
9699     /* current user product key exists */
9700     size = MAX_PATH;
9701     lstrcpyA(patch, "apple");
9702     lstrcpyA(transforms, "banana");
9703     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9704     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9705     ok(!lstrcmpA(patch, "apple"),
9706        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9707     ok(!lstrcmpA(transforms, "banana"),
9708        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9709     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9710
9711     res = RegCreateKeyA(prodkey, "Patches", &patches);
9712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9713
9714     /* Patches key exists */
9715     size = MAX_PATH;
9716     lstrcpyA(patch, "apple");
9717     lstrcpyA(transforms, "banana");
9718     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9719     ok(r == ERROR_NO_MORE_ITEMS ||
9720        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9721        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9722     ok(!lstrcmpA(patch, "apple"),
9723        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9724     ok(!lstrcmpA(transforms, "banana"),
9725        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9726     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9727
9728     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9729                          (const BYTE *)patch_squashed,
9730                          lstrlenA(patch_squashed) + 1);
9731     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9732
9733     /* Patches value exists, is not REG_MULTI_SZ */
9734     size = MAX_PATH;
9735     lstrcpyA(patch, "apple");
9736     lstrcpyA(transforms, "banana");
9737     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9738     ok(r == ERROR_BAD_CONFIGURATION ||
9739        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9740        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9741     ok(!lstrcmpA(patch, "apple"),
9742        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9743     ok(!lstrcmpA(transforms, "banana"),
9744        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9745     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9746
9747     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9748                          (const BYTE *)"a\0b\0c\0\0", 7);
9749     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9750
9751     /* Patches value exists, is not a squashed guid */
9752     size = MAX_PATH;
9753     lstrcpyA(patch, "apple");
9754     lstrcpyA(transforms, "banana");
9755     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9756     ok(r == ERROR_BAD_CONFIGURATION,
9757        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9758     ok(!lstrcmpA(patch, "apple"),
9759        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9760     ok(!lstrcmpA(transforms, "banana"),
9761        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9762     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9763
9764     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9765     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9766                          (const BYTE *)patch_squashed,
9767                          lstrlenA(patch_squashed) + 2);
9768     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9769
9770     /* Patches value exists */
9771     size = MAX_PATH;
9772     lstrcpyA(patch, "apple");
9773     lstrcpyA(transforms, "banana");
9774     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9775     ok(r == ERROR_NO_MORE_ITEMS ||
9776        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9777        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9778     ok(!lstrcmpA(patch, "apple") ||
9779        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9780        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9781     ok(!lstrcmpA(transforms, "banana"),
9782        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9783     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9784
9785     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9786                          (const BYTE *)"whatever", 9);
9787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9788
9789     /* patch code value exists */
9790     size = MAX_PATH;
9791     lstrcpyA(patch, "apple");
9792     lstrcpyA(transforms, "banana");
9793     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9794     ok(r == ERROR_NO_MORE_ITEMS ||
9795        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9796        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9797     ok(!lstrcmpA(patch, "apple") ||
9798        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9799        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9800     ok(!lstrcmpA(transforms, "banana") ||
9801        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
9802        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9803     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9804
9805     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9806     lstrcatA(keypath, usersid);
9807     lstrcatA(keypath, "\\Patches\\");
9808     lstrcatA(keypath, patch_squashed);
9809
9810     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
9811     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9812
9813     /* userdata patch key exists */
9814     size = MAX_PATH;
9815     lstrcpyA(patch, "apple");
9816     lstrcpyA(transforms, "banana");
9817     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9818     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9819     ok(!lstrcmpA(patch, patchcode),
9820        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9821     ok(!lstrcmpA(transforms, "whatever"),
9822        "Expected \"whatever\", got \"%s\"\n", transforms);
9823     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9824
9825     RegDeleteKeyA(userkey, "");
9826     RegCloseKey(userkey);
9827     RegDeleteValueA(patches, patch_squashed);
9828     RegDeleteValueA(patches, "Patches");
9829     RegDeleteKeyA(patches, "");
9830     RegCloseKey(patches);
9831     RegDeleteKeyA(prodkey, "");
9832     RegCloseKey(prodkey);
9833
9834     /* MSIINSTALLCONTEXT_MACHINE */
9835
9836     size = MAX_PATH;
9837     lstrcpyA(patch, "apple");
9838     lstrcpyA(transforms, "banana");
9839     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9840     ok(r == ERROR_UNKNOWN_PRODUCT,
9841        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9842     ok(!lstrcmpA(patch, "apple"),
9843        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9844     ok(!lstrcmpA(transforms, "banana"),
9845        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9846     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9847
9848     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9849     lstrcatA(keypath, prod_squashed);
9850
9851     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9852     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9853
9854     /* local product key exists */
9855     size = MAX_PATH;
9856     lstrcpyA(patch, "apple");
9857     lstrcpyA(transforms, "banana");
9858     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9859     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9860     ok(!lstrcmpA(patch, "apple"),
9861        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9862     ok(!lstrcmpA(transforms, "banana"),
9863        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9864     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9865
9866     res = RegCreateKeyA(prodkey, "Patches", &patches);
9867     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9868
9869     /* Patches key exists */
9870     size = MAX_PATH;
9871     lstrcpyA(patch, "apple");
9872     lstrcpyA(transforms, "banana");
9873     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9874     ok(r == ERROR_NO_MORE_ITEMS ||
9875        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9876        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9877     ok(!lstrcmpA(patch, "apple"),
9878        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9879     ok(!lstrcmpA(transforms, "banana"),
9880        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9881     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9882
9883     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9884                          (const BYTE *)patch_squashed,
9885                          lstrlenA(patch_squashed) + 1);
9886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9887
9888     /* Patches value exists, is not REG_MULTI_SZ */
9889     size = MAX_PATH;
9890     lstrcpyA(patch, "apple");
9891     lstrcpyA(transforms, "banana");
9892     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9893     ok(r == ERROR_BAD_CONFIGURATION ||
9894        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
9895        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9896     ok(!lstrcmpA(patch, "apple"),
9897        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9898     ok(!lstrcmpA(transforms, "banana"),
9899        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9900     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9901
9902     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9903                          (const BYTE *)"a\0b\0c\0\0", 7);
9904     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9905
9906     /* Patches value exists, is not a squashed guid */
9907     size = MAX_PATH;
9908     lstrcpyA(patch, "apple");
9909     lstrcpyA(transforms, "banana");
9910     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9911     ok(r == ERROR_BAD_CONFIGURATION,
9912        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9913     ok(!lstrcmpA(patch, "apple"),
9914        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9915     ok(!lstrcmpA(transforms, "banana"),
9916        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9917     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9918
9919     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9920     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9921                          (const BYTE *)patch_squashed,
9922                          lstrlenA(patch_squashed) + 2);
9923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9924
9925     /* Patches value exists */
9926     size = MAX_PATH;
9927     lstrcpyA(patch, "apple");
9928     lstrcpyA(transforms, "banana");
9929     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9930     ok(r == ERROR_NO_MORE_ITEMS ||
9931        broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
9932        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9933     ok(!lstrcmpA(patch, "apple") ||
9934        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
9935        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9936     ok(!lstrcmpA(transforms, "banana"),
9937        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9938     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9939
9940     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9941                          (const BYTE *)"whatever", 9);
9942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9943
9944     /* patch code value exists */
9945     size = MAX_PATH;
9946     lstrcpyA(patch, "apple");
9947     lstrcpyA(transforms, "banana");
9948     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9949     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9950     ok(!lstrcmpA(patch, patchcode),
9951        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9952     ok(!lstrcmpA(transforms, "whatever"),
9953        "Expected \"whatever\", got \"%s\"\n", transforms);
9954     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9955
9956     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9957     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9958     lstrcatA(keypath, prod_squashed);
9959
9960     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9962
9963     /* local UserData product key exists */
9964     size = MAX_PATH;
9965     lstrcpyA(patch, "apple");
9966     lstrcpyA(transforms, "banana");
9967     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9968     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9969     ok(!lstrcmpA(patch, patchcode),
9970        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9971     ok(!lstrcmpA(transforms, "whatever"),
9972        "Expected \"whatever\", got \"%s\"\n", transforms);
9973     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9974
9975     res = RegCreateKeyA(udprod, "Patches", &udpatch);
9976     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9977
9978     /* local UserData Patches key exists */
9979     size = MAX_PATH;
9980     lstrcpyA(patch, "apple");
9981     lstrcpyA(transforms, "banana");
9982     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9984     ok(!lstrcmpA(patch, patchcode),
9985        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9986     ok(!lstrcmpA(transforms, "whatever"),
9987        "Expected \"whatever\", got \"%s\"\n", transforms);
9988     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
9989
9990     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
9991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9992
9993     /* local UserData Product patch key exists */
9994     size = MAX_PATH;
9995     lstrcpyA(patch, "apple");
9996     lstrcpyA(transforms, "banana");
9997     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9998     ok(r == ERROR_NO_MORE_ITEMS ||
9999        broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
10000        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10001     ok(!lstrcmpA(patch, "apple") ||
10002        broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
10003        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
10004     ok(!lstrcmpA(transforms, "banana") ||
10005        broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
10006        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
10007     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10008
10009     data = MSIPATCHSTATE_APPLIED;
10010     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10011                          (const BYTE *)&data, sizeof(DWORD));
10012     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10013
10014     /* State value exists */
10015     size = MAX_PATH;
10016     lstrcpyA(patch, "apple");
10017     lstrcpyA(transforms, "banana");
10018     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
10019     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10020     ok(!lstrcmpA(patch, patchcode),
10021        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10022     ok(!lstrcmpA(transforms, "whatever"),
10023        "Expected \"whatever\", got \"%s\"\n", transforms);
10024     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10025
10026     /* now duplicate some of the tests for the W version */
10027
10028     /* pcchTransformsBuf is too small */
10029     size = 6;
10030     MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
10031     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10032     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10033     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10034     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10035     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10036     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10037     ok(!lstrcmpA(patch, patchcode),
10038        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10039     ok(!lstrcmpA(transforms, "whate") ||
10040        broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
10041        "Expected \"whate\", got \"%s\"\n", transforms);
10042     ok(size == 8, "Expected 8, got %d\n", size);
10043
10044     /* patch code value exists */
10045     size = MAX_PATH;
10046     MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
10047     MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
10048     r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
10049     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10050     WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
10051     WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
10052     ok(!lstrcmpA(patch, patchcode),
10053        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
10054     ok(!lstrcmpA(transforms, "whatever"),
10055        "Expected \"whatever\", got \"%s\"\n", transforms);
10056     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
10057
10058     RegDeleteValueA(patches, patch_squashed);
10059     RegDeleteValueA(patches, "Patches");
10060     RegDeleteKeyA(patches, "");
10061     RegCloseKey(patches);
10062     RegDeleteValueA(hpatch, "State");
10063     RegDeleteKeyA(hpatch, "");
10064     RegCloseKey(hpatch);
10065     RegDeleteKeyA(udpatch, "");
10066     RegCloseKey(udpatch);
10067     RegDeleteKeyA(udprod, "");
10068     RegCloseKey(udprod);
10069     RegDeleteKeyA(prodkey, "");
10070     RegCloseKey(prodkey);
10071     LocalFree(usersid);
10072 }
10073
10074 static void test_MsiGetPatchInfoEx(void)
10075 {
10076     CHAR keypath[MAX_PATH], val[MAX_PATH];
10077     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
10078     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10079     HKEY prodkey, patches, udprod, props;
10080     HKEY hpatch, udpatch, prodpatches;
10081     LPSTR usersid;
10082     DWORD size;
10083     LONG res;
10084     UINT r;
10085
10086     if (!pMsiGetPatchInfoExA)
10087     {
10088         win_skip("MsiGetPatchInfoEx not implemented\n");
10089         return;
10090     }
10091
10092     create_test_guid(prodcode, prod_squashed);
10093     create_test_guid(patchcode, patch_squashed);
10094     get_user_sid(&usersid);
10095
10096     /* NULL szPatchCode */
10097     lstrcpyA(val, "apple");
10098     size = MAX_PATH;
10099     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10100                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10101     ok(r == ERROR_INVALID_PARAMETER,
10102        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10103     ok(!lstrcmpA(val, "apple"),
10104        "Expected val to be unchanged, got \"%s\"\n", val);
10105     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10106
10107     /* empty szPatchCode */
10108     size = MAX_PATH;
10109     lstrcpyA(val, "apple");
10110     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10111                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10112     ok(r == ERROR_INVALID_PARAMETER,
10113        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10114     ok(!lstrcmpA(val, "apple"),
10115        "Expected val to be unchanged, got \"%s\"\n", val);
10116     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10117
10118     /* garbage szPatchCode */
10119     size = MAX_PATH;
10120     lstrcpyA(val, "apple");
10121     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
10122                             MSIINSTALLCONTEXT_USERMANAGED,
10123                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10124     ok(r == ERROR_INVALID_PARAMETER,
10125        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10126     ok(!lstrcmpA(val, "apple"),
10127        "Expected val to be unchanged, got \"%s\"\n", val);
10128     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10129
10130     /* guid without brackets */
10131     size = MAX_PATH;
10132     lstrcpyA(val, "apple");
10133     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
10134                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10135                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10136     ok(r == ERROR_INVALID_PARAMETER,
10137        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10138     ok(!lstrcmpA(val, "apple"),
10139        "Expected val to be unchanged, got \"%s\"\n", val);
10140     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10141
10142     /* guid with brackets */
10143     size = MAX_PATH;
10144     lstrcpyA(val, "apple");
10145     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
10146                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10147                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10148     ok(r == ERROR_UNKNOWN_PRODUCT,
10149        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10150     ok(!lstrcmpA(val, "apple"),
10151        "Expected val to be unchanged, got \"%s\"\n", val);
10152     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10153
10154     /* same length as guid, but random */
10155     size = MAX_PATH;
10156     lstrcpyA(val, "apple");
10157     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
10158                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10159                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10160     ok(r == ERROR_INVALID_PARAMETER,
10161        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10162     ok(!lstrcmpA(val, "apple"),
10163        "Expected val to be unchanged, got \"%s\"\n", val);
10164     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10165
10166     /* NULL szProductCode */
10167     lstrcpyA(val, "apple");
10168     size = MAX_PATH;
10169     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
10170                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10171     ok(r == ERROR_INVALID_PARAMETER,
10172        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10173     ok(!lstrcmpA(val, "apple"),
10174        "Expected val to be unchanged, got \"%s\"\n", val);
10175     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10176
10177     /* empty szProductCode */
10178     size = MAX_PATH;
10179     lstrcpyA(val, "apple");
10180     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
10181                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10182     ok(r == ERROR_INVALID_PARAMETER,
10183        "Expected ERROR_INVALID_PARAMETER, 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     /* garbage szProductCode */
10189     size = MAX_PATH;
10190     lstrcpyA(val, "apple");
10191     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
10192                             MSIINSTALLCONTEXT_USERMANAGED,
10193                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10194     ok(r == ERROR_INVALID_PARAMETER,
10195        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10196     ok(!lstrcmpA(val, "apple"),
10197        "Expected val to be unchanged, got \"%s\"\n", val);
10198     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10199
10200     /* guid without brackets */
10201     size = MAX_PATH;
10202     lstrcpyA(val, "apple");
10203     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
10204                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10205                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10206     ok(r == ERROR_INVALID_PARAMETER,
10207        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10208     ok(!lstrcmpA(val, "apple"),
10209        "Expected val to be unchanged, got \"%s\"\n", val);
10210     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10211
10212     /* guid with brackets */
10213     size = MAX_PATH;
10214     lstrcpyA(val, "apple");
10215     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
10216                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10217                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10218     ok(r == ERROR_UNKNOWN_PRODUCT,
10219        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10220     ok(!lstrcmpA(val, "apple"),
10221        "Expected val to be unchanged, got \"%s\"\n", val);
10222     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10223
10224     /* same length as guid, but random */
10225     size = MAX_PATH;
10226     lstrcpyA(val, "apple");
10227     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
10228                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
10229                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10230     ok(r == ERROR_INVALID_PARAMETER,
10231        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10232     ok(!lstrcmpA(val, "apple"),
10233        "Expected val to be unchanged, got \"%s\"\n", val);
10234     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10235
10236     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
10237     size = MAX_PATH;
10238     lstrcpyA(val, "apple");
10239     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10240                             MSIINSTALLCONTEXT_USERMANAGED,
10241                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10242     ok(r == ERROR_INVALID_PARAMETER,
10243        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10244     ok(!lstrcmpA(val, "apple"),
10245        "Expected val to be unchanged, got \"%s\"\n", val);
10246     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10247
10248     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
10249     size = MAX_PATH;
10250     lstrcpyA(val, "apple");
10251     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10252                             MSIINSTALLCONTEXT_USERUNMANAGED,
10253                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10254     ok(r == ERROR_INVALID_PARAMETER,
10255        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10256     ok(!lstrcmpA(val, "apple"),
10257        "Expected val to be unchanged, got \"%s\"\n", val);
10258     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10259
10260     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
10261     size = MAX_PATH;
10262     lstrcpyA(val, "apple");
10263     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
10264                             MSIINSTALLCONTEXT_MACHINE,
10265                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10266     ok(r == ERROR_INVALID_PARAMETER,
10267        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10268     ok(!lstrcmpA(val, "apple"),
10269        "Expected val to be unchanged, got \"%s\"\n", val);
10270     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10271
10272     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
10273     size = MAX_PATH;
10274     lstrcpyA(val, "apple");
10275     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10276                             MSIINSTALLCONTEXT_MACHINE,
10277                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10278     ok(r == ERROR_INVALID_PARAMETER,
10279        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10280     ok(!lstrcmpA(val, "apple"),
10281        "Expected val to be unchanged, got \"%s\"\n", val);
10282     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10283
10284     /* dwContext is out of range */
10285     size = MAX_PATH;
10286     lstrcpyA(val, "apple");
10287     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10288                             MSIINSTALLCONTEXT_NONE,
10289                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10290     ok(r == ERROR_INVALID_PARAMETER,
10291        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10292     ok(!lstrcmpA(val, "apple"),
10293        "Expected val to be unchanged, got \"%s\"\n", val);
10294     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10295
10296     /* dwContext is out of range */
10297     size = MAX_PATH;
10298     lstrcpyA(val, "apple");
10299     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10300                             MSIINSTALLCONTEXT_ALL,
10301                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10302     ok(r == ERROR_INVALID_PARAMETER,
10303        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10304     ok(!lstrcmpA(val, "apple"),
10305        "Expected val to be unchanged, got \"%s\"\n", val);
10306     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10307
10308     /* dwContext is invalid */
10309     size = MAX_PATH;
10310     lstrcpyA(val, "apple");
10311     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
10312                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10313     ok(r == ERROR_INVALID_PARAMETER,
10314        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10315     ok(!lstrcmpA(val, "apple"),
10316        "Expected val to be unchanged, got \"%s\"\n", val);
10317     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10318
10319     /* MSIINSTALLCONTEXT_USERMANAGED */
10320
10321     size = MAX_PATH;
10322     lstrcpyA(val, "apple");
10323     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10324                             MSIINSTALLCONTEXT_USERMANAGED,
10325                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10326     ok(r == ERROR_UNKNOWN_PRODUCT,
10327        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10328     ok(!lstrcmpA(val, "apple"),
10329        "Expected val to be unchanged, got \"%s\"\n", val);
10330     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10331
10332     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10333     lstrcatA(keypath, usersid);
10334     lstrcatA(keypath, "\\Products\\");
10335     lstrcatA(keypath, prod_squashed);
10336
10337     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10339
10340     /* local UserData product key exists */
10341     size = MAX_PATH;
10342     lstrcpyA(val, "apple");
10343     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10344                             MSIINSTALLCONTEXT_USERMANAGED,
10345                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10346     ok(r == ERROR_UNKNOWN_PRODUCT,
10347        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10348     ok(!lstrcmpA(val, "apple"),
10349        "Expected val to be unchanged, got \"%s\"\n", val);
10350     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10351
10352     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10353     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10354
10355     /* InstallProperties key exists */
10356     size = MAX_PATH;
10357     lstrcpyA(val, "apple");
10358     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10359                             MSIINSTALLCONTEXT_USERMANAGED,
10360                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10361     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10362     ok(!lstrcmpA(val, "apple"),
10363        "Expected val to be unchanged, got \"%s\"\n", val);
10364     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10365
10366     res = RegCreateKeyA(udprod, "Patches", &patches);
10367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10368
10369     /* Patches key exists */
10370     size = MAX_PATH;
10371     lstrcpyA(val, "apple");
10372     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10373                             MSIINSTALLCONTEXT_USERMANAGED,
10374                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10375     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10376     ok(!lstrcmpA(val, "apple"),
10377        "Expected val to be unchanged, got \"%s\"\n", val);
10378     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10379
10380     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10381     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10382
10383     /* Patches key exists */
10384     size = MAX_PATH;
10385     lstrcpyA(val, "apple");
10386     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10387                             MSIINSTALLCONTEXT_USERMANAGED,
10388                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10389     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10390     ok(!lstrcmpA(val, "apple"),
10391        "Expected val to be unchanged, got \"%s\"\n", val);
10392     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10393
10394     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10395     lstrcatA(keypath, usersid);
10396     lstrcatA(keypath, "\\Installer\\Products\\");
10397     lstrcatA(keypath, prod_squashed);
10398
10399     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10400     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10401
10402     /* managed product key exists */
10403     size = MAX_PATH;
10404     lstrcpyA(val, "apple");
10405     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10406                             MSIINSTALLCONTEXT_USERMANAGED,
10407                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10408     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10409     ok(!lstrcmpA(val, "apple"),
10410        "Expected val to be unchanged, got \"%s\"\n", val);
10411     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10412
10413     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10414     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10415
10416     /* Patches key exists */
10417     size = MAX_PATH;
10418     lstrcpyA(val, "apple");
10419     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10420                             MSIINSTALLCONTEXT_USERMANAGED,
10421                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10422     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10423     ok(!lstrcmpA(val, "apple"),
10424        "Expected val to be unchanged, got \"%s\"\n", val);
10425     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10426
10427     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10428                          (const BYTE *)"transforms", 11);
10429     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10430
10431     /* specific patch value exists */
10432     size = MAX_PATH;
10433     lstrcpyA(val, "apple");
10434     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10435                             MSIINSTALLCONTEXT_USERMANAGED,
10436                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10437     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10438     ok(!lstrcmpA(val, "apple"),
10439        "Expected val to be unchanged, got \"%s\"\n", val);
10440     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10441
10442     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10443     lstrcatA(keypath, usersid);
10444     lstrcatA(keypath, "\\Patches\\");
10445     lstrcatA(keypath, patch_squashed);
10446
10447     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10448     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10449
10450     /* UserData Patches key exists */
10451     size = MAX_PATH;
10452     lstrcpyA(val, "apple");
10453     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10454                             MSIINSTALLCONTEXT_USERMANAGED,
10455                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10457     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10458     ok(size == 0, "Expected 0, got %d\n", size);
10459
10460     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10461                          (const BYTE *)"pack", 5);
10462     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10463
10464     /* ManagedLocalPatch value exists */
10465     size = MAX_PATH;
10466     lstrcpyA(val, "apple");
10467     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10468                             MSIINSTALLCONTEXT_USERMANAGED,
10469                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10470     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10471     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10472     ok(size == 4, "Expected 4, got %d\n", size);
10473
10474     size = MAX_PATH;
10475     lstrcpyA(val, "apple");
10476     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10477                             MSIINSTALLCONTEXT_USERMANAGED,
10478                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10479     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10480     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10481     ok(size == 10, "Expected 10, got %d\n", size);
10482
10483     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10484                          (const BYTE *)"mydate", 7);
10485     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10486
10487     /* Installed value exists */
10488     size = MAX_PATH;
10489     lstrcpyA(val, "apple");
10490     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10491                             MSIINSTALLCONTEXT_USERMANAGED,
10492                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10494     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10495     ok(size == 6, "Expected 6, got %d\n", size);
10496
10497     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10498                          (const BYTE *)"yes", 4);
10499     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10500
10501     /* Uninstallable value exists */
10502     size = MAX_PATH;
10503     lstrcpyA(val, "apple");
10504     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10505                             MSIINSTALLCONTEXT_USERMANAGED,
10506                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10507     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10508     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10509     ok(size == 3, "Expected 3, got %d\n", size);
10510
10511     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10512                          (const BYTE *)"good", 5);
10513     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10514
10515     /* State value exists */
10516     size = MAX_PATH;
10517     lstrcpyA(val, "apple");
10518     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10519                             MSIINSTALLCONTEXT_USERMANAGED,
10520                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10522     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10523     ok(size == 4, "Expected 4, got %d\n", size);
10524
10525     size = 1;
10526     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10527                          (const BYTE *)&size, sizeof(DWORD));
10528     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10529
10530     /* State value exists */
10531     size = MAX_PATH;
10532     lstrcpyA(val, "apple");
10533     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10534                             MSIINSTALLCONTEXT_USERMANAGED,
10535                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10536     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10537     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10538     ok(size == 1, "Expected 1, got %d\n", size);
10539
10540     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10541                          (const BYTE *)"display", 8);
10542     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10543
10544     /* DisplayName value exists */
10545     size = MAX_PATH;
10546     lstrcpyA(val, "apple");
10547     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10548                             MSIINSTALLCONTEXT_USERMANAGED,
10549                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10551     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10552     ok(size == 7, "Expected 7, got %d\n", size);
10553
10554     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10555                          (const BYTE *)"moreinfo", 9);
10556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10557
10558     /* MoreInfoURL value exists */
10559     size = MAX_PATH;
10560     lstrcpyA(val, "apple");
10561     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10562                             MSIINSTALLCONTEXT_USERMANAGED,
10563                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10564     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10565     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10566     ok(size == 8, "Expected 8, got %d\n", size);
10567
10568     /* szProperty is invalid */
10569     size = MAX_PATH;
10570     lstrcpyA(val, "apple");
10571     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10572                             MSIINSTALLCONTEXT_USERMANAGED,
10573                             "IDontExist", val, &size);
10574     ok(r == ERROR_UNKNOWN_PROPERTY,
10575        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10576     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10577     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10578
10579     /* lpValue is NULL, while pcchValue is non-NULL */
10580     size = MAX_PATH;
10581     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10582                             MSIINSTALLCONTEXT_USERMANAGED,
10583                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10584     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10585     ok(size == 16, "Expected 16, got %d\n", size);
10586
10587     /* pcchValue is NULL, while lpValue is non-NULL */
10588     lstrcpyA(val, "apple");
10589     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10590                             MSIINSTALLCONTEXT_USERMANAGED,
10591                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10592     ok(r == ERROR_INVALID_PARAMETER,
10593        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10594     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10595
10596     /* both lpValue and pcchValue are NULL */
10597     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10598                             MSIINSTALLCONTEXT_USERMANAGED,
10599                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10600     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10601
10602     /* pcchValue doesn't have enough room for NULL terminator */
10603     size = 8;
10604     lstrcpyA(val, "apple");
10605     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10606                             MSIINSTALLCONTEXT_USERMANAGED,
10607                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10608     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10609     ok(!lstrcmpA(val, "moreinf"),
10610        "Expected \"moreinf\", got \"%s\"\n", val);
10611     ok(size == 16, "Expected 16, got %d\n", size);
10612
10613     /* pcchValue has exactly enough room for NULL terminator */
10614     size = 9;
10615     lstrcpyA(val, "apple");
10616     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10617                             MSIINSTALLCONTEXT_USERMANAGED,
10618                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10619     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10620     ok(!lstrcmpA(val, "moreinfo"),
10621        "Expected \"moreinfo\", got \"%s\"\n", val);
10622     ok(size == 8, "Expected 8, got %d\n", size);
10623
10624     /* pcchValue is too small, lpValue is NULL */
10625     size = 0;
10626     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10627                             MSIINSTALLCONTEXT_USERMANAGED,
10628                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10629     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10630     ok(size == 16, "Expected 16, got %d\n", size);
10631
10632     RegDeleteValueA(prodpatches, patch_squashed);
10633     RegDeleteKeyA(prodpatches, "");
10634     RegCloseKey(prodpatches);
10635     RegDeleteKeyA(prodkey, "");
10636     RegCloseKey(prodkey);
10637
10638     /* UserData is sufficient for all properties
10639      * except INSTALLPROPERTY_TRANSFORMS
10640      */
10641     size = MAX_PATH;
10642     lstrcpyA(val, "apple");
10643     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10644                             MSIINSTALLCONTEXT_USERMANAGED,
10645                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10646     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10647     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10648     ok(size == 4, "Expected 4, got %d\n", size);
10649
10650     /* UserData is sufficient for all properties
10651      * except INSTALLPROPERTY_TRANSFORMS
10652      */
10653     size = MAX_PATH;
10654     lstrcpyA(val, "apple");
10655     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10656                             MSIINSTALLCONTEXT_USERMANAGED,
10657                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10658     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10659     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10660     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10661
10662     RegDeleteValueA(hpatch, "MoreInfoURL");
10663     RegDeleteValueA(hpatch, "Display");
10664     RegDeleteValueA(hpatch, "State");
10665     RegDeleteValueA(hpatch, "Uninstallable");
10666     RegDeleteValueA(hpatch, "Installed");
10667     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10668     RegDeleteKeyA(udpatch, "");
10669     RegCloseKey(udpatch);
10670     RegDeleteKeyA(hpatch, "");
10671     RegCloseKey(hpatch);
10672     RegDeleteKeyA(patches, "");
10673     RegCloseKey(patches);
10674     RegDeleteKeyA(props, "");
10675     RegCloseKey(props);
10676     RegDeleteKeyA(udprod, "");
10677     RegCloseKey(udprod);
10678
10679     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10680
10681     size = MAX_PATH;
10682     lstrcpyA(val, "apple");
10683     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10684                             MSIINSTALLCONTEXT_USERUNMANAGED,
10685                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10686     ok(r == ERROR_UNKNOWN_PRODUCT,
10687        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10688     ok(!lstrcmpA(val, "apple"),
10689        "Expected val to be unchanged, got \"%s\"\n", val);
10690     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10691
10692     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10693     lstrcatA(keypath, usersid);
10694     lstrcatA(keypath, "\\Products\\");
10695     lstrcatA(keypath, prod_squashed);
10696
10697     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10698     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10699
10700     /* local UserData product key exists */
10701     size = MAX_PATH;
10702     lstrcpyA(val, "apple");
10703     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10704                             MSIINSTALLCONTEXT_USERUNMANAGED,
10705                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10706     ok(r == ERROR_UNKNOWN_PRODUCT,
10707        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10708     ok(!lstrcmpA(val, "apple"),
10709        "Expected val to be unchanged, got \"%s\"\n", val);
10710     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10711
10712     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10714
10715     /* InstallProperties key exists */
10716     size = MAX_PATH;
10717     lstrcpyA(val, "apple");
10718     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10719                             MSIINSTALLCONTEXT_USERUNMANAGED,
10720                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10721     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10722     ok(!lstrcmpA(val, "apple"),
10723        "Expected val to be unchanged, got \"%s\"\n", val);
10724     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10725
10726     res = RegCreateKeyA(udprod, "Patches", &patches);
10727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10728
10729     /* Patches key exists */
10730     size = MAX_PATH;
10731     lstrcpyA(val, "apple");
10732     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10733                             MSIINSTALLCONTEXT_USERUNMANAGED,
10734                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10735     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10736     ok(!lstrcmpA(val, "apple"),
10737        "Expected val to be unchanged, got \"%s\"\n", val);
10738     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10739
10740     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10741     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10742
10743     /* Patches key exists */
10744     size = MAX_PATH;
10745     lstrcpyA(val, "apple");
10746     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10747                             MSIINSTALLCONTEXT_USERUNMANAGED,
10748                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10749     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10750     ok(!lstrcmpA(val, "apple"),
10751        "Expected val to be unchanged, got \"%s\"\n", val);
10752     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10753
10754     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10755     lstrcatA(keypath, prod_squashed);
10756
10757     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10759
10760     /* current user product key exists */
10761     size = MAX_PATH;
10762     lstrcpyA(val, "apple");
10763     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10764                             MSIINSTALLCONTEXT_USERUNMANAGED,
10765                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10766     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10767     ok(!lstrcmpA(val, "apple"),
10768        "Expected val to be unchanged, got \"%s\"\n", val);
10769     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10770
10771     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10772     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10773
10774     /* Patches key exists */
10775     size = MAX_PATH;
10776     lstrcpyA(val, "apple");
10777     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10778                             MSIINSTALLCONTEXT_USERUNMANAGED,
10779                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10780     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10781     ok(!lstrcmpA(val, "apple"),
10782        "Expected val to be unchanged, got \"%s\"\n", val);
10783     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10784
10785     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10786                          (const BYTE *)"transforms", 11);
10787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10788
10789     /* specific patch value exists */
10790     size = MAX_PATH;
10791     lstrcpyA(val, "apple");
10792     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10793                             MSIINSTALLCONTEXT_USERUNMANAGED,
10794                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10795     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10796     ok(!lstrcmpA(val, "apple"),
10797        "Expected val to be unchanged, got \"%s\"\n", val);
10798     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10799
10800     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10801     lstrcatA(keypath, usersid);
10802     lstrcatA(keypath, "\\Patches\\");
10803     lstrcatA(keypath, patch_squashed);
10804
10805     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10806     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10807
10808     /* UserData Patches key exists */
10809     size = MAX_PATH;
10810     lstrcpyA(val, "apple");
10811     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10812                             MSIINSTALLCONTEXT_USERUNMANAGED,
10813                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10814     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10815     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10816     ok(size == 0, "Expected 0, got %d\n", size);
10817
10818     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10819                          (const BYTE *)"pack", 5);
10820     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10821
10822     /* LocalPatch value exists */
10823     size = MAX_PATH;
10824     lstrcpyA(val, "apple");
10825     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10826                             MSIINSTALLCONTEXT_USERUNMANAGED,
10827                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10828     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10829     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10830     ok(size == 4, "Expected 4, got %d\n", size);
10831
10832     size = MAX_PATH;
10833     lstrcpyA(val, "apple");
10834     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10835                             MSIINSTALLCONTEXT_USERUNMANAGED,
10836                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10837     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10838     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10839     ok(size == 10, "Expected 10, got %d\n", size);
10840
10841     RegDeleteValueA(prodpatches, patch_squashed);
10842     RegDeleteKeyA(prodpatches, "");
10843     RegCloseKey(prodpatches);
10844     RegDeleteKeyA(prodkey, "");
10845     RegCloseKey(prodkey);
10846
10847     /* UserData is sufficient for all properties
10848      * except INSTALLPROPERTY_TRANSFORMS
10849      */
10850     size = MAX_PATH;
10851     lstrcpyA(val, "apple");
10852     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10853                             MSIINSTALLCONTEXT_USERUNMANAGED,
10854                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10855     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10856     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10857     ok(size == 4, "Expected 4, got %d\n", size);
10858
10859     /* UserData is sufficient for all properties
10860      * except INSTALLPROPERTY_TRANSFORMS
10861      */
10862     size = MAX_PATH;
10863     lstrcpyA(val, "apple");
10864     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10865                             MSIINSTALLCONTEXT_USERUNMANAGED,
10866                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10867     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10868     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10869     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10870
10871     RegDeleteValueA(udpatch, "LocalPackage");
10872     RegDeleteKeyA(udpatch, "");
10873     RegCloseKey(udpatch);
10874     RegDeleteKeyA(hpatch, "");
10875     RegCloseKey(hpatch);
10876     RegDeleteKeyA(patches, "");
10877     RegCloseKey(patches);
10878     RegDeleteKeyA(props, "");
10879     RegCloseKey(props);
10880     RegDeleteKeyA(udprod, "");
10881     RegCloseKey(udprod);
10882
10883     /* MSIINSTALLCONTEXT_MACHINE */
10884
10885     size = MAX_PATH;
10886     lstrcpyA(val, "apple");
10887     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10888                             MSIINSTALLCONTEXT_MACHINE,
10889                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10890     ok(r == ERROR_UNKNOWN_PRODUCT,
10891        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10892     ok(!lstrcmpA(val, "apple"),
10893        "Expected val to be unchanged, got \"%s\"\n", val);
10894     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10895
10896     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10897     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10898     lstrcatA(keypath, prod_squashed);
10899
10900     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10901     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10902
10903     /* local UserData product key exists */
10904     size = MAX_PATH;
10905     lstrcpyA(val, "apple");
10906     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10907                             MSIINSTALLCONTEXT_MACHINE,
10908                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10909     ok(r == ERROR_UNKNOWN_PRODUCT,
10910        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10911     ok(!lstrcmpA(val, "apple"),
10912        "Expected val to be unchanged, got \"%s\"\n", val);
10913     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10914
10915     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10917
10918     /* InstallProperties key exists */
10919     size = MAX_PATH;
10920     lstrcpyA(val, "apple");
10921     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10922                             MSIINSTALLCONTEXT_MACHINE,
10923                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10924     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10925     ok(!lstrcmpA(val, "apple"),
10926        "Expected val to be unchanged, got \"%s\"\n", val);
10927     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10928
10929     res = RegCreateKeyA(udprod, "Patches", &patches);
10930     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10931
10932     /* Patches key exists */
10933     size = MAX_PATH;
10934     lstrcpyA(val, "apple");
10935     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10936                             MSIINSTALLCONTEXT_MACHINE,
10937                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10938     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10939     ok(!lstrcmpA(val, "apple"),
10940        "Expected val to be unchanged, got \"%s\"\n", val);
10941     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10942
10943     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10944     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10945
10946     /* Patches key exists */
10947     size = MAX_PATH;
10948     lstrcpyA(val, "apple");
10949     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10950                             MSIINSTALLCONTEXT_MACHINE,
10951                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10952     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10953     ok(!lstrcmpA(val, "apple"),
10954        "Expected val to be unchanged, got \"%s\"\n", val);
10955     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10956
10957     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10958     lstrcatA(keypath, prod_squashed);
10959
10960     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10962
10963     /* local product key exists */
10964     size = MAX_PATH;
10965     lstrcpyA(val, "apple");
10966     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10967                             MSIINSTALLCONTEXT_MACHINE,
10968                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10969     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10970     ok(!lstrcmpA(val, "apple"),
10971        "Expected val to be unchanged, got \"%s\"\n", val);
10972     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10973
10974     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10975     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10976
10977     /* Patches key exists */
10978     size = MAX_PATH;
10979     lstrcpyA(val, "apple");
10980     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10981                             MSIINSTALLCONTEXT_MACHINE,
10982                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10983     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10984     ok(!lstrcmpA(val, "apple"),
10985        "Expected val to be unchanged, got \"%s\"\n", val);
10986     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10987
10988     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10989                          (const BYTE *)"transforms", 11);
10990     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10991
10992     /* specific patch value exists */
10993     size = MAX_PATH;
10994     lstrcpyA(val, "apple");
10995     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10996                             MSIINSTALLCONTEXT_MACHINE,
10997                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10998     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10999     ok(!lstrcmpA(val, "apple"),
11000        "Expected val to be unchanged, got \"%s\"\n", val);
11001     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
11002
11003     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11004     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11005     lstrcatA(keypath, patch_squashed);
11006
11007     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
11008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11009
11010     /* UserData Patches key exists */
11011     size = MAX_PATH;
11012     lstrcpyA(val, "apple");
11013     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11014                             MSIINSTALLCONTEXT_MACHINE,
11015                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11016     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11017     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
11018     ok(size == 0, "Expected 0, got %d\n", size);
11019
11020     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
11021                          (const BYTE *)"pack", 5);
11022     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11023
11024     /* LocalPatch value exists */
11025     size = MAX_PATH;
11026     lstrcpyA(val, "apple");
11027     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11028                             MSIINSTALLCONTEXT_MACHINE,
11029                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11030     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11031     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11032     ok(size == 4, "Expected 4, got %d\n", size);
11033
11034     size = MAX_PATH;
11035     lstrcpyA(val, "apple");
11036     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11037                             MSIINSTALLCONTEXT_MACHINE,
11038                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11039     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11040     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
11041     ok(size == 10, "Expected 10, got %d\n", size);
11042
11043     RegDeleteValueA(prodpatches, patch_squashed);
11044     RegDeleteKeyA(prodpatches, "");
11045     RegCloseKey(prodpatches);
11046     RegDeleteKeyA(prodkey, "");
11047     RegCloseKey(prodkey);
11048
11049     /* UserData is sufficient for all properties
11050      * except INSTALLPROPERTY_TRANSFORMS
11051      */
11052     size = MAX_PATH;
11053     lstrcpyA(val, "apple");
11054     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11055                             MSIINSTALLCONTEXT_MACHINE,
11056                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
11057     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11058     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
11059     ok(size == 4, "Expected 4, got %d\n", size);
11060
11061     /* UserData is sufficient for all properties
11062      * except INSTALLPROPERTY_TRANSFORMS
11063      */
11064     size = MAX_PATH;
11065     lstrcpyA(val, "apple");
11066     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
11067                             MSIINSTALLCONTEXT_MACHINE,
11068                             INSTALLPROPERTY_TRANSFORMS, val, &size);
11069     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
11070     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
11071     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
11072
11073     RegDeleteValueA(udpatch, "LocalPackage");
11074     RegDeleteKeyA(udpatch, "");
11075     RegCloseKey(udpatch);
11076     RegDeleteKeyA(hpatch, "");
11077     RegCloseKey(hpatch);
11078     RegDeleteKeyA(patches, "");
11079     RegCloseKey(patches);
11080     RegDeleteKeyA(props, "");
11081     RegCloseKey(props);
11082     RegDeleteKeyA(udprod, "");
11083     RegCloseKey(udprod);
11084     LocalFree(usersid);
11085 }
11086
11087 static void test_MsiGetPatchInfo(void)
11088 {
11089     UINT r;
11090     char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
11091     char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
11092     WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
11093     HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
11094     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
11095     DWORD size;
11096     LONG res;
11097
11098     create_test_guid(patch_code, patch_squashed);
11099     create_test_guid(prod_code, prod_squashed);
11100     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
11101
11102     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
11103     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11104
11105     r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
11106     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11107
11108     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
11109     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
11110
11111     size = 0;
11112     r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
11113     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
11114
11115     r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
11116     ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
11117
11118     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11119     lstrcatA(keypath, prod_squashed);
11120
11121     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_product);
11122     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11123
11124     /* product key exists */
11125     size = MAX_PATH;
11126     lstrcpyA(val, "apple");
11127     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11128     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11129     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11130     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11131
11132     res = RegCreateKeyA(hkey_product, "Patches", &hkey_patches);
11133     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11134
11135     /* patches key exists */
11136     size = MAX_PATH;
11137     lstrcpyA(val, "apple");
11138     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11139     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11140     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11141     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11142
11143     res = RegCreateKeyA(hkey_patches, patch_squashed, &hkey_patch);
11144     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11145
11146     /* patch key exists */
11147     size = MAX_PATH;
11148     lstrcpyA(val, "apple");
11149     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11150     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11151     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11152     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11153
11154     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11155     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
11156     lstrcatA(keypath, prod_squashed);
11157
11158     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udproduct);
11159     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
11160
11161     /* UserData product key exists */
11162     size = MAX_PATH;
11163     lstrcpyA(val, "apple");
11164     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11165     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11166     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11167     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11168
11169     res = RegCreateKeyA(hkey_udproduct, "InstallProperties", &hkey_udprops);
11170     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11171
11172     /* InstallProperties key exists */
11173     size = MAX_PATH;
11174     lstrcpyA(val, "apple");
11175     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11176     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11177     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
11178     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11179
11180     res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udpatches);
11181     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11182
11183     /* UserData Patches key exists */
11184     size = MAX_PATH;
11185     lstrcpyA(val, "apple");
11186     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11187     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11188     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11189     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11190
11191     res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udproductpatches);
11192     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11193
11194     res = RegCreateKeyA(hkey_udproductpatches, patch_squashed, &hkey_udproductpatch);
11195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
11196
11197     /* UserData product patch key exists */
11198     size = MAX_PATH;
11199     lstrcpyA(val, "apple");
11200     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11201     ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
11202     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
11203     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
11204
11205     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
11206     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
11207     lstrcatA(keypath, patch_squashed);
11208
11209     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udpatch);
11210     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11211
11212     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
11213     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
11214
11215     /* UserData Patch key exists */
11216     size = 0;
11217     lstrcpyA(val, "apple");
11218     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11219     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11220     ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
11221     ok(size == 11, "expected 11 got %u\n", size);
11222
11223     size = MAX_PATH;
11224     lstrcpyA(val, "apple");
11225     r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
11226     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11227     ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
11228     ok(size == 11, "expected 11 got %u\n", size);
11229
11230     size = 0;
11231     valW[0] = 0;
11232     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11233     ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
11234     ok(!valW[0], "expected 0 got %u\n", valW[0]);
11235     ok(size == 11, "expected 11 got %u\n", size);
11236
11237     size = MAX_PATH;
11238     valW[0] = 0;
11239     r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
11240     ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
11241     ok(valW[0], "expected > 0 got %u\n", valW[0]);
11242     ok(size == 11, "expected 11 got %u\n", size);
11243
11244     RegDeleteKeyA(hkey_udproductpatch, "");
11245     RegCloseKey(hkey_udproductpatch);
11246     RegDeleteKeyA(hkey_udproductpatches, "");
11247     RegCloseKey(hkey_udproductpatches);
11248     RegDeleteKeyA(hkey_udpatch, "");
11249     RegCloseKey(hkey_udpatch);
11250     RegDeleteKeyA(hkey_patches, "");
11251     RegCloseKey(hkey_patches);
11252     RegDeleteKeyA(hkey_product, "");
11253     RegCloseKey(hkey_product);
11254     RegDeleteKeyA(hkey_patch, "");
11255     RegCloseKey(hkey_patch);
11256     RegDeleteKeyA(hkey_udpatches, "");
11257     RegCloseKey(hkey_udpatches);
11258     RegDeleteKeyA(hkey_udprops, "");
11259     RegCloseKey(hkey_udprops);
11260     RegDeleteKeyA(hkey_udproduct, "");
11261     RegCloseKey(hkey_udproduct);
11262 }
11263
11264 static void test_MsiEnumProducts(void)
11265 {
11266     UINT r;
11267     int found1, found2, found3;
11268     DWORD index;
11269     char product1[39], product2[39], product3[39], guid[39];
11270     char product_squashed1[33], product_squashed2[33], product_squashed3[33];
11271     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
11272     char *usersid;
11273     HKEY key1, key2, key3;
11274
11275     create_test_guid(product1, product_squashed1);
11276     create_test_guid(product2, product_squashed2);
11277     create_test_guid(product3, product_squashed3);
11278     get_user_sid(&usersid);
11279
11280     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
11281     strcat(keypath1, product_squashed1);
11282
11283     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath1, &key1);
11284     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11285
11286     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11287     strcat(keypath2, usersid);
11288     strcat(keypath2, "\\Installer\\Products\\");
11289     strcat(keypath2, product_squashed2);
11290
11291     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath2, &key2);
11292     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11293
11294     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
11295     strcat(keypath3, product_squashed3);
11296
11297     r = RegCreateKeyA(HKEY_CURRENT_USER, keypath3, &key3);
11298     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11299
11300     index = 0;
11301     r = MsiEnumProductsA(index, guid);
11302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11303
11304     r = MsiEnumProductsA(index, NULL);
11305     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11306
11307     index = 2;
11308     r = MsiEnumProductsA(index, guid);
11309     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
11310
11311     index = 0;
11312     r = MsiEnumProductsA(index, guid);
11313     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
11314
11315     found1 = found2 = found3 = 0;
11316     while ((r = MsiEnumProductsA(index, guid)) == ERROR_SUCCESS)
11317     {
11318         if (!strcmp(product1, guid)) found1 = 1;
11319         if (!strcmp(product2, guid)) found2 = 1;
11320         if (!strcmp(product3, guid)) found3 = 1;
11321         index++;
11322     }
11323     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %u\n", r);
11324     ok(found1, "product1 not found\n");
11325     ok(found2, "product2 not found\n");
11326     ok(found3, "product3 not found\n");
11327
11328     RegDeleteKeyA(key1, "");
11329     RegDeleteKeyA(key2, "");
11330     RegDeleteKeyA(key3, "");
11331     RegCloseKey(key1);
11332     RegCloseKey(key2);
11333     RegCloseKey(key3);
11334     LocalFree(usersid);
11335 }
11336
11337 START_TEST(msi)
11338 {
11339     init_functionpointers();
11340
11341     test_usefeature();
11342     test_null();
11343     test_getcomponentpath();
11344     test_MsiGetFileHash();
11345
11346     if (!pConvertSidToStringSidA)
11347         win_skip("ConvertSidToStringSidA not implemented\n");
11348     else
11349     {
11350         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
11351         test_MsiQueryProductState();
11352         test_MsiQueryFeatureState();
11353         test_MsiQueryComponentState();
11354         test_MsiGetComponentPath();
11355         test_MsiGetProductCode();
11356         test_MsiEnumClients();
11357         test_MsiGetProductInfo();
11358         test_MsiGetProductInfoEx();
11359         test_MsiGetUserInfo();
11360         test_MsiOpenProduct();
11361         test_MsiEnumPatchesEx();
11362         test_MsiEnumPatches();
11363         test_MsiGetPatchInfoEx();
11364         test_MsiGetPatchInfo();
11365         test_MsiEnumProducts();
11366     }
11367
11368     test_MsiGetFileVersion();
11369 }