user32/tests: Fix some window test failures on various Windows platforms.
[wine] / dlls / msi / tests / msi.c
1 /*
2  * tests for Microsoft Installer functionality
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define _WIN32_MSI 300
22
23 #include <stdio.h>
24 #include <windows.h>
25 #include <msi.h>
26 #include <msiquery.h>
27 #include <msidefs.h>
28 #include <sddl.h>
29
30 #include "wine/test.h"
31
32 static const char msifile[] = "winetest.msi";
33
34 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
35
36 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
37     (LPCSTR, LPCSTR, LPSTR, DWORD*);
38 static UINT (WINAPI *pMsiGetFileHashA)
39     (LPCSTR, DWORD, PMSIFILEHASHINFO);
40 static UINT (WINAPI *pMsiGetProductInfoExA)
41     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, LPDWORD);
42 static UINT (WINAPI *pMsiOpenPackageExA)
43     (LPCSTR, DWORD, MSIHANDLE*);
44 static UINT (WINAPI *pMsiOpenPackageExW)
45     (LPCWSTR, DWORD, MSIHANDLE*);
46 static UINT (WINAPI *pMsiEnumPatchesExA)
47     (LPCSTR, LPCSTR, DWORD, DWORD, DWORD, LPSTR, LPSTR,
48     MSIINSTALLCONTEXT*, LPSTR, LPDWORD);
49 static UINT (WINAPI *pMsiQueryComponentStateA)
50     (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*);
51 static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
52     (LPCSTR, LPCSTR ,DWORD, DWORD);
53 static UINT (WINAPI *pMsiGetPatchInfoExA)
54     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
55
56 static void init_functionpointers(void)
57 {
58     HMODULE hmsi = GetModuleHandleA("msi.dll");
59     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
60
61 #define GET_PROC(dll, func) \
62     p ## func = (void *)GetProcAddress(dll, #func); \
63     if(!p ## func) \
64       trace("GetProcAddress(%s) failed\n", #func);
65
66     GET_PROC(hmsi, MsiGetComponentPathA)
67     GET_PROC(hmsi, MsiGetFileHashA)
68     GET_PROC(hmsi, MsiGetProductInfoExA)
69     GET_PROC(hmsi, MsiOpenPackageExA)
70     GET_PROC(hmsi, MsiOpenPackageExW)
71     GET_PROC(hmsi, MsiEnumPatchesExA)
72     GET_PROC(hmsi, MsiQueryComponentStateA)
73     GET_PROC(hmsi, MsiUseFeatureExA)
74     GET_PROC(hmsi, MsiGetPatchInfoExA)
75
76     GET_PROC(hadvapi32, ConvertSidToStringSidA)
77
78 #undef GET_PROC
79 }
80
81 static UINT run_query(MSIHANDLE hdb, const char *query)
82 {
83     MSIHANDLE hview = 0;
84     UINT r;
85
86     r = MsiDatabaseOpenView(hdb, query, &hview);
87     if (r != ERROR_SUCCESS)
88         return r;
89
90     r = MsiViewExecute(hview, 0);
91     if (r == ERROR_SUCCESS)
92         r = MsiViewClose(hview);
93     MsiCloseHandle(hview);
94     return r;
95 }
96
97 static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
98 {
99     UINT res;
100     MSIHANDLE suminfo;
101
102     /* build summary info */
103     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
104     ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
105
106     res = MsiSummaryInfoSetProperty(suminfo, 2, VT_LPSTR, 0, NULL,
107                                     "Installation Database");
108     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
109
110     res = MsiSummaryInfoSetProperty(suminfo, 3, VT_LPSTR, 0, NULL,
111                                     "Installation Database");
112     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
113
114     res = MsiSummaryInfoSetProperty(suminfo, 4, VT_LPSTR, 0, NULL,
115                                     "Wine Hackers");
116     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
117
118     res = MsiSummaryInfoSetProperty(suminfo, 7, VT_LPSTR, 0, NULL,
119                                     ";1033");
120     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
121
122     res = MsiSummaryInfoSetProperty(suminfo, PID_REVNUMBER, VT_LPSTR, 0, NULL,
123                                     "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
124     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
125
126     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
127     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
128
129     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
130     ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
131
132     res = MsiSummaryInfoPersist(suminfo);
133     ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
134
135     res = MsiCloseHandle(suminfo);
136     ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
137
138     return res;
139 }
140
141 static MSIHANDLE create_package_db(LPSTR prodcode)
142 {
143     MSIHANDLE hdb = 0;
144     CHAR query[MAX_PATH];
145     UINT res;
146
147     DeleteFile(msifile);
148
149     /* create an empty database */
150     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
151     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
152     if (res != ERROR_SUCCESS)
153         return hdb;
154
155     res = MsiDatabaseCommit(hdb);
156     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
157
158     set_summary_info(hdb, prodcode);
159
160     res = run_query(hdb,
161             "CREATE TABLE `Directory` ( "
162             "`Directory` CHAR(255) NOT NULL, "
163             "`Directory_Parent` CHAR(255), "
164             "`DefaultDir` CHAR(255) NOT NULL "
165             "PRIMARY KEY `Directory`)");
166     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
167
168     res = run_query(hdb,
169             "CREATE TABLE `Property` ( "
170             "`Property` CHAR(72) NOT NULL, "
171             "`Value` CHAR(255) "
172             "PRIMARY KEY `Property`)");
173     ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
174
175     sprintf(query, "INSERT INTO `Property` "
176             "(`Property`, `Value`) "
177             "VALUES( 'ProductCode', '%s' )", prodcode);
178     res = run_query(hdb, query);
179     ok(res == ERROR_SUCCESS , "Failed\n");
180
181     res = MsiDatabaseCommit(hdb);
182     ok(res == ERROR_SUCCESS, "Failed to commit database\n");
183
184     return hdb;
185 }
186
187 static void test_usefeature(void)
188 {
189     INSTALLSTATE r;
190
191     if (!pMsiUseFeatureExA)
192     {
193         skip("MsiUseFeatureExA not implemented\n");
194         return;
195     }
196
197     r = MsiQueryFeatureState(NULL,NULL);
198     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
199
200     r = MsiQueryFeatureState("{9085040-6000-11d3-8cfe-0150048383c9}" ,NULL);
201     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
202
203     r = pMsiUseFeatureExA(NULL,NULL,0,0);
204     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
205
206     r = pMsiUseFeatureExA(NULL, "WORDVIEWFiles", -2, 1 );
207     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
208
209     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
210                          NULL, -2, 0 );
211     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
212
213     r = pMsiUseFeatureExA("{9085040-6000-11d3-8cfe-0150048383c9}", 
214                          "WORDVIEWFiles", -2, 0 );
215     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
216
217     r = pMsiUseFeatureExA("{0085040-6000-11d3-8cfe-0150048383c9}", 
218                          "WORDVIEWFiles", -2, 0 );
219     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
220
221     r = pMsiUseFeatureExA("{90850409-6000-11d3-8cfe-0150048383c9}", 
222                          "WORDVIEWFiles", -2, 1 );
223     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
224 }
225
226 static void test_null(void)
227 {
228     MSIHANDLE hpkg;
229     UINT r;
230     HKEY hkey;
231     DWORD dwType, cbData;
232     LPBYTE lpData = NULL;
233     INSTALLSTATE state;
234
235     r = pMsiOpenPackageExW(NULL, 0, &hpkg);
236     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
237
238     state = MsiQueryProductStateW(NULL);
239     ok( state == INSTALLSTATE_INVALIDARG, "wrong return\n");
240
241     r = MsiEnumFeaturesW(NULL,0,NULL,NULL);
242     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
243
244     r = MsiConfigureFeatureW(NULL, NULL, 0);
245     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
246
247     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
248     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
249
250     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", 0);
251     ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
252
253     r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", INSTALLSTATE_DEFAULT);
254     ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
255
256     /* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
257      * necessary registry values */
258
259     /* empty product string */
260     r = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", &hkey);
261     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
262
263     r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
264     ok ( r == ERROR_SUCCESS || r == ERROR_FILE_NOT_FOUND, "wrong error %d\n", r);
265     if ( r == ERROR_SUCCESS )
266     {
267         lpData = HeapAlloc(GetProcessHeap(), 0, cbData);
268         if (!lpData)
269             skip("Out of memory\n");
270         else
271         {
272             r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
273             ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
274         }
275     }
276
277     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
278     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
279
280     r = MsiGetProductInfoA("", "", NULL, NULL);
281     ok ( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
282
283     if (lpData)
284     {
285         r = RegSetValueExA(hkey, NULL, 0, dwType, lpData, cbData);
286         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
287
288         HeapFree(GetProcessHeap(), 0, lpData);
289     }
290     else
291     {
292         r = RegDeleteValueA(hkey, NULL);
293         ok ( r == ERROR_SUCCESS, "wrong error %d\n", r);
294     }
295
296     r = RegCloseKey(hkey);
297     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
298
299     /* empty attribute */
300     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", &hkey);
301     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
302
303     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
304     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
305
306     r = MsiGetProductInfoA("{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", "", NULL, NULL);
307     ok ( r == ERROR_UNKNOWN_PROPERTY, "wrong error %d\n", r);
308
309     r = RegCloseKey(hkey);
310     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
311
312     r = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}");
313     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
314 }
315
316 static void test_getcomponentpath(void)
317 {
318     INSTALLSTATE r;
319     char buffer[0x100];
320     DWORD sz;
321
322     if(!pMsiGetComponentPathA)
323         return;
324
325     r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
326     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
327
328     r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
329     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
330
331     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
332     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
333
334     sz = sizeof buffer;
335     buffer[0]=0;
336     r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
337     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
338
339     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
340         "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
341     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
342
343     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
344         "{00000000-0000-0000-0000-00000000}", buffer, &sz );
345     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
346
347     r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
348         "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
349     ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
350
351     r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
352                             "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
353     ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
354 }
355
356 static void create_file(LPCSTR name, LPCSTR data, DWORD size)
357 {
358     HANDLE file;
359     DWORD written;
360
361     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
362     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
363     WriteFile(file, data, strlen(data), &written, NULL);
364
365     if (size)
366     {
367         SetFilePointer(file, size, NULL, FILE_BEGIN);
368         SetEndOfFile(file);
369     }
370
371     CloseHandle(file);
372 }
373
374 #define HASHSIZE sizeof(MSIFILEHASHINFO)
375
376 static const struct
377 {
378     LPCSTR data;
379     DWORD size;
380     MSIFILEHASHINFO hash;
381 } hash_data[] =
382 {
383     { "abc", 0,
384       { HASHSIZE,
385         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
386       },
387     },
388
389     { "C:\\Program Files\\msitest\\caesar\n", 0,
390       { HASHSIZE,
391         { 0x2b566794, 0xfd42181b, 0x2514d6e4, 0x5768b4e2 },
392       },
393     },
394
395     { "C:\\Program Files\\msitest\\caesar\n", 500,
396       { HASHSIZE,
397         { 0x58095058, 0x805efeff, 0x10f3483e, 0x0147d653 },
398       },
399     },
400 };
401
402 static void test_MsiGetFileHash(void)
403 {
404     const char name[] = "msitest.bin";
405     UINT r;
406     MSIFILEHASHINFO hash;
407     DWORD i;
408
409     if (!pMsiGetFileHashA)
410     {
411         skip("MsiGetFileHash not implemented\n");
412         return;
413     }
414
415     hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
416
417     /* szFilePath is NULL */
418     r = pMsiGetFileHashA(NULL, 0, &hash);
419     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
420
421     /* szFilePath is empty */
422     r = pMsiGetFileHashA("", 0, &hash);
423     ok(r == ERROR_PATH_NOT_FOUND || r == ERROR_BAD_PATHNAME,
424        "Expected ERROR_PATH_NOT_FOUND or ERROR_BAD_PATHNAME, got %d\n", r);
425
426     /* szFilePath is nonexistent */
427     r = pMsiGetFileHashA(name, 0, &hash);
428     ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
429
430     /* dwOptions is non-zero */
431     r = pMsiGetFileHashA(name, 1, &hash);
432     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
433
434     /* pHash.dwFileHashInfoSize is not correct */
435     hash.dwFileHashInfoSize = 0;
436     r = pMsiGetFileHashA(name, 0, &hash);
437     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
438
439     /* pHash is NULL */
440     r = pMsiGetFileHashA(name, 0, NULL);
441     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
442
443     for (i = 0; i < sizeof(hash_data) / sizeof(hash_data[0]); i++)
444     {
445         int ret;
446
447         create_file(name, hash_data[i].data, hash_data[i].size);
448
449         memset(&hash, 0, sizeof(MSIFILEHASHINFO));
450         hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
451
452         r = pMsiGetFileHashA(name, 0, &hash);
453         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
454
455         ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
456         ok(ret == 0 ||
457            broken(ret != 0), /* win95 */
458            "Hash incorrect\n");
459
460         DeleteFile(name);
461     }
462 }
463
464 /* copied from dlls/msi/registry.c */
465 static BOOL squash_guid(LPCWSTR in, LPWSTR out)
466 {
467     DWORD i,n=1;
468     GUID guid;
469
470     if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
471         return FALSE;
472
473     for(i=0; i<8; i++)
474         out[7-i] = in[n++];
475     n++;
476     for(i=0; i<4; i++)
477         out[11-i] = in[n++];
478     n++;
479     for(i=0; i<4; i++)
480         out[15-i] = in[n++];
481     n++;
482     for(i=0; i<2; i++)
483     {
484         out[17+i*2] = in[n++];
485         out[16+i*2] = in[n++];
486     }
487     n++;
488     for( ; i<8; i++)
489     {
490         out[17+i*2] = in[n++];
491         out[16+i*2] = in[n++];
492     }
493     out[32]=0;
494     return TRUE;
495 }
496
497 static void create_test_guid(LPSTR prodcode, LPSTR squashed)
498 {
499     WCHAR guidW[MAX_PATH];
500     WCHAR squashedW[MAX_PATH];
501     GUID guid;
502     HRESULT hr;
503     int size;
504
505     hr = CoCreateGuid(&guid);
506     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
507
508     size = StringFromGUID2(&guid, guidW, MAX_PATH);
509     ok(size == 39, "Expected 39, got %d\n", hr);
510
511     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
512     squash_guid(guidW, squashedW);
513     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
514 }
515
516 static void get_user_sid(LPSTR *usersid)
517 {
518     HANDLE token;
519     BYTE buf[1024];
520     DWORD size;
521     PTOKEN_USER user;
522
523     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
524     size = sizeof(buf);
525     GetTokenInformation(token, TokenUser, buf, size, &size);
526     user = (PTOKEN_USER)buf;
527     pConvertSidToStringSidA(user->User.Sid, usersid);
528     CloseHandle(token);
529 }
530
531 static void test_MsiQueryProductState(void)
532 {
533     CHAR prodcode[MAX_PATH];
534     CHAR prod_squashed[MAX_PATH];
535     CHAR keypath[MAX_PATH*2];
536     LPSTR usersid;
537     INSTALLSTATE state;
538     LONG res;
539     HKEY userkey, localkey, props;
540     HKEY prodkey;
541     DWORD data;
542
543     create_test_guid(prodcode, prod_squashed);
544     get_user_sid(&usersid);
545
546     /* NULL prodcode */
547     state = MsiQueryProductStateA(NULL);
548     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
549
550     /* empty prodcode */
551     state = MsiQueryProductStateA("");
552     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
553
554     /* garbage prodcode */
555     state = MsiQueryProductStateA("garbage");
556     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
557
558     /* guid without brackets */
559     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
560     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
561
562     /* guid with brackets */
563     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
564     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
565
566     /* same length as guid, but random */
567     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
568     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
569
570     /* MSIINSTALLCONTEXT_USERUNMANAGED */
571
572     state = MsiQueryProductStateA(prodcode);
573     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
574
575     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
576     lstrcatA(keypath, prod_squashed);
577
578     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
580
581     /* user product key exists */
582     state = MsiQueryProductStateA(prodcode);
583     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
584
585     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
586     lstrcatA(keypath, prodcode);
587
588     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
590
591     /* local uninstall key exists */
592     state = MsiQueryProductStateA(prodcode);
593     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
594
595     data = 1;
596     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
597     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
598
599     /* WindowsInstaller value exists */
600     state = MsiQueryProductStateA(prodcode);
601     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
602
603     RegDeleteValueA(localkey, "WindowsInstaller");
604     RegDeleteKeyA(localkey, "");
605
606     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
607     lstrcatA(keypath, usersid);
608     lstrcatA(keypath, "\\Products\\");
609     lstrcatA(keypath, prod_squashed);
610
611     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
612     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
613
614     /* local product key exists */
615     state = MsiQueryProductStateA(prodcode);
616     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
617
618     res = RegCreateKeyA(localkey, "InstallProperties", &props);
619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
620
621     /* install properties key exists */
622     state = MsiQueryProductStateA(prodcode);
623     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
624
625     data = 1;
626     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
627     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
628
629     /* WindowsInstaller value exists */
630     state = MsiQueryProductStateA(prodcode);
631     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
632
633     data = 2;
634     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
635     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
636
637     /* WindowsInstaller value is not 1 */
638     state = MsiQueryProductStateA(prodcode);
639     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
640
641     RegDeleteKeyA(userkey, "");
642
643     /* user product key does not exist */
644     state = MsiQueryProductStateA(prodcode);
645     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
646
647     RegDeleteValueA(props, "WindowsInstaller");
648     RegDeleteKeyA(props, "");
649     RegCloseKey(props);
650     RegDeleteKeyA(localkey, "");
651     RegCloseKey(localkey);
652     RegDeleteKeyA(userkey, "");
653     RegCloseKey(userkey);
654
655     /* MSIINSTALLCONTEXT_USERMANAGED */
656
657     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
658     lstrcatA(keypath, usersid);
659     lstrcatA(keypath, "\\Installer\\Products\\");
660     lstrcatA(keypath, prod_squashed);
661
662     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
663     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
664
665     state = MsiQueryProductStateA(prodcode);
666     ok(state == INSTALLSTATE_ADVERTISED,
667        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
668
669     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
670     lstrcatA(keypath, usersid);
671     lstrcatA(keypath, "\\Products\\");
672     lstrcatA(keypath, prod_squashed);
673
674     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
675     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
676
677     state = MsiQueryProductStateA(prodcode);
678     ok(state == INSTALLSTATE_ADVERTISED,
679        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
680
681     res = RegCreateKeyA(localkey, "InstallProperties", &props);
682     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
683
684     state = MsiQueryProductStateA(prodcode);
685     ok(state == INSTALLSTATE_ADVERTISED,
686        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
687
688     data = 1;
689     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
690     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
691
692     /* WindowsInstaller value exists */
693     state = MsiQueryProductStateA(prodcode);
694     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
695
696     RegDeleteValueA(props, "WindowsInstaller");
697     RegDeleteKeyA(props, "");
698     RegCloseKey(props);
699     RegDeleteKeyA(localkey, "");
700     RegCloseKey(localkey);
701     RegDeleteKeyA(prodkey, "");
702     RegCloseKey(prodkey);
703
704     /* MSIINSTALLCONTEXT_MACHINE */
705
706     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
707     lstrcatA(keypath, prod_squashed);
708
709     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
711
712     state = MsiQueryProductStateA(prodcode);
713     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
714
715     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
716     lstrcatA(keypath, "S-1-5-18\\Products\\");
717     lstrcatA(keypath, prod_squashed);
718
719     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
721
722     state = MsiQueryProductStateA(prodcode);
723     ok(state == INSTALLSTATE_ADVERTISED,
724        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
725
726     res = RegCreateKeyA(localkey, "InstallProperties", &props);
727     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
728
729     state = MsiQueryProductStateA(prodcode);
730     ok(state == INSTALLSTATE_ADVERTISED,
731        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
732
733     data = 1;
734     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
735     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
736
737     /* WindowsInstaller value exists */
738     state = MsiQueryProductStateA(prodcode);
739     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
740
741     RegDeleteValueA(props, "WindowsInstaller");
742     RegDeleteKeyA(props, "");
743     RegCloseKey(props);
744     RegDeleteKeyA(localkey, "");
745     RegCloseKey(localkey);
746     RegDeleteKeyA(prodkey, "");
747     RegCloseKey(prodkey);
748
749     LocalFree(usersid);
750 }
751
752 static const char table_enc85[] =
753 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
754 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
755 "yz{}~";
756
757 /*
758  *  Encodes a base85 guid given a GUID pointer
759  *  Caller should provide a 21 character buffer for the encoded string.
760  *
761  *  returns TRUE if successful, FALSE if not
762  */
763 static BOOL encode_base85_guid( GUID *guid, LPWSTR str )
764 {
765     unsigned int x, *p, i;
766
767     p = (unsigned int*) guid;
768     for( i=0; i<4; i++ )
769     {
770         x = p[i];
771         *str++ = table_enc85[x%85];
772         x = x/85;
773         *str++ = table_enc85[x%85];
774         x = x/85;
775         *str++ = table_enc85[x%85];
776         x = x/85;
777         *str++ = table_enc85[x%85];
778         x = x/85;
779         *str++ = table_enc85[x%85];
780     }
781     *str = 0;
782
783     return TRUE;
784 }
785
786 static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
787 {
788     WCHAR guidW[MAX_PATH];
789     WCHAR base85W[MAX_PATH];
790     WCHAR squashedW[MAX_PATH];
791     GUID guid;
792     HRESULT hr;
793     int size;
794
795     hr = CoCreateGuid(&guid);
796     ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
797
798     size = StringFromGUID2(&guid, guidW, MAX_PATH);
799     ok(size == 39, "Expected 39, got %d\n", hr);
800
801     WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
802     encode_base85_guid(&guid, base85W);
803     WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
804     squash_guid(guidW, squashedW);
805     WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
806 }
807
808 static void test_MsiQueryFeatureState(void)
809 {
810     HKEY userkey, localkey, compkey;
811     CHAR prodcode[MAX_PATH];
812     CHAR prod_squashed[MAX_PATH];
813     CHAR component[MAX_PATH];
814     CHAR comp_base85[MAX_PATH];
815     CHAR comp_squashed[MAX_PATH];
816     CHAR keypath[MAX_PATH*2];
817     INSTALLSTATE state;
818     LPSTR usersid;
819     LONG res;
820
821     create_test_guid(prodcode, prod_squashed);
822     compose_base85_guid(component, comp_base85, comp_squashed);
823     get_user_sid(&usersid);
824
825     /* NULL prodcode */
826     state = MsiQueryFeatureStateA(NULL, "feature");
827     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
828
829     /* empty prodcode */
830     state = MsiQueryFeatureStateA("", "feature");
831     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
832
833     /* garbage prodcode */
834     state = MsiQueryFeatureStateA("garbage", "feature");
835     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
836
837     /* guid without brackets */
838     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
839     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
840
841     /* guid with brackets */
842     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
843     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
844
845     /* same length as guid, but random */
846     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
847     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
848
849     /* NULL szFeature */
850     state = MsiQueryFeatureStateA(prodcode, NULL);
851     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
852
853     /* empty szFeature */
854     state = MsiQueryFeatureStateA(prodcode, "");
855     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
856
857     /* feature key does not exist yet */
858     state = MsiQueryFeatureStateA(prodcode, "feature");
859     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
860
861     /* MSIINSTALLCONTEXT_USERUNMANAGED */
862
863     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Features\\");
864     lstrcatA(keypath, prod_squashed);
865
866     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &userkey);
867     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
868
869     /* feature key exists */
870     state = MsiQueryFeatureStateA(prodcode, "feature");
871     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
872
873     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
874     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
875
876     /* feature value exists */
877     state = MsiQueryFeatureStateA(prodcode, "feature");
878     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
879
880     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
881     lstrcatA(keypath, usersid);
882     lstrcatA(keypath, "\\Products\\");
883     lstrcatA(keypath, prod_squashed);
884     lstrcatA(keypath, "\\Features");
885
886     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
887     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
888
889     /* userdata features key exists */
890     state = MsiQueryFeatureStateA(prodcode, "feature");
891     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
892
893     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
894     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
895
896     state = MsiQueryFeatureStateA(prodcode, "feature");
897     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
898
899     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
900     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
901
902     state = MsiQueryFeatureStateA(prodcode, "feature");
903     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
904
905     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
907
908     state = MsiQueryFeatureStateA(prodcode, "feature");
909     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
910
911     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
913
914     state = MsiQueryFeatureStateA(prodcode, "feature");
915     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
916
917     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
918     lstrcatA(keypath, usersid);
919     lstrcatA(keypath, "\\Components\\");
920     lstrcatA(keypath, comp_squashed);
921
922     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
924
925     state = MsiQueryFeatureStateA(prodcode, "feature");
926     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
927
928     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
930
931     state = MsiQueryFeatureStateA(prodcode, "feature");
932     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
933
934     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
936
937     /* INSTALLSTATE_LOCAL */
938     state = MsiQueryFeatureStateA(prodcode, "feature");
939     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
940
941     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
943
944     /* INSTALLSTATE_SOURCE */
945     state = MsiQueryFeatureStateA(prodcode, "feature");
946     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
947
948     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
949     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
950
951     /* bad INSTALLSTATE_SOURCE */
952     state = MsiQueryFeatureStateA(prodcode, "feature");
953     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
954
955     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
957
958     /* INSTALLSTATE_SOURCE */
959     state = MsiQueryFeatureStateA(prodcode, "feature");
960     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
961
962     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
964
965     /* bad INSTALLSTATE_SOURCE */
966     state = MsiQueryFeatureStateA(prodcode, "feature");
967     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
968
969     RegDeleteValueA(compkey, prod_squashed);
970     RegDeleteKeyA(compkey, "");
971     RegDeleteValueA(localkey, "feature");
972     RegDeleteValueA(userkey, "feature");
973     RegDeleteKeyA(userkey, "");
974     RegCloseKey(compkey);
975     RegCloseKey(localkey);
976     RegCloseKey(userkey);
977
978     /* MSIINSTALLCONTEXT_USERMANAGED */
979
980     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
981     lstrcatA(keypath, usersid);
982     lstrcatA(keypath, "\\Installer\\Features\\");
983     lstrcatA(keypath, prod_squashed);
984
985     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
987
988     /* feature key exists */
989     state = MsiQueryFeatureStateA(prodcode, "feature");
990     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
991
992     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
993     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
994
995     /* feature value exists */
996     state = MsiQueryFeatureStateA(prodcode, "feature");
997     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
998
999     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1000     lstrcatA(keypath, usersid);
1001     lstrcatA(keypath, "\\Products\\");
1002     lstrcatA(keypath, prod_squashed);
1003     lstrcatA(keypath, "\\Features");
1004
1005     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1006     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1007
1008     /* userdata features key exists */
1009     state = MsiQueryFeatureStateA(prodcode, "feature");
1010     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1011
1012     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1014
1015     state = MsiQueryFeatureStateA(prodcode, "feature");
1016     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1017
1018     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1020
1021     state = MsiQueryFeatureStateA(prodcode, "feature");
1022     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1023
1024     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1026
1027     state = MsiQueryFeatureStateA(prodcode, "feature");
1028     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1029
1030     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
1031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1032
1033     state = MsiQueryFeatureStateA(prodcode, "feature");
1034     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1035
1036     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1037     lstrcatA(keypath, usersid);
1038     lstrcatA(keypath, "\\Components\\");
1039     lstrcatA(keypath, comp_squashed);
1040
1041     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1042     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1043
1044     state = MsiQueryFeatureStateA(prodcode, "feature");
1045     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1046
1047     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1049
1050     state = MsiQueryFeatureStateA(prodcode, "feature");
1051     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1052
1053     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
1054     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1055
1056     state = MsiQueryFeatureStateA(prodcode, "feature");
1057     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1058
1059     RegDeleteValueA(compkey, prod_squashed);
1060     RegDeleteKeyA(compkey, "");
1061     RegDeleteValueA(localkey, "feature");
1062     RegDeleteValueA(userkey, "feature");
1063     RegDeleteKeyA(userkey, "");
1064     RegCloseKey(compkey);
1065     RegCloseKey(localkey);
1066     RegCloseKey(userkey);
1067
1068     /* MSIINSTALLCONTEXT_MACHINE */
1069
1070     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
1071     lstrcatA(keypath, prod_squashed);
1072
1073     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
1074     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1075
1076     /* feature key exists */
1077     state = MsiQueryFeatureStateA(prodcode, "feature");
1078     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1079
1080     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
1081     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1082
1083     /* feature value exists */
1084     state = MsiQueryFeatureStateA(prodcode, "feature");
1085     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1086
1087     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1088     lstrcatA(keypath, "S-1-5-18\\Products\\");
1089     lstrcatA(keypath, prod_squashed);
1090     lstrcatA(keypath, "\\Features");
1091
1092     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
1093     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1094
1095     /* userdata features key exists */
1096     state = MsiQueryFeatureStateA(prodcode, "feature");
1097     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1098
1099     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
1100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1101
1102     state = MsiQueryFeatureStateA(prodcode, "feature");
1103     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
1104
1105     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
1106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1107
1108     state = MsiQueryFeatureStateA(prodcode, "feature");
1109     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1110
1111     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
1112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1113
1114     state = MsiQueryFeatureStateA(prodcode, "feature");
1115     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1116
1117     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 21);
1118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1119
1120     state = MsiQueryFeatureStateA(prodcode, "feature");
1121     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1122
1123     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1124     lstrcatA(keypath, "S-1-5-18\\Components\\");
1125     lstrcatA(keypath, comp_squashed);
1126
1127     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1128     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1129
1130     state = MsiQueryFeatureStateA(prodcode, "feature");
1131     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
1132
1133     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
1134     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1135
1136     state = MsiQueryFeatureStateA(prodcode, "feature");
1137     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1138
1139     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 1);
1140     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1141
1142     state = MsiQueryFeatureStateA(prodcode, "feature");
1143     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1144
1145     RegDeleteValueA(compkey, prod_squashed);
1146     RegDeleteKeyA(compkey, "");
1147     RegDeleteValueA(localkey, "feature");
1148     RegDeleteValueA(userkey, "feature");
1149     RegDeleteKeyA(userkey, "");
1150     RegCloseKey(compkey);
1151     RegCloseKey(localkey);
1152     RegCloseKey(userkey);
1153 }
1154
1155 static void test_MsiQueryComponentState(void)
1156 {
1157     HKEY compkey, prodkey;
1158     CHAR prodcode[MAX_PATH];
1159     CHAR prod_squashed[MAX_PATH];
1160     CHAR component[MAX_PATH];
1161     CHAR comp_base85[MAX_PATH];
1162     CHAR comp_squashed[MAX_PATH];
1163     CHAR keypath[MAX_PATH];
1164     INSTALLSTATE state;
1165     LPSTR usersid;
1166     LONG res;
1167     UINT r;
1168
1169     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
1170
1171     if (!pMsiQueryComponentStateA)
1172     {
1173         skip("MsiQueryComponentStateA not implemented\n");
1174         return;
1175     }
1176
1177     create_test_guid(prodcode, prod_squashed);
1178     compose_base85_guid(component, comp_base85, comp_squashed);
1179     get_user_sid(&usersid);
1180
1181     /* NULL szProductCode */
1182     state = MAGIC_ERROR;
1183     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1184     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1185     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1186
1187     /* empty szProductCode */
1188     state = MAGIC_ERROR;
1189     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1190     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1191     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1192
1193     /* random szProductCode */
1194     state = MAGIC_ERROR;
1195     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1196     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1197     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1198
1199     /* GUID-length szProductCode */
1200     state = MAGIC_ERROR;
1201     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1202     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1203     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1204
1205     /* GUID-length with brackets */
1206     state = MAGIC_ERROR;
1207     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1208     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1209     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1210
1211     /* actual GUID */
1212     state = MAGIC_ERROR;
1213     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1214     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1215     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1216
1217     state = MAGIC_ERROR;
1218     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1219     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1220     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1221
1222     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1223     lstrcatA(keypath, prod_squashed);
1224
1225     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1226     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1227
1228     state = MAGIC_ERROR;
1229     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1230     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1231     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1232
1233     RegDeleteKeyA(prodkey, "");
1234     RegCloseKey(prodkey);
1235
1236     /* create local system product key */
1237     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
1238     lstrcatA(keypath, prod_squashed);
1239     lstrcatA(keypath, "\\InstallProperties");
1240
1241     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1242     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1243
1244     /* local system product key exists */
1245     state = MAGIC_ERROR;
1246     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1247     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1248     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1249
1250     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1251     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1252
1253     /* LocalPackage value exists */
1254     state = MAGIC_ERROR;
1255     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1256     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1257     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1258
1259     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
1260     lstrcatA(keypath, comp_squashed);
1261
1262     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1263     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1264
1265     /* component key exists */
1266     state = MAGIC_ERROR;
1267     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1268     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1269     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1270
1271     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1273
1274     /* component\product exists */
1275     state = MAGIC_ERROR;
1276     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1277     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1278     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1279        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1280
1281     /* NULL component, product exists */
1282     state = MAGIC_ERROR;
1283     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
1284     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1285     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
1286
1287     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1289
1290     /* INSTALLSTATE_LOCAL */
1291     state = MAGIC_ERROR;
1292     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1293     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1294     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1295
1296     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1297     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1298
1299     /* INSTALLSTATE_SOURCE */
1300     state = MAGIC_ERROR;
1301     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1303     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1304
1305     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1306     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1307
1308     /* bad INSTALLSTATE_SOURCE */
1309     state = MAGIC_ERROR;
1310     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1311     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1312     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1313
1314     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1315     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1316
1317     /* INSTALLSTATE_SOURCE */
1318     state = MAGIC_ERROR;
1319     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1320     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1321     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1322
1323     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1324     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1325
1326     /* bad INSTALLSTATE_SOURCE */
1327     state = MAGIC_ERROR;
1328     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1329     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1330     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1331
1332     RegDeleteValueA(prodkey, "LocalPackage");
1333     RegDeleteKeyA(prodkey, "");
1334     RegDeleteValueA(compkey, prod_squashed);
1335     RegDeleteKeyA(prodkey, "");
1336     RegCloseKey(prodkey);
1337     RegCloseKey(compkey);
1338
1339     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1340
1341     state = MAGIC_ERROR;
1342     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1343     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1344     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1345
1346     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1347     lstrcatA(keypath, prod_squashed);
1348
1349     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1350     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1351
1352     state = MAGIC_ERROR;
1353     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1354     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1355     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1356
1357     RegDeleteKeyA(prodkey, "");
1358     RegCloseKey(prodkey);
1359
1360     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1361     lstrcatA(keypath, usersid);
1362     lstrcatA(keypath, "\\Products\\");
1363     lstrcatA(keypath, prod_squashed);
1364     lstrcatA(keypath, "\\InstallProperties");
1365
1366     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1368
1369     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1371
1372     RegCloseKey(prodkey);
1373
1374     state = MAGIC_ERROR;
1375     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1376     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1377     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1378
1379     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1380     lstrcatA(keypath, usersid);
1381     lstrcatA(keypath, "\\Components\\");
1382     lstrcatA(keypath, comp_squashed);
1383
1384     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1385     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1386
1387     /* component key exists */
1388     state = MAGIC_ERROR;
1389     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1390     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1391     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1392
1393     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1395
1396     /* component\product exists */
1397     state = MAGIC_ERROR;
1398     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1399     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1400     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1401        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1402
1403     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1404     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1405
1406     state = MAGIC_ERROR;
1407     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1408     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1409     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1410
1411     /* MSIINSTALLCONTEXT_USERMANAGED */
1412
1413     state = MAGIC_ERROR;
1414     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1415     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1416     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1417
1418     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1419     lstrcatA(keypath, prod_squashed);
1420
1421     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1422     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1423
1424     state = MAGIC_ERROR;
1425     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1426     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1427     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1428
1429     RegDeleteKeyA(prodkey, "");
1430     RegCloseKey(prodkey);
1431
1432     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1433     lstrcatA(keypath, usersid);
1434     lstrcatA(keypath, "\\Installer\\Products\\");
1435     lstrcatA(keypath, prod_squashed);
1436
1437     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1439
1440     state = MAGIC_ERROR;
1441     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1442     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1443     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1444
1445     RegDeleteKeyA(prodkey, "");
1446     RegCloseKey(prodkey);
1447
1448     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1449     lstrcatA(keypath, usersid);
1450     lstrcatA(keypath, "\\Products\\");
1451     lstrcatA(keypath, prod_squashed);
1452     lstrcatA(keypath, "\\InstallProperties");
1453
1454     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1455     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1456
1457     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1459
1460     state = MAGIC_ERROR;
1461     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1463     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1464
1465     RegDeleteValueA(prodkey, "LocalPackage");
1466     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1467     RegDeleteKeyA(prodkey, "");
1468     RegDeleteValueA(compkey, prod_squashed);
1469     RegDeleteKeyA(compkey, "");
1470     RegCloseKey(prodkey);
1471     RegCloseKey(compkey);
1472 }
1473
1474 static void test_MsiGetComponentPath(void)
1475 {
1476     HKEY compkey, prodkey, installprop;
1477     CHAR prodcode[MAX_PATH];
1478     CHAR prod_squashed[MAX_PATH];
1479     CHAR component[MAX_PATH];
1480     CHAR comp_base85[MAX_PATH];
1481     CHAR comp_squashed[MAX_PATH];
1482     CHAR keypath[MAX_PATH];
1483     CHAR path[MAX_PATH];
1484     INSTALLSTATE state;
1485     LPSTR usersid;
1486     DWORD size, val;
1487     LONG res;
1488
1489     create_test_guid(prodcode, prod_squashed);
1490     compose_base85_guid(component, comp_base85, comp_squashed);
1491     get_user_sid(&usersid);
1492
1493     /* NULL szProduct */
1494     size = MAX_PATH;
1495     state = MsiGetComponentPathA(NULL, component, path, &size);
1496     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1497     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1498
1499     /* NULL szComponent */
1500     size = MAX_PATH;
1501     state = MsiGetComponentPathA(prodcode, NULL, path, &size);
1502     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1503     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1504
1505     /* NULL lpPathBuf */
1506     size = MAX_PATH;
1507     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1508     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1509     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1510
1511     /* NULL pcchBuf */
1512     size = MAX_PATH;
1513     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1514     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1515     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1516
1517     /* all params valid */
1518     size = MAX_PATH;
1519     state = MsiGetComponentPathA(prodcode, component, path, &size);
1520     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1521     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1522
1523     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1524     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1525     lstrcatA(keypath, comp_squashed);
1526
1527     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1528     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1529
1530     /* local system component key exists */
1531     size = MAX_PATH;
1532     state = MsiGetComponentPathA(prodcode, component, path, &size);
1533     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1534     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1535
1536     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1537     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1538
1539     /* product value exists */
1540     size = MAX_PATH;
1541     state = MsiGetComponentPathA(prodcode, component, path, &size);
1542     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1543     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1544     ok(size == 10, "Expected 10, got %d\n", size);
1545
1546     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1547     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1548     lstrcatA(keypath, prod_squashed);
1549     lstrcatA(keypath, "\\InstallProperties");
1550
1551     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1552     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1553
1554     val = 1;
1555     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1556     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1557
1558     /* install properties key exists */
1559     size = MAX_PATH;
1560     state = MsiGetComponentPathA(prodcode, component, path, &size);
1561     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1562     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1563     ok(size == 10, "Expected 10, got %d\n", size);
1564
1565     create_file("C:\\imapath", "C:\\imapath", 11);
1566
1567     /* file exists */
1568     size = MAX_PATH;
1569     state = MsiGetComponentPathA(prodcode, component, path, &size);
1570     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1571     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1572     ok(size == 10, "Expected 10, got %d\n", size);
1573
1574     RegDeleteValueA(compkey, prod_squashed);
1575     RegDeleteKeyA(compkey, "");
1576     RegDeleteValueA(installprop, "WindowsInstaller");
1577     RegDeleteKeyA(installprop, "");
1578     RegCloseKey(compkey);
1579     RegCloseKey(installprop);
1580     DeleteFileA("C:\\imapath");
1581
1582     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1583     lstrcatA(keypath, "Installer\\UserData\\");
1584     lstrcatA(keypath, usersid);
1585     lstrcatA(keypath, "\\Components\\");
1586     lstrcatA(keypath, comp_squashed);
1587
1588     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1589     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1590
1591     /* user managed component key exists */
1592     size = MAX_PATH;
1593     state = MsiGetComponentPathA(prodcode, component, path, &size);
1594     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1595     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1596
1597     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1598     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1599
1600     /* product value exists */
1601     size = MAX_PATH;
1602     state = MsiGetComponentPathA(prodcode, component, path, &size);
1603     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1604     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1605     ok(size == 10, "Expected 10, got %d\n", size);
1606
1607     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1608     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1609     lstrcatA(keypath, prod_squashed);
1610     lstrcatA(keypath, "\\InstallProperties");
1611
1612     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1614
1615     val = 1;
1616     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1617     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1618
1619     /* install properties key exists */
1620     size = MAX_PATH;
1621     state = MsiGetComponentPathA(prodcode, component, path, &size);
1622     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1623     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1624     ok(size == 10, "Expected 10, got %d\n", size);
1625
1626     create_file("C:\\imapath", "C:\\imapath", 11);
1627
1628     /* file exists */
1629     size = MAX_PATH;
1630     state = MsiGetComponentPathA(prodcode, component, path, &size);
1631     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1632     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1633     ok(size == 10, "Expected 10, got %d\n", size);
1634
1635     RegDeleteValueA(compkey, prod_squashed);
1636     RegDeleteKeyA(compkey, "");
1637     RegDeleteValueA(installprop, "WindowsInstaller");
1638     RegDeleteKeyA(installprop, "");
1639     RegCloseKey(compkey);
1640     RegCloseKey(installprop);
1641     DeleteFileA("C:\\imapath");
1642
1643     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1644     lstrcatA(keypath, "Installer\\Managed\\");
1645     lstrcatA(keypath, usersid);
1646     lstrcatA(keypath, "\\Installer\\Products\\");
1647     lstrcatA(keypath, prod_squashed);
1648
1649     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1651
1652     /* user managed product key exists */
1653     size = MAX_PATH;
1654     state = MsiGetComponentPathA(prodcode, component, path, &size);
1655     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1656     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1657
1658     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1659     lstrcatA(keypath, "Installer\\UserData\\");
1660     lstrcatA(keypath, usersid);
1661     lstrcatA(keypath, "\\Components\\");
1662     lstrcatA(keypath, comp_squashed);
1663
1664     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1665     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1666
1667     /* user managed component key exists */
1668     size = MAX_PATH;
1669     state = MsiGetComponentPathA(prodcode, component, path, &size);
1670     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1671     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1672
1673     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1675
1676     /* product value exists */
1677     size = MAX_PATH;
1678     state = MsiGetComponentPathA(prodcode, component, path, &size);
1679     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1680     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1681     ok(size == 10, "Expected 10, got %d\n", size);
1682
1683     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1684     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1685     lstrcatA(keypath, prod_squashed);
1686     lstrcatA(keypath, "\\InstallProperties");
1687
1688     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1690
1691     val = 1;
1692     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1694
1695     /* install properties key exists */
1696     size = MAX_PATH;
1697     state = MsiGetComponentPathA(prodcode, component, path, &size);
1698     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1699     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1700     ok(size == 10, "Expected 10, got %d\n", size);
1701
1702     create_file("C:\\imapath", "C:\\imapath", 11);
1703
1704     /* file exists */
1705     size = MAX_PATH;
1706     state = MsiGetComponentPathA(prodcode, component, path, &size);
1707     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1708     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1709     ok(size == 10, "Expected 10, got %d\n", size);
1710
1711     RegDeleteValueA(compkey, prod_squashed);
1712     RegDeleteKeyA(prodkey, "");
1713     RegDeleteKeyA(compkey, "");
1714     RegDeleteValueA(installprop, "WindowsInstaller");
1715     RegDeleteKeyA(installprop, "");
1716     RegCloseKey(prodkey);
1717     RegCloseKey(compkey);
1718     RegCloseKey(installprop);
1719     DeleteFileA("C:\\imapath");
1720
1721     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1722     lstrcatA(keypath, prod_squashed);
1723
1724     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1726
1727     /* user unmanaged product key exists */
1728     size = MAX_PATH;
1729     state = MsiGetComponentPathA(prodcode, component, path, &size);
1730     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1731     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1732
1733     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1734     lstrcatA(keypath, "Installer\\UserData\\");
1735     lstrcatA(keypath, usersid);
1736     lstrcatA(keypath, "\\Components\\");
1737     lstrcatA(keypath, comp_squashed);
1738
1739     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1741
1742     /* user unmanaged component key exists */
1743     size = MAX_PATH;
1744     state = MsiGetComponentPathA(prodcode, component, path, &size);
1745     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1746     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1747
1748     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1749     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1750
1751     /* product value exists */
1752     size = MAX_PATH;
1753     state = MsiGetComponentPathA(prodcode, component, path, &size);
1754     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1755     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1756     ok(size == 10, "Expected 10, got %d\n", size);
1757
1758     create_file("C:\\imapath", "C:\\imapath", 11);
1759
1760     /* file exists */
1761     size = MAX_PATH;
1762     state = MsiGetComponentPathA(prodcode, component, path, &size);
1763     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1764     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1765     ok(size == 10, "Expected 10, got %d\n", size);
1766
1767     RegDeleteValueA(compkey, prod_squashed);
1768     RegDeleteKeyA(prodkey, "");
1769     RegDeleteKeyA(compkey, "");
1770     RegCloseKey(prodkey);
1771     RegCloseKey(compkey);
1772     DeleteFileA("C:\\imapath");
1773
1774     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1775     lstrcatA(keypath, prod_squashed);
1776
1777     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1778     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1779
1780     /* local classes product key exists */
1781     size = MAX_PATH;
1782     state = MsiGetComponentPathA(prodcode, component, path, &size);
1783     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1784     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1785
1786     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1787     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1788     lstrcatA(keypath, comp_squashed);
1789
1790     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1791     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1792
1793     /* local user component key exists */
1794     size = MAX_PATH;
1795     state = MsiGetComponentPathA(prodcode, component, path, &size);
1796     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1797     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1798
1799     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1800     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1801
1802     /* product value exists */
1803     size = MAX_PATH;
1804     state = MsiGetComponentPathA(prodcode, component, path, &size);
1805     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1806     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1807     ok(size == 10, "Expected 10, got %d\n", size);
1808
1809     create_file("C:\\imapath", "C:\\imapath", 11);
1810
1811     /* file exists */
1812     size = MAX_PATH;
1813     state = MsiGetComponentPathA(prodcode, component, path, &size);
1814     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1815     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1816     ok(size == 10, "Expected 10, got %d\n", size);
1817
1818     RegDeleteValueA(compkey, prod_squashed);
1819     RegDeleteKeyA(prodkey, "");
1820     RegDeleteKeyA(compkey, "");
1821     RegCloseKey(prodkey);
1822     RegCloseKey(compkey);
1823     DeleteFileA("C:\\imapath");
1824 }
1825
1826 static void test_MsiGetProductCode(void)
1827 {
1828     HKEY compkey, prodkey;
1829     CHAR prodcode[MAX_PATH];
1830     CHAR prod_squashed[MAX_PATH];
1831     CHAR prodcode2[MAX_PATH];
1832     CHAR prod2_squashed[MAX_PATH];
1833     CHAR component[MAX_PATH];
1834     CHAR comp_base85[MAX_PATH];
1835     CHAR comp_squashed[MAX_PATH];
1836     CHAR keypath[MAX_PATH];
1837     CHAR product[MAX_PATH];
1838     LPSTR usersid;
1839     LONG res;
1840     UINT r;
1841
1842     create_test_guid(prodcode, prod_squashed);
1843     create_test_guid(prodcode2, prod2_squashed);
1844     compose_base85_guid(component, comp_base85, comp_squashed);
1845     get_user_sid(&usersid);
1846
1847     /* szComponent is NULL */
1848     lstrcpyA(product, "prod");
1849     r = MsiGetProductCodeA(NULL, product);
1850     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1851     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1852
1853     /* szComponent is empty */
1854     lstrcpyA(product, "prod");
1855     r = MsiGetProductCodeA("", product);
1856     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1857     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1858
1859     /* garbage szComponent */
1860     lstrcpyA(product, "prod");
1861     r = MsiGetProductCodeA("garbage", product);
1862     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1863     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1864
1865     /* guid without brackets */
1866     lstrcpyA(product, "prod");
1867     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
1868     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1869     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1870
1871     /* guid with brackets */
1872     lstrcpyA(product, "prod");
1873     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
1874     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1875     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1876
1877     /* same length as guid, but random */
1878     lstrcpyA(product, "prod");
1879     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
1880     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1881     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1882
1883     /* all params correct, szComponent not published */
1884     lstrcpyA(product, "prod");
1885     r = MsiGetProductCodeA(component, product);
1886     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1887     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1888
1889     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1890     lstrcatA(keypath, "Installer\\UserData\\");
1891     lstrcatA(keypath, usersid);
1892     lstrcatA(keypath, "\\Components\\");
1893     lstrcatA(keypath, comp_squashed);
1894
1895     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1896     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1897
1898     /* user unmanaged component key exists */
1899     lstrcpyA(product, "prod");
1900     r = MsiGetProductCodeA(component, product);
1901     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1902     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1903
1904     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1906
1907     /* product value exists */
1908     lstrcpyA(product, "prod");
1909     r = MsiGetProductCodeA(component, product);
1910     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1911     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1912
1913     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1914     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1915
1916     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1917     lstrcatA(keypath, "Installer\\Managed\\");
1918     lstrcatA(keypath, usersid);
1919     lstrcatA(keypath, "\\Installer\\Products\\");
1920     lstrcatA(keypath, prod_squashed);
1921
1922     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1923     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1924
1925     /* user managed product key of first product exists */
1926     lstrcpyA(product, "prod");
1927     r = MsiGetProductCodeA(component, product);
1928     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1929     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1930
1931     RegDeleteKeyA(prodkey, "");
1932     RegCloseKey(prodkey);
1933
1934     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1935     lstrcatA(keypath, prod_squashed);
1936
1937     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1938     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1939
1940     /* user unmanaged product key exists */
1941     lstrcpyA(product, "prod");
1942     r = MsiGetProductCodeA(component, product);
1943     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1944     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1945
1946     RegDeleteKeyA(prodkey, "");
1947     RegCloseKey(prodkey);
1948
1949     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1950     lstrcatA(keypath, prod_squashed);
1951
1952     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1953     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1954
1955     /* local classes product key exists */
1956     lstrcpyA(product, "prod");
1957     r = MsiGetProductCodeA(component, product);
1958     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1959     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1960
1961     RegDeleteKeyA(prodkey, "");
1962     RegCloseKey(prodkey);
1963
1964     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1965     lstrcatA(keypath, "Installer\\Managed\\");
1966     lstrcatA(keypath, usersid);
1967     lstrcatA(keypath, "\\Installer\\Products\\");
1968     lstrcatA(keypath, prod2_squashed);
1969
1970     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1972
1973     /* user managed product key of second product exists */
1974     lstrcpyA(product, "prod");
1975     r = MsiGetProductCodeA(component, product);
1976     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1977     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
1978
1979     RegDeleteKeyA(prodkey, "");
1980     RegCloseKey(prodkey);
1981     RegDeleteValueA(compkey, prod_squashed);
1982     RegDeleteValueA(compkey, prod2_squashed);
1983     RegDeleteKeyA(compkey, "");
1984     RegCloseKey(compkey);
1985
1986     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1987     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1988     lstrcatA(keypath, comp_squashed);
1989
1990     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1992
1993     /* local user component key exists */
1994     lstrcpyA(product, "prod");
1995     r = MsiGetProductCodeA(component, product);
1996     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1997     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1998
1999     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2000     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2001
2002     /* product value exists */
2003     lstrcpyA(product, "prod");
2004     r = MsiGetProductCodeA(component, product);
2005     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2006     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2007
2008     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2010
2011     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2012     lstrcatA(keypath, "Installer\\Managed\\");
2013     lstrcatA(keypath, usersid);
2014     lstrcatA(keypath, "\\Installer\\Products\\");
2015     lstrcatA(keypath, prod_squashed);
2016
2017     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2018     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2019
2020     /* user managed product key of first product exists */
2021     lstrcpyA(product, "prod");
2022     r = MsiGetProductCodeA(component, product);
2023     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2024     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2025
2026     RegDeleteKeyA(prodkey, "");
2027     RegCloseKey(prodkey);
2028
2029     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2030     lstrcatA(keypath, prod_squashed);
2031
2032     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2033     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2034
2035     /* user unmanaged product key exists */
2036     lstrcpyA(product, "prod");
2037     r = MsiGetProductCodeA(component, product);
2038     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2039     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2040
2041     RegDeleteKeyA(prodkey, "");
2042     RegCloseKey(prodkey);
2043
2044     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2045     lstrcatA(keypath, prod_squashed);
2046
2047     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2048     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2049
2050     /* local classes product key exists */
2051     lstrcpyA(product, "prod");
2052     r = MsiGetProductCodeA(component, product);
2053     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2054     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2055
2056     RegDeleteKeyA(prodkey, "");
2057     RegCloseKey(prodkey);
2058
2059     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2060     lstrcatA(keypath, "Installer\\Managed\\");
2061     lstrcatA(keypath, usersid);
2062     lstrcatA(keypath, "\\Installer\\Products\\");
2063     lstrcatA(keypath, prod2_squashed);
2064
2065     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2067
2068     /* user managed product key of second product exists */
2069     lstrcpyA(product, "prod");
2070     r = MsiGetProductCodeA(component, product);
2071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2072     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2073
2074     RegDeleteKeyA(prodkey, "");
2075     RegCloseKey(prodkey);
2076     RegDeleteValueA(compkey, prod_squashed);
2077     RegDeleteValueA(compkey, prod2_squashed);
2078     RegDeleteKeyA(compkey, "");
2079     RegCloseKey(compkey);
2080 }
2081
2082 static void test_MsiEnumClients(void)
2083 {
2084     HKEY compkey;
2085     CHAR prodcode[MAX_PATH];
2086     CHAR prod_squashed[MAX_PATH];
2087     CHAR prodcode2[MAX_PATH];
2088     CHAR prod2_squashed[MAX_PATH];
2089     CHAR component[MAX_PATH];
2090     CHAR comp_base85[MAX_PATH];
2091     CHAR comp_squashed[MAX_PATH];
2092     CHAR product[MAX_PATH];
2093     CHAR keypath[MAX_PATH];
2094     LPSTR usersid;
2095     LONG res;
2096     UINT r;
2097
2098     create_test_guid(prodcode, prod_squashed);
2099     create_test_guid(prodcode2, prod2_squashed);
2100     compose_base85_guid(component, comp_base85, comp_squashed);
2101     get_user_sid(&usersid);
2102
2103     /* NULL szComponent */
2104     product[0] = '\0';
2105     r = MsiEnumClientsA(NULL, 0, product);
2106     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2107     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2108
2109     /* empty szComponent */
2110     product[0] = '\0';
2111     r = MsiEnumClientsA("", 0, product);
2112     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2113     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2114
2115     /* NULL lpProductBuf */
2116     r = MsiEnumClientsA(component, 0, NULL);
2117     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2118
2119     /* all params correct, component missing */
2120     product[0] = '\0';
2121     r = MsiEnumClientsA(component, 0, product);
2122     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2123     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2124
2125     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2126     lstrcatA(keypath, "Installer\\UserData\\");
2127     lstrcatA(keypath, usersid);
2128     lstrcatA(keypath, "\\Components\\");
2129     lstrcatA(keypath, comp_squashed);
2130
2131     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2132     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2133
2134     /* user unmanaged component key exists */
2135     product[0] = '\0';
2136     r = MsiEnumClientsA(component, 0, product);
2137     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2138     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2139
2140     /* index > 0, no products exist */
2141     product[0] = '\0';
2142     r = MsiEnumClientsA(component, 1, product);
2143     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2144     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2145
2146     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2148
2149     /* product value exists */
2150     r = MsiEnumClientsA(component, 0, product);
2151     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2152     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2153
2154     /* try index 0 again */
2155     product[0] = '\0';
2156     r = MsiEnumClientsA(component, 0, product);
2157     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2158     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2159
2160     /* try index 1, second product value does not exist */
2161     product[0] = '\0';
2162     r = MsiEnumClientsA(component, 1, product);
2163     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2164     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2165
2166     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2167     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2168
2169     /* try index 1, second product value does exist */
2170     product[0] = '\0';
2171     r = MsiEnumClientsA(component, 1, product);
2172     todo_wine
2173     {
2174         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2175         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2176     }
2177
2178     /* start the enumeration over */
2179     product[0] = '\0';
2180     r = MsiEnumClientsA(component, 0, product);
2181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2182     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2183        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2184
2185     /* correctly query second product */
2186     product[0] = '\0';
2187     r = MsiEnumClientsA(component, 1, product);
2188     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2189     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2190        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2191
2192     RegDeleteValueA(compkey, prod_squashed);
2193     RegDeleteValueA(compkey, prod2_squashed);
2194     RegDeleteKeyA(compkey, "");
2195     RegCloseKey(compkey);
2196
2197     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2198     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2199     lstrcatA(keypath, comp_squashed);
2200
2201     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2203
2204     /* user local component key exists */
2205     product[0] = '\0';
2206     r = MsiEnumClientsA(component, 0, product);
2207     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2208     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2209
2210     /* index > 0, no products exist */
2211     product[0] = '\0';
2212     r = MsiEnumClientsA(component, 1, product);
2213     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2214     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2215
2216     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2217     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2218
2219     /* product value exists */
2220     product[0] = '\0';
2221     r = MsiEnumClientsA(component, 0, product);
2222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2223     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2224
2225     /* try index 0 again */
2226     product[0] = '\0';
2227     r = MsiEnumClientsA(component, 0, product);
2228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2229
2230     /* try index 1, second product value does not exist */
2231     product[0] = '\0';
2232     r = MsiEnumClientsA(component, 1, product);
2233     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2234     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2235
2236     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2238
2239     /* try index 1, second product value does exist */
2240     product[0] = '\0';
2241     r = MsiEnumClientsA(component, 1, product);
2242     todo_wine
2243     {
2244         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2245         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2246     }
2247
2248     /* start the enumeration over */
2249     product[0] = '\0';
2250     r = MsiEnumClientsA(component, 0, product);
2251     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2252     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2253        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2254
2255     /* correctly query second product */
2256     product[0] = '\0';
2257     r = MsiEnumClientsA(component, 1, product);
2258     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2259     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2260        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2261
2262     RegDeleteValueA(compkey, prod_squashed);
2263     RegDeleteValueA(compkey, prod2_squashed);
2264     RegDeleteKeyA(compkey, "");
2265     RegCloseKey(compkey);
2266 }
2267
2268 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2269                              LPSTR *langcheck, LPDWORD langchecksz)
2270 {
2271     LPSTR version;
2272     VS_FIXEDFILEINFO *ffi;
2273     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2274     USHORT *lang;
2275
2276     version = HeapAlloc(GetProcessHeap(), 0, size);
2277     GetFileVersionInfoA(path, 0, size, version);
2278
2279     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2280     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2281     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2282             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2283             LOWORD(ffi->dwFileVersionLS));
2284     *verchecksz = lstrlenA(*vercheck);
2285
2286     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2287     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2288     sprintf(*langcheck, "%d", *lang);
2289     *langchecksz = lstrlenA(*langcheck);
2290
2291     HeapFree(GetProcessHeap(), 0, version);
2292 }
2293
2294 static void test_MsiGetFileVersion(void)
2295 {
2296     UINT r;
2297     DWORD versz, langsz;
2298     char version[MAX_PATH];
2299     char lang[MAX_PATH];
2300     char path[MAX_PATH];
2301     LPSTR vercheck, langcheck;
2302     DWORD verchecksz, langchecksz;
2303
2304     /* NULL szFilePath */
2305     versz = MAX_PATH;
2306     langsz = MAX_PATH;
2307     lstrcpyA(version, "version");
2308     lstrcpyA(lang, "lang");
2309     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2310     ok(r == ERROR_INVALID_PARAMETER,
2311        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2312     ok(!lstrcmpA(version, "version"),
2313        "Expected version to be unchanged, got %s\n", version);
2314     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2315     ok(!lstrcmpA(lang, "lang"),
2316        "Expected lang to be unchanged, got %s\n", lang);
2317     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2318
2319     /* empty szFilePath */
2320     versz = MAX_PATH;
2321     langsz = MAX_PATH;
2322     lstrcpyA(version, "version");
2323     lstrcpyA(lang, "lang");
2324     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2325     ok(r == ERROR_FILE_NOT_FOUND,
2326        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2327     ok(!lstrcmpA(version, "version"),
2328        "Expected version to be unchanged, got %s\n", version);
2329     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2330     ok(!lstrcmpA(lang, "lang"),
2331        "Expected lang to be unchanged, got %s\n", lang);
2332     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2333
2334     /* nonexistent szFilePath */
2335     versz = MAX_PATH;
2336     langsz = MAX_PATH;
2337     lstrcpyA(version, "version");
2338     lstrcpyA(lang, "lang");
2339     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2340     ok(r == ERROR_FILE_NOT_FOUND,
2341        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2342     ok(!lstrcmpA(version, "version"),
2343        "Expected version to be unchanged, got %s\n", version);
2344     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2345     ok(!lstrcmpA(lang, "lang"),
2346        "Expected lang to be unchanged, got %s\n", lang);
2347     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2348
2349     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2350     versz = MAX_PATH;
2351     langsz = MAX_PATH;
2352     lstrcpyA(version, "version");
2353     lstrcpyA(lang, "lang");
2354     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2355     ok(r == ERROR_INVALID_PARAMETER,
2356        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2357     ok(!lstrcmpA(version, "version"),
2358        "Expected version to be unchanged, got %s\n", version);
2359     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2360     ok(!lstrcmpA(lang, "lang"),
2361        "Expected lang to be unchanged, got %s\n", lang);
2362     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2363
2364     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2365     versz = MAX_PATH;
2366     langsz = MAX_PATH;
2367     lstrcpyA(version, "version");
2368     lstrcpyA(lang, "lang");
2369     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2370     ok(r == ERROR_INVALID_PARAMETER,
2371        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2372     ok(!lstrcmpA(version, "version"),
2373        "Expected version to be unchanged, got %s\n", version);
2374     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2375     ok(!lstrcmpA(lang, "lang"),
2376        "Expected lang to be unchanged, got %s\n", lang);
2377     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2378
2379     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2380     versz = 0;
2381     langsz = MAX_PATH;
2382     lstrcpyA(version, "version");
2383     lstrcpyA(lang, "lang");
2384     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2385     ok(r == ERROR_FILE_NOT_FOUND,
2386        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2387     ok(!lstrcmpA(version, "version"),
2388        "Expected version to be unchanged, got %s\n", version);
2389     ok(versz == 0, "Expected 0, got %d\n", versz);
2390     ok(!lstrcmpA(lang, "lang"),
2391        "Expected lang to be unchanged, got %s\n", lang);
2392     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2393
2394     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2395     versz = MAX_PATH;
2396     langsz = 0;
2397     lstrcpyA(version, "version");
2398     lstrcpyA(lang, "lang");
2399     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2400     ok(r == ERROR_FILE_NOT_FOUND,
2401        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2402     ok(!lstrcmpA(version, "version"),
2403        "Expected version to be unchanged, got %s\n", version);
2404     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2405     ok(!lstrcmpA(lang, "lang"),
2406        "Expected lang to be unchanged, got %s\n", lang);
2407     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2408
2409     /* nonexistent szFilePath, rest NULL */
2410     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2411     ok(r == ERROR_FILE_NOT_FOUND,
2412        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2413
2414     create_file("ver.txt", "ver.txt", 20);
2415
2416     /* file exists, no version information */
2417     versz = MAX_PATH;
2418     langsz = MAX_PATH;
2419     lstrcpyA(version, "version");
2420     lstrcpyA(lang, "lang");
2421     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2422     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2423     ok(!lstrcmpA(version, "version"),
2424        "Expected version to be unchanged, got %s\n", version);
2425     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2426     ok(!lstrcmpA(lang, "lang"),
2427        "Expected lang to be unchanged, got %s\n", lang);
2428     ok(r == ERROR_FILE_INVALID,
2429        "Expected ERROR_FILE_INVALID, got %d\n", r);
2430
2431     DeleteFileA("ver.txt");
2432
2433     /* relative path, has version information */
2434     versz = MAX_PATH;
2435     langsz = MAX_PATH;
2436     lstrcpyA(version, "version");
2437     lstrcpyA(lang, "lang");
2438     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2439     todo_wine
2440     {
2441         ok(r == ERROR_FILE_NOT_FOUND,
2442            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2443         ok(!lstrcmpA(version, "version"),
2444            "Expected version to be unchanged, got %s\n", version);
2445         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2446         ok(!lstrcmpA(lang, "lang"),
2447            "Expected lang to be unchanged, got %s\n", lang);
2448         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2449     }
2450
2451     GetSystemDirectoryA(path, MAX_PATH);
2452     lstrcatA(path, "\\kernel32.dll");
2453
2454     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2455
2456     /* absolute path, has version information */
2457     versz = MAX_PATH;
2458     langsz = MAX_PATH;
2459     lstrcpyA(version, "version");
2460     lstrcpyA(lang, "lang");
2461     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2462     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2463     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2464     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2465     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2466     ok(!lstrcmpA(version, vercheck),
2467         "Expected %s, got %s\n", vercheck, version);
2468
2469     /* only check version */
2470     versz = MAX_PATH;
2471     lstrcpyA(version, "version");
2472     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2473     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2474     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2475     ok(!lstrcmpA(version, vercheck),
2476        "Expected %s, got %s\n", vercheck, version);
2477
2478     /* only check language */
2479     langsz = MAX_PATH;
2480     lstrcpyA(lang, "lang");
2481     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2483     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2484     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2485
2486     /* check neither version nor language */
2487     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2488     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2489
2490     /* get pcchVersionBuf */
2491     versz = MAX_PATH;
2492     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2494     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2495
2496     /* get pcchLangBuf */
2497     langsz = MAX_PATH;
2498     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2499     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2500     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2501
2502     /* pcchVersionBuf not big enough */
2503     versz = 5;
2504     lstrcpyA(version, "version");
2505     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2506     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2507     ok(!strncmp(version, vercheck, 4),
2508        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2509     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2510
2511     /* pcchLangBuf not big enough */
2512     langsz = 3;
2513     lstrcpyA(lang, "lang");
2514     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2515     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2516     ok(!strncmp(lang, langcheck, 2),
2517        "Expected first character of %s, got %s\n", langcheck, lang);
2518     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2519
2520     HeapFree(GetProcessHeap(), 0, vercheck);
2521     HeapFree(GetProcessHeap(), 0, langcheck);
2522 }
2523
2524 static void test_MsiGetProductInfo(void)
2525 {
2526     UINT r;
2527     LONG res;
2528     HKEY propkey, source;
2529     HKEY prodkey, localkey;
2530     CHAR prodcode[MAX_PATH];
2531     CHAR prod_squashed[MAX_PATH];
2532     CHAR packcode[MAX_PATH];
2533     CHAR pack_squashed[MAX_PATH];
2534     CHAR buf[MAX_PATH];
2535     CHAR keypath[MAX_PATH];
2536     LPSTR usersid;
2537     DWORD sz, val = 42;
2538
2539     create_test_guid(prodcode, prod_squashed);
2540     create_test_guid(packcode, pack_squashed);
2541     get_user_sid(&usersid);
2542
2543     /* NULL szProduct */
2544     sz = MAX_PATH;
2545     lstrcpyA(buf, "apple");
2546     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2547     ok(r == ERROR_INVALID_PARAMETER,
2548        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2549     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2550     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2551
2552     /* empty szProduct */
2553     sz = MAX_PATH;
2554     lstrcpyA(buf, "apple");
2555     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2556     ok(r == ERROR_INVALID_PARAMETER,
2557        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2558     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2559     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2560
2561     /* garbage szProduct */
2562     sz = MAX_PATH;
2563     lstrcpyA(buf, "apple");
2564     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2565     ok(r == ERROR_INVALID_PARAMETER,
2566        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2567     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2568     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2569
2570     /* guid without brackets */
2571     sz = MAX_PATH;
2572     lstrcpyA(buf, "apple");
2573     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2574                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2575     ok(r == ERROR_INVALID_PARAMETER,
2576        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2577     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2578     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2579
2580     /* guid with brackets */
2581     sz = MAX_PATH;
2582     lstrcpyA(buf, "apple");
2583     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2584                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2585     ok(r == ERROR_UNKNOWN_PRODUCT,
2586        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2587     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2588     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2589
2590     /* same length as guid, but random */
2591     sz = MAX_PATH;
2592     lstrcpyA(buf, "apple");
2593     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2594                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2595     ok(r == ERROR_INVALID_PARAMETER,
2596        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2597     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2598     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2599
2600     /* not installed, NULL szAttribute */
2601     sz = MAX_PATH;
2602     lstrcpyA(buf, "apple");
2603     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2604     ok(r == ERROR_INVALID_PARAMETER,
2605        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2606     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2607     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2608
2609     /* not installed, NULL lpValueBuf */
2610     sz = MAX_PATH;
2611     lstrcpyA(buf, "apple");
2612     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2613     ok(r == ERROR_UNKNOWN_PRODUCT,
2614        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2615     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2616     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2617
2618     /* not installed, NULL pcchValueBuf */
2619     sz = MAX_PATH;
2620     lstrcpyA(buf, "apple");
2621     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2622     ok(r == ERROR_INVALID_PARAMETER,
2623        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2624     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2625     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2626
2627     /* created guid cannot possibly be an installed product code */
2628     sz = MAX_PATH;
2629     lstrcpyA(buf, "apple");
2630     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2631     ok(r == ERROR_UNKNOWN_PRODUCT,
2632        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2633     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2634     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2635
2636     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2637     lstrcatA(keypath, usersid);
2638     lstrcatA(keypath, "\\Installer\\Products\\");
2639     lstrcatA(keypath, prod_squashed);
2640
2641     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2643
2644     /* managed product code exists */
2645     sz = MAX_PATH;
2646     lstrcpyA(buf, "apple");
2647     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2648     ok(r == ERROR_UNKNOWN_PROPERTY,
2649        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2650     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2651     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2652
2653     RegDeleteKeyA(prodkey, "");
2654     RegCloseKey(prodkey);
2655
2656     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2657     lstrcatA(keypath, usersid);
2658     lstrcatA(keypath, "\\Products\\");
2659     lstrcatA(keypath, prod_squashed);
2660
2661     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2662     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2663
2664     /* local user product code exists */
2665     sz = MAX_PATH;
2666     lstrcpyA(buf, "apple");
2667     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2668     ok(r == ERROR_UNKNOWN_PRODUCT,
2669        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2670     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2671     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2672
2673     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2674     lstrcatA(keypath, usersid);
2675     lstrcatA(keypath, "\\Installer\\Products\\");
2676     lstrcatA(keypath, prod_squashed);
2677
2678     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2679     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2680
2681     /* both local and managed product code exist */
2682     sz = MAX_PATH;
2683     lstrcpyA(buf, "apple");
2684     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2685     ok(r == ERROR_UNKNOWN_PROPERTY,
2686        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2687     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2688     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2689
2690     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2691     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2692
2693     /* InstallProperties key exists */
2694     sz = MAX_PATH;
2695     lstrcpyA(buf, "apple");
2696     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2697     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2698     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2699     ok(sz == 0, "Expected 0, got %d\n", sz);
2700
2701     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2702     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2703
2704     /* HelpLink value exists */
2705     sz = MAX_PATH;
2706     lstrcpyA(buf, "apple");
2707     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2708     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2709     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2710     ok(sz == 4, "Expected 4, got %d\n", sz);
2711
2712     /* pcchBuf is NULL */
2713     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
2714     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2715
2716     /* lpValueBuf is NULL */
2717     sz = MAX_PATH;
2718     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2719     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2720     ok(sz == 4, "Expected 4, got %d\n", sz);
2721
2722     /* lpValueBuf is NULL, pcchValueBuf is too small */
2723     sz = 2;
2724     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2725     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2726     ok(sz == 4, "Expected 4, got %d\n", sz);
2727
2728     /* lpValueBuf is NULL, pcchValueBuf is too small */
2729     sz = 2;
2730     lstrcpyA(buf, "apple");
2731     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2732     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
2733     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2734     ok(sz == 4, "Expected 4, got %d\n", sz);
2735
2736     /* lpValueBuf is NULL, pcchValueBuf is exactly 4 */
2737     sz = 4;
2738     lstrcpyA(buf, "apple");
2739     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2740     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2741     ok(!lstrcmpA(buf, "apple"),
2742        "Expected buf to remain unchanged, got \"%s\"\n", buf);
2743     ok(sz == 4, "Expected 4, got %d\n", sz);
2744
2745     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
2746     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2747
2748     /* random property not supported by MSI, value exists */
2749     sz = MAX_PATH;
2750     lstrcpyA(buf, "apple");
2751     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
2752     ok(r == ERROR_UNKNOWN_PROPERTY,
2753        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2754     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2755     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2756
2757     RegDeleteValueA(propkey, "IMadeThis");
2758     RegDeleteValueA(propkey, "HelpLink");
2759     RegDeleteKeyA(propkey, "");
2760     RegDeleteKeyA(localkey, "");
2761     RegDeleteKeyA(prodkey, "");
2762     RegCloseKey(propkey);
2763     RegCloseKey(localkey);
2764     RegCloseKey(prodkey);
2765
2766     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2767     lstrcatA(keypath, prod_squashed);
2768
2769     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2770     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2771
2772     /* user product key exists */
2773     sz = MAX_PATH;
2774     lstrcpyA(buf, "apple");
2775     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2776     ok(r == ERROR_UNKNOWN_PROPERTY,
2777        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2778     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2779     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2780
2781     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2782     lstrcatA(keypath, usersid);
2783     lstrcatA(keypath, "\\Products\\");
2784     lstrcatA(keypath, prod_squashed);
2785
2786     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2788
2789     /* local user product key exists */
2790     sz = MAX_PATH;
2791     lstrcpyA(buf, "apple");
2792     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2793     ok(r == ERROR_UNKNOWN_PROPERTY,
2794        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2795     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2796     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2797
2798     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2799     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2800
2801     /* InstallProperties key exists */
2802     sz = MAX_PATH;
2803     lstrcpyA(buf, "apple");
2804     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2805     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2806     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2807     ok(sz == 0, "Expected 0, got %d\n", sz);
2808
2809     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2810     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2811
2812     /* HelpLink value exists */
2813     sz = MAX_PATH;
2814     lstrcpyA(buf, "apple");
2815     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2816     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2817     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2818     ok(sz == 4, "Expected 4, got %d\n", sz);
2819
2820     RegDeleteValueA(propkey, "HelpLink");
2821     RegDeleteKeyA(propkey, "");
2822     RegDeleteKeyA(localkey, "");
2823     RegDeleteKeyA(prodkey, "");
2824     RegCloseKey(propkey);
2825     RegCloseKey(localkey);
2826     RegCloseKey(prodkey);
2827
2828     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2829     lstrcatA(keypath, prod_squashed);
2830
2831     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2832     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2833
2834     /* classes product key exists */
2835     sz = MAX_PATH;
2836     lstrcpyA(buf, "apple");
2837     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2838     ok(r == ERROR_UNKNOWN_PROPERTY,
2839        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2840     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2841     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2842
2843     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2844     lstrcatA(keypath, usersid);
2845     lstrcatA(keypath, "\\Products\\");
2846     lstrcatA(keypath, prod_squashed);
2847
2848     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2849     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2850
2851     /* local user product key exists */
2852     sz = MAX_PATH;
2853     lstrcpyA(buf, "apple");
2854     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2855     ok(r == ERROR_UNKNOWN_PROPERTY,
2856        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2857     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2858     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2859
2860     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2861     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2862
2863     /* InstallProperties key exists */
2864     sz = MAX_PATH;
2865     lstrcpyA(buf, "apple");
2866     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2867     ok(r == ERROR_UNKNOWN_PROPERTY,
2868        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2869     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2870     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2871
2872     RegDeleteKeyA(propkey, "");
2873     RegDeleteKeyA(localkey, "");
2874     RegCloseKey(propkey);
2875     RegCloseKey(localkey);
2876
2877     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2878     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
2879     lstrcatA(keypath, prod_squashed);
2880
2881     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2882     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2883
2884     /* Local System product key exists */
2885     sz = MAX_PATH;
2886     lstrcpyA(buf, "apple");
2887     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2888     ok(r == ERROR_UNKNOWN_PROPERTY,
2889         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2890     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2891     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2892
2893     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2894     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2895
2896     /* InstallProperties key exists */
2897     sz = MAX_PATH;
2898     lstrcpyA(buf, "apple");
2899     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2900     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2901     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2902     ok(sz == 0, "Expected 0, got %d\n", sz);
2903
2904     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2905     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2906
2907     /* HelpLink value exists */
2908     sz = MAX_PATH;
2909     lstrcpyA(buf, "apple");
2910     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2911     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2912     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2913     ok(sz == 4, "Expected 4, got %d\n", sz);
2914
2915     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
2916                          (const BYTE *)&val, sizeof(DWORD));
2917     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2918
2919     /* HelpLink type is REG_DWORD */
2920     sz = MAX_PATH;
2921     lstrcpyA(buf, "apple");
2922     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2923     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2924     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2925     ok(sz == 2, "Expected 2, got %d\n", sz);
2926
2927     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
2928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2929
2930     /* DisplayName value exists */
2931     sz = MAX_PATH;
2932     lstrcpyA(buf, "apple");
2933     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2934     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2935     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
2936     ok(sz == 4, "Expected 4, got %d\n", sz);
2937
2938     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
2939                          (const BYTE *)&val, sizeof(DWORD));
2940     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2941
2942     /* DisplayName type is REG_DWORD */
2943     sz = MAX_PATH;
2944     lstrcpyA(buf, "apple");
2945     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2946     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2947     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2948     ok(sz == 2, "Expected 2, got %d\n", sz);
2949
2950     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
2951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2952
2953     /* DisplayVersion value exists */
2954     sz = MAX_PATH;
2955     lstrcpyA(buf, "apple");
2956     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2957     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2958     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
2959     ok(sz == 5, "Expected 5, got %d\n", sz);
2960
2961     res = RegSetValueExA(propkey, "DisplayVersion", 0,
2962                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2963     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2964
2965     /* DisplayVersion type is REG_DWORD */
2966     sz = MAX_PATH;
2967     lstrcpyA(buf, "apple");
2968     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2969     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2970     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2971     ok(sz == 2, "Expected 2, got %d\n", sz);
2972
2973     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
2974     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2975
2976     /* HelpTelephone value exists */
2977     sz = MAX_PATH;
2978     lstrcpyA(buf, "apple");
2979     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2980     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2981     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
2982     ok(sz == 4, "Expected 4, got %d\n", sz);
2983
2984     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
2985                          (const BYTE *)&val, sizeof(DWORD));
2986     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2987
2988     /* HelpTelephone type is REG_DWORD */
2989     sz = MAX_PATH;
2990     lstrcpyA(buf, "apple");
2991     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2992     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2993     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2994     ok(sz == 2, "Expected 2, got %d\n", sz);
2995
2996     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
2997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2998
2999     /* InstallLocation value exists */
3000     sz = MAX_PATH;
3001     lstrcpyA(buf, "apple");
3002     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3004     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
3005     ok(sz == 3, "Expected 3, got %d\n", sz);
3006
3007     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3008                          (const BYTE *)&val, sizeof(DWORD));
3009     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3010
3011     /* InstallLocation type is REG_DWORD */
3012     sz = MAX_PATH;
3013     lstrcpyA(buf, "apple");
3014     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3015     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3016     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3017     ok(sz == 2, "Expected 2, got %d\n", sz);
3018
3019     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3020     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3021
3022     /* InstallSource value exists */
3023     sz = MAX_PATH;
3024     lstrcpyA(buf, "apple");
3025     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3026     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3027     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3028     ok(sz == 6, "Expected 6, got %d\n", sz);
3029
3030     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3031                          (const BYTE *)&val, sizeof(DWORD));
3032     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3033
3034     /* InstallSource type is REG_DWORD */
3035     sz = MAX_PATH;
3036     lstrcpyA(buf, "apple");
3037     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3038     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3039     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3040     ok(sz == 2, "Expected 2, got %d\n", sz);
3041
3042     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3043     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3044
3045     /* InstallDate value exists */
3046     sz = MAX_PATH;
3047     lstrcpyA(buf, "apple");
3048     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3049     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3050     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3051     ok(sz == 4, "Expected 4, got %d\n", sz);
3052
3053     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3054                          (const BYTE *)&val, sizeof(DWORD));
3055     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3056
3057     /* InstallDate type is REG_DWORD */
3058     sz = MAX_PATH;
3059     lstrcpyA(buf, "apple");
3060     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3061     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3062     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3063     ok(sz == 2, "Expected 2, got %d\n", sz);
3064
3065     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3066     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3067
3068     /* Publisher value exists */
3069     sz = MAX_PATH;
3070     lstrcpyA(buf, "apple");
3071     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3072     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3073     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3074     ok(sz == 3, "Expected 3, got %d\n", sz);
3075
3076     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3077                          (const BYTE *)&val, sizeof(DWORD));
3078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3079
3080     /* Publisher type is REG_DWORD */
3081     sz = MAX_PATH;
3082     lstrcpyA(buf, "apple");
3083     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3084     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3085     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3086     ok(sz == 2, "Expected 2, got %d\n", sz);
3087
3088     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3089     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3090
3091     /* LocalPackage value exists */
3092     sz = MAX_PATH;
3093     lstrcpyA(buf, "apple");
3094     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3095     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3096     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3097     ok(sz == 4, "Expected 4, got %d\n", sz);
3098
3099     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3100                          (const BYTE *)&val, sizeof(DWORD));
3101     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3102
3103     /* LocalPackage type is REG_DWORD */
3104     sz = MAX_PATH;
3105     lstrcpyA(buf, "apple");
3106     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3107     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3108     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3109     ok(sz == 2, "Expected 2, got %d\n", sz);
3110
3111     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3112     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3113
3114     /* UrlInfoAbout value exists */
3115     sz = MAX_PATH;
3116     lstrcpyA(buf, "apple");
3117     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3118     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3119     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3120     ok(sz == 5, "Expected 5, got %d\n", sz);
3121
3122     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3123                          (const BYTE *)&val, sizeof(DWORD));
3124     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3125
3126     /* UrlInfoAbout type is REG_DWORD */
3127     sz = MAX_PATH;
3128     lstrcpyA(buf, "apple");
3129     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3130     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3131     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3132     ok(sz == 2, "Expected 2, got %d\n", sz);
3133
3134     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3135     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3136
3137     /* UrlUpdateInfo value exists */
3138     sz = MAX_PATH;
3139     lstrcpyA(buf, "apple");
3140     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3141     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3142     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3143     ok(sz == 4, "Expected 4, got %d\n", sz);
3144
3145     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3146                          (const BYTE *)&val, sizeof(DWORD));
3147     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3148
3149     /* UrlUpdateInfo type is REG_DWORD */
3150     sz = MAX_PATH;
3151     lstrcpyA(buf, "apple");
3152     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3153     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3154     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3155     ok(sz == 2, "Expected 2, got %d\n", sz);
3156
3157     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3159
3160     /* VersionMinor value exists */
3161     sz = MAX_PATH;
3162     lstrcpyA(buf, "apple");
3163     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3165     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3166     ok(sz == 1, "Expected 1, got %d\n", sz);
3167
3168     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3169                          (const BYTE *)&val, sizeof(DWORD));
3170     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3171
3172     /* VersionMinor type is REG_DWORD */
3173     sz = MAX_PATH;
3174     lstrcpyA(buf, "apple");
3175     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3176     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3177     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3178     ok(sz == 2, "Expected 2, got %d\n", sz);
3179
3180     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3181     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3182
3183     /* VersionMajor value exists */
3184     sz = MAX_PATH;
3185     lstrcpyA(buf, "apple");
3186     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3187     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3188     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3189     ok(sz == 1, "Expected 1, got %d\n", sz);
3190
3191     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3192                          (const BYTE *)&val, sizeof(DWORD));
3193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3194
3195     /* VersionMajor type is REG_DWORD */
3196     sz = MAX_PATH;
3197     lstrcpyA(buf, "apple");
3198     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3199     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3200     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3201     ok(sz == 2, "Expected 2, got %d\n", sz);
3202
3203     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3204     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3205
3206     /* ProductID value exists */
3207     sz = MAX_PATH;
3208     lstrcpyA(buf, "apple");
3209     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3211     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3212     ok(sz == 2, "Expected 2, got %d\n", sz);
3213
3214     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3215                          (const BYTE *)&val, sizeof(DWORD));
3216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3217
3218     /* ProductID type is REG_DWORD */
3219     sz = MAX_PATH;
3220     lstrcpyA(buf, "apple");
3221     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3223     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3224     ok(sz == 2, "Expected 2, got %d\n", sz);
3225
3226     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3227     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3228
3229     /* RegCompany value exists */
3230     sz = MAX_PATH;
3231     lstrcpyA(buf, "apple");
3232     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3233     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3234     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3235     ok(sz == 4, "Expected 4, got %d\n", sz);
3236
3237     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3238                          (const BYTE *)&val, sizeof(DWORD));
3239     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3240
3241     /* RegCompany type is REG_DWORD */
3242     sz = MAX_PATH;
3243     lstrcpyA(buf, "apple");
3244     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3246     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3247     ok(sz == 2, "Expected 2, got %d\n", sz);
3248
3249     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3250     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3251
3252     /* RegOwner value exists */
3253     sz = MAX_PATH;
3254     lstrcpyA(buf, "apple");
3255     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3256     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3257     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3258     ok(sz == 3, "Expected 3, got %d\n", sz);
3259
3260     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3261                          (const BYTE *)&val, sizeof(DWORD));
3262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3263
3264     /* RegOwner type is REG_DWORD */
3265     sz = MAX_PATH;
3266     lstrcpyA(buf, "apple");
3267     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3268     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3269     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3270     ok(sz == 2, "Expected 2, got %d\n", sz);
3271
3272     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3274
3275     /* InstanceType value exists */
3276     sz = MAX_PATH;
3277     lstrcpyA(buf, "apple");
3278     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3279     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3280     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3281     ok(sz == 0, "Expected 0, got %d\n", sz);
3282
3283     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3284                          (const BYTE *)&val, sizeof(DWORD));
3285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3286
3287     /* InstanceType type is REG_DWORD */
3288     sz = MAX_PATH;
3289     lstrcpyA(buf, "apple");
3290     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3291     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3292     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3293     ok(sz == 0, "Expected 0, got %d\n", sz);
3294
3295     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3297
3298     /* InstanceType value exists */
3299     sz = MAX_PATH;
3300     lstrcpyA(buf, "apple");
3301     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3302     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3303     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3304     ok(sz == 4, "Expected 4, got %d\n", sz);
3305
3306     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3307                          (const BYTE *)&val, sizeof(DWORD));
3308     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3309
3310     /* InstanceType type is REG_DWORD */
3311     sz = MAX_PATH;
3312     lstrcpyA(buf, "apple");
3313     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3315     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3316     ok(sz == 2, "Expected 2, got %d\n", sz);
3317
3318     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3319     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3320
3321     /* Transforms value exists */
3322     sz = MAX_PATH;
3323     lstrcpyA(buf, "apple");
3324     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3325     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3326     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3327     ok(sz == 0, "Expected 0, got %d\n", sz);
3328
3329     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3330                          (const BYTE *)&val, sizeof(DWORD));
3331     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3332
3333     /* Transforms type is REG_DWORD */
3334     sz = MAX_PATH;
3335     lstrcpyA(buf, "apple");
3336     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3337     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3338     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3339     ok(sz == 0, "Expected 0, got %d\n", sz);
3340
3341     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3343
3344     /* Transforms value exists */
3345     sz = MAX_PATH;
3346     lstrcpyA(buf, "apple");
3347     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3348     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3349     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3350     ok(sz == 6, "Expected 6, got %d\n", sz);
3351
3352     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3353                          (const BYTE *)&val, sizeof(DWORD));
3354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3355
3356     /* Transforms type is REG_DWORD */
3357     sz = MAX_PATH;
3358     lstrcpyA(buf, "apple");
3359     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3360     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3361     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3362     ok(sz == 2, "Expected 2, got %d\n", sz);
3363
3364     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3366
3367     /* Language value exists */
3368     sz = MAX_PATH;
3369     lstrcpyA(buf, "apple");
3370     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3371     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3372     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3373     ok(sz == 0, "Expected 0, got %d\n", sz);
3374
3375     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3376                          (const BYTE *)&val, sizeof(DWORD));
3377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3378
3379     /* Language type is REG_DWORD */
3380     sz = MAX_PATH;
3381     lstrcpyA(buf, "apple");
3382     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3383     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3384     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3385     ok(sz == 0, "Expected 0, got %d\n", sz);
3386
3387     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3389
3390     /* Language value exists */
3391     sz = MAX_PATH;
3392     lstrcpyA(buf, "apple");
3393     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3394     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3395     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3396     ok(sz == 4, "Expected 4, got %d\n", sz);
3397
3398     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3399                          (const BYTE *)&val, sizeof(DWORD));
3400     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3401
3402     /* Language type is REG_DWORD */
3403     sz = MAX_PATH;
3404     lstrcpyA(buf, "apple");
3405     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3406     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3407     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3408     ok(sz == 2, "Expected 2, got %d\n", sz);
3409
3410     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3412
3413     /* ProductName value exists */
3414     sz = MAX_PATH;
3415     lstrcpyA(buf, "apple");
3416     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3417     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3418     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3419     ok(sz == 0, "Expected 0, got %d\n", sz);
3420
3421     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3422                          (const BYTE *)&val, sizeof(DWORD));
3423     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3424
3425     /* ProductName type is REG_DWORD */
3426     sz = MAX_PATH;
3427     lstrcpyA(buf, "apple");
3428     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3429     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3430     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3431     ok(sz == 0, "Expected 0, got %d\n", sz);
3432
3433     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3434     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3435
3436     /* ProductName value exists */
3437     sz = MAX_PATH;
3438     lstrcpyA(buf, "apple");
3439     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3440     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3441     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3442     ok(sz == 4, "Expected 4, got %d\n", sz);
3443
3444     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3445                          (const BYTE *)&val, sizeof(DWORD));
3446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3447
3448     /* ProductName type is REG_DWORD */
3449     sz = MAX_PATH;
3450     lstrcpyA(buf, "apple");
3451     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3452     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3453     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3454     ok(sz == 2, "Expected 2, got %d\n", sz);
3455
3456     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3457     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3458
3459     /* Assignment value exists */
3460     sz = MAX_PATH;
3461     lstrcpyA(buf, "apple");
3462     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3463     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3464     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3465     ok(sz == 0, "Expected 0, got %d\n", sz);
3466
3467     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3468                          (const BYTE *)&val, sizeof(DWORD));
3469     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3470
3471     /* Assignment type is REG_DWORD */
3472     sz = MAX_PATH;
3473     lstrcpyA(buf, "apple");
3474     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3475     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3476     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3477     ok(sz == 0, "Expected 0, got %d\n", sz);
3478
3479     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3480     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3481
3482     /* Assignment value exists */
3483     sz = MAX_PATH;
3484     lstrcpyA(buf, "apple");
3485     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3486     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3487     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3488     ok(sz == 2, "Expected 2, got %d\n", sz);
3489
3490     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3491                          (const BYTE *)&val, sizeof(DWORD));
3492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3493
3494     /* Assignment type is REG_DWORD */
3495     sz = MAX_PATH;
3496     lstrcpyA(buf, "apple");
3497     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3498     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3499     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3500     ok(sz == 2, "Expected 2, got %d\n", sz);
3501
3502     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3504
3505     /* PackageCode value exists */
3506     sz = MAX_PATH;
3507     lstrcpyA(buf, "apple");
3508     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3509     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3510     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3511     ok(sz == 0, "Expected 0, got %d\n", sz);
3512
3513     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3514                          (const BYTE *)&val, sizeof(DWORD));
3515     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3516
3517     /* PackageCode type is REG_DWORD */
3518     sz = MAX_PATH;
3519     lstrcpyA(buf, "apple");
3520     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3521     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3522     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3523     ok(sz == 0, "Expected 0, got %d\n", sz);
3524
3525     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3527
3528     /* PackageCode value exists */
3529     sz = MAX_PATH;
3530     lstrcpyA(buf, "apple");
3531     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3532     ok(r == ERROR_BAD_CONFIGURATION,
3533        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3534     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3535     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3536
3537     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3538                          (const BYTE *)&val, sizeof(DWORD));
3539     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3540
3541     /* PackageCode type is REG_DWORD */
3542     sz = MAX_PATH;
3543     lstrcpyA(buf, "apple");
3544     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3545     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3546     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3547     ok(sz == 2, "Expected 2, got %d\n", sz);
3548
3549     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3551
3552     /* PackageCode value exists */
3553     sz = MAX_PATH;
3554     lstrcpyA(buf, "apple");
3555     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3556     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3557     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3558     ok(sz == 38, "Expected 38, got %d\n", sz);
3559
3560     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3561     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3562
3563     /* Version value exists */
3564     sz = MAX_PATH;
3565     lstrcpyA(buf, "apple");
3566     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3567     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3568     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3569     ok(sz == 0, "Expected 0, got %d\n", sz);
3570
3571     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3572                          (const BYTE *)&val, sizeof(DWORD));
3573     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3574
3575     /* Version type is REG_DWORD */
3576     sz = MAX_PATH;
3577     lstrcpyA(buf, "apple");
3578     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3579     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3580     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3581     ok(sz == 0, "Expected 0, got %d\n", sz);
3582
3583     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3584     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3585
3586     /* Version value exists */
3587     sz = MAX_PATH;
3588     lstrcpyA(buf, "apple");
3589     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3590     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3591     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3592     ok(sz == 3, "Expected 3, got %d\n", sz);
3593
3594     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3595                          (const BYTE *)&val, sizeof(DWORD));
3596     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3597
3598     /* Version type is REG_DWORD */
3599     sz = MAX_PATH;
3600     lstrcpyA(buf, "apple");
3601     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3602     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3603     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3604     ok(sz == 2, "Expected 2, got %d\n", sz);
3605
3606     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3608
3609     /* ProductIcon value exists */
3610     sz = MAX_PATH;
3611     lstrcpyA(buf, "apple");
3612     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3613     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3614     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3615     ok(sz == 0, "Expected 0, got %d\n", sz);
3616
3617     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3618                          (const BYTE *)&val, sizeof(DWORD));
3619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3620
3621     /* ProductIcon type is REG_DWORD */
3622     sz = MAX_PATH;
3623     lstrcpyA(buf, "apple");
3624     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3625     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3626     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3627     ok(sz == 0, "Expected 0, got %d\n", sz);
3628
3629     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3631
3632     /* ProductIcon value exists */
3633     sz = MAX_PATH;
3634     lstrcpyA(buf, "apple");
3635     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3636     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3637     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3638     ok(sz == 3, "Expected 3, got %d\n", sz);
3639
3640     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3641                          (const BYTE *)&val, sizeof(DWORD));
3642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3643
3644     /* ProductIcon type is REG_DWORD */
3645     sz = MAX_PATH;
3646     lstrcpyA(buf, "apple");
3647     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3648     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3649     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3650     ok(sz == 2, "Expected 2, got %d\n", sz);
3651
3652     res = RegCreateKeyA(prodkey, "SourceList", &source);
3653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3654
3655     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3657
3658     sz = MAX_PATH;
3659     lstrcpyA(buf, "apple");
3660     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3661     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3662     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
3663     ok(sz == 8, "Expected 8, got %d\n", sz);
3664
3665     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
3666                          (const BYTE *)&val, sizeof(DWORD));
3667     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3668
3669     /* PackageName type is REG_DWORD */
3670     sz = MAX_PATH;
3671     lstrcpyA(buf, "apple");
3672     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3673     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3674     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3675     ok(sz == 2, "Expected 2, got %d\n", sz);
3676
3677     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3678     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3679
3680     /* Authorized value exists */
3681     sz = MAX_PATH;
3682     lstrcpyA(buf, "apple");
3683     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3684     if (r != ERROR_UNKNOWN_PROPERTY)
3685     {
3686         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3687         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3688         ok(sz == 0, "Expected 0, got %d\n", sz);
3689     }
3690
3691     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
3692                          (const BYTE *)&val, sizeof(DWORD));
3693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3694
3695     /* AuthorizedLUAApp type is REG_DWORD */
3696     sz = MAX_PATH;
3697     lstrcpyA(buf, "apple");
3698     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3699     if (r != ERROR_UNKNOWN_PROPERTY)
3700     {
3701         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3702         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3703         ok(sz == 0, "Expected 0, got %d\n", sz);
3704     }
3705
3706     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3707     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3708
3709     /* Authorized value exists */
3710     sz = MAX_PATH;
3711     lstrcpyA(buf, "apple");
3712     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3713     if (r != ERROR_UNKNOWN_PROPERTY)
3714     {
3715         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3716         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
3717         ok(sz == 4, "Expected 4, got %d\n", sz);
3718     }
3719
3720     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
3721                          (const BYTE *)&val, sizeof(DWORD));
3722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3723
3724     /* AuthorizedLUAApp type is REG_DWORD */
3725     sz = MAX_PATH;
3726     lstrcpyA(buf, "apple");
3727     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3728     if (r != ERROR_UNKNOWN_PROPERTY)
3729     {
3730         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3731         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3732         ok(sz == 2, "Expected 2, got %d\n", sz);
3733     }
3734
3735     RegDeleteValueA(propkey, "HelpLink");
3736     RegDeleteValueA(propkey, "DisplayName");
3737     RegDeleteValueA(propkey, "DisplayVersion");
3738     RegDeleteValueA(propkey, "HelpTelephone");
3739     RegDeleteValueA(propkey, "InstallLocation");
3740     RegDeleteValueA(propkey, "InstallSource");
3741     RegDeleteValueA(propkey, "InstallDate");
3742     RegDeleteValueA(propkey, "Publisher");
3743     RegDeleteValueA(propkey, "LocalPackage");
3744     RegDeleteValueA(propkey, "UrlInfoAbout");
3745     RegDeleteValueA(propkey, "UrlUpdateInfo");
3746     RegDeleteValueA(propkey, "VersionMinor");
3747     RegDeleteValueA(propkey, "VersionMajor");
3748     RegDeleteValueA(propkey, "ProductID");
3749     RegDeleteValueA(propkey, "RegCompany");
3750     RegDeleteValueA(propkey, "RegOwner");
3751     RegDeleteValueA(propkey, "InstanceType");
3752     RegDeleteValueA(propkey, "Transforms");
3753     RegDeleteValueA(propkey, "Language");
3754     RegDeleteValueA(propkey, "ProductName");
3755     RegDeleteValueA(propkey, "Assignment");
3756     RegDeleteValueA(propkey, "PackageCode");
3757     RegDeleteValueA(propkey, "Version");
3758     RegDeleteValueA(propkey, "ProductIcon");
3759     RegDeleteValueA(propkey, "AuthorizedLUAApp");
3760     RegDeleteKeyA(propkey, "");
3761     RegDeleteKeyA(localkey, "");
3762     RegDeleteValueA(prodkey, "InstanceType");
3763     RegDeleteValueA(prodkey, "Transforms");
3764     RegDeleteValueA(prodkey, "Language");
3765     RegDeleteValueA(prodkey, "ProductName");
3766     RegDeleteValueA(prodkey, "Assignment");
3767     RegDeleteValueA(prodkey, "PackageCode");
3768     RegDeleteValueA(prodkey, "Version");
3769     RegDeleteValueA(prodkey, "ProductIcon");
3770     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
3771     RegDeleteValueA(source, "PackageName");
3772     RegDeleteKeyA(source, "");
3773     RegDeleteKeyA(prodkey, "");
3774     RegCloseKey(propkey);
3775     RegCloseKey(localkey);
3776     RegCloseKey(source);
3777     RegCloseKey(prodkey);
3778 }
3779
3780 static void test_MsiGetProductInfoEx(void)
3781 {
3782     UINT r;
3783     LONG res;
3784     HKEY propkey, userkey;
3785     HKEY prodkey, localkey;
3786     CHAR prodcode[MAX_PATH];
3787     CHAR prod_squashed[MAX_PATH];
3788     CHAR packcode[MAX_PATH];
3789     CHAR pack_squashed[MAX_PATH];
3790     CHAR buf[MAX_PATH];
3791     CHAR keypath[MAX_PATH];
3792     LPSTR usersid;
3793     DWORD sz;
3794
3795     if (!pMsiGetProductInfoExA)
3796     {
3797         skip("MsiGetProductInfoExA is not available\n");
3798         return;
3799     }
3800
3801     create_test_guid(prodcode, prod_squashed);
3802     create_test_guid(packcode, pack_squashed);
3803     get_user_sid(&usersid);
3804
3805     /* NULL szProductCode */
3806     sz = MAX_PATH;
3807     lstrcpyA(buf, "apple");
3808     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3809                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3810     ok(r == ERROR_INVALID_PARAMETER,
3811        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3812     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3813     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3814
3815     /* empty szProductCode */
3816     sz = MAX_PATH;
3817     lstrcpyA(buf, "apple");
3818     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3819                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3820     ok(r == ERROR_INVALID_PARAMETER,
3821        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3822     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3823     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3824
3825     /* garbage szProductCode */
3826     sz = MAX_PATH;
3827     lstrcpyA(buf, "apple");
3828     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3829                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3830     ok(r == ERROR_INVALID_PARAMETER,
3831        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3832     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3833     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3834
3835     /* guid without brackets */
3836     sz = MAX_PATH;
3837     lstrcpyA(buf, "apple");
3838     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
3839                               MSIINSTALLCONTEXT_USERUNMANAGED,
3840                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3841     ok(r == ERROR_INVALID_PARAMETER,
3842        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3843     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3844     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3845
3846     /* guid with brackets */
3847     sz = MAX_PATH;
3848     lstrcpyA(buf, "apple");
3849     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
3850                               MSIINSTALLCONTEXT_USERUNMANAGED,
3851                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3852     ok(r == ERROR_UNKNOWN_PRODUCT,
3853        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3854     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3855     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3856
3857     /* szValue is non-NULL while pcchValue is NULL */
3858     lstrcpyA(buf, "apple");
3859     r = pMsiGetProductInfoExA(prodcode, usersid,
3860                               MSIINSTALLCONTEXT_USERUNMANAGED,
3861                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
3862     ok(r == ERROR_INVALID_PARAMETER,
3863        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3864     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3865
3866     /* dwContext is out of range */
3867     sz = MAX_PATH;
3868     lstrcpyA(buf, "apple");
3869     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
3870                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3871     ok(r == ERROR_INVALID_PARAMETER,
3872        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3873     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3874     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3875
3876     /* szProperty is NULL */
3877     sz = MAX_PATH;
3878     lstrcpyA(buf, "apple");
3879     r = pMsiGetProductInfoExA(prodcode, usersid,
3880                               MSIINSTALLCONTEXT_USERUNMANAGED,
3881                               NULL, buf, &sz);
3882     ok(r == ERROR_INVALID_PARAMETER,
3883        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3884     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3885     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3886
3887     /* szProperty is empty */
3888     sz = MAX_PATH;
3889     lstrcpyA(buf, "apple");
3890     r = pMsiGetProductInfoExA(prodcode, usersid,
3891                               MSIINSTALLCONTEXT_USERUNMANAGED,
3892                               "", buf, &sz);
3893     ok(r == ERROR_INVALID_PARAMETER,
3894        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3895     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3896     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3897
3898     /* szProperty is not a valid property */
3899     sz = MAX_PATH;
3900     lstrcpyA(buf, "apple");
3901     r = pMsiGetProductInfoExA(prodcode, usersid,
3902                               MSIINSTALLCONTEXT_USERUNMANAGED,
3903                               "notvalid", buf, &sz);
3904     ok(r == ERROR_UNKNOWN_PRODUCT,
3905        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3906     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3907     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3908
3909     /* same length as guid, but random */
3910     sz = MAX_PATH;
3911     lstrcpyA(buf, "apple");
3912     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
3913                               MSIINSTALLCONTEXT_USERUNMANAGED,
3914                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3915     ok(r == ERROR_INVALID_PARAMETER,
3916        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3917     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3918     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3919
3920     /* MSIINSTALLCONTEXT_USERUNMANAGED */
3921
3922     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3923     lstrcatA(keypath, usersid);
3924     lstrcatA(keypath, "\\Products\\");
3925     lstrcatA(keypath, prod_squashed);
3926
3927     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
3928     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3929
3930     /* local user product key exists */
3931     sz = MAX_PATH;
3932     lstrcpyA(buf, "apple");
3933     r = pMsiGetProductInfoExA(prodcode, usersid,
3934                               MSIINSTALLCONTEXT_USERUNMANAGED,
3935                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3936     ok(r == ERROR_UNKNOWN_PRODUCT,
3937        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3938     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3939     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3940
3941     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
3942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3943
3944     /* InstallProperties key exists */
3945     sz = MAX_PATH;
3946     lstrcpyA(buf, "apple");
3947     r = pMsiGetProductInfoExA(prodcode, usersid,
3948                               MSIINSTALLCONTEXT_USERUNMANAGED,
3949                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3950     ok(r == ERROR_UNKNOWN_PRODUCT,
3951        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3952     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3953     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3954
3955     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3957
3958     /* LocalPackage value exists */
3959     sz = MAX_PATH;
3960     lstrcpyA(buf, "apple");
3961     r = pMsiGetProductInfoExA(prodcode, usersid,
3962                               MSIINSTALLCONTEXT_USERUNMANAGED,
3963                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3964     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3965     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
3966     ok(sz == 1, "Expected 1, got %d\n", sz);
3967
3968     RegDeleteValueA(propkey, "LocalPackage");
3969
3970     /* LocalPackage value must exist */
3971     sz = MAX_PATH;
3972     lstrcpyA(buf, "apple");
3973     r = pMsiGetProductInfoExA(prodcode, usersid,
3974                               MSIINSTALLCONTEXT_USERUNMANAGED,
3975                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3976     ok(r == ERROR_UNKNOWN_PRODUCT,
3977        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3978     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3979     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3980
3981     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3982     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3983
3984     /* LocalPackage exists, but HelpLink does not exist */
3985     sz = MAX_PATH;
3986     lstrcpyA(buf, "apple");
3987     r = pMsiGetProductInfoExA(prodcode, usersid,
3988                               MSIINSTALLCONTEXT_USERUNMANAGED,
3989                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3990     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3991     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3992     ok(sz == 0, "Expected 0, got %d\n", sz);
3993
3994     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3995     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3996
3997     /* HelpLink value exists */
3998     sz = MAX_PATH;
3999     lstrcpyA(buf, "apple");
4000     r = pMsiGetProductInfoExA(prodcode, usersid,
4001                               MSIINSTALLCONTEXT_USERUNMANAGED,
4002                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4003     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4004     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4005     ok(sz == 4, "Expected 4, got %d\n", sz);
4006
4007     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4009
4010     /* HelpTelephone value exists */
4011     sz = MAX_PATH;
4012     lstrcpyA(buf, "apple");
4013     r = pMsiGetProductInfoExA(prodcode, usersid,
4014                               MSIINSTALLCONTEXT_USERUNMANAGED,
4015                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4016     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4017     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4018     ok(sz == 5, "Expected 5, got %d\n", sz);
4019
4020     /* szValue and pcchValue are NULL */
4021     r = pMsiGetProductInfoExA(prodcode, usersid,
4022                               MSIINSTALLCONTEXT_USERUNMANAGED,
4023                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4025
4026     /* pcchValue is exactly 5 */
4027     sz = 5;
4028     lstrcpyA(buf, "apple");
4029     r = pMsiGetProductInfoExA(prodcode, usersid,
4030                               MSIINSTALLCONTEXT_USERUNMANAGED,
4031                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4032     ok(r == ERROR_MORE_DATA,
4033        "Expected ERROR_MORE_DATA, got %d\n", r);
4034     ok(sz == 10, "Expected 10, got %d\n", sz);
4035
4036     /* szValue is NULL, pcchValue is exactly 5 */
4037     sz = 5;
4038     r = pMsiGetProductInfoExA(prodcode, usersid,
4039                               MSIINSTALLCONTEXT_USERUNMANAGED,
4040                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4041     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4042     ok(sz == 10, "Expected 10, got %d\n", sz);
4043
4044     /* szValue is NULL, pcchValue is MAX_PATH */
4045     sz = MAX_PATH;
4046     r = pMsiGetProductInfoExA(prodcode, usersid,
4047                               MSIINSTALLCONTEXT_USERUNMANAGED,
4048                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4049     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4050     ok(sz == 10, "Expected 10, got %d\n", sz);
4051
4052     /* pcchValue is exactly 0 */
4053     sz = 0;
4054     lstrcpyA(buf, "apple");
4055     r = pMsiGetProductInfoExA(prodcode, usersid,
4056                               MSIINSTALLCONTEXT_USERUNMANAGED,
4057                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4058     ok(r == ERROR_MORE_DATA,
4059        "Expected ERROR_MORE_DATA, got %d\n", r);
4060     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4061     ok(sz == 10, "Expected 10, got %d\n", sz);
4062
4063     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4064     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4065
4066     /* szProperty is not a valid property */
4067     sz = MAX_PATH;
4068     lstrcpyA(buf, "apple");
4069     r = pMsiGetProductInfoExA(prodcode, usersid,
4070                               MSIINSTALLCONTEXT_USERUNMANAGED,
4071                               "notvalid", buf, &sz);
4072     ok(r == ERROR_UNKNOWN_PROPERTY,
4073        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4074     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4075     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4076
4077     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4078     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4079
4080     /* InstallDate value exists */
4081     sz = MAX_PATH;
4082     lstrcpyA(buf, "apple");
4083     r = pMsiGetProductInfoExA(prodcode, usersid,
4084                               MSIINSTALLCONTEXT_USERUNMANAGED,
4085                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4086     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4087     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4088     ok(sz == 4, "Expected 4, got %d\n", sz);
4089
4090     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4091     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4092
4093     /* DisplayName value exists */
4094     sz = MAX_PATH;
4095     lstrcpyA(buf, "apple");
4096     r = pMsiGetProductInfoExA(prodcode, usersid,
4097                               MSIINSTALLCONTEXT_USERUNMANAGED,
4098                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4099     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4100     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4101     ok(sz == 4, "Expected 4, got %d\n", sz);
4102
4103     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4104     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4105
4106     /* InstallLocation value exists */
4107     sz = MAX_PATH;
4108     lstrcpyA(buf, "apple");
4109     r = pMsiGetProductInfoExA(prodcode, usersid,
4110                               MSIINSTALLCONTEXT_USERUNMANAGED,
4111                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4112     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4113     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4114     ok(sz == 3, "Expected 3, got %d\n", sz);
4115
4116     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4117     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4118
4119     /* InstallSource value exists */
4120     sz = MAX_PATH;
4121     lstrcpyA(buf, "apple");
4122     r = pMsiGetProductInfoExA(prodcode, usersid,
4123                               MSIINSTALLCONTEXT_USERUNMANAGED,
4124                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4126     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4127     ok(sz == 6, "Expected 6, got %d\n", sz);
4128
4129     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4130     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4131
4132     /* LocalPackage value exists */
4133     sz = MAX_PATH;
4134     lstrcpyA(buf, "apple");
4135     r = pMsiGetProductInfoExA(prodcode, usersid,
4136                               MSIINSTALLCONTEXT_USERUNMANAGED,
4137                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4138     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4139     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4140     ok(sz == 5, "Expected 5, got %d\n", sz);
4141
4142     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4143     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4144
4145     /* Publisher value exists */
4146     sz = MAX_PATH;
4147     lstrcpyA(buf, "apple");
4148     r = pMsiGetProductInfoExA(prodcode, usersid,
4149                               MSIINSTALLCONTEXT_USERUNMANAGED,
4150                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4151     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4152     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4153     ok(sz == 3, "Expected 3, got %d\n", sz);
4154
4155     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4156     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4157
4158     /* URLInfoAbout value exists */
4159     sz = MAX_PATH;
4160     lstrcpyA(buf, "apple");
4161     r = pMsiGetProductInfoExA(prodcode, usersid,
4162                               MSIINSTALLCONTEXT_USERUNMANAGED,
4163                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4164     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4165     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4166     ok(sz == 5, "Expected 5, got %d\n", sz);
4167
4168     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4169     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4170
4171     /* URLUpdateInfo value exists */
4172     sz = MAX_PATH;
4173     lstrcpyA(buf, "apple");
4174     r = pMsiGetProductInfoExA(prodcode, usersid,
4175                               MSIINSTALLCONTEXT_USERUNMANAGED,
4176                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4177     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4178     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4179     ok(sz == 6, "Expected 6, got %d\n", sz);
4180
4181     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4182     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4183
4184     /* VersionMinor value exists */
4185     sz = MAX_PATH;
4186     lstrcpyA(buf, "apple");
4187     r = pMsiGetProductInfoExA(prodcode, usersid,
4188                               MSIINSTALLCONTEXT_USERUNMANAGED,
4189                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4190     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4191     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4192     ok(sz == 1, "Expected 1, got %d\n", sz);
4193
4194     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4195     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4196
4197     /* VersionMajor value exists */
4198     sz = MAX_PATH;
4199     lstrcpyA(buf, "apple");
4200     r = pMsiGetProductInfoExA(prodcode, usersid,
4201                               MSIINSTALLCONTEXT_USERUNMANAGED,
4202                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4203     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4204     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4205     ok(sz == 1, "Expected 1, got %d\n", sz);
4206
4207     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4208     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4209
4210     /* DisplayVersion value exists */
4211     sz = MAX_PATH;
4212     lstrcpyA(buf, "apple");
4213     r = pMsiGetProductInfoExA(prodcode, usersid,
4214                               MSIINSTALLCONTEXT_USERUNMANAGED,
4215                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4217     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4218     ok(sz == 5, "Expected 5, got %d\n", sz);
4219
4220     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4221     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4222
4223     /* ProductID value exists */
4224     sz = MAX_PATH;
4225     lstrcpyA(buf, "apple");
4226     r = pMsiGetProductInfoExA(prodcode, usersid,
4227                               MSIINSTALLCONTEXT_USERUNMANAGED,
4228                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4229     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4230     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4231     ok(sz == 2, "Expected 2, got %d\n", sz);
4232
4233     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4234     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4235
4236     /* RegCompany value exists */
4237     sz = MAX_PATH;
4238     lstrcpyA(buf, "apple");
4239     r = pMsiGetProductInfoExA(prodcode, usersid,
4240                               MSIINSTALLCONTEXT_USERUNMANAGED,
4241                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4242     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4243     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4244     ok(sz == 4, "Expected 4, got %d\n", sz);
4245
4246     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4247     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4248
4249     /* RegOwner value exists */
4250     sz = MAX_PATH;
4251     lstrcpyA(buf, "apple");
4252     r = pMsiGetProductInfoExA(prodcode, usersid,
4253                               MSIINSTALLCONTEXT_USERUNMANAGED,
4254                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4255     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4256     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4257     ok(sz == 5, "Expected 5, got %d\n", sz);
4258
4259     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4260     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4261
4262     /* Transforms value exists */
4263     sz = MAX_PATH;
4264     lstrcpyA(buf, "apple");
4265     r = pMsiGetProductInfoExA(prodcode, usersid,
4266                               MSIINSTALLCONTEXT_USERUNMANAGED,
4267                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4268     ok(r == ERROR_UNKNOWN_PRODUCT,
4269        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4270     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4271     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4272
4273     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4274     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4275
4276     /* Language value exists */
4277     sz = MAX_PATH;
4278     lstrcpyA(buf, "apple");
4279     r = pMsiGetProductInfoExA(prodcode, usersid,
4280                               MSIINSTALLCONTEXT_USERUNMANAGED,
4281                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4282     ok(r == ERROR_UNKNOWN_PRODUCT,
4283        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4284     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4285     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4286
4287     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4289
4290     /* ProductName value exists */
4291     sz = MAX_PATH;
4292     lstrcpyA(buf, "apple");
4293     r = pMsiGetProductInfoExA(prodcode, usersid,
4294                               MSIINSTALLCONTEXT_USERUNMANAGED,
4295                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4296     ok(r == ERROR_UNKNOWN_PRODUCT,
4297        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4298     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4299     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4300
4301     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4303
4304     /* FIXME */
4305
4306     /* AssignmentType value exists */
4307     sz = MAX_PATH;
4308     lstrcpyA(buf, "apple");
4309     r = pMsiGetProductInfoExA(prodcode, usersid,
4310                               MSIINSTALLCONTEXT_USERUNMANAGED,
4311                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4312     ok(r == ERROR_UNKNOWN_PRODUCT,
4313        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4314     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4315     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4316
4317     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4319
4320     /* PackageCode value exists */
4321     sz = MAX_PATH;
4322     lstrcpyA(buf, "apple");
4323     r = pMsiGetProductInfoExA(prodcode, usersid,
4324                               MSIINSTALLCONTEXT_USERUNMANAGED,
4325                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4326     ok(r == ERROR_UNKNOWN_PRODUCT,
4327        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4328     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4329     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4330
4331     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4333
4334     /* Version value exists */
4335     sz = MAX_PATH;
4336     lstrcpyA(buf, "apple");
4337     r = pMsiGetProductInfoExA(prodcode, usersid,
4338                               MSIINSTALLCONTEXT_USERUNMANAGED,
4339                               INSTALLPROPERTY_VERSION, buf, &sz);
4340     ok(r == ERROR_UNKNOWN_PRODUCT,
4341        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4342     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4343     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4344
4345     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4347
4348     /* ProductIcon value exists */
4349     sz = MAX_PATH;
4350     lstrcpyA(buf, "apple");
4351     r = pMsiGetProductInfoExA(prodcode, usersid,
4352                               MSIINSTALLCONTEXT_USERUNMANAGED,
4353                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4354     ok(r == ERROR_UNKNOWN_PRODUCT,
4355        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4356     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4357     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4358
4359     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4361
4362     /* PackageName value exists */
4363     sz = MAX_PATH;
4364     lstrcpyA(buf, "apple");
4365     r = pMsiGetProductInfoExA(prodcode, usersid,
4366                               MSIINSTALLCONTEXT_USERUNMANAGED,
4367                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4368     ok(r == ERROR_UNKNOWN_PRODUCT,
4369        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4370     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4371     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4372
4373     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4374     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4375
4376     /* AuthorizedLUAApp value exists */
4377     sz = MAX_PATH;
4378     lstrcpyA(buf, "apple");
4379     r = pMsiGetProductInfoExA(prodcode, usersid,
4380                               MSIINSTALLCONTEXT_USERUNMANAGED,
4381                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4382     ok(r == ERROR_UNKNOWN_PRODUCT,
4383        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4384     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4385     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4386
4387     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4388     RegDeleteValueA(propkey, "PackageName");
4389     RegDeleteValueA(propkey, "ProductIcon");
4390     RegDeleteValueA(propkey, "Version");
4391     RegDeleteValueA(propkey, "PackageCode");
4392     RegDeleteValueA(propkey, "AssignmentType");
4393     RegDeleteValueA(propkey, "ProductName");
4394     RegDeleteValueA(propkey, "Language");
4395     RegDeleteValueA(propkey, "Transforms");
4396     RegDeleteValueA(propkey, "RegOwner");
4397     RegDeleteValueA(propkey, "RegCompany");
4398     RegDeleteValueA(propkey, "ProductID");
4399     RegDeleteValueA(propkey, "DisplayVersion");
4400     RegDeleteValueA(propkey, "VersionMajor");
4401     RegDeleteValueA(propkey, "VersionMinor");
4402     RegDeleteValueA(propkey, "URLUpdateInfo");
4403     RegDeleteValueA(propkey, "URLInfoAbout");
4404     RegDeleteValueA(propkey, "Publisher");
4405     RegDeleteValueA(propkey, "LocalPackage");
4406     RegDeleteValueA(propkey, "InstallSource");
4407     RegDeleteValueA(propkey, "InstallLocation");
4408     RegDeleteValueA(propkey, "DisplayName");
4409     RegDeleteValueA(propkey, "InstallDate");
4410     RegDeleteValueA(propkey, "HelpTelephone");
4411     RegDeleteValueA(propkey, "HelpLink");
4412     RegDeleteValueA(propkey, "LocalPackage");
4413     RegDeleteKeyA(propkey, "");
4414     RegCloseKey(propkey);
4415     RegDeleteKeyA(localkey, "");
4416     RegCloseKey(localkey);
4417
4418     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4419     lstrcatA(keypath, usersid);
4420     lstrcatA(keypath, "\\Installer\\Products\\");
4421     lstrcatA(keypath, prod_squashed);
4422
4423     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
4424     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4425
4426     /* user product key exists */
4427     sz = MAX_PATH;
4428     lstrcpyA(buf, "apple");
4429     r = pMsiGetProductInfoExA(prodcode, usersid,
4430                               MSIINSTALLCONTEXT_USERUNMANAGED,
4431                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4432     ok(r == ERROR_UNKNOWN_PRODUCT,
4433        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4434     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4435     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4436
4437     RegDeleteKeyA(userkey, "");
4438     RegCloseKey(userkey);
4439
4440     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4441     lstrcatA(keypath, prod_squashed);
4442
4443     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4445
4446     sz = MAX_PATH;
4447     lstrcpyA(buf, "apple");
4448     r = pMsiGetProductInfoExA(prodcode, usersid,
4449                               MSIINSTALLCONTEXT_USERUNMANAGED,
4450                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4451     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4452     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4453     ok(sz == 1, "Expected 1, got %d\n", sz);
4454
4455     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4457
4458     /* HelpLink value exists */
4459     sz = MAX_PATH;
4460     lstrcpyA(buf, "apple");
4461     r = pMsiGetProductInfoExA(prodcode, usersid,
4462                               MSIINSTALLCONTEXT_USERUNMANAGED,
4463                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4464     ok(r == ERROR_UNKNOWN_PROPERTY,
4465        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4466     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4467     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4468
4469     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4470     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4471
4472     /* HelpTelephone value exists */
4473     sz = MAX_PATH;
4474     lstrcpyA(buf, "apple");
4475     r = pMsiGetProductInfoExA(prodcode, usersid,
4476                               MSIINSTALLCONTEXT_USERUNMANAGED,
4477                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4478     ok(r == ERROR_UNKNOWN_PROPERTY,
4479        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4480     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4481     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4482
4483     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4484     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4485
4486     /* InstallDate value exists */
4487     sz = MAX_PATH;
4488     lstrcpyA(buf, "apple");
4489     r = pMsiGetProductInfoExA(prodcode, usersid,
4490                               MSIINSTALLCONTEXT_USERUNMANAGED,
4491                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4492     ok(r == ERROR_UNKNOWN_PROPERTY,
4493        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4494     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4495     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4496
4497     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4499
4500     /* DisplayName value exists */
4501     sz = MAX_PATH;
4502     lstrcpyA(buf, "apple");
4503     r = pMsiGetProductInfoExA(prodcode, usersid,
4504                               MSIINSTALLCONTEXT_USERUNMANAGED,
4505                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4506     ok(r == ERROR_UNKNOWN_PROPERTY,
4507        "Expected ERROR_UNKNOWN_PROPERTY, 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(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4513
4514     /* InstallLocation value exists */
4515     sz = MAX_PATH;
4516     lstrcpyA(buf, "apple");
4517     r = pMsiGetProductInfoExA(prodcode, usersid,
4518                               MSIINSTALLCONTEXT_USERUNMANAGED,
4519                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4520     ok(r == ERROR_UNKNOWN_PROPERTY,
4521        "Expected ERROR_UNKNOWN_PROPERTY, 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(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4526     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4527
4528     /* InstallSource value exists */
4529     sz = MAX_PATH;
4530     lstrcpyA(buf, "apple");
4531     r = pMsiGetProductInfoExA(prodcode, usersid,
4532                               MSIINSTALLCONTEXT_USERUNMANAGED,
4533                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4534     ok(r == ERROR_UNKNOWN_PROPERTY,
4535        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4536     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4537     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4538
4539     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4540     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4541
4542     /* LocalPackage value exists */
4543     sz = MAX_PATH;
4544     lstrcpyA(buf, "apple");
4545     r = pMsiGetProductInfoExA(prodcode, usersid,
4546                               MSIINSTALLCONTEXT_USERUNMANAGED,
4547                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4548     ok(r == ERROR_UNKNOWN_PROPERTY,
4549        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4550     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4551     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4552
4553     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4555
4556     /* Publisher value exists */
4557     sz = MAX_PATH;
4558     lstrcpyA(buf, "apple");
4559     r = pMsiGetProductInfoExA(prodcode, usersid,
4560                               MSIINSTALLCONTEXT_USERUNMANAGED,
4561                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4562     ok(r == ERROR_UNKNOWN_PROPERTY,
4563        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4564     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4565     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4566
4567     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4569
4570     /* URLInfoAbout value exists */
4571     sz = MAX_PATH;
4572     lstrcpyA(buf, "apple");
4573     r = pMsiGetProductInfoExA(prodcode, usersid,
4574                               MSIINSTALLCONTEXT_USERUNMANAGED,
4575                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4576     ok(r == ERROR_UNKNOWN_PROPERTY,
4577        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4578     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4579     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4580
4581     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4583
4584     /* URLUpdateInfo value exists */
4585     sz = MAX_PATH;
4586     lstrcpyA(buf, "apple");
4587     r = pMsiGetProductInfoExA(prodcode, usersid,
4588                               MSIINSTALLCONTEXT_USERUNMANAGED,
4589                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4590     ok(r == ERROR_UNKNOWN_PROPERTY,
4591        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4592     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4593     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4594
4595     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4596     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4597
4598     /* VersionMinor value exists */
4599     sz = MAX_PATH;
4600     lstrcpyA(buf, "apple");
4601     r = pMsiGetProductInfoExA(prodcode, usersid,
4602                               MSIINSTALLCONTEXT_USERUNMANAGED,
4603                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4604     ok(r == ERROR_UNKNOWN_PROPERTY,
4605        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4606     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4607     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4608
4609     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4611
4612     /* VersionMajor value exists */
4613     sz = MAX_PATH;
4614     lstrcpyA(buf, "apple");
4615     r = pMsiGetProductInfoExA(prodcode, usersid,
4616                               MSIINSTALLCONTEXT_USERUNMANAGED,
4617                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4618     ok(r == ERROR_UNKNOWN_PROPERTY,
4619        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4620     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4621     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4622
4623     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4625
4626     /* DisplayVersion value exists */
4627     sz = MAX_PATH;
4628     lstrcpyA(buf, "apple");
4629     r = pMsiGetProductInfoExA(prodcode, usersid,
4630                               MSIINSTALLCONTEXT_USERUNMANAGED,
4631                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4632     ok(r == ERROR_UNKNOWN_PROPERTY,
4633        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4634     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4635     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4636
4637     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4638     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4639
4640     /* ProductID value exists */
4641     sz = MAX_PATH;
4642     lstrcpyA(buf, "apple");
4643     r = pMsiGetProductInfoExA(prodcode, usersid,
4644                               MSIINSTALLCONTEXT_USERUNMANAGED,
4645                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4646     ok(r == ERROR_UNKNOWN_PROPERTY,
4647        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4648     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4649     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4650
4651     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4653
4654     /* RegCompany value exists */
4655     sz = MAX_PATH;
4656     lstrcpyA(buf, "apple");
4657     r = pMsiGetProductInfoExA(prodcode, usersid,
4658                               MSIINSTALLCONTEXT_USERUNMANAGED,
4659                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4660     ok(r == ERROR_UNKNOWN_PROPERTY,
4661        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4662     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4663     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4664
4665     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4667
4668     /* RegOwner value exists */
4669     sz = MAX_PATH;
4670     lstrcpyA(buf, "apple");
4671     r = pMsiGetProductInfoExA(prodcode, usersid,
4672                               MSIINSTALLCONTEXT_USERUNMANAGED,
4673                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4674     ok(r == ERROR_UNKNOWN_PROPERTY,
4675        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4676     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4677     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4678
4679     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4680     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4681
4682     /* Transforms value exists */
4683     sz = MAX_PATH;
4684     lstrcpyA(buf, "apple");
4685     r = pMsiGetProductInfoExA(prodcode, usersid,
4686                               MSIINSTALLCONTEXT_USERUNMANAGED,
4687                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4688     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4689     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
4690     ok(sz == 5, "Expected 5, got %d\n", sz);
4691
4692     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4694
4695     /* Language value exists */
4696     sz = MAX_PATH;
4697     lstrcpyA(buf, "apple");
4698     r = pMsiGetProductInfoExA(prodcode, usersid,
4699                               MSIINSTALLCONTEXT_USERUNMANAGED,
4700                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4702     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4703     ok(sz == 4, "Expected 4, got %d\n", sz);
4704
4705     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4706     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4707
4708     /* ProductName value exists */
4709     sz = MAX_PATH;
4710     lstrcpyA(buf, "apple");
4711     r = pMsiGetProductInfoExA(prodcode, usersid,
4712                               MSIINSTALLCONTEXT_USERUNMANAGED,
4713                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4714     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4715     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4716     ok(sz == 4, "Expected 4, got %d\n", sz);
4717
4718     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4720
4721     /* FIXME */
4722
4723     /* AssignmentType value exists */
4724     sz = MAX_PATH;
4725     lstrcpyA(buf, "apple");
4726     r = pMsiGetProductInfoExA(prodcode, usersid,
4727                               MSIINSTALLCONTEXT_USERUNMANAGED,
4728                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4729     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4730     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4731     ok(sz == 0, "Expected 0, got %d\n", sz);
4732
4733     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4735
4736     /* FIXME */
4737
4738     /* PackageCode value exists */
4739     sz = MAX_PATH;
4740     lstrcpyA(buf, "apple");
4741     r = pMsiGetProductInfoExA(prodcode, usersid,
4742                               MSIINSTALLCONTEXT_USERUNMANAGED,
4743                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4744     todo_wine
4745     {
4746         ok(r == ERROR_BAD_CONFIGURATION,
4747            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4748         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4749         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4750     }
4751
4752     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4754
4755     /* Version value exists */
4756     sz = MAX_PATH;
4757     lstrcpyA(buf, "apple");
4758     r = pMsiGetProductInfoExA(prodcode, usersid,
4759                               MSIINSTALLCONTEXT_USERUNMANAGED,
4760                               INSTALLPROPERTY_VERSION, buf, &sz);
4761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4762     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4763     ok(sz == 3, "Expected 3, got %d\n", sz);
4764
4765     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4767
4768     /* ProductIcon value exists */
4769     sz = MAX_PATH;
4770     lstrcpyA(buf, "apple");
4771     r = pMsiGetProductInfoExA(prodcode, usersid,
4772                               MSIINSTALLCONTEXT_USERUNMANAGED,
4773                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4774     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4775     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
4776     ok(sz == 4, "Expected 4, got %d\n", sz);
4777
4778     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4780
4781     /* PackageName value exists */
4782     sz = MAX_PATH;
4783     lstrcpyA(buf, "apple");
4784     r = pMsiGetProductInfoExA(prodcode, usersid,
4785                               MSIINSTALLCONTEXT_USERUNMANAGED,
4786                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4787     todo_wine
4788     {
4789         ok(r == ERROR_UNKNOWN_PRODUCT,
4790            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4791         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4792         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4793     }
4794
4795     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4796     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4797
4798     /* AuthorizedLUAApp value exists */
4799     sz = MAX_PATH;
4800     lstrcpyA(buf, "apple");
4801     r = pMsiGetProductInfoExA(prodcode, usersid,
4802                               MSIINSTALLCONTEXT_USERUNMANAGED,
4803                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4804     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4805     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4806     ok(sz == 4, "Expected 4, got %d\n", sz);
4807
4808     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4809     RegDeleteValueA(prodkey, "PackageName");
4810     RegDeleteValueA(prodkey, "ProductIcon");
4811     RegDeleteValueA(prodkey, "Version");
4812     RegDeleteValueA(prodkey, "PackageCode");
4813     RegDeleteValueA(prodkey, "AssignmentType");
4814     RegDeleteValueA(prodkey, "ProductName");
4815     RegDeleteValueA(prodkey, "Language");
4816     RegDeleteValueA(prodkey, "Transforms");
4817     RegDeleteValueA(prodkey, "RegOwner");
4818     RegDeleteValueA(prodkey, "RegCompany");
4819     RegDeleteValueA(prodkey, "ProductID");
4820     RegDeleteValueA(prodkey, "DisplayVersion");
4821     RegDeleteValueA(prodkey, "VersionMajor");
4822     RegDeleteValueA(prodkey, "VersionMinor");
4823     RegDeleteValueA(prodkey, "URLUpdateInfo");
4824     RegDeleteValueA(prodkey, "URLInfoAbout");
4825     RegDeleteValueA(prodkey, "Publisher");
4826     RegDeleteValueA(prodkey, "LocalPackage");
4827     RegDeleteValueA(prodkey, "InstallSource");
4828     RegDeleteValueA(prodkey, "InstallLocation");
4829     RegDeleteValueA(prodkey, "DisplayName");
4830     RegDeleteValueA(prodkey, "InstallDate");
4831     RegDeleteValueA(prodkey, "HelpTelephone");
4832     RegDeleteValueA(prodkey, "HelpLink");
4833     RegDeleteValueA(prodkey, "LocalPackage");
4834     RegDeleteKeyA(prodkey, "");
4835     RegCloseKey(prodkey);
4836
4837     /* MSIINSTALLCONTEXT_USERMANAGED */
4838
4839     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4840     lstrcatA(keypath, usersid);
4841     lstrcatA(keypath, "\\Products\\");
4842     lstrcatA(keypath, prod_squashed);
4843
4844     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4845     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4846
4847     /* local user product key exists */
4848     sz = MAX_PATH;
4849     lstrcpyA(buf, "apple");
4850     r = pMsiGetProductInfoExA(prodcode, usersid,
4851                               MSIINSTALLCONTEXT_USERMANAGED,
4852                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4853     ok(r == ERROR_UNKNOWN_PRODUCT,
4854        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4855     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4856     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4857
4858     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4859     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4860
4861     /* InstallProperties key exists */
4862     sz = MAX_PATH;
4863     lstrcpyA(buf, "apple");
4864     r = pMsiGetProductInfoExA(prodcode, usersid,
4865                               MSIINSTALLCONTEXT_USERMANAGED,
4866                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4867     ok(r == ERROR_UNKNOWN_PRODUCT,
4868        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4869     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4870     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4871
4872     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4873     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4874
4875     /* ManagedLocalPackage value exists */
4876     sz = MAX_PATH;
4877     lstrcpyA(buf, "apple");
4878     r = pMsiGetProductInfoExA(prodcode, usersid,
4879                               MSIINSTALLCONTEXT_USERMANAGED,
4880                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4881     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4882     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4883     ok(sz == 1, "Expected 1, got %d\n", sz);
4884
4885     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4886     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4887
4888     /* HelpLink value exists */
4889     sz = MAX_PATH;
4890     lstrcpyA(buf, "apple");
4891     r = pMsiGetProductInfoExA(prodcode, usersid,
4892                               MSIINSTALLCONTEXT_USERMANAGED,
4893                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4894     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4895     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4896     ok(sz == 4, "Expected 4, got %d\n", sz);
4897
4898     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4899     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4900
4901     /* HelpTelephone value exists */
4902     sz = MAX_PATH;
4903     lstrcpyA(buf, "apple");
4904     r = pMsiGetProductInfoExA(prodcode, usersid,
4905                               MSIINSTALLCONTEXT_USERMANAGED,
4906                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4907     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4908     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4909     ok(sz == 5, "Expected 5, got %d\n", sz);
4910
4911     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4912     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4913
4914     /* InstallDate value exists */
4915     sz = MAX_PATH;
4916     lstrcpyA(buf, "apple");
4917     r = pMsiGetProductInfoExA(prodcode, usersid,
4918                               MSIINSTALLCONTEXT_USERMANAGED,
4919                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4920     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4921     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4922     ok(sz == 4, "Expected 4, got %d\n", sz);
4923
4924     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4925     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4926
4927     /* DisplayName value exists */
4928     sz = MAX_PATH;
4929     lstrcpyA(buf, "apple");
4930     r = pMsiGetProductInfoExA(prodcode, usersid,
4931                               MSIINSTALLCONTEXT_USERMANAGED,
4932                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4933     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4934     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4935     ok(sz == 4, "Expected 4, got %d\n", sz);
4936
4937     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4938     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4939
4940     /* InstallLocation value exists */
4941     sz = MAX_PATH;
4942     lstrcpyA(buf, "apple");
4943     r = pMsiGetProductInfoExA(prodcode, usersid,
4944                               MSIINSTALLCONTEXT_USERMANAGED,
4945                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4946     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4947     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4948     ok(sz == 3, "Expected 3, got %d\n", sz);
4949
4950     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4951     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4952
4953     /* InstallSource value exists */
4954     sz = MAX_PATH;
4955     lstrcpyA(buf, "apple");
4956     r = pMsiGetProductInfoExA(prodcode, usersid,
4957                               MSIINSTALLCONTEXT_USERMANAGED,
4958                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4959     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4960     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4961     ok(sz == 6, "Expected 6, got %d\n", sz);
4962
4963     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4964     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4965
4966     /* LocalPackage value exists */
4967     sz = MAX_PATH;
4968     lstrcpyA(buf, "apple");
4969     r = pMsiGetProductInfoExA(prodcode, usersid,
4970                               MSIINSTALLCONTEXT_USERMANAGED,
4971                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4972     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4973     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4974     ok(sz == 5, "Expected 5, got %d\n", sz);
4975
4976     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4977     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4978
4979     /* Publisher value exists */
4980     sz = MAX_PATH;
4981     lstrcpyA(buf, "apple");
4982     r = pMsiGetProductInfoExA(prodcode, usersid,
4983                               MSIINSTALLCONTEXT_USERMANAGED,
4984                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4985     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4986     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4987     ok(sz == 3, "Expected 3, got %d\n", sz);
4988
4989     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4990     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4991
4992     /* URLInfoAbout value exists */
4993     sz = MAX_PATH;
4994     lstrcpyA(buf, "apple");
4995     r = pMsiGetProductInfoExA(prodcode, usersid,
4996                               MSIINSTALLCONTEXT_USERMANAGED,
4997                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4998     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4999     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5000     ok(sz == 5, "Expected 5, got %d\n", sz);
5001
5002     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5003     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5004
5005     /* URLUpdateInfo value exists */
5006     sz = MAX_PATH;
5007     lstrcpyA(buf, "apple");
5008     r = pMsiGetProductInfoExA(prodcode, usersid,
5009                               MSIINSTALLCONTEXT_USERMANAGED,
5010                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5011     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5012     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5013     ok(sz == 6, "Expected 6, got %d\n", sz);
5014
5015     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5016     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5017
5018     /* VersionMinor value exists */
5019     sz = MAX_PATH;
5020     lstrcpyA(buf, "apple");
5021     r = pMsiGetProductInfoExA(prodcode, usersid,
5022                               MSIINSTALLCONTEXT_USERMANAGED,
5023                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5024     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5025     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5026     ok(sz == 1, "Expected 1, got %d\n", sz);
5027
5028     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5029     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5030
5031     /* VersionMajor value exists */
5032     sz = MAX_PATH;
5033     lstrcpyA(buf, "apple");
5034     r = pMsiGetProductInfoExA(prodcode, usersid,
5035                               MSIINSTALLCONTEXT_USERMANAGED,
5036                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5037     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5038     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5039     ok(sz == 1, "Expected 1, got %d\n", sz);
5040
5041     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5042     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5043
5044     /* DisplayVersion value exists */
5045     sz = MAX_PATH;
5046     lstrcpyA(buf, "apple");
5047     r = pMsiGetProductInfoExA(prodcode, usersid,
5048                               MSIINSTALLCONTEXT_USERMANAGED,
5049                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5050     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5051     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5052     ok(sz == 5, "Expected 5, got %d\n", sz);
5053
5054     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5055     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5056
5057     /* ProductID value exists */
5058     sz = MAX_PATH;
5059     lstrcpyA(buf, "apple");
5060     r = pMsiGetProductInfoExA(prodcode, usersid,
5061                               MSIINSTALLCONTEXT_USERMANAGED,
5062                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5063     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5064     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5065     ok(sz == 2, "Expected 2, got %d\n", sz);
5066
5067     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5068     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5069
5070     /* RegCompany value exists */
5071     sz = MAX_PATH;
5072     lstrcpyA(buf, "apple");
5073     r = pMsiGetProductInfoExA(prodcode, usersid,
5074                               MSIINSTALLCONTEXT_USERMANAGED,
5075                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5076     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5077     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5078     ok(sz == 4, "Expected 4, got %d\n", sz);
5079
5080     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5081     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5082
5083     /* RegOwner value exists */
5084     sz = MAX_PATH;
5085     lstrcpyA(buf, "apple");
5086     r = pMsiGetProductInfoExA(prodcode, usersid,
5087                               MSIINSTALLCONTEXT_USERMANAGED,
5088                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5090     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5091     ok(sz == 5, "Expected 5, got %d\n", sz);
5092
5093     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5094     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5095
5096     /* Transforms value exists */
5097     sz = MAX_PATH;
5098     lstrcpyA(buf, "apple");
5099     r = pMsiGetProductInfoExA(prodcode, usersid,
5100                               MSIINSTALLCONTEXT_USERMANAGED,
5101                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5102     ok(r == ERROR_UNKNOWN_PRODUCT,
5103        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5104     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5105     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5106
5107     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5108     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5109
5110     /* Language value exists */
5111     sz = MAX_PATH;
5112     lstrcpyA(buf, "apple");
5113     r = pMsiGetProductInfoExA(prodcode, usersid,
5114                               MSIINSTALLCONTEXT_USERMANAGED,
5115                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5116     ok(r == ERROR_UNKNOWN_PRODUCT,
5117        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5118     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5119     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5120
5121     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5122     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5123
5124     /* ProductName value exists */
5125     sz = MAX_PATH;
5126     lstrcpyA(buf, "apple");
5127     r = pMsiGetProductInfoExA(prodcode, usersid,
5128                               MSIINSTALLCONTEXT_USERMANAGED,
5129                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5130     ok(r == ERROR_UNKNOWN_PRODUCT,
5131        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5132     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5133     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5134
5135     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5136     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5137
5138     /* FIXME */
5139
5140     /* AssignmentType value exists */
5141     sz = MAX_PATH;
5142     lstrcpyA(buf, "apple");
5143     r = pMsiGetProductInfoExA(prodcode, usersid,
5144                               MSIINSTALLCONTEXT_USERMANAGED,
5145                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5146     ok(r == ERROR_UNKNOWN_PRODUCT,
5147        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5148     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5149     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5150
5151     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5152     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5153
5154     /* PackageCode value exists */
5155     sz = MAX_PATH;
5156     lstrcpyA(buf, "apple");
5157     r = pMsiGetProductInfoExA(prodcode, usersid,
5158                               MSIINSTALLCONTEXT_USERMANAGED,
5159                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5160     ok(r == ERROR_UNKNOWN_PRODUCT,
5161        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5162     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5163     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5164
5165     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5166     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5167
5168     /* Version value exists */
5169     sz = MAX_PATH;
5170     lstrcpyA(buf, "apple");
5171     r = pMsiGetProductInfoExA(prodcode, usersid,
5172                               MSIINSTALLCONTEXT_USERMANAGED,
5173                               INSTALLPROPERTY_VERSION, buf, &sz);
5174     ok(r == ERROR_UNKNOWN_PRODUCT,
5175        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5176     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5177     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5178
5179     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5180     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5181
5182     /* ProductIcon value exists */
5183     sz = MAX_PATH;
5184     lstrcpyA(buf, "apple");
5185     r = pMsiGetProductInfoExA(prodcode, usersid,
5186                               MSIINSTALLCONTEXT_USERMANAGED,
5187                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5188     ok(r == ERROR_UNKNOWN_PRODUCT,
5189        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5190     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5191     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5192
5193     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5194     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5195
5196     /* PackageName value exists */
5197     sz = MAX_PATH;
5198     lstrcpyA(buf, "apple");
5199     r = pMsiGetProductInfoExA(prodcode, usersid,
5200                               MSIINSTALLCONTEXT_USERMANAGED,
5201                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5202     ok(r == ERROR_UNKNOWN_PRODUCT,
5203        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5204     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5205     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5206
5207     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5208     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5209
5210     /* AuthorizedLUAApp value exists */
5211     sz = MAX_PATH;
5212     lstrcpyA(buf, "apple");
5213     r = pMsiGetProductInfoExA(prodcode, usersid,
5214                               MSIINSTALLCONTEXT_USERMANAGED,
5215                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5216     ok(r == ERROR_UNKNOWN_PRODUCT,
5217        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5218     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5219     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5220
5221     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5222     RegDeleteValueA(propkey, "PackageName");
5223     RegDeleteValueA(propkey, "ProductIcon");
5224     RegDeleteValueA(propkey, "Version");
5225     RegDeleteValueA(propkey, "PackageCode");
5226     RegDeleteValueA(propkey, "AssignmentType");
5227     RegDeleteValueA(propkey, "ProductName");
5228     RegDeleteValueA(propkey, "Language");
5229     RegDeleteValueA(propkey, "Transforms");
5230     RegDeleteValueA(propkey, "RegOwner");
5231     RegDeleteValueA(propkey, "RegCompany");
5232     RegDeleteValueA(propkey, "ProductID");
5233     RegDeleteValueA(propkey, "DisplayVersion");
5234     RegDeleteValueA(propkey, "VersionMajor");
5235     RegDeleteValueA(propkey, "VersionMinor");
5236     RegDeleteValueA(propkey, "URLUpdateInfo");
5237     RegDeleteValueA(propkey, "URLInfoAbout");
5238     RegDeleteValueA(propkey, "Publisher");
5239     RegDeleteValueA(propkey, "LocalPackage");
5240     RegDeleteValueA(propkey, "InstallSource");
5241     RegDeleteValueA(propkey, "InstallLocation");
5242     RegDeleteValueA(propkey, "DisplayName");
5243     RegDeleteValueA(propkey, "InstallDate");
5244     RegDeleteValueA(propkey, "HelpTelephone");
5245     RegDeleteValueA(propkey, "HelpLink");
5246     RegDeleteValueA(propkey, "ManagedLocalPackage");
5247     RegDeleteKeyA(propkey, "");
5248     RegCloseKey(propkey);
5249     RegDeleteKeyA(localkey, "");
5250     RegCloseKey(localkey);
5251
5252     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5253     lstrcatA(keypath, usersid);
5254     lstrcatA(keypath, "\\Installer\\Products\\");
5255     lstrcatA(keypath, prod_squashed);
5256
5257     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5258     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5259
5260     /* user product key exists */
5261     sz = MAX_PATH;
5262     lstrcpyA(buf, "apple");
5263     r = pMsiGetProductInfoExA(prodcode, usersid,
5264                               MSIINSTALLCONTEXT_USERMANAGED,
5265                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5266     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5267     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5268     ok(sz == 1, "Expected 1, got %d\n", sz);
5269
5270     RegDeleteKeyA(userkey, "");
5271     RegCloseKey(userkey);
5272
5273     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5274     lstrcatA(keypath, prod_squashed);
5275
5276     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5277     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5278
5279     /* current user product key exists */
5280     sz = MAX_PATH;
5281     lstrcpyA(buf, "apple");
5282     r = pMsiGetProductInfoExA(prodcode, usersid,
5283                               MSIINSTALLCONTEXT_USERMANAGED,
5284                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5285     ok(r == ERROR_UNKNOWN_PRODUCT,
5286        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5287     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5288     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5289
5290     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5292
5293     /* HelpLink value exists, user product key does not exist */
5294     sz = MAX_PATH;
5295     lstrcpyA(buf, "apple");
5296     r = pMsiGetProductInfoExA(prodcode, usersid,
5297                               MSIINSTALLCONTEXT_USERMANAGED,
5298                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5299     ok(r == ERROR_UNKNOWN_PRODUCT,
5300        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5301     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5302     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5303
5304     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5305     lstrcatA(keypath, usersid);
5306     lstrcatA(keypath, "\\Installer\\Products\\");
5307     lstrcatA(keypath, prod_squashed);
5308
5309     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5310     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5311
5312     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5313     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5314
5315     /* HelpLink value exists, user product key does exist */
5316     sz = MAX_PATH;
5317     lstrcpyA(buf, "apple");
5318     r = pMsiGetProductInfoExA(prodcode, usersid,
5319                               MSIINSTALLCONTEXT_USERMANAGED,
5320                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5321     ok(r == ERROR_UNKNOWN_PROPERTY,
5322        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5323     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5324     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5325
5326     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5327     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5328
5329     /* HelpTelephone value exists */
5330     sz = MAX_PATH;
5331     lstrcpyA(buf, "apple");
5332     r = pMsiGetProductInfoExA(prodcode, usersid,
5333                               MSIINSTALLCONTEXT_USERMANAGED,
5334                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5335     ok(r == ERROR_UNKNOWN_PROPERTY,
5336        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5337     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5338     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5339
5340     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5341     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5342
5343     /* InstallDate value exists */
5344     sz = MAX_PATH;
5345     lstrcpyA(buf, "apple");
5346     r = pMsiGetProductInfoExA(prodcode, usersid,
5347                               MSIINSTALLCONTEXT_USERMANAGED,
5348                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5349     ok(r == ERROR_UNKNOWN_PROPERTY,
5350        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5351     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5352     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5353
5354     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5355     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5356
5357     /* DisplayName value exists */
5358     sz = MAX_PATH;
5359     lstrcpyA(buf, "apple");
5360     r = pMsiGetProductInfoExA(prodcode, usersid,
5361                               MSIINSTALLCONTEXT_USERMANAGED,
5362                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5363     ok(r == ERROR_UNKNOWN_PROPERTY,
5364        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5365     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5366     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5367
5368     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5369     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5370
5371     /* InstallLocation value exists */
5372     sz = MAX_PATH;
5373     lstrcpyA(buf, "apple");
5374     r = pMsiGetProductInfoExA(prodcode, usersid,
5375                               MSIINSTALLCONTEXT_USERMANAGED,
5376                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5377     ok(r == ERROR_UNKNOWN_PROPERTY,
5378        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5379     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5380     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5381
5382     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5383     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5384
5385     /* InstallSource value exists */
5386     sz = MAX_PATH;
5387     lstrcpyA(buf, "apple");
5388     r = pMsiGetProductInfoExA(prodcode, usersid,
5389                               MSIINSTALLCONTEXT_USERMANAGED,
5390                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5391     ok(r == ERROR_UNKNOWN_PROPERTY,
5392        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5393     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5394     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5395
5396     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5397     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5398
5399     /* LocalPackage value exists */
5400     sz = MAX_PATH;
5401     lstrcpyA(buf, "apple");
5402     r = pMsiGetProductInfoExA(prodcode, usersid,
5403                               MSIINSTALLCONTEXT_USERMANAGED,
5404                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5405     ok(r == ERROR_UNKNOWN_PROPERTY,
5406        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5407     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5408     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5409
5410     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5411     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5412
5413     /* Publisher value exists */
5414     sz = MAX_PATH;
5415     lstrcpyA(buf, "apple");
5416     r = pMsiGetProductInfoExA(prodcode, usersid,
5417                               MSIINSTALLCONTEXT_USERMANAGED,
5418                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5419     ok(r == ERROR_UNKNOWN_PROPERTY,
5420        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5421     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5422     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5423
5424     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5425     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5426
5427     /* URLInfoAbout value exists */
5428     sz = MAX_PATH;
5429     lstrcpyA(buf, "apple");
5430     r = pMsiGetProductInfoExA(prodcode, usersid,
5431                               MSIINSTALLCONTEXT_USERMANAGED,
5432                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5433     ok(r == ERROR_UNKNOWN_PROPERTY,
5434        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5435     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5436     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5437
5438     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5439     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5440
5441     /* URLUpdateInfo value exists */
5442     sz = MAX_PATH;
5443     lstrcpyA(buf, "apple");
5444     r = pMsiGetProductInfoExA(prodcode, usersid,
5445                               MSIINSTALLCONTEXT_USERMANAGED,
5446                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5447     ok(r == ERROR_UNKNOWN_PROPERTY,
5448        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5449     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5450     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5451
5452     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5453     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5454
5455     /* VersionMinor value exists */
5456     sz = MAX_PATH;
5457     lstrcpyA(buf, "apple");
5458     r = pMsiGetProductInfoExA(prodcode, usersid,
5459                               MSIINSTALLCONTEXT_USERMANAGED,
5460                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5461     ok(r == ERROR_UNKNOWN_PROPERTY,
5462        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5463     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5464     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5465
5466     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5467     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5468
5469     /* VersionMajor value exists */
5470     sz = MAX_PATH;
5471     lstrcpyA(buf, "apple");
5472     r = pMsiGetProductInfoExA(prodcode, usersid,
5473                               MSIINSTALLCONTEXT_USERMANAGED,
5474                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5475     ok(r == ERROR_UNKNOWN_PROPERTY,
5476        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5477     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5478     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5479
5480     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5481     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5482
5483     /* DisplayVersion value exists */
5484     sz = MAX_PATH;
5485     lstrcpyA(buf, "apple");
5486     r = pMsiGetProductInfoExA(prodcode, usersid,
5487                               MSIINSTALLCONTEXT_USERMANAGED,
5488                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5489     ok(r == ERROR_UNKNOWN_PROPERTY,
5490        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5491     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5492     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5493
5494     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5495     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5496
5497     /* ProductID value exists */
5498     sz = MAX_PATH;
5499     lstrcpyA(buf, "apple");
5500     r = pMsiGetProductInfoExA(prodcode, usersid,
5501                               MSIINSTALLCONTEXT_USERMANAGED,
5502                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5503     ok(r == ERROR_UNKNOWN_PROPERTY,
5504        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5505     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5506     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5507
5508     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5510
5511     /* RegCompany value exists */
5512     sz = MAX_PATH;
5513     lstrcpyA(buf, "apple");
5514     r = pMsiGetProductInfoExA(prodcode, usersid,
5515                               MSIINSTALLCONTEXT_USERMANAGED,
5516                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5517     ok(r == ERROR_UNKNOWN_PROPERTY,
5518        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5519     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5520     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5521
5522     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5523     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5524
5525     /* RegOwner value exists */
5526     sz = MAX_PATH;
5527     lstrcpyA(buf, "apple");
5528     r = pMsiGetProductInfoExA(prodcode, usersid,
5529                               MSIINSTALLCONTEXT_USERMANAGED,
5530                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5531     ok(r == ERROR_UNKNOWN_PROPERTY,
5532        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5533     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5534     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5535
5536     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5537     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5538
5539     /* Transforms value exists */
5540     sz = MAX_PATH;
5541     lstrcpyA(buf, "apple");
5542     r = pMsiGetProductInfoExA(prodcode, usersid,
5543                               MSIINSTALLCONTEXT_USERMANAGED,
5544                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5545     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5546     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5547     ok(sz == 5, "Expected 5, got %d\n", sz);
5548
5549     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5551
5552     /* Language value exists */
5553     sz = MAX_PATH;
5554     lstrcpyA(buf, "apple");
5555     r = pMsiGetProductInfoExA(prodcode, usersid,
5556                               MSIINSTALLCONTEXT_USERMANAGED,
5557                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5558     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5559     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5560     ok(sz == 4, "Expected 4, got %d\n", sz);
5561
5562     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5563     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5564
5565     /* ProductName value exists */
5566     sz = MAX_PATH;
5567     lstrcpyA(buf, "apple");
5568     r = pMsiGetProductInfoExA(prodcode, usersid,
5569                               MSIINSTALLCONTEXT_USERMANAGED,
5570                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5571     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5572     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5573     ok(sz == 4, "Expected 4, got %d\n", sz);
5574
5575     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5576     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5577
5578     /* FIXME */
5579
5580     /* AssignmentType value exists */
5581     sz = MAX_PATH;
5582     lstrcpyA(buf, "apple");
5583     r = pMsiGetProductInfoExA(prodcode, usersid,
5584                               MSIINSTALLCONTEXT_USERMANAGED,
5585                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5586     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5587     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5588     ok(sz == 0, "Expected 0, got %d\n", sz);
5589
5590     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5591     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5592
5593     /* FIXME */
5594
5595     /* PackageCode value exists */
5596     sz = MAX_PATH;
5597     lstrcpyA(buf, "apple");
5598     r = pMsiGetProductInfoExA(prodcode, usersid,
5599                               MSIINSTALLCONTEXT_USERMANAGED,
5600                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5601     todo_wine
5602     {
5603         ok(r == ERROR_BAD_CONFIGURATION,
5604            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5605         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5606         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5607     }
5608
5609     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5610     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5611
5612     /* Version value exists */
5613     sz = MAX_PATH;
5614     lstrcpyA(buf, "apple");
5615     r = pMsiGetProductInfoExA(prodcode, usersid,
5616                               MSIINSTALLCONTEXT_USERMANAGED,
5617                               INSTALLPROPERTY_VERSION, buf, &sz);
5618     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5619     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5620     ok(sz == 3, "Expected 3, got %d\n", sz);
5621
5622     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5624
5625     /* ProductIcon value exists */
5626     sz = MAX_PATH;
5627     lstrcpyA(buf, "apple");
5628     r = pMsiGetProductInfoExA(prodcode, usersid,
5629                               MSIINSTALLCONTEXT_USERMANAGED,
5630                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5631     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5632     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5633     ok(sz == 4, "Expected 4, got %d\n", sz);
5634
5635     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5637
5638     /* PackageName value exists */
5639     sz = MAX_PATH;
5640     lstrcpyA(buf, "apple");
5641     r = pMsiGetProductInfoExA(prodcode, usersid,
5642                               MSIINSTALLCONTEXT_USERMANAGED,
5643                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5644     todo_wine
5645     {
5646         ok(r == ERROR_UNKNOWN_PRODUCT,
5647            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5648         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5649         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5650     }
5651
5652     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5653     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5654
5655     /* AuthorizedLUAApp value exists */
5656     sz = MAX_PATH;
5657     lstrcpyA(buf, "apple");
5658     r = pMsiGetProductInfoExA(prodcode, usersid,
5659                               MSIINSTALLCONTEXT_USERMANAGED,
5660                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5661     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5662     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5663     ok(sz == 4, "Expected 4, got %d\n", sz);
5664
5665     RegDeleteValueA(userkey, "AuthorizedLUAApp");
5666     RegDeleteValueA(userkey, "PackageName");
5667     RegDeleteValueA(userkey, "ProductIcon");
5668     RegDeleteValueA(userkey, "Version");
5669     RegDeleteValueA(userkey, "PackageCode");
5670     RegDeleteValueA(userkey, "AssignmentType");
5671     RegDeleteValueA(userkey, "ProductName");
5672     RegDeleteValueA(userkey, "Language");
5673     RegDeleteValueA(userkey, "Transforms");
5674     RegDeleteValueA(userkey, "RegOwner");
5675     RegDeleteValueA(userkey, "RegCompany");
5676     RegDeleteValueA(userkey, "ProductID");
5677     RegDeleteValueA(userkey, "DisplayVersion");
5678     RegDeleteValueA(userkey, "VersionMajor");
5679     RegDeleteValueA(userkey, "VersionMinor");
5680     RegDeleteValueA(userkey, "URLUpdateInfo");
5681     RegDeleteValueA(userkey, "URLInfoAbout");
5682     RegDeleteValueA(userkey, "Publisher");
5683     RegDeleteValueA(userkey, "LocalPackage");
5684     RegDeleteValueA(userkey, "InstallSource");
5685     RegDeleteValueA(userkey, "InstallLocation");
5686     RegDeleteValueA(userkey, "DisplayName");
5687     RegDeleteValueA(userkey, "InstallDate");
5688     RegDeleteValueA(userkey, "HelpTelephone");
5689     RegDeleteValueA(userkey, "HelpLink");
5690     RegDeleteKeyA(userkey, "");
5691     RegCloseKey(userkey);
5692     RegDeleteKeyA(prodkey, "");
5693     RegCloseKey(prodkey);
5694
5695     /* MSIINSTALLCONTEXT_MACHINE */
5696
5697     /* szUserSid is non-NULL */
5698     sz = MAX_PATH;
5699     lstrcpyA(buf, "apple");
5700     r = pMsiGetProductInfoExA(prodcode, usersid,
5701                               MSIINSTALLCONTEXT_MACHINE,
5702                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5703     ok(r == ERROR_INVALID_PARAMETER,
5704        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5705     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5706     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5707
5708     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
5709     lstrcatA(keypath, prod_squashed);
5710
5711     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5713
5714     /* local system product key exists */
5715     sz = MAX_PATH;
5716     lstrcpyA(buf, "apple");
5717     r = pMsiGetProductInfoExA(prodcode, NULL,
5718                               MSIINSTALLCONTEXT_MACHINE,
5719                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5720     ok(r == ERROR_UNKNOWN_PRODUCT,
5721        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5722     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5723     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5724
5725     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5726     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5727
5728     /* InstallProperties key exists */
5729     sz = MAX_PATH;
5730     lstrcpyA(buf, "apple");
5731     r = pMsiGetProductInfoExA(prodcode, NULL,
5732                               MSIINSTALLCONTEXT_MACHINE,
5733                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5734     ok(r == ERROR_UNKNOWN_PRODUCT,
5735        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5736     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5737     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5738
5739     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5741
5742     /* LocalPackage value exists */
5743     sz = MAX_PATH;
5744     lstrcpyA(buf, "apple");
5745     r = pMsiGetProductInfoExA(prodcode, NULL,
5746                               MSIINSTALLCONTEXT_MACHINE,
5747                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5748     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5749     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5750     ok(sz == 1, "Expected 1, got %d\n", sz);
5751
5752     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5753     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5754
5755     /* HelpLink value exists */
5756     sz = MAX_PATH;
5757     lstrcpyA(buf, "apple");
5758     r = pMsiGetProductInfoExA(prodcode, NULL,
5759                               MSIINSTALLCONTEXT_MACHINE,
5760                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5762     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5763     ok(sz == 4, "Expected 4, got %d\n", sz);
5764
5765     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5767
5768     /* HelpTelephone value exists */
5769     sz = MAX_PATH;
5770     lstrcpyA(buf, "apple");
5771     r = pMsiGetProductInfoExA(prodcode, NULL,
5772                               MSIINSTALLCONTEXT_MACHINE,
5773                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5774     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5775     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5776     ok(sz == 5, "Expected 5, got %d\n", sz);
5777
5778     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5780
5781     /* InstallDate value exists */
5782     sz = MAX_PATH;
5783     lstrcpyA(buf, "apple");
5784     r = pMsiGetProductInfoExA(prodcode, NULL,
5785                               MSIINSTALLCONTEXT_MACHINE,
5786                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5787     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5788     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5789     ok(sz == 4, "Expected 4, got %d\n", sz);
5790
5791     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5792     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5793
5794     /* DisplayName value exists */
5795     sz = MAX_PATH;
5796     lstrcpyA(buf, "apple");
5797     r = pMsiGetProductInfoExA(prodcode, NULL,
5798                               MSIINSTALLCONTEXT_MACHINE,
5799                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5801     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5802     ok(sz == 4, "Expected 4, got %d\n", sz);
5803
5804     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5805     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5806
5807     /* InstallLocation value exists */
5808     sz = MAX_PATH;
5809     lstrcpyA(buf, "apple");
5810     r = pMsiGetProductInfoExA(prodcode, NULL,
5811                               MSIINSTALLCONTEXT_MACHINE,
5812                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5813     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5814     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5815     ok(sz == 3, "Expected 3, got %d\n", sz);
5816
5817     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5818     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5819
5820     /* InstallSource value exists */
5821     sz = MAX_PATH;
5822     lstrcpyA(buf, "apple");
5823     r = pMsiGetProductInfoExA(prodcode, NULL,
5824                               MSIINSTALLCONTEXT_MACHINE,
5825                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5826     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5827     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5828     ok(sz == 6, "Expected 6, got %d\n", sz);
5829
5830     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5831     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5832
5833     /* LocalPackage value exists */
5834     sz = MAX_PATH;
5835     lstrcpyA(buf, "apple");
5836     r = pMsiGetProductInfoExA(prodcode, NULL,
5837                               MSIINSTALLCONTEXT_MACHINE,
5838                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5839     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5840     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5841     ok(sz == 5, "Expected 5, got %d\n", sz);
5842
5843     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5844     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5845
5846     /* Publisher value exists */
5847     sz = MAX_PATH;
5848     lstrcpyA(buf, "apple");
5849     r = pMsiGetProductInfoExA(prodcode, NULL,
5850                               MSIINSTALLCONTEXT_MACHINE,
5851                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5852     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5853     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5854     ok(sz == 3, "Expected 3, got %d\n", sz);
5855
5856     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5857     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5858
5859     /* URLInfoAbout value exists */
5860     sz = MAX_PATH;
5861     lstrcpyA(buf, "apple");
5862     r = pMsiGetProductInfoExA(prodcode, NULL,
5863                               MSIINSTALLCONTEXT_MACHINE,
5864                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5865     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5866     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5867     ok(sz == 5, "Expected 5, got %d\n", sz);
5868
5869     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5870     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5871
5872     /* URLUpdateInfo value exists */
5873     sz = MAX_PATH;
5874     lstrcpyA(buf, "apple");
5875     r = pMsiGetProductInfoExA(prodcode, NULL,
5876                               MSIINSTALLCONTEXT_MACHINE,
5877                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5878     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5879     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5880     ok(sz == 6, "Expected 6, got %d\n", sz);
5881
5882     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5883     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5884
5885     /* VersionMinor value exists */
5886     sz = MAX_PATH;
5887     lstrcpyA(buf, "apple");
5888     r = pMsiGetProductInfoExA(prodcode, NULL,
5889                               MSIINSTALLCONTEXT_MACHINE,
5890                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5891     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5892     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5893     ok(sz == 1, "Expected 1, got %d\n", sz);
5894
5895     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5896     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5897
5898     /* VersionMajor value exists */
5899     sz = MAX_PATH;
5900     lstrcpyA(buf, "apple");
5901     r = pMsiGetProductInfoExA(prodcode, NULL,
5902                               MSIINSTALLCONTEXT_MACHINE,
5903                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5904     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5905     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5906     ok(sz == 1, "Expected 1, got %d\n", sz);
5907
5908     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5909     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5910
5911     /* DisplayVersion value exists */
5912     sz = MAX_PATH;
5913     lstrcpyA(buf, "apple");
5914     r = pMsiGetProductInfoExA(prodcode, NULL,
5915                               MSIINSTALLCONTEXT_MACHINE,
5916                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5917     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5918     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5919     ok(sz == 5, "Expected 5, got %d\n", sz);
5920
5921     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5922     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5923
5924     /* ProductID value exists */
5925     sz = MAX_PATH;
5926     lstrcpyA(buf, "apple");
5927     r = pMsiGetProductInfoExA(prodcode, NULL,
5928                               MSIINSTALLCONTEXT_MACHINE,
5929                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5930     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5931     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5932     ok(sz == 2, "Expected 2, got %d\n", sz);
5933
5934     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5935     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5936
5937     /* RegCompany value exists */
5938     sz = MAX_PATH;
5939     lstrcpyA(buf, "apple");
5940     r = pMsiGetProductInfoExA(prodcode, NULL,
5941                               MSIINSTALLCONTEXT_MACHINE,
5942                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5943     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5944     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5945     ok(sz == 4, "Expected 4, got %d\n", sz);
5946
5947     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5948     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5949
5950     /* RegOwner value exists */
5951     sz = MAX_PATH;
5952     lstrcpyA(buf, "apple");
5953     r = pMsiGetProductInfoExA(prodcode, NULL,
5954                               MSIINSTALLCONTEXT_MACHINE,
5955                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5956     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5957     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5958     ok(sz == 5, "Expected 5, got %d\n", sz);
5959
5960     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5961     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5962
5963     /* Transforms value exists */
5964     sz = MAX_PATH;
5965     lstrcpyA(buf, "apple");
5966     r = pMsiGetProductInfoExA(prodcode, NULL,
5967                               MSIINSTALLCONTEXT_MACHINE,
5968                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5969     ok(r == ERROR_UNKNOWN_PRODUCT,
5970        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5971     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5972     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5973
5974     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5975     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5976
5977     /* Language value exists */
5978     sz = MAX_PATH;
5979     lstrcpyA(buf, "apple");
5980     r = pMsiGetProductInfoExA(prodcode, NULL,
5981                               MSIINSTALLCONTEXT_MACHINE,
5982                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5983     ok(r == ERROR_UNKNOWN_PRODUCT,
5984        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5985     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5986     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5987
5988     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5989     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5990
5991     /* ProductName value exists */
5992     sz = MAX_PATH;
5993     lstrcpyA(buf, "apple");
5994     r = pMsiGetProductInfoExA(prodcode, NULL,
5995                               MSIINSTALLCONTEXT_MACHINE,
5996                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5997     ok(r == ERROR_UNKNOWN_PRODUCT,
5998        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5999     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6000     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6001
6002     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6003     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6004
6005     /* FIXME */
6006
6007     /* AssignmentType value exists */
6008     sz = MAX_PATH;
6009     lstrcpyA(buf, "apple");
6010     r = pMsiGetProductInfoExA(prodcode, NULL,
6011                               MSIINSTALLCONTEXT_MACHINE,
6012                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6013     ok(r == ERROR_UNKNOWN_PRODUCT,
6014        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6015     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6016     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6017
6018     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6020
6021     /* PackageCode value exists */
6022     sz = MAX_PATH;
6023     lstrcpyA(buf, "apple");
6024     r = pMsiGetProductInfoExA(prodcode, NULL,
6025                               MSIINSTALLCONTEXT_MACHINE,
6026                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6027     ok(r == ERROR_UNKNOWN_PRODUCT,
6028        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6029     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6030     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6031
6032     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6033     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6034
6035     /* Version value exists */
6036     sz = MAX_PATH;
6037     lstrcpyA(buf, "apple");
6038     r = pMsiGetProductInfoExA(prodcode, NULL,
6039                               MSIINSTALLCONTEXT_MACHINE,
6040                               INSTALLPROPERTY_VERSION, buf, &sz);
6041     ok(r == ERROR_UNKNOWN_PRODUCT,
6042        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6043     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6044     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6045
6046     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6047     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6048
6049     /* ProductIcon value exists */
6050     sz = MAX_PATH;
6051     lstrcpyA(buf, "apple");
6052     r = pMsiGetProductInfoExA(prodcode, NULL,
6053                               MSIINSTALLCONTEXT_MACHINE,
6054                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6055     ok(r == ERROR_UNKNOWN_PRODUCT,
6056        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6057     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6058     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6059
6060     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6061     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6062
6063     /* PackageName value exists */
6064     sz = MAX_PATH;
6065     lstrcpyA(buf, "apple");
6066     r = pMsiGetProductInfoExA(prodcode, NULL,
6067                               MSIINSTALLCONTEXT_MACHINE,
6068                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6069     ok(r == ERROR_UNKNOWN_PRODUCT,
6070        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6071     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6072     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6073
6074     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6076
6077     /* AuthorizedLUAApp value exists */
6078     sz = MAX_PATH;
6079     lstrcpyA(buf, "apple");
6080     r = pMsiGetProductInfoExA(prodcode, NULL,
6081                               MSIINSTALLCONTEXT_MACHINE,
6082                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6083     ok(r == ERROR_UNKNOWN_PRODUCT,
6084        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6085     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6086     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6087
6088     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6089     RegDeleteValueA(propkey, "PackageName");
6090     RegDeleteValueA(propkey, "ProductIcon");
6091     RegDeleteValueA(propkey, "Version");
6092     RegDeleteValueA(propkey, "PackageCode");
6093     RegDeleteValueA(propkey, "AssignmentType");
6094     RegDeleteValueA(propkey, "ProductName");
6095     RegDeleteValueA(propkey, "Language");
6096     RegDeleteValueA(propkey, "Transforms");
6097     RegDeleteValueA(propkey, "RegOwner");
6098     RegDeleteValueA(propkey, "RegCompany");
6099     RegDeleteValueA(propkey, "ProductID");
6100     RegDeleteValueA(propkey, "DisplayVersion");
6101     RegDeleteValueA(propkey, "VersionMajor");
6102     RegDeleteValueA(propkey, "VersionMinor");
6103     RegDeleteValueA(propkey, "URLUpdateInfo");
6104     RegDeleteValueA(propkey, "URLInfoAbout");
6105     RegDeleteValueA(propkey, "Publisher");
6106     RegDeleteValueA(propkey, "LocalPackage");
6107     RegDeleteValueA(propkey, "InstallSource");
6108     RegDeleteValueA(propkey, "InstallLocation");
6109     RegDeleteValueA(propkey, "DisplayName");
6110     RegDeleteValueA(propkey, "InstallDate");
6111     RegDeleteValueA(propkey, "HelpTelephone");
6112     RegDeleteValueA(propkey, "HelpLink");
6113     RegDeleteValueA(propkey, "LocalPackage");
6114     RegDeleteKeyA(propkey, "");
6115     RegCloseKey(propkey);
6116     RegDeleteKeyA(localkey, "");
6117     RegCloseKey(localkey);
6118
6119     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6120     lstrcatA(keypath, prod_squashed);
6121
6122     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6124
6125     /* local classes product key exists */
6126     sz = MAX_PATH;
6127     lstrcpyA(buf, "apple");
6128     r = pMsiGetProductInfoExA(prodcode, NULL,
6129                               MSIINSTALLCONTEXT_MACHINE,
6130                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6131     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6132     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6133     ok(sz == 1, "Expected 1, got %d\n", sz);
6134
6135     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6136     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6137
6138     /* HelpLink value exists */
6139     sz = MAX_PATH;
6140     lstrcpyA(buf, "apple");
6141     r = pMsiGetProductInfoExA(prodcode, NULL,
6142                               MSIINSTALLCONTEXT_MACHINE,
6143                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6144     ok(r == ERROR_UNKNOWN_PROPERTY,
6145        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6146     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6147     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6148
6149     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6151
6152     /* HelpTelephone value exists */
6153     sz = MAX_PATH;
6154     lstrcpyA(buf, "apple");
6155     r = pMsiGetProductInfoExA(prodcode, NULL,
6156                               MSIINSTALLCONTEXT_MACHINE,
6157                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6158     ok(r == ERROR_UNKNOWN_PROPERTY,
6159        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6160     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6161     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6162
6163     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6165
6166     /* InstallDate value exists */
6167     sz = MAX_PATH;
6168     lstrcpyA(buf, "apple");
6169     r = pMsiGetProductInfoExA(prodcode, NULL,
6170                               MSIINSTALLCONTEXT_MACHINE,
6171                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6172     ok(r == ERROR_UNKNOWN_PROPERTY,
6173        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6174     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6175     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6176
6177     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6178     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6179
6180     /* DisplayName value exists */
6181     sz = MAX_PATH;
6182     lstrcpyA(buf, "apple");
6183     r = pMsiGetProductInfoExA(prodcode, NULL,
6184                               MSIINSTALLCONTEXT_MACHINE,
6185                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6186     ok(r == ERROR_UNKNOWN_PROPERTY,
6187        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6188     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6189     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6190
6191     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6192     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6193
6194     /* InstallLocation value exists */
6195     sz = MAX_PATH;
6196     lstrcpyA(buf, "apple");
6197     r = pMsiGetProductInfoExA(prodcode, NULL,
6198                               MSIINSTALLCONTEXT_MACHINE,
6199                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6200     ok(r == ERROR_UNKNOWN_PROPERTY,
6201        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6202     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6203     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6204
6205     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6206     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6207
6208     /* InstallSource value exists */
6209     sz = MAX_PATH;
6210     lstrcpyA(buf, "apple");
6211     r = pMsiGetProductInfoExA(prodcode, NULL,
6212                               MSIINSTALLCONTEXT_MACHINE,
6213                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6214     ok(r == ERROR_UNKNOWN_PROPERTY,
6215        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6216     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6217     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6218
6219     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6220     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6221
6222     /* LocalPackage value exists */
6223     sz = MAX_PATH;
6224     lstrcpyA(buf, "apple");
6225     r = pMsiGetProductInfoExA(prodcode, NULL,
6226                               MSIINSTALLCONTEXT_MACHINE,
6227                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6228     ok(r == ERROR_UNKNOWN_PROPERTY,
6229        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6230     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6231     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6232
6233     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6234     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6235
6236     /* Publisher value exists */
6237     sz = MAX_PATH;
6238     lstrcpyA(buf, "apple");
6239     r = pMsiGetProductInfoExA(prodcode, NULL,
6240                               MSIINSTALLCONTEXT_MACHINE,
6241                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6242     ok(r == ERROR_UNKNOWN_PROPERTY,
6243        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6244     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6245     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6246
6247     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6248     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6249
6250     /* URLInfoAbout value exists */
6251     sz = MAX_PATH;
6252     lstrcpyA(buf, "apple");
6253     r = pMsiGetProductInfoExA(prodcode, NULL,
6254                               MSIINSTALLCONTEXT_MACHINE,
6255                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6256     ok(r == ERROR_UNKNOWN_PROPERTY,
6257        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6258     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6259     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6260
6261     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6263
6264     /* URLUpdateInfo value exists */
6265     sz = MAX_PATH;
6266     lstrcpyA(buf, "apple");
6267     r = pMsiGetProductInfoExA(prodcode, NULL,
6268                               MSIINSTALLCONTEXT_MACHINE,
6269                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6270     ok(r == ERROR_UNKNOWN_PROPERTY,
6271        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6272     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6273     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6274
6275     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6276     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6277
6278     /* VersionMinor value exists */
6279     sz = MAX_PATH;
6280     lstrcpyA(buf, "apple");
6281     r = pMsiGetProductInfoExA(prodcode, NULL,
6282                               MSIINSTALLCONTEXT_MACHINE,
6283                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6284     ok(r == ERROR_UNKNOWN_PROPERTY,
6285        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6286     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6287     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6288
6289     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6290     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6291
6292     /* VersionMajor value exists */
6293     sz = MAX_PATH;
6294     lstrcpyA(buf, "apple");
6295     r = pMsiGetProductInfoExA(prodcode, NULL,
6296                               MSIINSTALLCONTEXT_MACHINE,
6297                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6298     ok(r == ERROR_UNKNOWN_PROPERTY,
6299        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6300     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6301     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6302
6303     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6305
6306     /* DisplayVersion value exists */
6307     sz = MAX_PATH;
6308     lstrcpyA(buf, "apple");
6309     r = pMsiGetProductInfoExA(prodcode, NULL,
6310                               MSIINSTALLCONTEXT_MACHINE,
6311                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6312     ok(r == ERROR_UNKNOWN_PROPERTY,
6313        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6314     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6315     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6316
6317     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6319
6320     /* ProductID value exists */
6321     sz = MAX_PATH;
6322     lstrcpyA(buf, "apple");
6323     r = pMsiGetProductInfoExA(prodcode, NULL,
6324                               MSIINSTALLCONTEXT_MACHINE,
6325                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6326     ok(r == ERROR_UNKNOWN_PROPERTY,
6327        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6328     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6329     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6330
6331     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6333
6334     /* RegCompany value exists */
6335     sz = MAX_PATH;
6336     lstrcpyA(buf, "apple");
6337     r = pMsiGetProductInfoExA(prodcode, NULL,
6338                               MSIINSTALLCONTEXT_MACHINE,
6339                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6340     ok(r == ERROR_UNKNOWN_PROPERTY,
6341        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6342     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6343     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6344
6345     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6347
6348     /* RegOwner value exists */
6349     sz = MAX_PATH;
6350     lstrcpyA(buf, "apple");
6351     r = pMsiGetProductInfoExA(prodcode, NULL,
6352                               MSIINSTALLCONTEXT_MACHINE,
6353                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6354     ok(r == ERROR_UNKNOWN_PROPERTY,
6355        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6356     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6357     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6358
6359     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6360     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6361
6362     /* Transforms value exists */
6363     sz = MAX_PATH;
6364     lstrcpyA(buf, "apple");
6365     r = pMsiGetProductInfoExA(prodcode, NULL,
6366                               MSIINSTALLCONTEXT_MACHINE,
6367                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6368     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6369     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6370     ok(sz == 5, "Expected 5, got %d\n", sz);
6371
6372     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6373     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6374
6375     /* Language value exists */
6376     sz = MAX_PATH;
6377     lstrcpyA(buf, "apple");
6378     r = pMsiGetProductInfoExA(prodcode, NULL,
6379                               MSIINSTALLCONTEXT_MACHINE,
6380                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6381     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6382     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6383     ok(sz == 4, "Expected 4, got %d\n", sz);
6384
6385     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6386     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6387
6388     /* ProductName value exists */
6389     sz = MAX_PATH;
6390     lstrcpyA(buf, "apple");
6391     r = pMsiGetProductInfoExA(prodcode, NULL,
6392                               MSIINSTALLCONTEXT_MACHINE,
6393                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6394     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6395     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6396     ok(sz == 4, "Expected 4, got %d\n", sz);
6397
6398     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6399     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6400
6401     /* FIXME */
6402
6403     /* AssignmentType value exists */
6404     sz = MAX_PATH;
6405     lstrcpyA(buf, "apple");
6406     r = pMsiGetProductInfoExA(prodcode, NULL,
6407                               MSIINSTALLCONTEXT_MACHINE,
6408                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6409     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6410     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6411     ok(sz == 0, "Expected 0, got %d\n", sz);
6412
6413     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6414     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6415
6416     /* FIXME */
6417
6418     /* PackageCode value exists */
6419     sz = MAX_PATH;
6420     lstrcpyA(buf, "apple");
6421     r = pMsiGetProductInfoExA(prodcode, NULL,
6422                               MSIINSTALLCONTEXT_MACHINE,
6423                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6424     todo_wine
6425     {
6426         ok(r == ERROR_BAD_CONFIGURATION,
6427            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6428         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6429         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6430     }
6431
6432     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6434
6435     /* Version value exists */
6436     sz = MAX_PATH;
6437     lstrcpyA(buf, "apple");
6438     r = pMsiGetProductInfoExA(prodcode, NULL,
6439                               MSIINSTALLCONTEXT_MACHINE,
6440                               INSTALLPROPERTY_VERSION, buf, &sz);
6441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6442     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6443     ok(sz == 3, "Expected 3, got %d\n", sz);
6444
6445     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6446     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6447
6448     /* ProductIcon value exists */
6449     sz = MAX_PATH;
6450     lstrcpyA(buf, "apple");
6451     r = pMsiGetProductInfoExA(prodcode, NULL,
6452                               MSIINSTALLCONTEXT_MACHINE,
6453                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6454     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6455     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6456     ok(sz == 4, "Expected 4, got %d\n", sz);
6457
6458     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6459     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6460
6461     /* PackageName value exists */
6462     sz = MAX_PATH;
6463     lstrcpyA(buf, "apple");
6464     r = pMsiGetProductInfoExA(prodcode, NULL,
6465                               MSIINSTALLCONTEXT_MACHINE,
6466                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6467     todo_wine
6468     {
6469         ok(r == ERROR_UNKNOWN_PRODUCT,
6470            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6471         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6472         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6473     }
6474
6475     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6476     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6477
6478     /* AuthorizedLUAApp value exists */
6479     sz = MAX_PATH;
6480     lstrcpyA(buf, "apple");
6481     r = pMsiGetProductInfoExA(prodcode, NULL,
6482                               MSIINSTALLCONTEXT_MACHINE,
6483                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6484     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6485     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6486     ok(sz == 4, "Expected 4, got %d\n", sz);
6487
6488     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6489     RegDeleteValueA(prodkey, "PackageName");
6490     RegDeleteValueA(prodkey, "ProductIcon");
6491     RegDeleteValueA(prodkey, "Version");
6492     RegDeleteValueA(prodkey, "PackageCode");
6493     RegDeleteValueA(prodkey, "AssignmentType");
6494     RegDeleteValueA(prodkey, "ProductName");
6495     RegDeleteValueA(prodkey, "Language");
6496     RegDeleteValueA(prodkey, "Transforms");
6497     RegDeleteValueA(prodkey, "RegOwner");
6498     RegDeleteValueA(prodkey, "RegCompany");
6499     RegDeleteValueA(prodkey, "ProductID");
6500     RegDeleteValueA(prodkey, "DisplayVersion");
6501     RegDeleteValueA(prodkey, "VersionMajor");
6502     RegDeleteValueA(prodkey, "VersionMinor");
6503     RegDeleteValueA(prodkey, "URLUpdateInfo");
6504     RegDeleteValueA(prodkey, "URLInfoAbout");
6505     RegDeleteValueA(prodkey, "Publisher");
6506     RegDeleteValueA(prodkey, "LocalPackage");
6507     RegDeleteValueA(prodkey, "InstallSource");
6508     RegDeleteValueA(prodkey, "InstallLocation");
6509     RegDeleteValueA(prodkey, "DisplayName");
6510     RegDeleteValueA(prodkey, "InstallDate");
6511     RegDeleteValueA(prodkey, "HelpTelephone");
6512     RegDeleteValueA(prodkey, "HelpLink");
6513     RegDeleteKeyA(prodkey, "");
6514     RegCloseKey(prodkey);
6515 }
6516
6517 #define INIT_USERINFO() \
6518     lstrcpyA(user, "apple"); \
6519     lstrcpyA(org, "orange"); \
6520     lstrcpyA(serial, "banana"); \
6521     usersz = orgsz = serialsz = MAX_PATH;
6522
6523 static void test_MsiGetUserInfo(void)
6524 {
6525     USERINFOSTATE state;
6526     CHAR user[MAX_PATH];
6527     CHAR org[MAX_PATH];
6528     CHAR serial[MAX_PATH];
6529     DWORD usersz, orgsz, serialsz;
6530     CHAR keypath[MAX_PATH * 2];
6531     CHAR prodcode[MAX_PATH];
6532     CHAR prod_squashed[MAX_PATH];
6533     HKEY prodkey, userprod, props;
6534     LPSTR usersid;
6535     LONG res;
6536
6537     create_test_guid(prodcode, prod_squashed);
6538     get_user_sid(&usersid);
6539
6540     /* NULL szProduct */
6541     INIT_USERINFO();
6542     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6543     ok(state == USERINFOSTATE_INVALIDARG,
6544        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6545     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6546     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6547     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6548     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6549     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6550     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6551
6552     /* empty szProductCode */
6553     INIT_USERINFO();
6554     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6555     ok(state == USERINFOSTATE_INVALIDARG,
6556        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6557     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6558     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6559     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6560     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6561     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6562     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6563
6564     /* garbage szProductCode */
6565     INIT_USERINFO();
6566     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6567     ok(state == USERINFOSTATE_INVALIDARG,
6568        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6569     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6570     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6571     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6572     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6573     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6574     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6575
6576     /* guid without brackets */
6577     INIT_USERINFO();
6578     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6579                             user, &usersz, org, &orgsz, serial, &serialsz);
6580     ok(state == USERINFOSTATE_INVALIDARG,
6581        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6582     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6583     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6584     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6585     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6586     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6587     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6588
6589     /* guid with brackets */
6590     INIT_USERINFO();
6591     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6592                             user, &usersz, org, &orgsz, serial, &serialsz);
6593     ok(state == USERINFOSTATE_UNKNOWN,
6594        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6595     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6596     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6597     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6598     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6599     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6600     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6601
6602     /* NULL lpUserNameBuf */
6603     INIT_USERINFO();
6604     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6605     ok(state == USERINFOSTATE_UNKNOWN,
6606        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6607     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6608     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6609     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6610     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6611     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6612
6613     /* NULL pcchUserNameBuf */
6614     INIT_USERINFO();
6615     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6616     ok(state == USERINFOSTATE_INVALIDARG,
6617        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6618     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6619     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6620     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6621     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6622     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6623
6624     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6625     INIT_USERINFO();
6626     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6627     ok(state == USERINFOSTATE_UNKNOWN,
6628        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6629     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6630     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6631     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6632     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6633
6634     /* NULL lpOrgNameBuf */
6635     INIT_USERINFO();
6636     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6637     ok(state == USERINFOSTATE_UNKNOWN,
6638        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6639     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6640     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6641     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6642     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6643     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6644
6645     /* NULL pcchOrgNameBuf */
6646     INIT_USERINFO();
6647     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
6648     ok(state == USERINFOSTATE_INVALIDARG,
6649        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6650     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6651     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6652     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6653     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6654     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6655
6656     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
6657     INIT_USERINFO();
6658     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
6659     ok(state == USERINFOSTATE_UNKNOWN,
6660        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6661     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6662     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6663     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6664     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6665
6666     /* NULL lpSerialBuf */
6667     INIT_USERINFO();
6668     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
6669     ok(state == USERINFOSTATE_UNKNOWN,
6670        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6671     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6672     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6673     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6674     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6675     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6676
6677     /* NULL pcchSerialBuf */
6678     INIT_USERINFO();
6679     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
6680     ok(state == USERINFOSTATE_INVALIDARG,
6681        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6682     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6683     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6684     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6685     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6686     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6687
6688     /* both lpSerialBuf and pcchSerialBuf NULL */
6689     INIT_USERINFO();
6690     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
6691     ok(state == USERINFOSTATE_UNKNOWN,
6692        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6693     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6694     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6695     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6696     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6697
6698     /* MSIINSTALLCONTEXT_USERMANAGED */
6699
6700     /* create local system product key */
6701     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6702     lstrcatA(keypath, usersid);
6703     lstrcatA(keypath, "\\Installer\\Products\\");
6704     lstrcatA(keypath, prod_squashed);
6705
6706     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6707     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6708
6709     /* managed product key exists */
6710     INIT_USERINFO();
6711     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6712     ok(state == USERINFOSTATE_ABSENT,
6713        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6714     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6715     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6716     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6717     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6718     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6719     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6720
6721     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6722     lstrcatA(keypath, "Installer\\UserData\\");
6723     lstrcatA(keypath, usersid);
6724     lstrcatA(keypath, "\\Products\\");
6725     lstrcatA(keypath, prod_squashed);
6726
6727     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6729
6730     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6731     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6732
6733     /* InstallProperties key exists */
6734     INIT_USERINFO();
6735     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6736     ok(state == USERINFOSTATE_ABSENT,
6737        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6738     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6739     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6740     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6741     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6742     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6743     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6744
6745     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6746     INIT_USERINFO();
6747     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6748     ok(state == USERINFOSTATE_ABSENT,
6749        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6750     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6751     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6752     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6753     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6754
6755     /* RegOwner, RegCompany don't exist, out params are NULL */
6756     INIT_USERINFO();
6757     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6758     ok(state == USERINFOSTATE_ABSENT,
6759        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6760     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6761     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6762
6763     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6764     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6765
6766     /* RegOwner value exists */
6767     INIT_USERINFO();
6768     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6769     ok(state == USERINFOSTATE_ABSENT,
6770        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6771     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6772     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6773     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6774     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6775     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6776     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6777
6778     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6779     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6780
6781     /* RegCompany value exists */
6782     INIT_USERINFO();
6783     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6784     ok(state == USERINFOSTATE_ABSENT,
6785        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6786     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6787     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6788     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6789     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6790     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6791     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6792
6793     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6794     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6795
6796     /* ProductID value exists */
6797     INIT_USERINFO();
6798     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6799     ok(state == USERINFOSTATE_PRESENT,
6800        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6801     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6802     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6803     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6804     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6805     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6806     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6807
6808     /* pcchUserNameBuf is too small */
6809     INIT_USERINFO();
6810     usersz = 0;
6811     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6812     ok(state == USERINFOSTATE_MOREDATA,
6813        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6814     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6815     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6816     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6817     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6818     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6819     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6820
6821     /* pcchUserNameBuf has no room for NULL terminator */
6822     INIT_USERINFO();
6823     usersz = 5;
6824     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6825     ok(state == USERINFOSTATE_MOREDATA,
6826        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6827     todo_wine
6828     {
6829         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6830     }
6831     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6832     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6833     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6834     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6835     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6836
6837     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
6838     INIT_USERINFO();
6839     usersz = 0;
6840     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6841     ok(state == USERINFOSTATE_PRESENT,
6842        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6843     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6844     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6845     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6846     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6847     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6848     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6849
6850     RegDeleteValueA(props, "ProductID");
6851     RegDeleteValueA(props, "RegCompany");
6852     RegDeleteValueA(props, "RegOwner");
6853     RegDeleteKeyA(props, "");
6854     RegCloseKey(props);
6855     RegDeleteKeyA(userprod, "");
6856     RegCloseKey(userprod);
6857     RegDeleteKeyA(prodkey, "");
6858     RegCloseKey(prodkey);
6859
6860     /* MSIINSTALLCONTEXT_USERUNMANAGED */
6861
6862     /* create local system product key */
6863     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6864     lstrcatA(keypath, prod_squashed);
6865
6866     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6867     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6868
6869     /* product key exists */
6870     INIT_USERINFO();
6871     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6872     ok(state == USERINFOSTATE_ABSENT,
6873        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6874     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6875     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6876     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6877     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6878     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6879     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6880
6881     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6882     lstrcatA(keypath, "Installer\\UserData\\");
6883     lstrcatA(keypath, usersid);
6884     lstrcatA(keypath, "\\Products\\");
6885     lstrcatA(keypath, prod_squashed);
6886
6887     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6889
6890     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6892
6893     /* InstallProperties key exists */
6894     INIT_USERINFO();
6895     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6896     ok(state == USERINFOSTATE_ABSENT,
6897        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6898     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6899     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6900     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6901     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6902     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6903     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6904
6905     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6906     INIT_USERINFO();
6907     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6908     ok(state == USERINFOSTATE_ABSENT,
6909        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6910     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6911     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6912     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6913     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6914
6915     /* RegOwner, RegCompany don't exist, out params are NULL */
6916     INIT_USERINFO();
6917     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6918     ok(state == USERINFOSTATE_ABSENT,
6919        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6920     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6921     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6922
6923     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6924     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6925
6926     /* RegOwner value exists */
6927     INIT_USERINFO();
6928     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6929     ok(state == USERINFOSTATE_ABSENT,
6930        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6931     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6932     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6933     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6934     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6935     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6936     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6937
6938     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6939     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6940
6941     /* RegCompany value exists */
6942     INIT_USERINFO();
6943     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6944     ok(state == USERINFOSTATE_ABSENT,
6945        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6946     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6947     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6948     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6949     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6950     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6951     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6952
6953     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6954     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6955
6956     /* ProductID value exists */
6957     INIT_USERINFO();
6958     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6959     ok(state == USERINFOSTATE_PRESENT,
6960        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6961     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6962     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6963     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6964     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6965     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6966     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6967
6968     RegDeleteValueA(props, "ProductID");
6969     RegDeleteValueA(props, "RegCompany");
6970     RegDeleteValueA(props, "RegOwner");
6971     RegDeleteKeyA(props, "");
6972     RegCloseKey(props);
6973     RegDeleteKeyA(userprod, "");
6974     RegCloseKey(userprod);
6975     RegDeleteKeyA(prodkey, "");
6976     RegCloseKey(prodkey);
6977
6978     /* MSIINSTALLCONTEXT_MACHINE */
6979
6980     /* create local system product key */
6981     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6982     lstrcatA(keypath, prod_squashed);
6983
6984     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6986
6987     /* product key exists */
6988     INIT_USERINFO();
6989     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6990     ok(state == USERINFOSTATE_ABSENT,
6991        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6992     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6993     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6994     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6995     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6996     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6997     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6998
6999     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7000     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
7001     lstrcatA(keypath, "\\Products\\");
7002     lstrcatA(keypath, prod_squashed);
7003
7004     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
7005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7006
7007     res = RegCreateKeyA(userprod, "InstallProperties", &props);
7008     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7009
7010     /* InstallProperties key exists */
7011     INIT_USERINFO();
7012     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7013     ok(state == USERINFOSTATE_ABSENT,
7014        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7015     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7016     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7017     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7018     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7019     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7020     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7021
7022     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7023     INIT_USERINFO();
7024     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7025     ok(state == USERINFOSTATE_ABSENT,
7026        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7027     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7028     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7029     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7030     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7031
7032     /* RegOwner, RegCompany don't exist, out params are NULL */
7033     INIT_USERINFO();
7034     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7035     ok(state == USERINFOSTATE_ABSENT,
7036        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7037     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7038     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7039
7040     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7041     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7042
7043     /* RegOwner value exists */
7044     INIT_USERINFO();
7045     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7046     ok(state == USERINFOSTATE_ABSENT,
7047        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7048     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7049     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7050     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7051     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7052     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7053     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7054
7055     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7056     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7057
7058     /* RegCompany value exists */
7059     INIT_USERINFO();
7060     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7061     ok(state == USERINFOSTATE_ABSENT,
7062        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7063     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7064     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7065     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7066     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7067     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7068     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7069
7070     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7071     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7072
7073     /* ProductID value exists */
7074     INIT_USERINFO();
7075     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7076     ok(state == USERINFOSTATE_PRESENT,
7077        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7078     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7079     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7080     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7081     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7082     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7083     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7084
7085     RegDeleteValueA(props, "ProductID");
7086     RegDeleteValueA(props, "RegCompany");
7087     RegDeleteValueA(props, "RegOwner");
7088     RegDeleteKeyA(props, "");
7089     RegCloseKey(props);
7090     RegDeleteKeyA(userprod, "");
7091     RegCloseKey(userprod);
7092     RegDeleteKeyA(prodkey, "");
7093     RegCloseKey(prodkey);
7094 }
7095
7096 static void test_MsiOpenProduct(void)
7097 {
7098     MSIHANDLE hprod, hdb;
7099     CHAR val[MAX_PATH];
7100     CHAR path[MAX_PATH];
7101     CHAR keypath[MAX_PATH*2];
7102     CHAR prodcode[MAX_PATH];
7103     CHAR prod_squashed[MAX_PATH];
7104     HKEY prodkey, userkey, props;
7105     LPSTR usersid;
7106     DWORD size;
7107     LONG res;
7108     UINT r;
7109
7110     GetCurrentDirectoryA(MAX_PATH, path);
7111     lstrcatA(path, "\\");
7112
7113     create_test_guid(prodcode, prod_squashed);
7114     get_user_sid(&usersid);
7115
7116     hdb = create_package_db(prodcode);
7117     MsiCloseHandle(hdb);
7118
7119     /* NULL szProduct */
7120     hprod = 0xdeadbeef;
7121     r = MsiOpenProductA(NULL, &hprod);
7122     ok(r == ERROR_INVALID_PARAMETER,
7123        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7124     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7125
7126     /* empty szProduct */
7127     hprod = 0xdeadbeef;
7128     r = MsiOpenProductA("", &hprod);
7129     ok(r == ERROR_INVALID_PARAMETER,
7130        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7131     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7132
7133     /* garbage szProduct */
7134     hprod = 0xdeadbeef;
7135     r = MsiOpenProductA("garbage", &hprod);
7136     ok(r == ERROR_INVALID_PARAMETER,
7137        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7138     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7139
7140     /* guid without brackets */
7141     hprod = 0xdeadbeef;
7142     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7143     ok(r == ERROR_INVALID_PARAMETER,
7144        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7145     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7146
7147     /* guid with brackets */
7148     hprod = 0xdeadbeef;
7149     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7150     ok(r == ERROR_UNKNOWN_PRODUCT,
7151        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7152     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7153
7154     /* same length as guid, but random */
7155     hprod = 0xdeadbeef;
7156     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7157     ok(r == ERROR_INVALID_PARAMETER,
7158        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7159     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7160
7161     /* hProduct is NULL */
7162     hprod = 0xdeadbeef;
7163     r = MsiOpenProductA(prodcode, NULL);
7164     ok(r == ERROR_INVALID_PARAMETER,
7165        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7166     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7167
7168     /* MSIINSTALLCONTEXT_USERMANAGED */
7169
7170     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7171     lstrcatA(keypath, "Installer\\Managed\\");
7172     lstrcatA(keypath, usersid);
7173     lstrcatA(keypath, "\\Installer\\Products\\");
7174     lstrcatA(keypath, prod_squashed);
7175
7176     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7177     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7178
7179     /* managed product key exists */
7180     hprod = 0xdeadbeef;
7181     r = MsiOpenProductA(prodcode, &hprod);
7182     ok(r == ERROR_UNKNOWN_PRODUCT,
7183        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7184     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7185
7186     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7187     lstrcatA(keypath, "Installer\\UserData\\");
7188     lstrcatA(keypath, usersid);
7189     lstrcatA(keypath, "\\Products\\");
7190     lstrcatA(keypath, prod_squashed);
7191
7192     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7193     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7194
7195     /* user product key exists */
7196     hprod = 0xdeadbeef;
7197     r = MsiOpenProductA(prodcode, &hprod);
7198     ok(r == ERROR_UNKNOWN_PRODUCT,
7199        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7200     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7201
7202     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7203     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7204
7205     /* InstallProperties key exists */
7206     hprod = 0xdeadbeef;
7207     r = MsiOpenProductA(prodcode, &hprod);
7208     ok(r == ERROR_UNKNOWN_PRODUCT,
7209        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7210     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7211
7212     lstrcpyA(val, path);
7213     lstrcatA(val, "\\winetest.msi");
7214     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7215                          (const BYTE *)val, lstrlenA(val) + 1);
7216     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7217
7218     /* ManagedLocalPackage value exists */
7219     hprod = 0xdeadbeef;
7220     r = MsiOpenProductA(prodcode, &hprod);
7221     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7222     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7223
7224     size = MAX_PATH;
7225     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7226     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7227     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7228     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7229
7230     MsiCloseHandle(hprod);
7231
7232     RegDeleteValueA(props, "ManagedLocalPackage");
7233     RegDeleteKeyA(props, "");
7234     RegCloseKey(props);
7235     RegDeleteKeyA(userkey, "");
7236     RegCloseKey(userkey);
7237     RegDeleteKeyA(prodkey, "");
7238     RegCloseKey(prodkey);
7239
7240     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7241
7242     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7243     lstrcatA(keypath, prod_squashed);
7244
7245     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7246     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7247
7248     /* unmanaged product key exists */
7249     hprod = 0xdeadbeef;
7250     r = MsiOpenProductA(prodcode, &hprod);
7251     ok(r == ERROR_UNKNOWN_PRODUCT,
7252        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7253     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7254
7255     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7256     lstrcatA(keypath, "Installer\\UserData\\");
7257     lstrcatA(keypath, usersid);
7258     lstrcatA(keypath, "\\Products\\");
7259     lstrcatA(keypath, prod_squashed);
7260
7261     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7262     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7263
7264     /* user product key exists */
7265     hprod = 0xdeadbeef;
7266     r = MsiOpenProductA(prodcode, &hprod);
7267     ok(r == ERROR_UNKNOWN_PRODUCT,
7268        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7269     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7270
7271     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7272     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7273
7274     /* InstallProperties key exists */
7275     hprod = 0xdeadbeef;
7276     r = MsiOpenProductA(prodcode, &hprod);
7277     ok(r == ERROR_UNKNOWN_PRODUCT,
7278        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7279     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7280
7281     lstrcpyA(val, path);
7282     lstrcatA(val, "\\winetest.msi");
7283     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7284                          (const BYTE *)val, lstrlenA(val) + 1);
7285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7286
7287     /* LocalPackage value exists */
7288     hprod = 0xdeadbeef;
7289     r = MsiOpenProductA(prodcode, &hprod);
7290     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7291     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7292
7293     size = MAX_PATH;
7294     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7295     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7296     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7297     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7298
7299     MsiCloseHandle(hprod);
7300
7301     RegDeleteValueA(props, "LocalPackage");
7302     RegDeleteKeyA(props, "");
7303     RegCloseKey(props);
7304     RegDeleteKeyA(userkey, "");
7305     RegCloseKey(userkey);
7306     RegDeleteKeyA(prodkey, "");
7307     RegCloseKey(prodkey);
7308
7309     /* MSIINSTALLCONTEXT_MACHINE */
7310
7311     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7312     lstrcatA(keypath, prod_squashed);
7313
7314     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7315     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7316
7317     /* managed product key exists */
7318     hprod = 0xdeadbeef;
7319     r = MsiOpenProductA(prodcode, &hprod);
7320     ok(r == ERROR_UNKNOWN_PRODUCT,
7321        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7322     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7323
7324     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7325     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7326     lstrcatA(keypath, prod_squashed);
7327
7328     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7329     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7330
7331     /* user product key exists */
7332     hprod = 0xdeadbeef;
7333     r = MsiOpenProductA(prodcode, &hprod);
7334     ok(r == ERROR_UNKNOWN_PRODUCT,
7335        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7336     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7337
7338     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7339     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7340
7341     /* InstallProperties key exists */
7342     hprod = 0xdeadbeef;
7343     r = MsiOpenProductA(prodcode, &hprod);
7344     ok(r == ERROR_UNKNOWN_PRODUCT,
7345        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7346     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7347
7348     lstrcpyA(val, path);
7349     lstrcatA(val, "\\winetest.msi");
7350     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7351                          (const BYTE *)val, lstrlenA(val) + 1);
7352     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7353
7354     /* LocalPackage value exists */
7355     hprod = 0xdeadbeef;
7356     r = MsiOpenProductA(prodcode, &hprod);
7357     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7358     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7359
7360     size = MAX_PATH;
7361     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7362     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7363     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7364     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7365
7366     MsiCloseHandle(hprod);
7367
7368     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7369                          (const BYTE *)"winetest.msi", 13);
7370     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7371
7372     /* LocalPackage has just the package name */
7373     hprod = 0xdeadbeef;
7374     r = MsiOpenProductA(prodcode, &hprod);
7375     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7376        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7377     if (r == ERROR_SUCCESS)
7378         MsiCloseHandle(hprod);
7379     else
7380         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7381
7382     lstrcpyA(val, path);
7383     lstrcatA(val, "\\winetest.msi");
7384     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7385                          (const BYTE *)val, lstrlenA(val) + 1);
7386     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7387
7388     DeleteFileA(msifile);
7389
7390     /* local package does not exist */
7391     hprod = 0xdeadbeef;
7392     r = MsiOpenProductA(prodcode, &hprod);
7393     ok(r == ERROR_UNKNOWN_PRODUCT,
7394        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7395     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7396
7397     RegDeleteValueA(props, "LocalPackage");
7398     RegDeleteKeyA(props, "");
7399     RegCloseKey(props);
7400     RegDeleteKeyA(userkey, "");
7401     RegCloseKey(userkey);
7402     RegDeleteKeyA(prodkey, "");
7403     RegCloseKey(prodkey);
7404
7405     DeleteFileA(msifile);
7406 }
7407
7408 static void test_MsiEnumPatchesEx(void)
7409 {
7410     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7411     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7412     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7413     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7414     HKEY prodkey, patches, udprod, udpatch;
7415     HKEY userkey, hpatch;
7416     MSIINSTALLCONTEXT context;
7417     DWORD size, data;
7418     LPSTR usersid;
7419     LONG res;
7420     UINT r;
7421
7422     if (!pMsiEnumPatchesExA)
7423     {
7424         win_skip("MsiEnumPatchesExA not implemented\n");
7425         return;
7426     }
7427
7428     create_test_guid(prodcode, prod_squashed);
7429     create_test_guid(patch, patch_squashed);
7430     get_user_sid(&usersid);
7431
7432     /* empty szProductCode */
7433     lstrcpyA(patchcode, "apple");
7434     lstrcpyA(targetprod, "banana");
7435     context = 0xdeadbeef;
7436     lstrcpyA(targetsid, "kiwi");
7437     size = MAX_PATH;
7438     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7439                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
7440                            targetsid, &size);
7441     ok(r == ERROR_INVALID_PARAMETER,
7442        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7443     ok(!lstrcmpA(patchcode, "apple"),
7444        "Expected patchcode to be unchanged, got %s\n", patchcode);
7445     ok(!lstrcmpA(targetprod, "banana"),
7446        "Expected targetprod to be unchanged, got %s\n", targetprod);
7447     ok(context == 0xdeadbeef,
7448        "Expected context to be unchanged, got %d\n", context);
7449     ok(!lstrcmpA(targetsid, "kiwi"),
7450        "Expected targetsid to be unchanged, got %s\n", targetsid);
7451     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7452
7453     /* garbage szProductCode */
7454     lstrcpyA(patchcode, "apple");
7455     lstrcpyA(targetprod, "banana");
7456     context = 0xdeadbeef;
7457     lstrcpyA(targetsid, "kiwi");
7458     size = MAX_PATH;
7459     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7460                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
7461                            targetsid, &size);
7462     ok(r == ERROR_INVALID_PARAMETER,
7463        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7464     ok(!lstrcmpA(patchcode, "apple"),
7465        "Expected patchcode to be unchanged, got %s\n", patchcode);
7466     ok(!lstrcmpA(targetprod, "banana"),
7467        "Expected targetprod to be unchanged, got %s\n", targetprod);
7468     ok(context == 0xdeadbeef,
7469        "Expected context to be unchanged, got %d\n", context);
7470     ok(!lstrcmpA(targetsid, "kiwi"),
7471        "Expected targetsid to be unchanged, got %s\n", targetsid);
7472     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7473
7474     /* guid without brackets */
7475     lstrcpyA(patchcode, "apple");
7476     lstrcpyA(targetprod, "banana");
7477     context = 0xdeadbeef;
7478     lstrcpyA(targetsid, "kiwi");
7479     size = MAX_PATH;
7480     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
7481                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7482                            0, patchcode, targetprod, &context,
7483                            targetsid, &size);
7484     ok(r == ERROR_INVALID_PARAMETER,
7485        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7486     ok(!lstrcmpA(patchcode, "apple"),
7487        "Expected patchcode to be unchanged, got %s\n", patchcode);
7488     ok(!lstrcmpA(targetprod, "banana"),
7489        "Expected targetprod to be unchanged, got %s\n", targetprod);
7490     ok(context == 0xdeadbeef,
7491        "Expected context to be unchanged, got %d\n", context);
7492     ok(!lstrcmpA(targetsid, "kiwi"),
7493        "Expected targetsid to be unchanged, got %s\n", targetsid);
7494     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7495
7496     /* guid with brackets */
7497     lstrcpyA(patchcode, "apple");
7498     lstrcpyA(targetprod, "banana");
7499     context = 0xdeadbeef;
7500     lstrcpyA(targetsid, "kiwi");
7501     size = MAX_PATH;
7502     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
7503                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7504                            0, patchcode, targetprod, &context,
7505                            targetsid, &size);
7506     ok(r == ERROR_NO_MORE_ITEMS,
7507        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7508     ok(!lstrcmpA(patchcode, "apple"),
7509        "Expected patchcode to be unchanged, got %s\n", patchcode);
7510     ok(!lstrcmpA(targetprod, "banana"),
7511        "Expected targetprod to be unchanged, got %s\n", targetprod);
7512     ok(context == 0xdeadbeef,
7513        "Expected context to be unchanged, got %d\n", context);
7514     ok(!lstrcmpA(targetsid, "kiwi"),
7515        "Expected targetsid to be unchanged, got %s\n", targetsid);
7516     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7517
7518     /* szUserSid is S-1-5-18 */
7519     lstrcpyA(patchcode, "apple");
7520     lstrcpyA(targetprod, "banana");
7521     context = 0xdeadbeef;
7522     lstrcpyA(targetsid, "kiwi");
7523     size = MAX_PATH;
7524     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
7525                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7526                            0, patchcode, targetprod, &context,
7527                            targetsid, &size);
7528     ok(r == ERROR_INVALID_PARAMETER,
7529        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7530     ok(!lstrcmpA(patchcode, "apple"),
7531        "Expected patchcode to be unchanged, got %s\n", patchcode);
7532     ok(!lstrcmpA(targetprod, "banana"),
7533        "Expected targetprod to be unchanged, got %s\n", targetprod);
7534     ok(context == 0xdeadbeef,
7535        "Expected context to be unchanged, got %d\n", context);
7536     ok(!lstrcmpA(targetsid, "kiwi"),
7537        "Expected targetsid to be unchanged, got %s\n", targetsid);
7538     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7539
7540     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
7541     lstrcpyA(patchcode, "apple");
7542     lstrcpyA(targetprod, "banana");
7543     context = 0xdeadbeef;
7544     lstrcpyA(targetsid, "kiwi");
7545     size = MAX_PATH;
7546     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
7547                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7548                            &context, targetsid, &size);
7549     ok(r == ERROR_INVALID_PARAMETER,
7550        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7551     ok(!lstrcmpA(patchcode, "apple"),
7552        "Expected patchcode to be unchanged, got %s\n", patchcode);
7553     ok(!lstrcmpA(targetprod, "banana"),
7554        "Expected targetprod to be unchanged, got %s\n", targetprod);
7555     ok(context == 0xdeadbeef,
7556        "Expected context to be unchanged, got %d\n", context);
7557     ok(!lstrcmpA(targetsid, "kiwi"),
7558        "Expected targetsid to be unchanged, got %s\n", targetsid);
7559     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7560
7561     /* dwContext is out of bounds */
7562     lstrcpyA(patchcode, "apple");
7563     lstrcpyA(targetprod, "banana");
7564     context = 0xdeadbeef;
7565     lstrcpyA(targetsid, "kiwi");
7566     size = MAX_PATH;
7567     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
7568                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7569                            &context, targetsid, &size);
7570     ok(r == ERROR_INVALID_PARAMETER,
7571        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7572     ok(!lstrcmpA(patchcode, "apple"),
7573        "Expected patchcode to be unchanged, got %s\n", patchcode);
7574     ok(!lstrcmpA(targetprod, "banana"),
7575        "Expected targetprod to be unchanged, got %s\n", targetprod);
7576     ok(context == 0xdeadbeef,
7577        "Expected context to be unchanged, got %d\n", context);
7578     ok(!lstrcmpA(targetsid, "kiwi"),
7579        "Expected targetsid to be unchanged, got %s\n", targetsid);
7580     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7581
7582     /* dwContext is out of bounds */
7583     lstrcpyA(patchcode, "apple");
7584     lstrcpyA(targetprod, "banana");
7585     context = 0xdeadbeef;
7586     lstrcpyA(targetsid, "kiwi");
7587     size = MAX_PATH;
7588     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
7589                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7590                            &context, targetsid, &size);
7591     ok(r == ERROR_INVALID_PARAMETER,
7592        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7593     ok(!lstrcmpA(patchcode, "apple"),
7594        "Expected patchcode to be unchanged, got %s\n", patchcode);
7595     ok(!lstrcmpA(targetprod, "banana"),
7596        "Expected targetprod to be unchanged, got %s\n", targetprod);
7597     ok(context == 0xdeadbeef,
7598        "Expected context to be unchanged, got %d\n", context);
7599     ok(!lstrcmpA(targetsid, "kiwi"),
7600        "Expected targetsid to be unchanged, got %s\n", targetsid);
7601     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7602
7603     /* dwFilter is out of bounds */
7604     lstrcpyA(patchcode, "apple");
7605     lstrcpyA(targetprod, "banana");
7606     context = 0xdeadbeef;
7607     lstrcpyA(targetsid, "kiwi");
7608     size = MAX_PATH;
7609     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7610                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
7611                            &context, targetsid, &size);
7612     ok(r == ERROR_INVALID_PARAMETER,
7613        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7614     ok(!lstrcmpA(patchcode, "apple"),
7615        "Expected patchcode to be unchanged, got %s\n", patchcode);
7616     ok(!lstrcmpA(targetprod, "banana"),
7617        "Expected targetprod to be unchanged, got %s\n", targetprod);
7618     ok(context == 0xdeadbeef,
7619        "Expected context to be unchanged, got %d\n", context);
7620     ok(!lstrcmpA(targetsid, "kiwi"),
7621        "Expected targetsid to be unchanged, got %s\n", targetsid);
7622     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7623
7624     /* dwFilter is out of bounds */
7625     lstrcpyA(patchcode, "apple");
7626     lstrcpyA(targetprod, "banana");
7627     context = 0xdeadbeef;
7628     lstrcpyA(targetsid, "kiwi");
7629     size = MAX_PATH;
7630     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7631                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
7632                            &context, targetsid, &size);
7633     ok(r == ERROR_INVALID_PARAMETER,
7634        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7635     ok(!lstrcmpA(patchcode, "apple"),
7636        "Expected patchcode to be unchanged, got %s\n", patchcode);
7637     ok(!lstrcmpA(targetprod, "banana"),
7638        "Expected targetprod to be unchanged, got %s\n", targetprod);
7639     ok(context == 0xdeadbeef,
7640        "Expected context to be unchanged, got %d\n", context);
7641     ok(!lstrcmpA(targetsid, "kiwi"),
7642        "Expected targetsid to be unchanged, got %s\n", targetsid);
7643     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7644
7645     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
7646     lstrcpyA(patchcode, "apple");
7647     lstrcpyA(targetprod, "banana");
7648     context = 0xdeadbeef;
7649     lstrcpyA(targetsid, "kiwi");
7650     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7651                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7652                            &context, targetsid, NULL);
7653     ok(r == ERROR_INVALID_PARAMETER,
7654        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7655     ok(!lstrcmpA(patchcode, "apple"),
7656        "Expected patchcode to be unchanged, got %s\n", patchcode);
7657     ok(!lstrcmpA(targetprod, "banana"),
7658        "Expected targetprod to be unchanged, got %s\n", targetprod);
7659     ok(context == 0xdeadbeef,
7660        "Expected context to be unchanged, got %d\n", context);
7661     ok(!lstrcmpA(targetsid, "kiwi"),
7662        "Expected targetsid to be unchanged, got %s\n", targetsid);
7663
7664     /* MSIINSTALLCONTEXT_USERMANAGED */
7665
7666     /* MSIPATCHSTATE_APPLIED */
7667
7668     lstrcpyA(patchcode, "apple");
7669     lstrcpyA(targetprod, "banana");
7670     context = 0xdeadbeef;
7671     lstrcpyA(targetsid, "kiwi");
7672     size = MAX_PATH;
7673     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7674                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7675                            &context, targetsid, &size);
7676     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7677     ok(!lstrcmpA(patchcode, "apple"),
7678        "Expected patchcode to be unchanged, got %s\n", patchcode);
7679     ok(!lstrcmpA(targetprod, "banana"),
7680        "Expected targetprod to be unchanged, got %s\n", targetprod);
7681     ok(context == 0xdeadbeef,
7682        "Expected context to be unchanged, got %d\n", context);
7683     ok(!lstrcmpA(targetsid, "kiwi"),
7684        "Expected targetsid to be unchanged, got %s\n", targetsid);
7685     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7686
7687     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7688     lstrcatA(keypath, usersid);
7689     lstrcatA(keypath, "\\Installer\\Products\\");
7690     lstrcatA(keypath, prod_squashed);
7691
7692     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7693     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7694
7695     /* managed product key exists */
7696     lstrcpyA(patchcode, "apple");
7697     lstrcpyA(targetprod, "banana");
7698     context = 0xdeadbeef;
7699     lstrcpyA(targetsid, "kiwi");
7700     size = MAX_PATH;
7701     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7702                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7703                            &context, targetsid, &size);
7704     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7705     ok(!lstrcmpA(patchcode, "apple"),
7706        "Expected patchcode to be unchanged, got %s\n", patchcode);
7707     ok(!lstrcmpA(targetprod, "banana"),
7708        "Expected targetprod to be unchanged, got %s\n", targetprod);
7709     ok(context == 0xdeadbeef,
7710        "Expected context to be unchanged, got %d\n", context);
7711     ok(!lstrcmpA(targetsid, "kiwi"),
7712        "Expected targetsid to be unchanged, got %s\n", targetsid);
7713     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7714
7715     res = RegCreateKeyA(prodkey, "Patches", &patches);
7716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7717
7718     /* patches key exists */
7719     lstrcpyA(patchcode, "apple");
7720     lstrcpyA(targetprod, "banana");
7721     context = 0xdeadbeef;
7722     lstrcpyA(targetsid, "kiwi");
7723     size = MAX_PATH;
7724     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7725                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7726                            &context, targetsid, &size);
7727     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7728     ok(!lstrcmpA(patchcode, "apple"),
7729        "Expected patchcode to be unchanged, got %s\n", patchcode);
7730     ok(!lstrcmpA(targetprod, "banana"),
7731        "Expected targetprod to be unchanged, got %s\n", targetprod);
7732     ok(context == 0xdeadbeef,
7733        "Expected context to be unchanged, got %d\n", context);
7734     ok(!lstrcmpA(targetsid, "kiwi"),
7735        "Expected targetsid to be unchanged, got %s\n", targetsid);
7736     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7737
7738     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7739                          (const BYTE *)patch_squashed,
7740                          lstrlenA(patch_squashed) + 1);
7741     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7742
7743     /* Patches value exists, is not REG_MULTI_SZ */
7744     lstrcpyA(patchcode, "apple");
7745     lstrcpyA(targetprod, "banana");
7746     context = 0xdeadbeef;
7747     lstrcpyA(targetsid, "kiwi");
7748     size = MAX_PATH;
7749     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7750                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7751                            &context, targetsid, &size);
7752     ok(r == ERROR_BAD_CONFIGURATION,
7753        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7754     ok(!lstrcmpA(patchcode, "apple"),
7755        "Expected patchcode to be unchanged, got %s\n", patchcode);
7756     ok(!lstrcmpA(targetprod, "banana"),
7757        "Expected targetprod to be unchanged, got %s\n", targetprod);
7758     ok(context == 0xdeadbeef,
7759        "Expected context to be unchanged, got %d\n", context);
7760     ok(!lstrcmpA(targetsid, "kiwi"),
7761        "Expected targetsid to be unchanged, got %s\n", targetsid);
7762     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7763
7764     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7765                          (const BYTE *)"a\0b\0c\0\0", 7);
7766     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7767
7768     /* Patches value exists, is not a squashed guid */
7769     lstrcpyA(patchcode, "apple");
7770     lstrcpyA(targetprod, "banana");
7771     context = 0xdeadbeef;
7772     lstrcpyA(targetsid, "kiwi");
7773     size = MAX_PATH;
7774     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
7775                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7776                            &context, targetsid, &size);
7777     ok(r == ERROR_BAD_CONFIGURATION,
7778        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7779     ok(!lstrcmpA(patchcode, "apple"),
7780        "Expected patchcode to be unchanged, got %s\n", patchcode);
7781     ok(!lstrcmpA(targetprod, "banana"),
7782        "Expected targetprod to be unchanged, got %s\n", targetprod);
7783     ok(context == 0xdeadbeef,
7784        "Expected context to be unchanged, got %d\n", context);
7785     ok(!lstrcmpA(targetsid, "kiwi"),
7786        "Expected targetsid to be unchanged, got %s\n", targetsid);
7787     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7788
7789     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
7790     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7791                          (const BYTE *)patch_squashed,
7792                          lstrlenA(patch_squashed) + 2);
7793     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7794
7795     /* Patches value exists */
7796     lstrcpyA(patchcode, "apple");
7797     lstrcpyA(targetprod, "banana");
7798     context = 0xdeadbeef;
7799     lstrcpyA(targetsid, "kiwi");
7800     size = MAX_PATH;
7801     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7802                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7803                            &context, targetsid, &size);
7804     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7805     ok(!lstrcmpA(patchcode, "apple"),
7806        "Expected patchcode to be unchanged, got %s\n", patchcode);
7807     ok(!lstrcmpA(targetprod, "banana"),
7808        "Expected targetprod to be unchanged, got %s\n", targetprod);
7809     ok(context == 0xdeadbeef,
7810        "Expected context to be unchanged, got %d\n", context);
7811     ok(!lstrcmpA(targetsid, "kiwi"),
7812        "Expected targetsid to be unchanged, got %s\n", targetsid);
7813     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7814
7815     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7816                          (const BYTE *)"whatever", 9);
7817     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7818
7819     /* patch squashed value exists */
7820     lstrcpyA(patchcode, "apple");
7821     lstrcpyA(targetprod, "banana");
7822     context = 0xdeadbeef;
7823     lstrcpyA(targetsid, "kiwi");
7824     size = MAX_PATH;
7825     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7826                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7827                            &context, targetsid, &size);
7828     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7829     ok(!lstrcmpA(patchcode, patch),
7830        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7831     ok(!lstrcmpA(targetprod, prodcode),
7832        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7833     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7834        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7835     ok(!lstrcmpA(targetsid, usersid),
7836        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7837     ok(size == lstrlenA(usersid),
7838        "Expected %d, got %d\n", lstrlenA(usersid), size);
7839
7840     /* increase the index */
7841     lstrcpyA(patchcode, "apple");
7842     lstrcpyA(targetprod, "banana");
7843     context = 0xdeadbeef;
7844     lstrcpyA(targetsid, "kiwi");
7845     size = MAX_PATH;
7846     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7847                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7848                            &context, targetsid, &size);
7849     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7850     ok(!lstrcmpA(patchcode, "apple"),
7851        "Expected patchcode to be unchanged, got %s\n", patchcode);
7852     ok(!lstrcmpA(targetprod, "banana"),
7853        "Expected targetprod to be unchanged, got %s\n", targetprod);
7854     ok(context == 0xdeadbeef,
7855        "Expected context to be unchanged, got %d\n", context);
7856     ok(!lstrcmpA(targetsid, "kiwi"),
7857        "Expected targetsid to be unchanged, got %s\n", targetsid);
7858     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7859
7860     /* increase again */
7861     lstrcpyA(patchcode, "apple");
7862     lstrcpyA(targetprod, "banana");
7863     context = 0xdeadbeef;
7864     lstrcpyA(targetsid, "kiwi");
7865     size = MAX_PATH;
7866     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7867                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
7868                            &context, targetsid, &size);
7869     ok(r == ERROR_INVALID_PARAMETER,
7870        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7871     ok(!lstrcmpA(patchcode, "apple"),
7872        "Expected patchcode to be unchanged, got %s\n", patchcode);
7873     ok(!lstrcmpA(targetprod, "banana"),
7874        "Expected targetprod to be unchanged, got %s\n", targetprod);
7875     ok(context == 0xdeadbeef,
7876        "Expected context to be unchanged, got %d\n", context);
7877     ok(!lstrcmpA(targetsid, "kiwi"),
7878        "Expected targetsid to be unchanged, got %s\n", targetsid);
7879     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7880
7881     /* szPatchCode is NULL */
7882     lstrcpyA(targetprod, "banana");
7883     context = 0xdeadbeef;
7884     lstrcpyA(targetsid, "kiwi");
7885     size = MAX_PATH;
7886     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7887                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
7888                            &context, targetsid, &size);
7889     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7890     ok(!lstrcmpA(targetprod, prodcode),
7891        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7892     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7893        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7894     ok(!lstrcmpA(targetsid, usersid),
7895        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7896     ok(size == lstrlenA(usersid),
7897        "Expected %d, got %d\n", lstrlenA(usersid), size);
7898
7899     /* szTargetProductCode is NULL */
7900     lstrcpyA(patchcode, "apple");
7901     context = 0xdeadbeef;
7902     lstrcpyA(targetsid, "kiwi");
7903     size = MAX_PATH;
7904     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7905                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
7906                            &context, targetsid, &size);
7907     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7908     ok(!lstrcmpA(patchcode, patch),
7909        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7910     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7911        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7912     ok(!lstrcmpA(targetsid, usersid),
7913        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7914     ok(size == lstrlenA(usersid),
7915        "Expected %d, got %d\n", lstrlenA(usersid), size);
7916
7917     /* pdwTargetProductContext is NULL */
7918     lstrcpyA(patchcode, "apple");
7919     lstrcpyA(targetprod, "banana");
7920     lstrcpyA(targetsid, "kiwi");
7921     size = MAX_PATH;
7922     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7923                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7924                            NULL, targetsid, &size);
7925     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7926     ok(!lstrcmpA(patchcode, patch),
7927        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7928     ok(!lstrcmpA(targetprod, prodcode),
7929        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7930     ok(!lstrcmpA(targetsid, usersid),
7931        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7932     ok(size == lstrlenA(usersid),
7933        "Expected %d, got %d\n", lstrlenA(usersid), size);
7934
7935     /* szTargetUserSid is NULL */
7936     lstrcpyA(patchcode, "apple");
7937     lstrcpyA(targetprod, "banana");
7938     context = 0xdeadbeef;
7939     size = MAX_PATH;
7940     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7941                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7942                            &context, NULL, &size);
7943     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7944     ok(!lstrcmpA(patchcode, patch),
7945        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7946     ok(!lstrcmpA(targetprod, prodcode),
7947        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7948     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7949        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7950     ok(size == lstrlenA(usersid) * sizeof(WCHAR),
7951        "Got %d\n", size);
7952
7953     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
7954     lstrcpyA(patchcode, "apple");
7955     lstrcpyA(targetprod, "banana");
7956     context = 0xdeadbeef;
7957     lstrcpyA(targetsid, "kiwi");
7958     size = lstrlenA(usersid);
7959     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7960                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7961                            &context, targetsid, &size);
7962     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
7963     ok(!lstrcmpA(patchcode, patch),
7964        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7965     ok(!lstrcmpA(targetprod, prodcode),
7966        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7967     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7968        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7969     ok(!strncmp(targetsid, usersid, lstrlenA(usersid) - 1),
7970        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7971     ok(size == lstrlenA(usersid) * sizeof(WCHAR),
7972        "Got %d\n", size);
7973
7974     /* pcchTargetUserSid has enough room for NULL terminator */
7975     lstrcpyA(patchcode, "apple");
7976     lstrcpyA(targetprod, "banana");
7977     context = 0xdeadbeef;
7978     lstrcpyA(targetsid, "kiwi");
7979     size = lstrlenA(usersid) + 1;
7980     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7981                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7982                            &context, targetsid, &size);
7983     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7984     ok(!lstrcmpA(patchcode, patch),
7985        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7986     ok(!lstrcmpA(targetprod, prodcode),
7987        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7988     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7989        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7990     ok(!lstrcmpA(targetsid, usersid),
7991        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7992     ok(size == lstrlenA(usersid),
7993        "Expected %d, got %d\n", lstrlenA(usersid), size);
7994
7995     /* both szTargetuserSid and pcchTargetUserSid are NULL */
7996     lstrcpyA(patchcode, "apple");
7997     lstrcpyA(targetprod, "banana");
7998     context = 0xdeadbeef;
7999     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8000                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8001                            &context, NULL, NULL);
8002     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8003     ok(!lstrcmpA(patchcode, patch),
8004        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8005     ok(!lstrcmpA(targetprod, prodcode),
8006        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8007     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8008        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8009
8010     /* MSIPATCHSTATE_SUPERSEDED */
8011
8012     lstrcpyA(patchcode, "apple");
8013     lstrcpyA(targetprod, "banana");
8014     context = 0xdeadbeef;
8015     lstrcpyA(targetsid, "kiwi");
8016     size = MAX_PATH;
8017     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8018                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8019                            &context, targetsid, &size);
8020     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8021     ok(!lstrcmpA(patchcode, "apple"),
8022        "Expected patchcode to be unchanged, got %s\n", patchcode);
8023     ok(!lstrcmpA(targetprod, "banana"),
8024        "Expected targetprod to be unchanged, got %s\n", targetprod);
8025     ok(context == 0xdeadbeef,
8026        "Expected context to be unchanged, got %d\n", context);
8027     ok(!lstrcmpA(targetsid, "kiwi"),
8028        "Expected targetsid to be unchanged, got %s\n", targetsid);
8029     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8030
8031     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8032     lstrcatA(keypath, usersid);
8033     lstrcatA(keypath, "\\Products\\");
8034     lstrcatA(keypath, prod_squashed);
8035
8036     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8037     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8038
8039     /* UserData product key exists */
8040     lstrcpyA(patchcode, "apple");
8041     lstrcpyA(targetprod, "banana");
8042     context = 0xdeadbeef;
8043     lstrcpyA(targetsid, "kiwi");
8044     size = MAX_PATH;
8045     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8046                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8047                            &context, targetsid, &size);
8048     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8049     ok(!lstrcmpA(patchcode, "apple"),
8050        "Expected patchcode to be unchanged, got %s\n", patchcode);
8051     ok(!lstrcmpA(targetprod, "banana"),
8052        "Expected targetprod to be unchanged, got %s\n", targetprod);
8053     ok(context == 0xdeadbeef,
8054        "Expected context to be unchanged, got %d\n", context);
8055     ok(!lstrcmpA(targetsid, "kiwi"),
8056        "Expected targetsid to be unchanged, got %s\n", targetsid);
8057     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8058
8059     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8061
8062     /* UserData patches key exists */
8063     lstrcpyA(patchcode, "apple");
8064     lstrcpyA(targetprod, "banana");
8065     context = 0xdeadbeef;
8066     lstrcpyA(targetsid, "kiwi");
8067     size = MAX_PATH;
8068     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8069                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8070                            &context, targetsid, &size);
8071     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8072     ok(!lstrcmpA(patchcode, "apple"),
8073        "Expected patchcode to be unchanged, got %s\n", patchcode);
8074     ok(!lstrcmpA(targetprod, "banana"),
8075        "Expected targetprod to be unchanged, got %s\n", targetprod);
8076     ok(context == 0xdeadbeef,
8077        "Expected context to be unchanged, got %d\n", context);
8078     ok(!lstrcmpA(targetsid, "kiwi"),
8079        "Expected targetsid to be unchanged, got %s\n", targetsid);
8080     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8081
8082     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8084
8085     /* specific UserData patch key exists */
8086     lstrcpyA(patchcode, "apple");
8087     lstrcpyA(targetprod, "banana");
8088     context = 0xdeadbeef;
8089     lstrcpyA(targetsid, "kiwi");
8090     size = MAX_PATH;
8091     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8092                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8093                            &context, targetsid, &size);
8094     ok(r == ERROR_BAD_CONFIGURATION,
8095        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8096     ok(!lstrcmpA(patchcode, "apple"),
8097        "Expected patchcode to be unchanged, got %s\n", patchcode);
8098     ok(!lstrcmpA(targetprod, "banana"),
8099        "Expected targetprod to be unchanged, got %s\n", targetprod);
8100     ok(context == 0xdeadbeef,
8101        "Expected context to be unchanged, got %d\n", context);
8102     ok(!lstrcmpA(targetsid, "kiwi"),
8103        "Expected targetsid to be unchanged, got %s\n", targetsid);
8104     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8105
8106     data = MSIPATCHSTATE_SUPERSEDED;
8107     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8108                          (const BYTE *)&data, sizeof(DWORD));
8109     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8110
8111     /* State value exists */
8112     lstrcpyA(patchcode, "apple");
8113     lstrcpyA(targetprod, "banana");
8114     context = 0xdeadbeef;
8115     lstrcpyA(targetsid, "kiwi");
8116     size = MAX_PATH;
8117     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8118                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8119                            &context, targetsid, &size);
8120     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8121     ok(!lstrcmpA(patchcode, patch),
8122        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8123     ok(!lstrcmpA(targetprod, prodcode),
8124        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8125     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8126        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8127     ok(!lstrcmpA(targetsid, usersid),
8128        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8129     ok(size == lstrlenA(usersid),
8130        "Expected %d, got %d\n", lstrlenA(usersid), size);
8131
8132     /* MSIPATCHSTATE_OBSOLETED */
8133
8134     lstrcpyA(patchcode, "apple");
8135     lstrcpyA(targetprod, "banana");
8136     context = 0xdeadbeef;
8137     lstrcpyA(targetsid, "kiwi");
8138     size = MAX_PATH;
8139     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8140                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8141                            &context, targetsid, &size);
8142     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8143     ok(!lstrcmpA(patchcode, "apple"),
8144        "Expected patchcode to be unchanged, got %s\n", patchcode);
8145     ok(!lstrcmpA(targetprod, "banana"),
8146        "Expected targetprod to be unchanged, got %s\n", targetprod);
8147     ok(context == 0xdeadbeef,
8148        "Expected context to be unchanged, got %d\n", context);
8149     ok(!lstrcmpA(targetsid, "kiwi"),
8150        "Expected targetsid to be unchanged, got %s\n", targetsid);
8151     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8152
8153     data = MSIPATCHSTATE_OBSOLETED;
8154     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8155                          (const BYTE *)&data, sizeof(DWORD));
8156     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8157
8158     /* State value is obsoleted */
8159     lstrcpyA(patchcode, "apple");
8160     lstrcpyA(targetprod, "banana");
8161     context = 0xdeadbeef;
8162     lstrcpyA(targetsid, "kiwi");
8163     size = MAX_PATH;
8164     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8165                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8166                            &context, targetsid, &size);
8167     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8168     ok(!lstrcmpA(patchcode, patch),
8169        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8170     ok(!lstrcmpA(targetprod, prodcode),
8171        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8172     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8173        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8174     ok(!lstrcmpA(targetsid, usersid),
8175        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8176     ok(size == lstrlenA(usersid),
8177        "Expected %d, got %d\n", lstrlenA(usersid), size);
8178
8179     /* MSIPATCHSTATE_REGISTERED */
8180     /* FIXME */
8181
8182     /* MSIPATCHSTATE_ALL */
8183
8184     /* 1st */
8185     lstrcpyA(patchcode, "apple");
8186     lstrcpyA(targetprod, "banana");
8187     context = 0xdeadbeef;
8188     lstrcpyA(targetsid, "kiwi");
8189     size = MAX_PATH;
8190     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8191                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8192                            &context, targetsid, &size);
8193     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8194     ok(!lstrcmpA(patchcode, patch),
8195        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8196     ok(!lstrcmpA(targetprod, prodcode),
8197        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8198     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8199        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8200     ok(!lstrcmpA(targetsid, usersid),
8201        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8202     ok(size == lstrlenA(usersid),
8203        "Expected %d, got %d\n", lstrlenA(usersid), size);
8204
8205     /* same patch in multiple places, only one is enumerated */
8206     lstrcpyA(patchcode, "apple");
8207     lstrcpyA(targetprod, "banana");
8208     context = 0xdeadbeef;
8209     lstrcpyA(targetsid, "kiwi");
8210     size = MAX_PATH;
8211     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8212                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8213                            &context, targetsid, &size);
8214     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8215     ok(!lstrcmpA(patchcode, "apple"),
8216        "Expected patchcode to be unchanged, got %s\n", patchcode);
8217     ok(!lstrcmpA(targetprod, "banana"),
8218        "Expected targetprod to be unchanged, got %s\n", targetprod);
8219     ok(context == 0xdeadbeef,
8220        "Expected context to be unchanged, got %d\n", context);
8221     ok(!lstrcmpA(targetsid, "kiwi"),
8222        "Expected targetsid to be unchanged, got %s\n", targetsid);
8223     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8224
8225     RegDeleteValueA(hpatch, "State");
8226     RegDeleteKeyA(hpatch, "");
8227     RegCloseKey(hpatch);
8228     RegDeleteKeyA(udpatch, "");
8229     RegCloseKey(udpatch);
8230     RegDeleteKeyA(udprod, "");
8231     RegCloseKey(udprod);
8232     RegDeleteValueA(patches, "Patches");
8233     RegDeleteKeyA(patches, "");
8234     RegCloseKey(patches);
8235     RegDeleteKeyA(prodkey, "");
8236     RegCloseKey(prodkey);
8237
8238     /* MSIINSTALLCONTEXT_USERUNMANAGED */
8239
8240     /* MSIPATCHSTATE_APPLIED */
8241
8242     lstrcpyA(patchcode, "apple");
8243     lstrcpyA(targetprod, "banana");
8244     context = 0xdeadbeef;
8245     lstrcpyA(targetsid, "kiwi");
8246     size = MAX_PATH;
8247     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8248                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8249                            &context, targetsid, &size);
8250     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8251     ok(!lstrcmpA(patchcode, "apple"),
8252        "Expected patchcode to be unchanged, got %s\n", patchcode);
8253     ok(!lstrcmpA(targetprod, "banana"),
8254        "Expected targetprod to be unchanged, got %s\n", targetprod);
8255     ok(context == 0xdeadbeef,
8256        "Expected context to be unchanged, got %d\n", context);
8257     ok(!lstrcmpA(targetsid, "kiwi"),
8258        "Expected targetsid to be unchanged, got %s\n", targetsid);
8259     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8260
8261     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8262     lstrcatA(keypath, prod_squashed);
8263
8264     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8265     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8266
8267     /* current user product key exists */
8268     lstrcpyA(patchcode, "apple");
8269     lstrcpyA(targetprod, "banana");
8270     context = 0xdeadbeef;
8271     lstrcpyA(targetsid, "kiwi");
8272     size = MAX_PATH;
8273     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8274                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8275                            &context, targetsid, &size);
8276     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8277     ok(!lstrcmpA(patchcode, "apple"),
8278        "Expected patchcode to be unchanged, got %s\n", patchcode);
8279     ok(!lstrcmpA(targetprod, "banana"),
8280        "Expected targetprod to be unchanged, got %s\n", targetprod);
8281     ok(context == 0xdeadbeef,
8282        "Expected context to be unchanged, got %d\n", context);
8283     ok(!lstrcmpA(targetsid, "kiwi"),
8284        "Expected targetsid to be unchanged, got %s\n", targetsid);
8285     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8286
8287     res = RegCreateKeyA(prodkey, "Patches", &patches);
8288     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8289
8290     /* Patches key exists */
8291     lstrcpyA(patchcode, "apple");
8292     lstrcpyA(targetprod, "banana");
8293     context = 0xdeadbeef;
8294     lstrcpyA(targetsid, "kiwi");
8295     size = MAX_PATH;
8296     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8297                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8298                            &context, targetsid, &size);
8299     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8300     ok(!lstrcmpA(patchcode, "apple"),
8301        "Expected patchcode to be unchanged, got %s\n", patchcode);
8302     ok(!lstrcmpA(targetprod, "banana"),
8303        "Expected targetprod to be unchanged, got %s\n", targetprod);
8304     ok(context == 0xdeadbeef,
8305        "Expected context to be unchanged, got %d\n", context);
8306     ok(!lstrcmpA(targetsid, "kiwi"),
8307        "Expected targetsid to be unchanged, got %s\n", targetsid);
8308     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8309
8310     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8311                          (const BYTE *)patch_squashed,
8312                          lstrlenA(patch_squashed) + 1);
8313     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8314
8315     /* Patches value exists, is not REG_MULTI_SZ */
8316     lstrcpyA(patchcode, "apple");
8317     lstrcpyA(targetprod, "banana");
8318     context = 0xdeadbeef;
8319     lstrcpyA(targetsid, "kiwi");
8320     size = MAX_PATH;
8321     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8322                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8323                            &context, targetsid, &size);
8324     ok(r == ERROR_BAD_CONFIGURATION,
8325        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8326     ok(!lstrcmpA(patchcode, "apple"),
8327        "Expected patchcode to be unchanged, got %s\n", patchcode);
8328     ok(!lstrcmpA(targetprod, "banana"),
8329        "Expected targetprod to be unchanged, got %s\n", targetprod);
8330     ok(context == 0xdeadbeef,
8331        "Expected context to be unchanged, got %d\n", context);
8332     ok(!lstrcmpA(targetsid, "kiwi"),
8333        "Expected targetsid to be unchanged, got %s\n", targetsid);
8334     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8335
8336     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8337                          (const BYTE *)"a\0b\0c\0\0", 7);
8338     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8339
8340     /* Patches value exists, is not a squashed guid */
8341     lstrcpyA(patchcode, "apple");
8342     lstrcpyA(targetprod, "banana");
8343     context = 0xdeadbeef;
8344     lstrcpyA(targetsid, "kiwi");
8345     size = MAX_PATH;
8346     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8347                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8348                            &context, targetsid, &size);
8349     ok(r == ERROR_BAD_CONFIGURATION,
8350        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8351     ok(!lstrcmpA(patchcode, "apple"),
8352        "Expected patchcode to be unchanged, got %s\n", patchcode);
8353     ok(!lstrcmpA(targetprod, "banana"),
8354        "Expected targetprod to be unchanged, got %s\n", targetprod);
8355     ok(context == 0xdeadbeef,
8356        "Expected context to be unchanged, got %d\n", context);
8357     ok(!lstrcmpA(targetsid, "kiwi"),
8358        "Expected targetsid to be unchanged, got %s\n", targetsid);
8359     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8360
8361     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8362                          (const BYTE *)patch_squashed,
8363                          lstrlenA(patch_squashed) + 1);
8364     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8365
8366     /* Patches value exists */
8367     lstrcpyA(patchcode, "apple");
8368     lstrcpyA(targetprod, "banana");
8369     context = 0xdeadbeef;
8370     lstrcpyA(targetsid, "kiwi");
8371     size = MAX_PATH;
8372     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8373                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8374                            &context, targetsid, &size);
8375     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8376     ok(!lstrcmpA(patchcode, "apple"),
8377        "Expected patchcode to be unchanged, got %s\n", patchcode);
8378     ok(!lstrcmpA(targetprod, "banana"),
8379        "Expected targetprod to be unchanged, got %s\n", targetprod);
8380     ok(context == 0xdeadbeef,
8381        "Expected context to be unchanged, got %d\n", context);
8382     ok(!lstrcmpA(targetsid, "kiwi"),
8383        "Expected targetsid to be unchanged, got %s\n", targetsid);
8384     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8385
8386     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8387                          (const BYTE *)"whatever", 9);
8388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8389
8390     /* patch code value exists */
8391     lstrcpyA(patchcode, "apple");
8392     lstrcpyA(targetprod, "banana");
8393     context = 0xdeadbeef;
8394     lstrcpyA(targetsid, "kiwi");
8395     size = MAX_PATH;
8396     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8397                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8398                            &context, targetsid, &size);
8399     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8400     ok(!lstrcmpA(patchcode, "apple"),
8401        "Expected patchcode to be unchanged, got %s\n", patchcode);
8402     ok(!lstrcmpA(targetprod, "banana"),
8403        "Expected targetprod to be unchanged, got %s\n", targetprod);
8404     ok(context == 0xdeadbeef,
8405        "Expected context to be unchanged, got %d\n", context);
8406     ok(!lstrcmpA(targetsid, "kiwi"),
8407        "Expected targetsid to be unchanged, got %s\n", targetsid);
8408     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8409
8410     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8411     lstrcatA(keypath, usersid);
8412     lstrcatA(keypath, "\\Patches\\");
8413     lstrcatA(keypath, patch_squashed);
8414
8415     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
8416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8417
8418     /* userdata patch key exists */
8419     lstrcpyA(patchcode, "apple");
8420     lstrcpyA(targetprod, "banana");
8421     context = 0xdeadbeef;
8422     lstrcpyA(targetsid, "kiwi");
8423     size = MAX_PATH;
8424     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8425                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8426                            &context, targetsid, &size);
8427     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8428     ok(!lstrcmpA(patchcode, patch),
8429        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8430     ok(!lstrcmpA(targetprod, prodcode),
8431        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8432     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8433        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8434     ok(!lstrcmpA(targetsid, usersid),
8435        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8436     ok(size == lstrlenA(usersid),
8437        "Expected %d, got %d\n", lstrlenA(usersid), size);
8438
8439     /* MSIPATCHSTATE_SUPERSEDED */
8440
8441     lstrcpyA(patchcode, "apple");
8442     lstrcpyA(targetprod, "banana");
8443     context = 0xdeadbeef;
8444     lstrcpyA(targetsid, "kiwi");
8445     size = MAX_PATH;
8446     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8447                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8448                            &context, targetsid, &size);
8449     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8450     ok(!lstrcmpA(patchcode, "apple"),
8451        "Expected patchcode to be unchanged, got %s\n", patchcode);
8452     ok(!lstrcmpA(targetprod, "banana"),
8453        "Expected targetprod to be unchanged, got %s\n", targetprod);
8454     ok(context == 0xdeadbeef,
8455        "Expected context to be unchanged, got %d\n", context);
8456     ok(!lstrcmpA(targetsid, "kiwi"),
8457        "Expected targetsid to be unchanged, got %s\n", targetsid);
8458     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8459
8460     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8461     lstrcatA(keypath, usersid);
8462     lstrcatA(keypath, "\\Products\\");
8463     lstrcatA(keypath, prod_squashed);
8464
8465     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8466     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8467
8468     /* UserData product key exists */
8469     lstrcpyA(patchcode, "apple");
8470     lstrcpyA(targetprod, "banana");
8471     context = 0xdeadbeef;
8472     lstrcpyA(targetsid, "kiwi");
8473     size = MAX_PATH;
8474     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8475                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8476                            &context, targetsid, &size);
8477     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8478     ok(!lstrcmpA(patchcode, "apple"),
8479        "Expected patchcode to be unchanged, got %s\n", patchcode);
8480     ok(!lstrcmpA(targetprod, "banana"),
8481        "Expected targetprod to be unchanged, got %s\n", targetprod);
8482     ok(context == 0xdeadbeef,
8483        "Expected context to be unchanged, got %d\n", context);
8484     ok(!lstrcmpA(targetsid, "kiwi"),
8485        "Expected targetsid to be unchanged, got %s\n", targetsid);
8486     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8487
8488     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8489     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8490
8491     /* UserData patches key exists */
8492     lstrcpyA(patchcode, "apple");
8493     lstrcpyA(targetprod, "banana");
8494     context = 0xdeadbeef;
8495     lstrcpyA(targetsid, "kiwi");
8496     size = MAX_PATH;
8497     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8498                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8499                            &context, targetsid, &size);
8500     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8501     ok(!lstrcmpA(patchcode, "apple"),
8502        "Expected patchcode to be unchanged, got %s\n", patchcode);
8503     ok(!lstrcmpA(targetprod, "banana"),
8504        "Expected targetprod to be unchanged, got %s\n", targetprod);
8505     ok(context == 0xdeadbeef,
8506        "Expected context to be unchanged, got %d\n", context);
8507     ok(!lstrcmpA(targetsid, "kiwi"),
8508        "Expected targetsid to be unchanged, got %s\n", targetsid);
8509     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8510
8511     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8512     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8513
8514     /* specific UserData patch key exists */
8515     lstrcpyA(patchcode, "apple");
8516     lstrcpyA(targetprod, "banana");
8517     context = 0xdeadbeef;
8518     lstrcpyA(targetsid, "kiwi");
8519     size = MAX_PATH;
8520     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8521                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8522                            &context, targetsid, &size);
8523     ok(r == ERROR_BAD_CONFIGURATION,
8524        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8525     ok(!lstrcmpA(patchcode, "apple"),
8526        "Expected patchcode to be unchanged, got %s\n", patchcode);
8527     ok(!lstrcmpA(targetprod, "banana"),
8528        "Expected targetprod to be unchanged, got %s\n", targetprod);
8529     ok(context == 0xdeadbeef,
8530        "Expected context to be unchanged, got %d\n", context);
8531     ok(!lstrcmpA(targetsid, "kiwi"),
8532        "Expected targetsid to be unchanged, got %s\n", targetsid);
8533     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8534
8535     data = MSIPATCHSTATE_SUPERSEDED;
8536     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8537                          (const BYTE *)&data, sizeof(DWORD));
8538     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8539
8540     /* State value exists */
8541     lstrcpyA(patchcode, "apple");
8542     lstrcpyA(targetprod, "banana");
8543     context = 0xdeadbeef;
8544     lstrcpyA(targetsid, "kiwi");
8545     size = MAX_PATH;
8546     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8547                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8548                            &context, targetsid, &size);
8549     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8550     ok(!lstrcmpA(patchcode, patch),
8551        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8552     ok(!lstrcmpA(targetprod, prodcode),
8553        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8554     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8555        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8556     ok(!lstrcmpA(targetsid, usersid),
8557        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8558     ok(size == lstrlenA(usersid),
8559        "Expected %d, got %d\n", lstrlenA(usersid), size);
8560
8561     /* MSIPATCHSTATE_OBSOLETED */
8562
8563     lstrcpyA(patchcode, "apple");
8564     lstrcpyA(targetprod, "banana");
8565     context = 0xdeadbeef;
8566     lstrcpyA(targetsid, "kiwi");
8567     size = MAX_PATH;
8568     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8569                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8570                            &context, targetsid, &size);
8571     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8572     ok(!lstrcmpA(patchcode, "apple"),
8573        "Expected patchcode to be unchanged, got %s\n", patchcode);
8574     ok(!lstrcmpA(targetprod, "banana"),
8575        "Expected targetprod to be unchanged, got %s\n", targetprod);
8576     ok(context == 0xdeadbeef,
8577        "Expected context to be unchanged, got %d\n", context);
8578     ok(!lstrcmpA(targetsid, "kiwi"),
8579        "Expected targetsid to be unchanged, got %s\n", targetsid);
8580     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8581
8582     data = MSIPATCHSTATE_OBSOLETED;
8583     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8584                          (const BYTE *)&data, sizeof(DWORD));
8585     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8586
8587     /* State value is obsoleted */
8588     lstrcpyA(patchcode, "apple");
8589     lstrcpyA(targetprod, "banana");
8590     context = 0xdeadbeef;
8591     lstrcpyA(targetsid, "kiwi");
8592     size = MAX_PATH;
8593     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8594                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8595                            &context, targetsid, &size);
8596     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8597     ok(!lstrcmpA(patchcode, patch),
8598        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8599     ok(!lstrcmpA(targetprod, prodcode),
8600        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8601     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8602        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8603     ok(!lstrcmpA(targetsid, usersid),
8604        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8605     ok(size == lstrlenA(usersid),
8606        "Expected %d, got %d\n", lstrlenA(usersid), size);
8607
8608     /* MSIPATCHSTATE_REGISTERED */
8609     /* FIXME */
8610
8611     /* MSIPATCHSTATE_ALL */
8612
8613     /* 1st */
8614     lstrcpyA(patchcode, "apple");
8615     lstrcpyA(targetprod, "banana");
8616     context = 0xdeadbeef;
8617     lstrcpyA(targetsid, "kiwi");
8618     size = MAX_PATH;
8619     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8620                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8621                            &context, targetsid, &size);
8622     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8623     ok(!lstrcmpA(patchcode, patch),
8624        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8625     ok(!lstrcmpA(targetprod, prodcode),
8626        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8627     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8628        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8629     ok(!lstrcmpA(targetsid, usersid),
8630        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8631     ok(size == lstrlenA(usersid),
8632        "Expected %d, got %d\n", lstrlenA(usersid), size);
8633
8634     /* same patch in multiple places, only one is enumerated */
8635     lstrcpyA(patchcode, "apple");
8636     lstrcpyA(targetprod, "banana");
8637     context = 0xdeadbeef;
8638     lstrcpyA(targetsid, "kiwi");
8639     size = MAX_PATH;
8640     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8641                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8642                            &context, targetsid, &size);
8643     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8644     ok(!lstrcmpA(patchcode, "apple"),
8645        "Expected patchcode to be unchanged, got %s\n", patchcode);
8646     ok(!lstrcmpA(targetprod, "banana"),
8647        "Expected targetprod to be unchanged, got %s\n", targetprod);
8648     ok(context == 0xdeadbeef,
8649        "Expected context to be unchanged, got %d\n", context);
8650     ok(!lstrcmpA(targetsid, "kiwi"),
8651        "Expected targetsid to be unchanged, got %s\n", targetsid);
8652     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8653
8654     RegDeleteValueA(hpatch, "State");
8655     RegDeleteKeyA(hpatch, "");
8656     RegCloseKey(hpatch);
8657     RegDeleteKeyA(udpatch, "");
8658     RegCloseKey(udpatch);
8659     RegDeleteKeyA(userkey, "");
8660     RegCloseKey(userkey);
8661     RegDeleteValueA(patches, patch_squashed);
8662     RegDeleteValueA(patches, "Patches");
8663     RegDeleteKeyA(patches, "");
8664     RegCloseKey(patches);
8665     RegDeleteKeyA(prodkey, "");
8666     RegCloseKey(prodkey);
8667
8668     /* MSIINSTALLCONTEXT_MACHINE */
8669
8670     /* MSIPATCHSTATE_APPLIED */
8671
8672     lstrcpyA(patchcode, "apple");
8673     lstrcpyA(targetprod, "banana");
8674     context = 0xdeadbeef;
8675     lstrcpyA(targetsid, "kiwi");
8676     size = MAX_PATH;
8677     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8678                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8679                            &context, targetsid, &size);
8680     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8681     ok(!lstrcmpA(patchcode, "apple"),
8682        "Expected patchcode to be unchanged, got %s\n", patchcode);
8683     ok(!lstrcmpA(targetprod, "banana"),
8684        "Expected targetprod to be unchanged, got %s\n", targetprod);
8685     ok(context == 0xdeadbeef,
8686        "Expected context to be unchanged, got %d\n", context);
8687     ok(!lstrcmpA(targetsid, "kiwi"),
8688        "Expected targetsid to be unchanged, got %s\n", targetsid);
8689     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8690
8691     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8692     lstrcatA(keypath, prod_squashed);
8693
8694     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
8695     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8696
8697     /* local product key exists */
8698     lstrcpyA(patchcode, "apple");
8699     lstrcpyA(targetprod, "banana");
8700     context = 0xdeadbeef;
8701     lstrcpyA(targetsid, "kiwi");
8702     size = MAX_PATH;
8703     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8704                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8705                            &context, targetsid, &size);
8706     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8707     ok(!lstrcmpA(patchcode, "apple"),
8708        "Expected patchcode to be unchanged, got %s\n", patchcode);
8709     ok(!lstrcmpA(targetprod, "banana"),
8710        "Expected targetprod to be unchanged, got %s\n", targetprod);
8711     ok(context == 0xdeadbeef,
8712        "Expected context to be unchanged, got %d\n", context);
8713     ok(!lstrcmpA(targetsid, "kiwi"),
8714        "Expected targetsid to be unchanged, got %s\n", targetsid);
8715     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8716
8717     res = RegCreateKeyA(prodkey, "Patches", &patches);
8718     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8719
8720     /* Patches key exists */
8721     lstrcpyA(patchcode, "apple");
8722     lstrcpyA(targetprod, "banana");
8723     context = 0xdeadbeef;
8724     lstrcpyA(targetsid, "kiwi");
8725     size = MAX_PATH;
8726     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8727                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8728                            &context, targetsid, &size);
8729     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8730     ok(!lstrcmpA(patchcode, "apple"),
8731        "Expected patchcode to be unchanged, got %s\n", patchcode);
8732     ok(!lstrcmpA(targetprod, "banana"),
8733        "Expected targetprod to be unchanged, got %s\n", targetprod);
8734     ok(context == 0xdeadbeef,
8735        "Expected context to be unchanged, got %d\n", context);
8736     ok(!lstrcmpA(targetsid, "kiwi"),
8737        "Expected targetsid to be unchanged, got %s\n", targetsid);
8738     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8739
8740     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8741                          (const BYTE *)patch_squashed,
8742                          lstrlenA(patch_squashed) + 1);
8743     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8744
8745     /* Patches value exists, is not REG_MULTI_SZ */
8746     lstrcpyA(patchcode, "apple");
8747     lstrcpyA(targetprod, "banana");
8748     context = 0xdeadbeef;
8749     lstrcpyA(targetsid, "kiwi");
8750     size = MAX_PATH;
8751     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8752                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8753                            &context, targetsid, &size);
8754     ok(r == ERROR_BAD_CONFIGURATION,
8755        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8756     ok(!lstrcmpA(patchcode, "apple"),
8757        "Expected patchcode to be unchanged, got %s\n", patchcode);
8758     ok(!lstrcmpA(targetprod, "banana"),
8759        "Expected targetprod to be unchanged, got %s\n", targetprod);
8760     ok(context == 0xdeadbeef,
8761        "Expected context to be unchanged, got %d\n", context);
8762     ok(!lstrcmpA(targetsid, "kiwi"),
8763        "Expected targetsid to be unchanged, got %s\n", targetsid);
8764     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8765
8766     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8767                          (const BYTE *)"a\0b\0c\0\0", 7);
8768     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8769
8770     /* Patches value exists, is not a squashed guid */
8771     lstrcpyA(patchcode, "apple");
8772     lstrcpyA(targetprod, "banana");
8773     context = 0xdeadbeef;
8774     lstrcpyA(targetsid, "kiwi");
8775     size = MAX_PATH;
8776     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8777                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8778                            &context, targetsid, &size);
8779     ok(r == ERROR_BAD_CONFIGURATION,
8780        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8781     ok(!lstrcmpA(patchcode, "apple"),
8782        "Expected patchcode to be unchanged, got %s\n", patchcode);
8783     ok(!lstrcmpA(targetprod, "banana"),
8784        "Expected targetprod to be unchanged, got %s\n", targetprod);
8785     ok(context == 0xdeadbeef,
8786        "Expected context to be unchanged, got %d\n", context);
8787     ok(!lstrcmpA(targetsid, "kiwi"),
8788        "Expected targetsid to be unchanged, got %s\n", targetsid);
8789     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8790
8791     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8792     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8793                          (const BYTE *)patch_squashed,
8794                          lstrlenA(patch_squashed) + 2);
8795     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8796
8797     /* Patches value exists */
8798     lstrcpyA(patchcode, "apple");
8799     lstrcpyA(targetprod, "banana");
8800     context = 0xdeadbeef;
8801     lstrcpyA(targetsid, "kiwi");
8802     size = MAX_PATH;
8803     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8804                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8805                            &context, targetsid, &size);
8806     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8807     ok(!lstrcmpA(patchcode, "apple"),
8808        "Expected patchcode to be unchanged, got %s\n", patchcode);
8809     ok(!lstrcmpA(targetprod, "banana"),
8810        "Expected targetprod to be unchanged, got %s\n", targetprod);
8811     ok(context == 0xdeadbeef,
8812        "Expected context to be unchanged, got %d\n", context);
8813     ok(!lstrcmpA(targetsid, "kiwi"),
8814        "Expected targetsid to be unchanged, got %s\n", targetsid);
8815     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8816
8817     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8818                          (const BYTE *)"whatever", 9);
8819     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8820
8821     /* patch code value exists */
8822     lstrcpyA(patchcode, "apple");
8823     lstrcpyA(targetprod, "banana");
8824     context = 0xdeadbeef;
8825     lstrcpyA(targetsid, "kiwi");
8826     size = MAX_PATH;
8827     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8828                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8829                            &context, targetsid, &size);
8830     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8831     ok(!lstrcmpA(patchcode, patch),
8832        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8833     ok(!lstrcmpA(targetprod, prodcode),
8834        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8835     ok(context == MSIINSTALLCONTEXT_MACHINE,
8836        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8837     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8838     ok(size == 0, "Expected 0, got %d\n", size);
8839
8840     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8841     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8842     lstrcatA(keypath, prod_squashed);
8843
8844     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8845     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8846
8847     /* local UserData product key exists */
8848     lstrcpyA(patchcode, "apple");
8849     lstrcpyA(targetprod, "banana");
8850     context = 0xdeadbeef;
8851     lstrcpyA(targetsid, "kiwi");
8852     size = MAX_PATH;
8853     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8854                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8855                            &context, targetsid, &size);
8856     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8857     ok(!lstrcmpA(patchcode, patch),
8858        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8859     ok(!lstrcmpA(targetprod, prodcode),
8860        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8861     ok(context == MSIINSTALLCONTEXT_MACHINE,
8862        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8863     ok(!lstrcmpA(targetsid, ""),
8864        "Expected \"\", got \"%s\"\n", targetsid);
8865     ok(size == 0, "Expected 0, got %d\n", size);
8866
8867     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8868     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8869
8870     /* local UserData Patches key exists */
8871     lstrcpyA(patchcode, "apple");
8872     lstrcpyA(targetprod, "banana");
8873     context = 0xdeadbeef;
8874     lstrcpyA(targetsid, "kiwi");
8875     size = MAX_PATH;
8876     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8877                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8878                            &context, targetsid, &size);
8879     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8880     ok(!lstrcmpA(patchcode, patch),
8881        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8882     ok(!lstrcmpA(targetprod, prodcode),
8883        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8884     ok(context == MSIINSTALLCONTEXT_MACHINE,
8885        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8886     ok(!lstrcmpA(targetsid, ""),
8887        "Expected \"\", got \"%s\"\n", targetsid);
8888     ok(size == 0, "Expected 0, got %d\n", size);
8889
8890     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8891     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8892
8893     /* local UserData Product patch key exists */
8894     lstrcpyA(patchcode, "apple");
8895     lstrcpyA(targetprod, "banana");
8896     context = 0xdeadbeef;
8897     lstrcpyA(targetsid, "kiwi");
8898     size = MAX_PATH;
8899     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8900                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8901                            &context, targetsid, &size);
8902     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8903     ok(!lstrcmpA(patchcode, "apple"),
8904        "Expected patchcode to be unchanged, got %s\n", patchcode);
8905     ok(!lstrcmpA(targetprod, "banana"),
8906        "Expected targetprod to be unchanged, got %s\n", targetprod);
8907     ok(context == 0xdeadbeef,
8908        "Expected context to be unchanged, got %d\n", context);
8909     ok(!lstrcmpA(targetsid, "kiwi"),
8910        "Expected targetsid to be unchanged, got %s\n", targetsid);
8911     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8912
8913     data = MSIPATCHSTATE_APPLIED;
8914     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8915                          (const BYTE *)&data, sizeof(DWORD));
8916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8917
8918     /* State value exists */
8919     lstrcpyA(patchcode, "apple");
8920     lstrcpyA(targetprod, "banana");
8921     context = 0xdeadbeef;
8922     lstrcpyA(targetsid, "kiwi");
8923     size = MAX_PATH;
8924     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8925                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8926                            &context, targetsid, &size);
8927     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8928     ok(!lstrcmpA(patchcode, patch),
8929        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8930     ok(!lstrcmpA(targetprod, prodcode),
8931        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8932     ok(context == MSIINSTALLCONTEXT_MACHINE,
8933        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8934     ok(!lstrcmpA(targetsid, ""),
8935        "Expected \"\", got \"%s\"\n", targetsid);
8936     ok(size == 0, "Expected 0, got %d\n", size);
8937
8938     /* MSIPATCHSTATE_SUPERSEDED */
8939
8940     lstrcpyA(patchcode, "apple");
8941     lstrcpyA(targetprod, "banana");
8942     context = 0xdeadbeef;
8943     lstrcpyA(targetsid, "kiwi");
8944     size = MAX_PATH;
8945     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8946                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8947                            &context, targetsid, &size);
8948     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8949     ok(!lstrcmpA(patchcode, "apple"),
8950        "Expected patchcode to be unchanged, got %s\n", patchcode);
8951     ok(!lstrcmpA(targetprod, "banana"),
8952        "Expected targetprod to be unchanged, got %s\n", targetprod);
8953     ok(context == 0xdeadbeef,
8954        "Expected context to be unchanged, got %d\n", context);
8955     ok(!lstrcmpA(targetsid, "kiwi"),
8956        "Expected targetsid to be unchanged, got %s\n", targetsid);
8957     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8958
8959     data = MSIPATCHSTATE_SUPERSEDED;
8960     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8961                          (const BYTE *)&data, sizeof(DWORD));
8962     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8963
8964     /* State value is MSIPATCHSTATE_SUPERSEDED */
8965     lstrcpyA(patchcode, "apple");
8966     lstrcpyA(targetprod, "banana");
8967     context = 0xdeadbeef;
8968     lstrcpyA(targetsid, "kiwi");
8969     size = MAX_PATH;
8970     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8971                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8972                            &context, targetsid, &size);
8973     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8974     ok(!lstrcmpA(patchcode, patch),
8975        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8976     ok(!lstrcmpA(targetprod, prodcode),
8977        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8978     ok(context == MSIINSTALLCONTEXT_MACHINE,
8979        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8980     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8981     ok(size == 0, "Expected 0, got %d\n", size);
8982
8983     /* MSIPATCHSTATE_OBSOLETED */
8984
8985     lstrcpyA(patchcode, "apple");
8986     lstrcpyA(targetprod, "banana");
8987     context = 0xdeadbeef;
8988     lstrcpyA(targetsid, "kiwi");
8989     size = MAX_PATH;
8990     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8991                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8992                            &context, targetsid, &size);
8993     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8994     ok(!lstrcmpA(patchcode, "apple"),
8995        "Expected patchcode to be unchanged, got %s\n", patchcode);
8996     ok(!lstrcmpA(targetprod, "banana"),
8997        "Expected targetprod to be unchanged, got %s\n", targetprod);
8998     ok(context == 0xdeadbeef,
8999        "Expected context to be unchanged, got %d\n", context);
9000     ok(!lstrcmpA(targetsid, "kiwi"),
9001        "Expected targetsid to be unchanged, got %s\n", targetsid);
9002     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9003
9004     data = MSIPATCHSTATE_OBSOLETED;
9005     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9006                          (const BYTE *)&data, sizeof(DWORD));
9007     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9008
9009     /* State value is obsoleted */
9010     lstrcpyA(patchcode, "apple");
9011     lstrcpyA(targetprod, "banana");
9012     context = 0xdeadbeef;
9013     lstrcpyA(targetsid, "kiwi");
9014     size = MAX_PATH;
9015     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9016                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9017                            &context, targetsid, &size);
9018     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9019     ok(!lstrcmpA(patchcode, patch),
9020        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9021     ok(!lstrcmpA(targetprod, prodcode),
9022        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9023     ok(context == MSIINSTALLCONTEXT_MACHINE,
9024        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9025     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9026     ok(size == 0, "Expected 0, got %d\n", size);
9027
9028     /* MSIPATCHSTATE_REGISTERED */
9029     /* FIXME */
9030
9031     /* MSIPATCHSTATE_ALL */
9032
9033     /* 1st */
9034     lstrcpyA(patchcode, "apple");
9035     lstrcpyA(targetprod, "banana");
9036     context = 0xdeadbeef;
9037     lstrcpyA(targetsid, "kiwi");
9038     size = MAX_PATH;
9039     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9040                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9041                            &context, targetsid, &size);
9042     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9043     ok(!lstrcmpA(patchcode, patch),
9044        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9045     ok(!lstrcmpA(targetprod, prodcode),
9046        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9047     ok(context == MSIINSTALLCONTEXT_MACHINE,
9048        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9049     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9050     ok(size == 0, "Expected 0, got %d\n", size);
9051
9052     /* same patch in multiple places, only one is enumerated */
9053     lstrcpyA(patchcode, "apple");
9054     lstrcpyA(targetprod, "banana");
9055     context = 0xdeadbeef;
9056     lstrcpyA(targetsid, "kiwi");
9057     size = MAX_PATH;
9058     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9059                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9060                            &context, targetsid, &size);
9061     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9062     ok(!lstrcmpA(patchcode, "apple"),
9063        "Expected patchcode to be unchanged, got %s\n", patchcode);
9064     ok(!lstrcmpA(targetprod, "banana"),
9065        "Expected targetprod to be unchanged, got %s\n", targetprod);
9066     ok(context == 0xdeadbeef,
9067        "Expected context to be unchanged, got %d\n", context);
9068     ok(!lstrcmpA(targetsid, "kiwi"),
9069        "Expected targetsid to be unchanged, got %s\n", targetsid);
9070     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9071
9072     RegDeleteValueA(patches, patch_squashed);
9073     RegDeleteValueA(patches, "Patches");
9074     RegDeleteKeyA(patches, "");
9075     RegCloseKey(patches);
9076     RegDeleteValueA(hpatch, "State");
9077     RegDeleteKeyA(hpatch, "");
9078     RegCloseKey(hpatch);
9079     RegDeleteKeyA(udpatch, "");
9080     RegCloseKey(udpatch);
9081     RegDeleteKeyA(udprod, "");
9082     RegCloseKey(udprod);
9083     RegDeleteKeyA(prodkey, "");
9084     RegCloseKey(prodkey);
9085 }
9086
9087 static void test_MsiEnumPatches(void)
9088 {
9089     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9090     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9091     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9092     CHAR transforms[MAX_PATH];
9093     HKEY prodkey, patches, udprod;
9094     HKEY userkey, hpatch, udpatch;
9095     DWORD size, data;
9096     LPSTR usersid;
9097     LONG res;
9098     UINT r;
9099
9100     create_test_guid(prodcode, prod_squashed);
9101     create_test_guid(patchcode, patch_squashed);
9102     get_user_sid(&usersid);
9103
9104     /* NULL szProduct */
9105     size = MAX_PATH;
9106     lstrcpyA(patch, "apple");
9107     lstrcpyA(transforms, "banana");
9108     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9109     ok(r == ERROR_INVALID_PARAMETER,
9110        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9111     ok(!lstrcmpA(patch, "apple"),
9112        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9113     ok(!lstrcmpA(transforms, "banana"),
9114        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9115     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9116
9117     /* empty szProduct */
9118     size = MAX_PATH;
9119     lstrcpyA(patch, "apple");
9120     lstrcpyA(transforms, "banana");
9121     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9122     ok(r == ERROR_INVALID_PARAMETER,
9123        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9124     ok(!lstrcmpA(patch, "apple"),
9125        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9126     ok(!lstrcmpA(transforms, "banana"),
9127        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9128     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9129
9130     /* garbage szProduct */
9131     size = MAX_PATH;
9132     lstrcpyA(patch, "apple");
9133     lstrcpyA(transforms, "banana");
9134     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9135     ok(r == ERROR_INVALID_PARAMETER,
9136        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9137     ok(!lstrcmpA(patch, "apple"),
9138        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9139     ok(!lstrcmpA(transforms, "banana"),
9140        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9141     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9142
9143     /* guid without brackets */
9144     size = MAX_PATH;
9145     lstrcpyA(patch, "apple");
9146     lstrcpyA(transforms, "banana");
9147     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9148                         transforms, &size);
9149     ok(r == ERROR_INVALID_PARAMETER,
9150        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9151     ok(!lstrcmpA(patch, "apple"),
9152        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9153     ok(!lstrcmpA(transforms, "banana"),
9154        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9155     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9156
9157     /* guid with brackets */
9158     size = MAX_PATH;
9159     lstrcpyA(patch, "apple");
9160     lstrcpyA(transforms, "banana");
9161     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9162                         transforms, &size);
9163     ok(r == ERROR_UNKNOWN_PRODUCT,
9164        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9165     ok(!lstrcmpA(patch, "apple"),
9166        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9167     ok(!lstrcmpA(transforms, "banana"),
9168        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9169     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9170
9171     /* same length as guid, but random */
9172     size = MAX_PATH;
9173     lstrcpyA(patch, "apple");
9174     lstrcpyA(transforms, "banana");
9175     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9176                         transforms, &size);
9177     ok(r == ERROR_INVALID_PARAMETER,
9178        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9179     ok(!lstrcmpA(patch, "apple"),
9180        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9181     ok(!lstrcmpA(transforms, "banana"),
9182        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9183     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9184
9185     /* MSIINSTALLCONTEXT_USERMANAGED */
9186
9187     size = MAX_PATH;
9188     lstrcpyA(patch, "apple");
9189     lstrcpyA(transforms, "banana");
9190     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9191     ok(r == ERROR_UNKNOWN_PRODUCT,
9192        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9193     ok(!lstrcmpA(patch, "apple"),
9194        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9195     ok(!lstrcmpA(transforms, "banana"),
9196        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9197     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9198
9199     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9200     lstrcatA(keypath, usersid);
9201     lstrcatA(keypath, "\\Installer\\Products\\");
9202     lstrcatA(keypath, prod_squashed);
9203
9204     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9205     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9206
9207     /* managed product key exists */
9208     size = MAX_PATH;
9209     lstrcpyA(patch, "apple");
9210     lstrcpyA(transforms, "banana");
9211     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9212     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9213     ok(!lstrcmpA(patch, "apple"),
9214        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9215     ok(!lstrcmpA(transforms, "banana"),
9216        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9217     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9218
9219     res = RegCreateKeyA(prodkey, "Patches", &patches);
9220     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9221
9222     /* patches key exists */
9223     size = MAX_PATH;
9224     lstrcpyA(patch, "apple");
9225     lstrcpyA(transforms, "banana");
9226     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9227     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9228     ok(!lstrcmpA(patch, "apple"),
9229        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9230     ok(!lstrcmpA(transforms, "banana"),
9231        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9232     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9233
9234     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9235                          (const BYTE *)patch_squashed,
9236                          lstrlenA(patch_squashed) + 1);
9237     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9238
9239     /* Patches value exists, is not REG_MULTI_SZ */
9240     size = MAX_PATH;
9241     lstrcpyA(patch, "apple");
9242     lstrcpyA(transforms, "banana");
9243     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9244     ok(r == ERROR_BAD_CONFIGURATION,
9245        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9246     ok(!lstrcmpA(patch, "apple"),
9247        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9248     ok(!lstrcmpA(transforms, "banana"),
9249        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9250     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9251
9252     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9253                          (const BYTE *)"a\0b\0c\0\0", 7);
9254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9255
9256     /* Patches value exists, is not a squashed guid */
9257     size = MAX_PATH;
9258     lstrcpyA(patch, "apple");
9259     lstrcpyA(transforms, "banana");
9260     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9261     ok(r == ERROR_BAD_CONFIGURATION,
9262        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9263     ok(!lstrcmpA(patch, "apple"),
9264        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9265     ok(!lstrcmpA(transforms, "banana"),
9266        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9267     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9268
9269     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9270     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9271                          (const BYTE *)patch_squashed,
9272                          lstrlenA(patch_squashed) + 2);
9273     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9274
9275     /* Patches value exists */
9276     size = MAX_PATH;
9277     lstrcpyA(patch, "apple");
9278     lstrcpyA(transforms, "banana");
9279     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9280     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9281     ok(!lstrcmpA(patch, "apple"),
9282        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9283     ok(!lstrcmpA(transforms, "banana"),
9284        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9285     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9286
9287     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9288                          (const BYTE *)"whatever", 9);
9289     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9290
9291     /* patch squashed value exists */
9292     size = MAX_PATH;
9293     lstrcpyA(patch, "apple");
9294     lstrcpyA(transforms, "banana");
9295     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9296     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9297     ok(!lstrcmpA(patch, patchcode),
9298        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9299     ok(!lstrcmpA(transforms, "whatever"),
9300        "Expected \"whatever\", got \"%s\"\n", transforms);
9301     ok(size == 8, "Expected 8, got %d\n", size);
9302
9303     /* lpPatchBuf is NULL */
9304     size = MAX_PATH;
9305     lstrcpyA(transforms, "banana");
9306     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9307     ok(r == ERROR_INVALID_PARAMETER,
9308        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9309     ok(!lstrcmpA(transforms, "banana"),
9310        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9311     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9312
9313     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9314     size = MAX_PATH;
9315     lstrcpyA(patch, "apple");
9316     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9317     ok(r == ERROR_INVALID_PARAMETER,
9318        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9319     ok(!lstrcmpA(patch, "apple"),
9320        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9321     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9322
9323     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9324     lstrcpyA(patch, "apple");
9325     lstrcpyA(transforms, "banana");
9326     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9327     ok(r == ERROR_INVALID_PARAMETER,
9328        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9329     ok(!lstrcmpA(patch, "apple"),
9330        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9331     ok(!lstrcmpA(transforms, "banana"),
9332        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9333
9334     /* pcchTransformsBuf is too small */
9335     size = 6;
9336     lstrcpyA(patch, "apple");
9337     lstrcpyA(transforms, "banana");
9338     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9339     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9340     ok(!lstrcmpA(patch, patchcode),
9341        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9342     ok(!lstrcmpA(transforms, "whate"),
9343        "Expected \"whate\", got \"%s\"\n", transforms);
9344     ok(size == 16, "Expected 16, got %d\n", size);
9345
9346     /* increase the index */
9347     size = MAX_PATH;
9348     lstrcpyA(patch, "apple");
9349     lstrcpyA(transforms, "banana");
9350     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9351     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9352     ok(!lstrcmpA(patch, "apple"),
9353        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9354     ok(!lstrcmpA(transforms, "banana"),
9355        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9356     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9357
9358     /* increase again */
9359     size = MAX_PATH;
9360     lstrcpyA(patch, "apple");
9361     lstrcpyA(transforms, "banana");
9362     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9363     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9364     ok(!lstrcmpA(patch, "apple"),
9365        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9366     ok(!lstrcmpA(transforms, "banana"),
9367        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9368     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9369
9370     RegDeleteValueA(patches, "Patches");
9371     RegDeleteKeyA(patches, "");
9372     RegCloseKey(patches);
9373     RegDeleteKeyA(prodkey, "");
9374     RegCloseKey(prodkey);
9375
9376     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9377
9378     size = MAX_PATH;
9379     lstrcpyA(patch, "apple");
9380     lstrcpyA(transforms, "banana");
9381     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9382     ok(r == ERROR_UNKNOWN_PRODUCT,
9383        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9384     ok(!lstrcmpA(patch, "apple"),
9385        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9386     ok(!lstrcmpA(transforms, "banana"),
9387        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9388     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9389
9390     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9391     lstrcatA(keypath, prod_squashed);
9392
9393     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9395
9396     /* current user product key exists */
9397     size = MAX_PATH;
9398     lstrcpyA(patch, "apple");
9399     lstrcpyA(transforms, "banana");
9400     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9401     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9402     ok(!lstrcmpA(patch, "apple"),
9403        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9404     ok(!lstrcmpA(transforms, "banana"),
9405        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9406     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9407
9408     res = RegCreateKeyA(prodkey, "Patches", &patches);
9409     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9410
9411     /* Patches key exists */
9412     size = MAX_PATH;
9413     lstrcpyA(patch, "apple");
9414     lstrcpyA(transforms, "banana");
9415     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9416     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9417     ok(!lstrcmpA(patch, "apple"),
9418        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9419     ok(!lstrcmpA(transforms, "banana"),
9420        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9421     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9422
9423     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9424                          (const BYTE *)patch_squashed,
9425                          lstrlenA(patch_squashed) + 1);
9426     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9427
9428     /* Patches value exists, is not REG_MULTI_SZ */
9429     size = MAX_PATH;
9430     lstrcpyA(patch, "apple");
9431     lstrcpyA(transforms, "banana");
9432     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9433     ok(r == ERROR_BAD_CONFIGURATION,
9434        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9435     ok(!lstrcmpA(patch, "apple"),
9436        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9437     ok(!lstrcmpA(transforms, "banana"),
9438        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9439     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9440
9441     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9442                          (const BYTE *)"a\0b\0c\0\0", 7);
9443     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9444
9445     /* Patches value exists, is not a squashed guid */
9446     size = MAX_PATH;
9447     lstrcpyA(patch, "apple");
9448     lstrcpyA(transforms, "banana");
9449     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9450     ok(r == ERROR_BAD_CONFIGURATION,
9451        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9452     ok(!lstrcmpA(patch, "apple"),
9453        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9454     ok(!lstrcmpA(transforms, "banana"),
9455        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9456     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9457
9458     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9459     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9460                          (const BYTE *)patch_squashed,
9461                          lstrlenA(patch_squashed) + 2);
9462     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9463
9464     /* Patches value exists */
9465     size = MAX_PATH;
9466     lstrcpyA(patch, "apple");
9467     lstrcpyA(transforms, "banana");
9468     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9469     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9470     ok(!lstrcmpA(patch, "apple"),
9471        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9472     ok(!lstrcmpA(transforms, "banana"),
9473        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9474     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9475
9476     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9477                          (const BYTE *)"whatever", 9);
9478     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9479
9480     /* patch code value exists */
9481     size = MAX_PATH;
9482     lstrcpyA(patch, "apple");
9483     lstrcpyA(transforms, "banana");
9484     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9485     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9486     ok(!lstrcmpA(patch, "apple"),
9487        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9488     ok(!lstrcmpA(transforms, "banana"),
9489        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9490     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9491
9492     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9493     lstrcatA(keypath, usersid);
9494     lstrcatA(keypath, "\\Patches\\");
9495     lstrcatA(keypath, patch_squashed);
9496
9497     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
9498     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9499
9500     /* userdata patch key exists */
9501     size = MAX_PATH;
9502     lstrcpyA(patch, "apple");
9503     lstrcpyA(transforms, "banana");
9504     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9505     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9506     ok(!lstrcmpA(patch, patchcode),
9507        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9508     ok(!lstrcmpA(transforms, "whatever"),
9509        "Expected \"whatever\", got \"%s\"\n", transforms);
9510     ok(size == 8, "Expected 8, got %d\n", size);
9511
9512     RegDeleteKeyA(userkey, "");
9513     RegCloseKey(userkey);
9514     RegDeleteValueA(patches, patch_squashed);
9515     RegDeleteValueA(patches, "Patches");
9516     RegDeleteKeyA(patches, "");
9517     RegCloseKey(patches);
9518     RegDeleteKeyA(prodkey, "");
9519     RegCloseKey(prodkey);
9520
9521     /* MSIINSTALLCONTEXT_MACHINE */
9522
9523     size = MAX_PATH;
9524     lstrcpyA(patch, "apple");
9525     lstrcpyA(transforms, "banana");
9526     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9527     ok(r == ERROR_UNKNOWN_PRODUCT,
9528        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9529     ok(!lstrcmpA(patch, "apple"),
9530        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9531     ok(!lstrcmpA(transforms, "banana"),
9532        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9533     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9534
9535     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9536     lstrcatA(keypath, prod_squashed);
9537
9538     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9539     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9540
9541     /* local product key exists */
9542     size = MAX_PATH;
9543     lstrcpyA(patch, "apple");
9544     lstrcpyA(transforms, "banana");
9545     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9546     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9547     ok(!lstrcmpA(patch, "apple"),
9548        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9549     ok(!lstrcmpA(transforms, "banana"),
9550        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9551     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9552
9553     res = RegCreateKeyA(prodkey, "Patches", &patches);
9554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9555
9556     /* Patches key exists */
9557     size = MAX_PATH;
9558     lstrcpyA(patch, "apple");
9559     lstrcpyA(transforms, "banana");
9560     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9561     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, 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     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9569                          (const BYTE *)patch_squashed,
9570                          lstrlenA(patch_squashed) + 1);
9571     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9572
9573     /* Patches value exists, is not REG_MULTI_SZ */
9574     size = MAX_PATH;
9575     lstrcpyA(patch, "apple");
9576     lstrcpyA(transforms, "banana");
9577     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9578     ok(r == ERROR_BAD_CONFIGURATION,
9579        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9580     ok(!lstrcmpA(patch, "apple"),
9581        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9582     ok(!lstrcmpA(transforms, "banana"),
9583        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9584     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9585
9586     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9587                          (const BYTE *)"a\0b\0c\0\0", 7);
9588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9589
9590     /* Patches value exists, is not a squashed guid */
9591     size = MAX_PATH;
9592     lstrcpyA(patch, "apple");
9593     lstrcpyA(transforms, "banana");
9594     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9595     ok(r == ERROR_BAD_CONFIGURATION,
9596        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9597     ok(!lstrcmpA(patch, "apple"),
9598        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9599     ok(!lstrcmpA(transforms, "banana"),
9600        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9601     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9602
9603     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9604     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9605                          (const BYTE *)patch_squashed,
9606                          lstrlenA(patch_squashed) + 2);
9607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9608
9609     /* Patches value exists */
9610     size = MAX_PATH;
9611     lstrcpyA(patch, "apple");
9612     lstrcpyA(transforms, "banana");
9613     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9614     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9615     ok(!lstrcmpA(patch, "apple"),
9616        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9617     ok(!lstrcmpA(transforms, "banana"),
9618        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9619     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9620
9621     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9622                          (const BYTE *)"whatever", 9);
9623     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9624
9625     /* patch code value exists */
9626     size = MAX_PATH;
9627     lstrcpyA(patch, "apple");
9628     lstrcpyA(transforms, "banana");
9629     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9630     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9631     ok(!lstrcmpA(patch, patchcode),
9632        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9633     ok(!lstrcmpA(transforms, "whatever"),
9634        "Expected \"whatever\", got \"%s\"\n", transforms);
9635     ok(size == 8, "Expected 8, got %d\n", size);
9636
9637     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9638     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9639     lstrcatA(keypath, prod_squashed);
9640
9641     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9642     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9643
9644     /* local UserData product key exists */
9645     size = MAX_PATH;
9646     lstrcpyA(patch, "apple");
9647     lstrcpyA(transforms, "banana");
9648     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9649     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9650     ok(!lstrcmpA(patch, patchcode),
9651        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9652     ok(!lstrcmpA(transforms, "whatever"),
9653        "Expected \"whatever\", got \"%s\"\n", transforms);
9654     ok(size == 8, "Expected 8, got %d\n", size);
9655
9656     res = RegCreateKeyA(udprod, "Patches", &udpatch);
9657     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9658
9659     /* local UserData Patches key exists */
9660     size = MAX_PATH;
9661     lstrcpyA(patch, "apple");
9662     lstrcpyA(transforms, "banana");
9663     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9664     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9665     ok(!lstrcmpA(patch, patchcode),
9666        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9667     ok(!lstrcmpA(transforms, "whatever"),
9668        "Expected \"whatever\", got \"%s\"\n", transforms);
9669     ok(size == 8, "Expected 8, got %d\n", size);
9670
9671     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
9672     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9673
9674     /* local UserData Product patch key exists */
9675     size = MAX_PATH;
9676     lstrcpyA(patch, "apple");
9677     lstrcpyA(transforms, "banana");
9678     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9679     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9680     ok(!lstrcmpA(patch, "apple"),
9681        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9682     ok(!lstrcmpA(transforms, "banana"),
9683        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9684     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9685
9686     data = MSIPATCHSTATE_APPLIED;
9687     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9688                          (const BYTE *)&data, sizeof(DWORD));
9689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9690
9691     /* State value exists */
9692     size = MAX_PATH;
9693     lstrcpyA(patch, "apple");
9694     lstrcpyA(transforms, "banana");
9695     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9696     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9697     ok(!lstrcmpA(patch, patchcode),
9698        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9699     ok(!lstrcmpA(transforms, "whatever"),
9700        "Expected \"whatever\", got \"%s\"\n", transforms);
9701     ok(size == 8, "Expected 8, got %d\n", size);
9702
9703     RegDeleteValueA(patches, patch_squashed);
9704     RegDeleteValueA(patches, "Patches");
9705     RegDeleteKeyA(patches, "");
9706     RegCloseKey(patches);
9707     RegDeleteValueA(hpatch, "State");
9708     RegDeleteKeyA(hpatch, "");
9709     RegCloseKey(hpatch);
9710     RegDeleteKeyA(udpatch, "");
9711     RegCloseKey(udpatch);
9712     RegDeleteKeyA(udprod, "");
9713     RegCloseKey(udprod);
9714     RegDeleteKeyA(prodkey, "");
9715     RegCloseKey(prodkey);
9716 }
9717
9718 static void test_MsiGetPatchInfoEx(void)
9719 {
9720     CHAR keypath[MAX_PATH], val[MAX_PATH];
9721     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9722     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9723     HKEY prodkey, patches, udprod, props;
9724     HKEY hpatch, udpatch, prodpatches;
9725     LPSTR usersid;
9726     DWORD size;
9727     LONG res;
9728     UINT r;
9729
9730     if (!pMsiGetPatchInfoExA)
9731     {
9732         win_skip("MsiGetPatchInfoEx not implemented\n");
9733         return;
9734     }
9735
9736     create_test_guid(prodcode, prod_squashed);
9737     create_test_guid(patchcode, patch_squashed);
9738     get_user_sid(&usersid);
9739
9740     /* NULL szPatchCode */
9741     lstrcpyA(val, "apple");
9742     size = MAX_PATH;
9743     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9744                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9745     ok(r == ERROR_INVALID_PARAMETER,
9746        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9747     ok(!lstrcmpA(val, "apple"),
9748        "Expected val to be unchanged, got \"%s\"\n", val);
9749     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9750
9751     /* empty szPatchCode */
9752     size = MAX_PATH;
9753     lstrcpyA(val, "apple");
9754     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9755                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9756     ok(r == ERROR_INVALID_PARAMETER,
9757        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9758     ok(!lstrcmpA(val, "apple"),
9759        "Expected val to be unchanged, got \"%s\"\n", val);
9760     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9761
9762     /* garbage szPatchCode */
9763     size = MAX_PATH;
9764     lstrcpyA(val, "apple");
9765     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
9766                             MSIINSTALLCONTEXT_USERMANAGED,
9767                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9768     ok(r == ERROR_INVALID_PARAMETER,
9769        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9770     ok(!lstrcmpA(val, "apple"),
9771        "Expected val to be unchanged, got \"%s\"\n", val);
9772     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9773
9774     /* guid without brackets */
9775     size = MAX_PATH;
9776     lstrcpyA(val, "apple");
9777     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
9778                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9779                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9780     ok(r == ERROR_INVALID_PARAMETER,
9781        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9782     ok(!lstrcmpA(val, "apple"),
9783        "Expected val to be unchanged, got \"%s\"\n", val);
9784     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9785
9786     /* guid with brackets */
9787     size = MAX_PATH;
9788     lstrcpyA(val, "apple");
9789     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
9790                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9791                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9792     ok(r == ERROR_UNKNOWN_PRODUCT,
9793        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9794     ok(!lstrcmpA(val, "apple"),
9795        "Expected val to be unchanged, got \"%s\"\n", val);
9796     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9797
9798     /* same length as guid, but random */
9799     size = MAX_PATH;
9800     lstrcpyA(val, "apple");
9801     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
9802                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9803                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9804     ok(r == ERROR_INVALID_PARAMETER,
9805        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9806     ok(!lstrcmpA(val, "apple"),
9807        "Expected val to be unchanged, got \"%s\"\n", val);
9808     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9809
9810     /* NULL szProductCode */
9811     lstrcpyA(val, "apple");
9812     size = MAX_PATH;
9813     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9814                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9815     ok(r == ERROR_INVALID_PARAMETER,
9816        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9817     ok(!lstrcmpA(val, "apple"),
9818        "Expected val to be unchanged, got \"%s\"\n", val);
9819     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9820
9821     /* empty szProductCode */
9822     size = MAX_PATH;
9823     lstrcpyA(val, "apple");
9824     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
9825                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9826     ok(r == ERROR_INVALID_PARAMETER,
9827        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9828     ok(!lstrcmpA(val, "apple"),
9829        "Expected val to be unchanged, got \"%s\"\n", val);
9830     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9831
9832     /* garbage szProductCode */
9833     size = MAX_PATH;
9834     lstrcpyA(val, "apple");
9835     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
9836                             MSIINSTALLCONTEXT_USERMANAGED,
9837                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9838     ok(r == ERROR_INVALID_PARAMETER,
9839        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9840     ok(!lstrcmpA(val, "apple"),
9841        "Expected val to be unchanged, got \"%s\"\n", val);
9842     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9843
9844     /* guid without brackets */
9845     size = MAX_PATH;
9846     lstrcpyA(val, "apple");
9847     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
9848                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9849                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9850     ok(r == ERROR_INVALID_PARAMETER,
9851        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9852     ok(!lstrcmpA(val, "apple"),
9853        "Expected val to be unchanged, got \"%s\"\n", val);
9854     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9855
9856     /* guid with brackets */
9857     size = MAX_PATH;
9858     lstrcpyA(val, "apple");
9859     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
9860                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9861                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9862     ok(r == ERROR_UNKNOWN_PRODUCT,
9863        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9864     ok(!lstrcmpA(val, "apple"),
9865        "Expected val to be unchanged, got \"%s\"\n", val);
9866     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9867
9868     /* same length as guid, but random */
9869     size = MAX_PATH;
9870     lstrcpyA(val, "apple");
9871     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
9872                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9873                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9874     ok(r == ERROR_INVALID_PARAMETER,
9875        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9876     ok(!lstrcmpA(val, "apple"),
9877        "Expected val to be unchanged, got \"%s\"\n", val);
9878     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9879
9880     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
9881     size = MAX_PATH;
9882     lstrcpyA(val, "apple");
9883     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9884                             MSIINSTALLCONTEXT_USERMANAGED,
9885                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9886     ok(r == ERROR_INVALID_PARAMETER,
9887        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9888     ok(!lstrcmpA(val, "apple"),
9889        "Expected val to be unchanged, got \"%s\"\n", val);
9890     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9891
9892     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
9893     size = MAX_PATH;
9894     lstrcpyA(val, "apple");
9895     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9896                             MSIINSTALLCONTEXT_USERUNMANAGED,
9897                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9898     ok(r == ERROR_INVALID_PARAMETER,
9899        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9900     ok(!lstrcmpA(val, "apple"),
9901        "Expected val to be unchanged, got \"%s\"\n", val);
9902     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9903
9904     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
9905     size = MAX_PATH;
9906     lstrcpyA(val, "apple");
9907     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9908                             MSIINSTALLCONTEXT_MACHINE,
9909                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9910     ok(r == ERROR_INVALID_PARAMETER,
9911        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9912     ok(!lstrcmpA(val, "apple"),
9913        "Expected val to be unchanged, got \"%s\"\n", val);
9914     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9915
9916     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
9917     size = MAX_PATH;
9918     lstrcpyA(val, "apple");
9919     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9920                             MSIINSTALLCONTEXT_MACHINE,
9921                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9922     ok(r == ERROR_INVALID_PARAMETER,
9923        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9924     ok(!lstrcmpA(val, "apple"),
9925        "Expected val to be unchanged, got \"%s\"\n", val);
9926     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9927
9928     /* dwContext is out of range */
9929     size = MAX_PATH;
9930     lstrcpyA(val, "apple");
9931     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9932                             MSIINSTALLCONTEXT_NONE,
9933                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9934     ok(r == ERROR_INVALID_PARAMETER,
9935        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9936     ok(!lstrcmpA(val, "apple"),
9937        "Expected val to be unchanged, got \"%s\"\n", val);
9938     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9939
9940     /* dwContext is out of range */
9941     size = MAX_PATH;
9942     lstrcpyA(val, "apple");
9943     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9944                             MSIINSTALLCONTEXT_ALL,
9945                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9946     ok(r == ERROR_INVALID_PARAMETER,
9947        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9948     ok(!lstrcmpA(val, "apple"),
9949        "Expected val to be unchanged, got \"%s\"\n", val);
9950     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9951
9952     /* dwContext is invalid */
9953     size = MAX_PATH;
9954     lstrcpyA(val, "apple");
9955     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
9956                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9957     ok(r == ERROR_INVALID_PARAMETER,
9958        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9959     ok(!lstrcmpA(val, "apple"),
9960        "Expected val to be unchanged, got \"%s\"\n", val);
9961     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9962
9963     /* MSIINSTALLCONTEXT_USERMANAGED */
9964
9965     size = MAX_PATH;
9966     lstrcpyA(val, "apple");
9967     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9968                             MSIINSTALLCONTEXT_USERMANAGED,
9969                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9970     ok(r == ERROR_UNKNOWN_PRODUCT,
9971        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9972     ok(!lstrcmpA(val, "apple"),
9973        "Expected val to be unchanged, got \"%s\"\n", val);
9974     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9975
9976     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9977     lstrcatA(keypath, usersid);
9978     lstrcatA(keypath, "\\Products\\");
9979     lstrcatA(keypath, prod_squashed);
9980
9981     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9982     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9983
9984     /* local UserData product key exists */
9985     size = MAX_PATH;
9986     lstrcpyA(val, "apple");
9987     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9988                             MSIINSTALLCONTEXT_USERMANAGED,
9989                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9990     ok(r == ERROR_UNKNOWN_PRODUCT,
9991        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9992     ok(!lstrcmpA(val, "apple"),
9993        "Expected val to be unchanged, got \"%s\"\n", val);
9994     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9995
9996     res = RegCreateKeyA(udprod, "InstallProperties", &props);
9997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9998
9999     /* InstallProperties key exists */
10000     size = MAX_PATH;
10001     lstrcpyA(val, "apple");
10002     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10003                             MSIINSTALLCONTEXT_USERMANAGED,
10004                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10005     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10006     ok(!lstrcmpA(val, "apple"),
10007        "Expected val to be unchanged, got \"%s\"\n", val);
10008     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10009
10010     res = RegCreateKeyA(udprod, "Patches", &patches);
10011     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10012
10013     /* Patches key exists */
10014     size = MAX_PATH;
10015     lstrcpyA(val, "apple");
10016     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10017                             MSIINSTALLCONTEXT_USERMANAGED,
10018                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10019     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10020     ok(!lstrcmpA(val, "apple"),
10021        "Expected val to be unchanged, got \"%s\"\n", val);
10022     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10023
10024     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10025     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10026
10027     /* Patches key exists */
10028     size = MAX_PATH;
10029     lstrcpyA(val, "apple");
10030     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10031                             MSIINSTALLCONTEXT_USERMANAGED,
10032                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10033     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10034     ok(!lstrcmpA(val, "apple"),
10035        "Expected val to be unchanged, got \"%s\"\n", val);
10036     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10037
10038     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10039     lstrcatA(keypath, usersid);
10040     lstrcatA(keypath, "\\Installer\\Products\\");
10041     lstrcatA(keypath, prod_squashed);
10042
10043     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10044     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10045
10046     /* managed product key exists */
10047     size = MAX_PATH;
10048     lstrcpyA(val, "apple");
10049     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10050                             MSIINSTALLCONTEXT_USERMANAGED,
10051                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10052     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10053     ok(!lstrcmpA(val, "apple"),
10054        "Expected val to be unchanged, got \"%s\"\n", val);
10055     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10056
10057     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10058     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10059
10060     /* Patches key exists */
10061     size = MAX_PATH;
10062     lstrcpyA(val, "apple");
10063     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10064                             MSIINSTALLCONTEXT_USERMANAGED,
10065                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10066     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10067     ok(!lstrcmpA(val, "apple"),
10068        "Expected val to be unchanged, got \"%s\"\n", val);
10069     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10070
10071     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10072                          (const BYTE *)"transforms", 11);
10073     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10074
10075     /* specific patch value exists */
10076     size = MAX_PATH;
10077     lstrcpyA(val, "apple");
10078     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10079                             MSIINSTALLCONTEXT_USERMANAGED,
10080                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10081     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10082     ok(!lstrcmpA(val, "apple"),
10083        "Expected val to be unchanged, got \"%s\"\n", val);
10084     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10085
10086     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10087     lstrcatA(keypath, usersid);
10088     lstrcatA(keypath, "\\Patches\\");
10089     lstrcatA(keypath, patch_squashed);
10090
10091     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10092     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10093
10094     /* UserData Patches key exists */
10095     size = MAX_PATH;
10096     lstrcpyA(val, "apple");
10097     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10098                             MSIINSTALLCONTEXT_USERMANAGED,
10099                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10100     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10101     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10102     ok(size == 0, "Expected 0, got %d\n", size);
10103
10104     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10105                          (const BYTE *)"pack", 5);
10106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10107
10108     /* ManagedLocalPatch value exists */
10109     size = MAX_PATH;
10110     lstrcpyA(val, "apple");
10111     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10112                             MSIINSTALLCONTEXT_USERMANAGED,
10113                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10114     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10115     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10116     ok(size == 4, "Expected 4, got %d\n", size);
10117
10118     size = MAX_PATH;
10119     lstrcpyA(val, "apple");
10120     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10121                             MSIINSTALLCONTEXT_USERMANAGED,
10122                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10123     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10124     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10125     ok(size == 10, "Expected 10, got %d\n", size);
10126
10127     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10128                          (const BYTE *)"mydate", 7);
10129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10130
10131     /* Installed value exists */
10132     size = MAX_PATH;
10133     lstrcpyA(val, "apple");
10134     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10135                             MSIINSTALLCONTEXT_USERMANAGED,
10136                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10137     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10138     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10139     ok(size == 6, "Expected 6, got %d\n", size);
10140
10141     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10142                          (const BYTE *)"yes", 4);
10143     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10144
10145     /* Uninstallable value exists */
10146     size = MAX_PATH;
10147     lstrcpyA(val, "apple");
10148     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10149                             MSIINSTALLCONTEXT_USERMANAGED,
10150                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10151     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10152     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10153     ok(size == 3, "Expected 3, got %d\n", size);
10154
10155     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10156                          (const BYTE *)"good", 5);
10157     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10158
10159     /* State value exists */
10160     size = MAX_PATH;
10161     lstrcpyA(val, "apple");
10162     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10163                             MSIINSTALLCONTEXT_USERMANAGED,
10164                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10165     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10166     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10167     ok(size == 4, "Expected 4, got %d\n", size);
10168
10169     size = 1;
10170     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10171                          (const BYTE *)&size, sizeof(DWORD));
10172     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10173
10174     /* State value exists */
10175     size = MAX_PATH;
10176     lstrcpyA(val, "apple");
10177     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10178                             MSIINSTALLCONTEXT_USERMANAGED,
10179                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10180     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10181     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10182     ok(size == 1, "Expected 1, got %d\n", size);
10183
10184     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10185                          (const BYTE *)"display", 8);
10186     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10187
10188     /* DisplayName value exists */
10189     size = MAX_PATH;
10190     lstrcpyA(val, "apple");
10191     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10192                             MSIINSTALLCONTEXT_USERMANAGED,
10193                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10194     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10195     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10196     ok(size == 7, "Expected 7, got %d\n", size);
10197
10198     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10199                          (const BYTE *)"moreinfo", 9);
10200     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10201
10202     /* MoreInfoURL value exists */
10203     size = MAX_PATH;
10204     lstrcpyA(val, "apple");
10205     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10206                             MSIINSTALLCONTEXT_USERMANAGED,
10207                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10208     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10209     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10210     ok(size == 8, "Expected 8, got %d\n", size);
10211
10212     /* szProperty is invalid */
10213     size = MAX_PATH;
10214     lstrcpyA(val, "apple");
10215     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10216                             MSIINSTALLCONTEXT_USERMANAGED,
10217                             "IDontExist", val, &size);
10218     ok(r == ERROR_UNKNOWN_PROPERTY,
10219        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10220     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10221     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10222
10223     /* lpValue is NULL, while pcchValue is non-NULL */
10224     size = MAX_PATH;
10225     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10226                             MSIINSTALLCONTEXT_USERMANAGED,
10227                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10228     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10229     ok(size == 16, "Expected 16, got %d\n", size);
10230
10231     /* pcchValue is NULL, while lpValue is non-NULL */
10232     lstrcpyA(val, "apple");
10233     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10234                             MSIINSTALLCONTEXT_USERMANAGED,
10235                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10236     ok(r == ERROR_INVALID_PARAMETER,
10237        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10238     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10239
10240     /* both lpValue and pcchValue are NULL */
10241     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10242                             MSIINSTALLCONTEXT_USERMANAGED,
10243                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10244     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10245
10246     /* pcchValue doesn't have enough room for NULL terminator */
10247     size = 8;
10248     lstrcpyA(val, "apple");
10249     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10250                             MSIINSTALLCONTEXT_USERMANAGED,
10251                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10252     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10253     ok(!lstrcmpA(val, "moreinf"),
10254        "Expected \"moreinf\", got \"%s\"\n", val);
10255     ok(size == 16, "Expected 16, got %d\n", size);
10256
10257     /* pcchValue has exactly enough room for NULL terminator */
10258     size = 9;
10259     lstrcpyA(val, "apple");
10260     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10261                             MSIINSTALLCONTEXT_USERMANAGED,
10262                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10263     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10264     ok(!lstrcmpA(val, "moreinfo"),
10265        "Expected \"moreinfo\", got \"%s\"\n", val);
10266     ok(size == 8, "Expected 8, got %d\n", size);
10267
10268     /* pcchValue is too small, lpValue is NULL */
10269     size = 0;
10270     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10271                             MSIINSTALLCONTEXT_USERMANAGED,
10272                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10274     ok(size == 16, "Expected 16, got %d\n", size);
10275
10276     RegDeleteValueA(prodpatches, patch_squashed);
10277     RegDeleteKeyA(prodpatches, "");
10278     RegCloseKey(prodpatches);
10279     RegDeleteKeyA(prodkey, "");
10280     RegCloseKey(prodkey);
10281
10282     /* UserData is sufficient for all properties
10283      * except INSTALLPROPERTY_TRANSFORMS
10284      */
10285     size = MAX_PATH;
10286     lstrcpyA(val, "apple");
10287     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10288                             MSIINSTALLCONTEXT_USERMANAGED,
10289                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10290     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10291     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10292     ok(size == 4, "Expected 4, got %d\n", size);
10293
10294     /* UserData is sufficient for all properties
10295      * except INSTALLPROPERTY_TRANSFORMS
10296      */
10297     size = MAX_PATH;
10298     lstrcpyA(val, "apple");
10299     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10300                             MSIINSTALLCONTEXT_USERMANAGED,
10301                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10302     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10303     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10304     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10305
10306     RegDeleteValueA(hpatch, "MoreInfoURL");
10307     RegDeleteValueA(hpatch, "Display");
10308     RegDeleteValueA(hpatch, "State");
10309     RegDeleteValueA(hpatch, "Uninstallable");
10310     RegDeleteValueA(hpatch, "Installed");
10311     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10312     RegDeleteKeyA(udpatch, "");
10313     RegCloseKey(udpatch);
10314     RegDeleteKeyA(hpatch, "");
10315     RegCloseKey(hpatch);
10316     RegDeleteKeyA(patches, "");
10317     RegCloseKey(patches);
10318     RegDeleteKeyA(props, "");
10319     RegCloseKey(props);
10320     RegDeleteKeyA(udprod, "");
10321     RegCloseKey(udprod);
10322
10323     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10324
10325     size = MAX_PATH;
10326     lstrcpyA(val, "apple");
10327     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10328                             MSIINSTALLCONTEXT_USERUNMANAGED,
10329                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10330     ok(r == ERROR_UNKNOWN_PRODUCT,
10331        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10332     ok(!lstrcmpA(val, "apple"),
10333        "Expected val to be unchanged, got \"%s\"\n", val);
10334     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10335
10336     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10337     lstrcatA(keypath, usersid);
10338     lstrcatA(keypath, "\\Products\\");
10339     lstrcatA(keypath, prod_squashed);
10340
10341     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10342     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10343
10344     /* local UserData product key exists */
10345     size = MAX_PATH;
10346     lstrcpyA(val, "apple");
10347     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10348                             MSIINSTALLCONTEXT_USERUNMANAGED,
10349                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10350     ok(r == ERROR_UNKNOWN_PRODUCT,
10351        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10352     ok(!lstrcmpA(val, "apple"),
10353        "Expected val to be unchanged, got \"%s\"\n", val);
10354     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10355
10356     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10357     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10358
10359     /* InstallProperties key exists */
10360     size = MAX_PATH;
10361     lstrcpyA(val, "apple");
10362     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10363                             MSIINSTALLCONTEXT_USERUNMANAGED,
10364                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10365     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10366     ok(!lstrcmpA(val, "apple"),
10367        "Expected val to be unchanged, got \"%s\"\n", val);
10368     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10369
10370     res = RegCreateKeyA(udprod, "Patches", &patches);
10371     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10372
10373     /* Patches key exists */
10374     size = MAX_PATH;
10375     lstrcpyA(val, "apple");
10376     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10377                             MSIINSTALLCONTEXT_USERUNMANAGED,
10378                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10379     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10380     ok(!lstrcmpA(val, "apple"),
10381        "Expected val to be unchanged, got \"%s\"\n", val);
10382     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10383
10384     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10385     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10386
10387     /* Patches key exists */
10388     size = MAX_PATH;
10389     lstrcpyA(val, "apple");
10390     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10391                             MSIINSTALLCONTEXT_USERUNMANAGED,
10392                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10393     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10394     ok(!lstrcmpA(val, "apple"),
10395        "Expected val to be unchanged, got \"%s\"\n", val);
10396     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10397
10398     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10399     lstrcatA(keypath, prod_squashed);
10400
10401     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10402     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10403
10404     /* current user product key exists */
10405     size = MAX_PATH;
10406     lstrcpyA(val, "apple");
10407     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10408                             MSIINSTALLCONTEXT_USERUNMANAGED,
10409                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10410     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10411     ok(!lstrcmpA(val, "apple"),
10412        "Expected val to be unchanged, got \"%s\"\n", val);
10413     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10414
10415     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10417
10418     /* Patches key exists */
10419     size = MAX_PATH;
10420     lstrcpyA(val, "apple");
10421     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10422                             MSIINSTALLCONTEXT_USERUNMANAGED,
10423                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10424     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10425     ok(!lstrcmpA(val, "apple"),
10426        "Expected val to be unchanged, got \"%s\"\n", val);
10427     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10428
10429     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10430                          (const BYTE *)"transforms", 11);
10431     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10432
10433     /* specific patch value exists */
10434     size = MAX_PATH;
10435     lstrcpyA(val, "apple");
10436     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10437                             MSIINSTALLCONTEXT_USERUNMANAGED,
10438                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10439     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10440     ok(!lstrcmpA(val, "apple"),
10441        "Expected val to be unchanged, got \"%s\"\n", val);
10442     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10443
10444     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10445     lstrcatA(keypath, usersid);
10446     lstrcatA(keypath, "\\Patches\\");
10447     lstrcatA(keypath, patch_squashed);
10448
10449     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10450     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10451
10452     /* UserData Patches key exists */
10453     size = MAX_PATH;
10454     lstrcpyA(val, "apple");
10455     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10456                             MSIINSTALLCONTEXT_USERUNMANAGED,
10457                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10458     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10459     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10460     ok(size == 0, "Expected 0, got %d\n", size);
10461
10462     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10463                          (const BYTE *)"pack", 5);
10464     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10465
10466     /* LocalPatch value exists */
10467     size = MAX_PATH;
10468     lstrcpyA(val, "apple");
10469     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10470                             MSIINSTALLCONTEXT_USERUNMANAGED,
10471                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10472     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10473     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10474     ok(size == 4, "Expected 4, got %d\n", size);
10475
10476     size = MAX_PATH;
10477     lstrcpyA(val, "apple");
10478     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10479                             MSIINSTALLCONTEXT_USERUNMANAGED,
10480                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10481     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10482     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10483     ok(size == 10, "Expected 10, got %d\n", size);
10484
10485     RegDeleteValueA(prodpatches, patch_squashed);
10486     RegDeleteKeyA(prodpatches, "");
10487     RegCloseKey(prodpatches);
10488     RegDeleteKeyA(prodkey, "");
10489     RegCloseKey(prodkey);
10490
10491     /* UserData is sufficient for all properties
10492      * except INSTALLPROPERTY_TRANSFORMS
10493      */
10494     size = MAX_PATH;
10495     lstrcpyA(val, "apple");
10496     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10497                             MSIINSTALLCONTEXT_USERUNMANAGED,
10498                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10499     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10500     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10501     ok(size == 4, "Expected 4, got %d\n", size);
10502
10503     /* UserData is sufficient for all properties
10504      * except INSTALLPROPERTY_TRANSFORMS
10505      */
10506     size = MAX_PATH;
10507     lstrcpyA(val, "apple");
10508     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10509                             MSIINSTALLCONTEXT_USERUNMANAGED,
10510                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10511     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10512     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10513     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10514
10515     RegDeleteValueA(udpatch, "LocalPackage");
10516     RegDeleteKeyA(udpatch, "");
10517     RegCloseKey(udpatch);
10518     RegDeleteKeyA(hpatch, "");
10519     RegCloseKey(hpatch);
10520     RegDeleteKeyA(patches, "");
10521     RegCloseKey(patches);
10522     RegDeleteKeyA(props, "");
10523     RegCloseKey(props);
10524     RegDeleteKeyA(udprod, "");
10525     RegCloseKey(udprod);
10526
10527     /* MSIINSTALLCONTEXT_MACHINE */
10528
10529     size = MAX_PATH;
10530     lstrcpyA(val, "apple");
10531     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10532                             MSIINSTALLCONTEXT_MACHINE,
10533                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10534     ok(r == ERROR_UNKNOWN_PRODUCT,
10535        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10536     ok(!lstrcmpA(val, "apple"),
10537        "Expected val to be unchanged, got \"%s\"\n", val);
10538     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10539
10540     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10541     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10542     lstrcatA(keypath, prod_squashed);
10543
10544     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10545     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10546
10547     /* local UserData product key exists */
10548     size = MAX_PATH;
10549     lstrcpyA(val, "apple");
10550     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10551                             MSIINSTALLCONTEXT_MACHINE,
10552                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10553     ok(r == ERROR_UNKNOWN_PRODUCT,
10554        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10555     ok(!lstrcmpA(val, "apple"),
10556        "Expected val to be unchanged, got \"%s\"\n", val);
10557     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10558
10559     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10560     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10561
10562     /* InstallProperties key exists */
10563     size = MAX_PATH;
10564     lstrcpyA(val, "apple");
10565     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10566                             MSIINSTALLCONTEXT_MACHINE,
10567                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10568     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10569     ok(!lstrcmpA(val, "apple"),
10570        "Expected val to be unchanged, got \"%s\"\n", val);
10571     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10572
10573     res = RegCreateKeyA(udprod, "Patches", &patches);
10574     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10575
10576     /* Patches key exists */
10577     size = MAX_PATH;
10578     lstrcpyA(val, "apple");
10579     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10580                             MSIINSTALLCONTEXT_MACHINE,
10581                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10582     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10583     ok(!lstrcmpA(val, "apple"),
10584        "Expected val to be unchanged, got \"%s\"\n", val);
10585     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10586
10587     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10588     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10589
10590     /* Patches key exists */
10591     size = MAX_PATH;
10592     lstrcpyA(val, "apple");
10593     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10594                             MSIINSTALLCONTEXT_MACHINE,
10595                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10596     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10597     ok(!lstrcmpA(val, "apple"),
10598        "Expected val to be unchanged, got \"%s\"\n", val);
10599     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10600
10601     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10602     lstrcatA(keypath, prod_squashed);
10603
10604     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10605     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10606
10607     /* local product key exists */
10608     size = MAX_PATH;
10609     lstrcpyA(val, "apple");
10610     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10611                             MSIINSTALLCONTEXT_MACHINE,
10612                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10613     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10614     ok(!lstrcmpA(val, "apple"),
10615        "Expected val to be unchanged, got \"%s\"\n", val);
10616     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10617
10618     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10619     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10620
10621     /* Patches key exists */
10622     size = MAX_PATH;
10623     lstrcpyA(val, "apple");
10624     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10625                             MSIINSTALLCONTEXT_MACHINE,
10626                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10627     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10628     ok(!lstrcmpA(val, "apple"),
10629        "Expected val to be unchanged, got \"%s\"\n", val);
10630     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10631
10632     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10633                          (const BYTE *)"transforms", 11);
10634     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10635
10636     /* specific patch value exists */
10637     size = MAX_PATH;
10638     lstrcpyA(val, "apple");
10639     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10640                             MSIINSTALLCONTEXT_MACHINE,
10641                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10642     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10643     ok(!lstrcmpA(val, "apple"),
10644        "Expected val to be unchanged, got \"%s\"\n", val);
10645     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10646
10647     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10648     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
10649     lstrcatA(keypath, patch_squashed);
10650
10651     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10652     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10653
10654     /* UserData Patches key exists */
10655     size = MAX_PATH;
10656     lstrcpyA(val, "apple");
10657     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10658                             MSIINSTALLCONTEXT_MACHINE,
10659                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10660     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10661     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10662     ok(size == 0, "Expected 0, got %d\n", size);
10663
10664     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10665                          (const BYTE *)"pack", 5);
10666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10667
10668     /* LocalPatch value exists */
10669     size = MAX_PATH;
10670     lstrcpyA(val, "apple");
10671     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10672                             MSIINSTALLCONTEXT_MACHINE,
10673                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10674     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10675     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10676     ok(size == 4, "Expected 4, got %d\n", size);
10677
10678     size = MAX_PATH;
10679     lstrcpyA(val, "apple");
10680     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10681                             MSIINSTALLCONTEXT_MACHINE,
10682                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10683     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10684     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10685     ok(size == 10, "Expected 10, got %d\n", size);
10686
10687     RegDeleteValueA(prodpatches, patch_squashed);
10688     RegDeleteKeyA(prodpatches, "");
10689     RegCloseKey(prodpatches);
10690     RegDeleteKeyA(prodkey, "");
10691     RegCloseKey(prodkey);
10692
10693     /* UserData is sufficient for all properties
10694      * except INSTALLPROPERTY_TRANSFORMS
10695      */
10696     size = MAX_PATH;
10697     lstrcpyA(val, "apple");
10698     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10699                             MSIINSTALLCONTEXT_MACHINE,
10700                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10701     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10702     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10703     ok(size == 4, "Expected 4, got %d\n", size);
10704
10705     /* UserData is sufficient for all properties
10706      * except INSTALLPROPERTY_TRANSFORMS
10707      */
10708     size = MAX_PATH;
10709     lstrcpyA(val, "apple");
10710     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10711                             MSIINSTALLCONTEXT_MACHINE,
10712                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10713     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10714     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10715     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10716
10717     RegDeleteValueA(udpatch, "LocalPackage");
10718     RegDeleteKeyA(udpatch, "");
10719     RegCloseKey(udpatch);
10720     RegDeleteKeyA(hpatch, "");
10721     RegCloseKey(hpatch);
10722     RegDeleteKeyA(patches, "");
10723     RegCloseKey(patches);
10724     RegDeleteKeyA(props, "");
10725     RegCloseKey(props);
10726     RegDeleteKeyA(udprod, "");
10727     RegCloseKey(udprod);
10728 }
10729
10730 START_TEST(msi)
10731 {
10732     init_functionpointers();
10733
10734     test_usefeature();
10735     test_null();
10736     test_getcomponentpath();
10737     test_MsiGetFileHash();
10738
10739     if (!pConvertSidToStringSidA)
10740         skip("ConvertSidToStringSidA not implemented\n");
10741     else
10742     {
10743         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
10744         test_MsiQueryProductState();
10745         test_MsiQueryFeatureState();
10746         test_MsiQueryComponentState();
10747         test_MsiGetComponentPath();
10748         test_MsiGetProductCode();
10749         test_MsiEnumClients();
10750         test_MsiGetProductInfo();
10751         test_MsiGetProductInfoEx();
10752         test_MsiGetUserInfo();
10753         test_MsiOpenProduct();
10754         test_MsiEnumPatchesEx();
10755         test_MsiEnumPatches();
10756         test_MsiGetPatchInfoEx();
10757     }
10758
10759     test_MsiGetFileVersion();
10760 }