ddraw: Get rid of ddcomimpl.h.
[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     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1283
1284     /* INSTALLSTATE_LOCAL */
1285     state = MAGIC_ERROR;
1286     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1287     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1288     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1289
1290     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
1291     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1292
1293     /* INSTALLSTATE_SOURCE */
1294     state = MAGIC_ERROR;
1295     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1296     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1297     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1298
1299     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1300     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1301
1302     /* bad INSTALLSTATE_SOURCE */
1303     state = MAGIC_ERROR;
1304     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1305     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1306     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1307
1308     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
1309     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1310
1311     /* INSTALLSTATE_SOURCE */
1312     state = MAGIC_ERROR;
1313     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1314     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1315     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
1316
1317     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
1318     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1319
1320     /* bad INSTALLSTATE_SOURCE */
1321     state = MAGIC_ERROR;
1322     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
1323     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1324     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1325
1326     RegDeleteValueA(prodkey, "LocalPackage");
1327     RegDeleteKeyA(prodkey, "");
1328     RegDeleteValueA(compkey, prod_squashed);
1329     RegDeleteKeyA(prodkey, "");
1330     RegCloseKey(prodkey);
1331     RegCloseKey(compkey);
1332
1333     /* MSIINSTALLCONTEXT_USERUNMANAGED */
1334
1335     state = MAGIC_ERROR;
1336     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1337     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1338     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1339
1340     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1341     lstrcatA(keypath, prod_squashed);
1342
1343     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1344     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1345
1346     state = MAGIC_ERROR;
1347     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1348     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1349     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1350
1351     RegDeleteKeyA(prodkey, "");
1352     RegCloseKey(prodkey);
1353
1354     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1355     lstrcatA(keypath, usersid);
1356     lstrcatA(keypath, "\\Products\\");
1357     lstrcatA(keypath, prod_squashed);
1358     lstrcatA(keypath, "\\InstallProperties");
1359
1360     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1361     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1362
1363     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1364     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1365
1366     RegCloseKey(prodkey);
1367
1368     state = MAGIC_ERROR;
1369     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1370     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1371     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1372
1373     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1374     lstrcatA(keypath, usersid);
1375     lstrcatA(keypath, "\\Components\\");
1376     lstrcatA(keypath, comp_squashed);
1377
1378     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1380
1381     /* component key exists */
1382     state = MAGIC_ERROR;
1383     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1384     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1385     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1386
1387     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
1388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1389
1390     /* component\product exists */
1391     state = MAGIC_ERROR;
1392     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1393     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1394     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
1395        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
1396
1397     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
1398     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1399
1400     state = MAGIC_ERROR;
1401     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
1402     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1403     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1404
1405     /* MSIINSTALLCONTEXT_USERMANAGED */
1406
1407     state = MAGIC_ERROR;
1408     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1409     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1410     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1411
1412     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1413     lstrcatA(keypath, prod_squashed);
1414
1415     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1416     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1417
1418     state = MAGIC_ERROR;
1419     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1420     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
1421     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
1422
1423     RegDeleteKeyA(prodkey, "");
1424     RegCloseKey(prodkey);
1425
1426     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
1427     lstrcatA(keypath, usersid);
1428     lstrcatA(keypath, "\\Installer\\Products\\");
1429     lstrcatA(keypath, prod_squashed);
1430
1431     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1432     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1433
1434     state = MAGIC_ERROR;
1435     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1436     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1437     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1438
1439     RegDeleteKeyA(prodkey, "");
1440     RegCloseKey(prodkey);
1441
1442     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
1443     lstrcatA(keypath, usersid);
1444     lstrcatA(keypath, "\\Products\\");
1445     lstrcatA(keypath, prod_squashed);
1446     lstrcatA(keypath, "\\InstallProperties");
1447
1448     res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1449     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1450
1451     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
1452     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1453
1454     state = MAGIC_ERROR;
1455     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
1456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1457     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1458
1459     RegDeleteValueA(prodkey, "LocalPackage");
1460     RegDeleteValueA(prodkey, "ManagedLocalPackage");
1461     RegDeleteKeyA(prodkey, "");
1462     RegDeleteValueA(compkey, prod_squashed);
1463     RegDeleteKeyA(compkey, "");
1464     RegCloseKey(prodkey);
1465     RegCloseKey(compkey);
1466 }
1467
1468 static void test_MsiGetComponentPath(void)
1469 {
1470     HKEY compkey, prodkey, installprop;
1471     CHAR prodcode[MAX_PATH];
1472     CHAR prod_squashed[MAX_PATH];
1473     CHAR component[MAX_PATH];
1474     CHAR comp_base85[MAX_PATH];
1475     CHAR comp_squashed[MAX_PATH];
1476     CHAR keypath[MAX_PATH];
1477     CHAR path[MAX_PATH];
1478     INSTALLSTATE state;
1479     LPSTR usersid;
1480     DWORD size, val;
1481     LONG res;
1482
1483     create_test_guid(prodcode, prod_squashed);
1484     compose_base85_guid(component, comp_base85, comp_squashed);
1485     get_user_sid(&usersid);
1486
1487     /* NULL szProduct */
1488     size = MAX_PATH;
1489     state = MsiGetComponentPathA(NULL, component, path, &size);
1490     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1491     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1492
1493     /* NULL szComponent */
1494     size = MAX_PATH;
1495     state = MsiGetComponentPathA(prodcode, NULL, 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 lpPathBuf */
1500     size = MAX_PATH;
1501     state = MsiGetComponentPathA(prodcode, component, NULL, &size);
1502     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1503     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1504
1505     /* NULL pcchBuf */
1506     size = MAX_PATH;
1507     state = MsiGetComponentPathA(prodcode, component, path, NULL);
1508     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
1509     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1510
1511     /* all params valid */
1512     size = MAX_PATH;
1513     state = MsiGetComponentPathA(prodcode, component, path, &size);
1514     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1515     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1516
1517     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1518     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1519     lstrcatA(keypath, comp_squashed);
1520
1521     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1522     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1523
1524     /* local system component key exists */
1525     size = MAX_PATH;
1526     state = MsiGetComponentPathA(prodcode, component, path, &size);
1527     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1528     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1529
1530     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1531     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1532
1533     /* product value exists */
1534     size = MAX_PATH;
1535     state = MsiGetComponentPathA(prodcode, component, path, &size);
1536     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1537     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1538     ok(size == 10, "Expected 10, got %d\n", size);
1539
1540     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1541     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1542     lstrcatA(keypath, prod_squashed);
1543     lstrcatA(keypath, "\\InstallProperties");
1544
1545     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1546     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1547
1548     val = 1;
1549     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1550     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1551
1552     /* install properties key exists */
1553     size = MAX_PATH;
1554     state = MsiGetComponentPathA(prodcode, component, path, &size);
1555     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1556     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1557     ok(size == 10, "Expected 10, got %d\n", size);
1558
1559     create_file("C:\\imapath", "C:\\imapath", 11);
1560
1561     /* file exists */
1562     size = MAX_PATH;
1563     state = MsiGetComponentPathA(prodcode, component, path, &size);
1564     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1565     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1566     ok(size == 10, "Expected 10, got %d\n", size);
1567
1568     RegDeleteValueA(compkey, prod_squashed);
1569     RegDeleteKeyA(compkey, "");
1570     RegDeleteValueA(installprop, "WindowsInstaller");
1571     RegDeleteKeyA(installprop, "");
1572     RegCloseKey(compkey);
1573     RegCloseKey(installprop);
1574     DeleteFileA("C:\\imapath");
1575
1576     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1577     lstrcatA(keypath, "Installer\\UserData\\");
1578     lstrcatA(keypath, usersid);
1579     lstrcatA(keypath, "\\Components\\");
1580     lstrcatA(keypath, comp_squashed);
1581
1582     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1583     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1584
1585     /* user managed component key exists */
1586     size = MAX_PATH;
1587     state = MsiGetComponentPathA(prodcode, component, path, &size);
1588     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1589     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1590
1591     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1592     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1593
1594     /* product value exists */
1595     size = MAX_PATH;
1596     state = MsiGetComponentPathA(prodcode, component, path, &size);
1597     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1598     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1599     ok(size == 10, "Expected 10, got %d\n", size);
1600
1601     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1602     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1603     lstrcatA(keypath, prod_squashed);
1604     lstrcatA(keypath, "\\InstallProperties");
1605
1606     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1607     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1608
1609     val = 1;
1610     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1611     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1612
1613     /* install properties key exists */
1614     size = MAX_PATH;
1615     state = MsiGetComponentPathA(prodcode, component, path, &size);
1616     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1617     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1618     ok(size == 10, "Expected 10, got %d\n", size);
1619
1620     create_file("C:\\imapath", "C:\\imapath", 11);
1621
1622     /* file exists */
1623     size = MAX_PATH;
1624     state = MsiGetComponentPathA(prodcode, component, path, &size);
1625     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1626     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1627     ok(size == 10, "Expected 10, got %d\n", size);
1628
1629     RegDeleteValueA(compkey, prod_squashed);
1630     RegDeleteKeyA(compkey, "");
1631     RegDeleteValueA(installprop, "WindowsInstaller");
1632     RegDeleteKeyA(installprop, "");
1633     RegCloseKey(compkey);
1634     RegCloseKey(installprop);
1635     DeleteFileA("C:\\imapath");
1636
1637     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1638     lstrcatA(keypath, "Installer\\Managed\\");
1639     lstrcatA(keypath, usersid);
1640     lstrcatA(keypath, "\\Installer\\Products\\");
1641     lstrcatA(keypath, prod_squashed);
1642
1643     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1644     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1645
1646     /* user managed product key exists */
1647     size = MAX_PATH;
1648     state = MsiGetComponentPathA(prodcode, component, path, &size);
1649     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1650     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1651
1652     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1653     lstrcatA(keypath, "Installer\\UserData\\");
1654     lstrcatA(keypath, usersid);
1655     lstrcatA(keypath, "\\Components\\");
1656     lstrcatA(keypath, comp_squashed);
1657
1658     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1659     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1660
1661     /* user managed component key exists */
1662     size = MAX_PATH;
1663     state = MsiGetComponentPathA(prodcode, component, path, &size);
1664     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1665     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1666
1667     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1668     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1669
1670     /* product value exists */
1671     size = MAX_PATH;
1672     state = MsiGetComponentPathA(prodcode, component, path, &size);
1673     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1674     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1675     ok(size == 10, "Expected 10, got %d\n", size);
1676
1677     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1678     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
1679     lstrcatA(keypath, prod_squashed);
1680     lstrcatA(keypath, "\\InstallProperties");
1681
1682     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
1683     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1684
1685     val = 1;
1686     res = RegSetValueExA(installprop, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
1687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1688
1689     /* install properties key exists */
1690     size = MAX_PATH;
1691     state = MsiGetComponentPathA(prodcode, component, path, &size);
1692     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1693     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1694     ok(size == 10, "Expected 10, got %d\n", size);
1695
1696     create_file("C:\\imapath", "C:\\imapath", 11);
1697
1698     /* file exists */
1699     size = MAX_PATH;
1700     state = MsiGetComponentPathA(prodcode, component, path, &size);
1701     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1702     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1703     ok(size == 10, "Expected 10, got %d\n", size);
1704
1705     RegDeleteValueA(compkey, prod_squashed);
1706     RegDeleteKeyA(prodkey, "");
1707     RegDeleteKeyA(compkey, "");
1708     RegDeleteValueA(installprop, "WindowsInstaller");
1709     RegDeleteKeyA(installprop, "");
1710     RegCloseKey(prodkey);
1711     RegCloseKey(compkey);
1712     RegCloseKey(installprop);
1713     DeleteFileA("C:\\imapath");
1714
1715     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1716     lstrcatA(keypath, prod_squashed);
1717
1718     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1719     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1720
1721     /* user unmanaged product key exists */
1722     size = MAX_PATH;
1723     state = MsiGetComponentPathA(prodcode, component, path, &size);
1724     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1725     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1726
1727     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1728     lstrcatA(keypath, "Installer\\UserData\\");
1729     lstrcatA(keypath, usersid);
1730     lstrcatA(keypath, "\\Components\\");
1731     lstrcatA(keypath, comp_squashed);
1732
1733     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1735
1736     /* user unmanaged component key exists */
1737     size = MAX_PATH;
1738     state = MsiGetComponentPathA(prodcode, component, path, &size);
1739     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1740     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1741
1742     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1743     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1744
1745     /* product value exists */
1746     size = MAX_PATH;
1747     state = MsiGetComponentPathA(prodcode, component, path, &size);
1748     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1749     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1750     ok(size == 10, "Expected 10, got %d\n", size);
1751
1752     create_file("C:\\imapath", "C:\\imapath", 11);
1753
1754     /* file exists */
1755     size = MAX_PATH;
1756     state = MsiGetComponentPathA(prodcode, component, path, &size);
1757     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1758     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1759     ok(size == 10, "Expected 10, got %d\n", size);
1760
1761     RegDeleteValueA(compkey, prod_squashed);
1762     RegDeleteKeyA(prodkey, "");
1763     RegDeleteKeyA(compkey, "");
1764     RegCloseKey(prodkey);
1765     RegCloseKey(compkey);
1766     DeleteFileA("C:\\imapath");
1767
1768     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1769     lstrcatA(keypath, prod_squashed);
1770
1771     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1772     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1773
1774     /* local classes product key exists */
1775     size = MAX_PATH;
1776     state = MsiGetComponentPathA(prodcode, component, path, &size);
1777     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1778     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1779
1780     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1781     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1782     lstrcatA(keypath, comp_squashed);
1783
1784     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1785     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1786
1787     /* local user component key exists */
1788     size = MAX_PATH;
1789     state = MsiGetComponentPathA(prodcode, component, path, &size);
1790     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1791     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
1792
1793     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1794     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1795
1796     /* product value exists */
1797     size = MAX_PATH;
1798     state = MsiGetComponentPathA(prodcode, component, path, &size);
1799     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1800     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1801     ok(size == 10, "Expected 10, got %d\n", size);
1802
1803     create_file("C:\\imapath", "C:\\imapath", 11);
1804
1805     /* file exists */
1806     size = MAX_PATH;
1807     state = MsiGetComponentPathA(prodcode, component, path, &size);
1808     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
1809     ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
1810     ok(size == 10, "Expected 10, got %d\n", size);
1811
1812     RegDeleteValueA(compkey, prod_squashed);
1813     RegDeleteKeyA(prodkey, "");
1814     RegDeleteKeyA(compkey, "");
1815     RegCloseKey(prodkey);
1816     RegCloseKey(compkey);
1817     DeleteFileA("C:\\imapath");
1818 }
1819
1820 static void test_MsiGetProductCode(void)
1821 {
1822     HKEY compkey, prodkey;
1823     CHAR prodcode[MAX_PATH];
1824     CHAR prod_squashed[MAX_PATH];
1825     CHAR prodcode2[MAX_PATH];
1826     CHAR prod2_squashed[MAX_PATH];
1827     CHAR component[MAX_PATH];
1828     CHAR comp_base85[MAX_PATH];
1829     CHAR comp_squashed[MAX_PATH];
1830     CHAR keypath[MAX_PATH];
1831     CHAR product[MAX_PATH];
1832     LPSTR usersid;
1833     LONG res;
1834     UINT r;
1835
1836     create_test_guid(prodcode, prod_squashed);
1837     create_test_guid(prodcode2, prod2_squashed);
1838     compose_base85_guid(component, comp_base85, comp_squashed);
1839     get_user_sid(&usersid);
1840
1841     /* szComponent is NULL */
1842     lstrcpyA(product, "prod");
1843     r = MsiGetProductCodeA(NULL, product);
1844     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1845     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1846
1847     /* szComponent is empty */
1848     lstrcpyA(product, "prod");
1849     r = MsiGetProductCodeA("", 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     /* garbage szComponent */
1854     lstrcpyA(product, "prod");
1855     r = MsiGetProductCodeA("garbage", 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     /* guid without brackets */
1860     lstrcpyA(product, "prod");
1861     r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 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 with brackets */
1866     lstrcpyA(product, "prod");
1867     r = MsiGetProductCodeA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", product);
1868     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1869     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1870
1871     /* same length as guid, but random */
1872     lstrcpyA(product, "prod");
1873     r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
1874     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
1875     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1876
1877     /* all params correct, szComponent not published */
1878     lstrcpyA(product, "prod");
1879     r = MsiGetProductCodeA(component, product);
1880     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1881     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1882
1883     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1884     lstrcatA(keypath, "Installer\\UserData\\");
1885     lstrcatA(keypath, usersid);
1886     lstrcatA(keypath, "\\Components\\");
1887     lstrcatA(keypath, comp_squashed);
1888
1889     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1891
1892     /* user unmanaged component key exists */
1893     lstrcpyA(product, "prod");
1894     r = MsiGetProductCodeA(component, product);
1895     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1896     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1897
1898     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1899     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1900
1901     /* product value exists */
1902     lstrcpyA(product, "prod");
1903     r = MsiGetProductCodeA(component, product);
1904     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1905     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1906
1907     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
1908     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1909
1910     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1911     lstrcatA(keypath, "Installer\\Managed\\");
1912     lstrcatA(keypath, usersid);
1913     lstrcatA(keypath, "\\Installer\\Products\\");
1914     lstrcatA(keypath, prod_squashed);
1915
1916     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1917     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1918
1919     /* user managed product key of first product exists */
1920     lstrcpyA(product, "prod");
1921     r = MsiGetProductCodeA(component, product);
1922     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1923     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1924
1925     RegDeleteKeyA(prodkey, "");
1926     RegCloseKey(prodkey);
1927
1928     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
1929     lstrcatA(keypath, prod_squashed);
1930
1931     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
1932     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1933
1934     /* user unmanaged product key exists */
1935     lstrcpyA(product, "prod");
1936     r = MsiGetProductCodeA(component, product);
1937     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1938     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1939
1940     RegDeleteKeyA(prodkey, "");
1941     RegCloseKey(prodkey);
1942
1943     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
1944     lstrcatA(keypath, prod_squashed);
1945
1946     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1947     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1948
1949     /* local classes product key exists */
1950     lstrcpyA(product, "prod");
1951     r = MsiGetProductCodeA(component, product);
1952     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1953     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
1954
1955     RegDeleteKeyA(prodkey, "");
1956     RegCloseKey(prodkey);
1957
1958     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1959     lstrcatA(keypath, "Installer\\Managed\\");
1960     lstrcatA(keypath, usersid);
1961     lstrcatA(keypath, "\\Installer\\Products\\");
1962     lstrcatA(keypath, prod2_squashed);
1963
1964     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
1965     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1966
1967     /* user managed product key of second product exists */
1968     lstrcpyA(product, "prod");
1969     r = MsiGetProductCodeA(component, product);
1970     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1971     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
1972
1973     RegDeleteKeyA(prodkey, "");
1974     RegCloseKey(prodkey);
1975     RegDeleteValueA(compkey, prod_squashed);
1976     RegDeleteValueA(compkey, prod2_squashed);
1977     RegDeleteKeyA(compkey, "");
1978     RegCloseKey(compkey);
1979
1980     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
1981     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
1982     lstrcatA(keypath, comp_squashed);
1983
1984     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
1985     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1986
1987     /* local user component key exists */
1988     lstrcpyA(product, "prod");
1989     r = MsiGetProductCodeA(component, product);
1990     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
1991     ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
1992
1993     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
1994     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
1995
1996     /* product value exists */
1997     lstrcpyA(product, "prod");
1998     r = MsiGetProductCodeA(component, product);
1999     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2000     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2001
2002     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2003     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2004
2005     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2006     lstrcatA(keypath, "Installer\\Managed\\");
2007     lstrcatA(keypath, usersid);
2008     lstrcatA(keypath, "\\Installer\\Products\\");
2009     lstrcatA(keypath, prod_squashed);
2010
2011     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2012     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2013
2014     /* user managed product key of first product exists */
2015     lstrcpyA(product, "prod");
2016     r = MsiGetProductCodeA(component, product);
2017     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2018     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2019
2020     RegDeleteKeyA(prodkey, "");
2021     RegCloseKey(prodkey);
2022
2023     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2024     lstrcatA(keypath, prod_squashed);
2025
2026     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2027     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2028
2029     /* user unmanaged product key exists */
2030     lstrcpyA(product, "prod");
2031     r = MsiGetProductCodeA(component, product);
2032     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2033     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2034
2035     RegDeleteKeyA(prodkey, "");
2036     RegCloseKey(prodkey);
2037
2038     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2039     lstrcatA(keypath, prod_squashed);
2040
2041     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2042     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2043
2044     /* local classes product key exists */
2045     lstrcpyA(product, "prod");
2046     r = MsiGetProductCodeA(component, product);
2047     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2048     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2049
2050     RegDeleteKeyA(prodkey, "");
2051     RegCloseKey(prodkey);
2052
2053     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2054     lstrcatA(keypath, "Installer\\Managed\\");
2055     lstrcatA(keypath, usersid);
2056     lstrcatA(keypath, "\\Installer\\Products\\");
2057     lstrcatA(keypath, prod2_squashed);
2058
2059     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2061
2062     /* user managed product key of second product exists */
2063     lstrcpyA(product, "prod");
2064     r = MsiGetProductCodeA(component, product);
2065     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2066     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
2067
2068     RegDeleteKeyA(prodkey, "");
2069     RegCloseKey(prodkey);
2070     RegDeleteValueA(compkey, prod_squashed);
2071     RegDeleteValueA(compkey, prod2_squashed);
2072     RegDeleteKeyA(compkey, "");
2073     RegCloseKey(compkey);
2074 }
2075
2076 static void test_MsiEnumClients(void)
2077 {
2078     HKEY compkey;
2079     CHAR prodcode[MAX_PATH];
2080     CHAR prod_squashed[MAX_PATH];
2081     CHAR prodcode2[MAX_PATH];
2082     CHAR prod2_squashed[MAX_PATH];
2083     CHAR component[MAX_PATH];
2084     CHAR comp_base85[MAX_PATH];
2085     CHAR comp_squashed[MAX_PATH];
2086     CHAR product[MAX_PATH];
2087     CHAR keypath[MAX_PATH];
2088     LPSTR usersid;
2089     LONG res;
2090     UINT r;
2091
2092     create_test_guid(prodcode, prod_squashed);
2093     create_test_guid(prodcode2, prod2_squashed);
2094     compose_base85_guid(component, comp_base85, comp_squashed);
2095     get_user_sid(&usersid);
2096
2097     /* NULL szComponent */
2098     product[0] = '\0';
2099     r = MsiEnumClientsA(NULL, 0, product);
2100     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2101     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2102
2103     /* empty szComponent */
2104     product[0] = '\0';
2105     r = MsiEnumClientsA("", 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     /* NULL lpProductBuf */
2110     r = MsiEnumClientsA(component, 0, NULL);
2111     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2112
2113     /* all params correct, component missing */
2114     product[0] = '\0';
2115     r = MsiEnumClientsA(component, 0, product);
2116     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2117     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2118
2119     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2120     lstrcatA(keypath, "Installer\\UserData\\");
2121     lstrcatA(keypath, usersid);
2122     lstrcatA(keypath, "\\Components\\");
2123     lstrcatA(keypath, comp_squashed);
2124
2125     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2126     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2127
2128     /* user unmanaged component key exists */
2129     product[0] = '\0';
2130     r = MsiEnumClientsA(component, 0, product);
2131     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2132     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2133
2134     /* index > 0, no products exist */
2135     product[0] = '\0';
2136     r = MsiEnumClientsA(component, 1, product);
2137     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2138     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2139
2140     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2142
2143     /* product value exists */
2144     r = MsiEnumClientsA(component, 0, product);
2145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2146     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2147
2148     /* try index 0 again */
2149     product[0] = '\0';
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 1, second product value does not exist */
2155     product[0] = '\0';
2156     r = MsiEnumClientsA(component, 1, product);
2157     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2158     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2159
2160     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2161     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2162
2163     /* try index 1, second product value does exist */
2164     product[0] = '\0';
2165     r = MsiEnumClientsA(component, 1, product);
2166     todo_wine
2167     {
2168         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2169         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2170     }
2171
2172     /* start the enumeration over */
2173     product[0] = '\0';
2174     r = MsiEnumClientsA(component, 0, product);
2175     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2176     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2177        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2178
2179     /* correctly query second product */
2180     product[0] = '\0';
2181     r = MsiEnumClientsA(component, 1, product);
2182     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2183     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2184        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2185
2186     RegDeleteValueA(compkey, prod_squashed);
2187     RegDeleteValueA(compkey, prod2_squashed);
2188     RegDeleteKeyA(compkey, "");
2189     RegCloseKey(compkey);
2190
2191     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
2192     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
2193     lstrcatA(keypath, comp_squashed);
2194
2195     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
2196     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2197
2198     /* user local component key exists */
2199     product[0] = '\0';
2200     r = MsiEnumClientsA(component, 0, product);
2201     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
2202     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2203
2204     /* index > 0, no products exist */
2205     product[0] = '\0';
2206     r = MsiEnumClientsA(component, 1, product);
2207     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2208     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2209
2210     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
2211     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2212
2213     /* product value exists */
2214     product[0] = '\0';
2215     r = MsiEnumClientsA(component, 0, product);
2216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2217     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
2218
2219     /* try index 0 again */
2220     product[0] = '\0';
2221     r = MsiEnumClientsA(component, 0, product);
2222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2223
2224     /* try index 1, second product value does not exist */
2225     product[0] = '\0';
2226     r = MsiEnumClientsA(component, 1, product);
2227     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
2228     ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2229
2230     res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
2231     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2232
2233     /* try index 1, second product value does exist */
2234     product[0] = '\0';
2235     r = MsiEnumClientsA(component, 1, product);
2236     todo_wine
2237     {
2238         ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2239         ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
2240     }
2241
2242     /* start the enumeration over */
2243     product[0] = '\0';
2244     r = MsiEnumClientsA(component, 0, product);
2245     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2246     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2247        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2248
2249     /* correctly query second product */
2250     product[0] = '\0';
2251     r = MsiEnumClientsA(component, 1, product);
2252     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2253     ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
2254        "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
2255
2256     RegDeleteValueA(compkey, prod_squashed);
2257     RegDeleteValueA(compkey, prod2_squashed);
2258     RegDeleteKeyA(compkey, "");
2259     RegCloseKey(compkey);
2260 }
2261
2262 static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz,
2263                              LPSTR *langcheck, LPDWORD langchecksz)
2264 {
2265     LPSTR version;
2266     VS_FIXEDFILEINFO *ffi;
2267     DWORD size = GetFileVersionInfoSizeA(path, NULL);
2268     USHORT *lang;
2269
2270     version = HeapAlloc(GetProcessHeap(), 0, size);
2271     GetFileVersionInfoA(path, 0, size, version);
2272
2273     VerQueryValueA(version, "\\", (LPVOID *)&ffi, &size);
2274     *vercheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2275     sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
2276             LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
2277             LOWORD(ffi->dwFileVersionLS));
2278     *verchecksz = lstrlenA(*vercheck);
2279
2280     VerQueryValue(version, "\\VarFileInfo\\Translation", (void **)&lang, &size);
2281     *langcheck = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
2282     sprintf(*langcheck, "%d", *lang);
2283     *langchecksz = lstrlenA(*langcheck);
2284
2285     HeapFree(GetProcessHeap(), 0, version);
2286 }
2287
2288 static void test_MsiGetFileVersion(void)
2289 {
2290     UINT r;
2291     DWORD versz, langsz;
2292     char version[MAX_PATH];
2293     char lang[MAX_PATH];
2294     char path[MAX_PATH];
2295     LPSTR vercheck, langcheck;
2296     DWORD verchecksz, langchecksz;
2297
2298     /* NULL szFilePath */
2299     versz = MAX_PATH;
2300     langsz = MAX_PATH;
2301     lstrcpyA(version, "version");
2302     lstrcpyA(lang, "lang");
2303     r = MsiGetFileVersionA(NULL, version, &versz, lang, &langsz);
2304     ok(r == ERROR_INVALID_PARAMETER,
2305        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2306     ok(!lstrcmpA(version, "version"),
2307        "Expected version to be unchanged, got %s\n", version);
2308     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2309     ok(!lstrcmpA(lang, "lang"),
2310        "Expected lang to be unchanged, got %s\n", lang);
2311     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2312
2313     /* empty szFilePath */
2314     versz = MAX_PATH;
2315     langsz = MAX_PATH;
2316     lstrcpyA(version, "version");
2317     lstrcpyA(lang, "lang");
2318     r = MsiGetFileVersionA("", version, &versz, lang, &langsz);
2319     ok(r == ERROR_FILE_NOT_FOUND,
2320        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2321     ok(!lstrcmpA(version, "version"),
2322        "Expected version to be unchanged, got %s\n", version);
2323     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2324     ok(!lstrcmpA(lang, "lang"),
2325        "Expected lang to be unchanged, got %s\n", lang);
2326     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2327
2328     /* nonexistent szFilePath */
2329     versz = MAX_PATH;
2330     langsz = MAX_PATH;
2331     lstrcpyA(version, "version");
2332     lstrcpyA(lang, "lang");
2333     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2334     ok(r == ERROR_FILE_NOT_FOUND,
2335        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2336     ok(!lstrcmpA(version, "version"),
2337        "Expected version to be unchanged, got %s\n", version);
2338     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2339     ok(!lstrcmpA(lang, "lang"),
2340        "Expected lang to be unchanged, got %s\n", lang);
2341     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2342
2343     /* nonexistent szFilePath, valid lpVersionBuf, NULL pcchVersionBuf */
2344     versz = MAX_PATH;
2345     langsz = MAX_PATH;
2346     lstrcpyA(version, "version");
2347     lstrcpyA(lang, "lang");
2348     r = MsiGetFileVersionA("nonexistent", version, NULL, lang, &langsz);
2349     ok(r == ERROR_INVALID_PARAMETER,
2350        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2351     ok(!lstrcmpA(version, "version"),
2352        "Expected version to be unchanged, got %s\n", version);
2353     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2354     ok(!lstrcmpA(lang, "lang"),
2355        "Expected lang to be unchanged, got %s\n", lang);
2356     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2357
2358     /* nonexistent szFilePath, valid lpLangBuf, NULL pcchLangBuf */
2359     versz = MAX_PATH;
2360     langsz = MAX_PATH;
2361     lstrcpyA(version, "version");
2362     lstrcpyA(lang, "lang");
2363     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, NULL);
2364     ok(r == ERROR_INVALID_PARAMETER,
2365        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2366     ok(!lstrcmpA(version, "version"),
2367        "Expected version to be unchanged, got %s\n", version);
2368     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2369     ok(!lstrcmpA(lang, "lang"),
2370        "Expected lang to be unchanged, got %s\n", lang);
2371     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2372
2373     /* nonexistent szFilePath, valid lpVersionBuf, pcchVersionBuf is zero */
2374     versz = 0;
2375     langsz = MAX_PATH;
2376     lstrcpyA(version, "version");
2377     lstrcpyA(lang, "lang");
2378     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2379     ok(r == ERROR_FILE_NOT_FOUND,
2380        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2381     ok(!lstrcmpA(version, "version"),
2382        "Expected version to be unchanged, got %s\n", version);
2383     ok(versz == 0, "Expected 0, got %d\n", versz);
2384     ok(!lstrcmpA(lang, "lang"),
2385        "Expected lang to be unchanged, got %s\n", lang);
2386     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2387
2388     /* nonexistent szFilePath, valid lpLangBuf, pcchLangBuf is zero */
2389     versz = MAX_PATH;
2390     langsz = 0;
2391     lstrcpyA(version, "version");
2392     lstrcpyA(lang, "lang");
2393     r = MsiGetFileVersionA("nonexistent", version, &versz, lang, &langsz);
2394     ok(r == ERROR_FILE_NOT_FOUND,
2395        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2396     ok(!lstrcmpA(version, "version"),
2397        "Expected version to be unchanged, got %s\n", version);
2398     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2399     ok(!lstrcmpA(lang, "lang"),
2400        "Expected lang to be unchanged, got %s\n", lang);
2401     ok(langsz == 0, "Expected 0, got %d\n", langsz);
2402
2403     /* nonexistent szFilePath, rest NULL */
2404     r = MsiGetFileVersionA("nonexistent", NULL, NULL, NULL, NULL);
2405     ok(r == ERROR_FILE_NOT_FOUND,
2406        "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2407
2408     create_file("ver.txt", "ver.txt", 20);
2409
2410     /* file exists, no version information */
2411     versz = MAX_PATH;
2412     langsz = MAX_PATH;
2413     lstrcpyA(version, "version");
2414     lstrcpyA(lang, "lang");
2415     r = MsiGetFileVersionA("ver.txt", version, &versz, lang, &langsz);
2416     ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2417     ok(!lstrcmpA(version, "version"),
2418        "Expected version to be unchanged, got %s\n", version);
2419     ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2420     ok(!lstrcmpA(lang, "lang"),
2421        "Expected lang to be unchanged, got %s\n", lang);
2422     ok(r == ERROR_FILE_INVALID,
2423        "Expected ERROR_FILE_INVALID, got %d\n", r);
2424
2425     DeleteFileA("ver.txt");
2426
2427     /* relative path, has version information */
2428     versz = MAX_PATH;
2429     langsz = MAX_PATH;
2430     lstrcpyA(version, "version");
2431     lstrcpyA(lang, "lang");
2432     r = MsiGetFileVersionA("kernel32.dll", version, &versz, lang, &langsz);
2433     todo_wine
2434     {
2435         ok(r == ERROR_FILE_NOT_FOUND,
2436            "Expected ERROR_FILE_NOT_FOUND, got %d\n", r);
2437         ok(!lstrcmpA(version, "version"),
2438            "Expected version to be unchanged, got %s\n", version);
2439         ok(versz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, versz);
2440         ok(!lstrcmpA(lang, "lang"),
2441            "Expected lang to be unchanged, got %s\n", lang);
2442         ok(langsz == MAX_PATH, "Expected %d, got %d\n", MAX_PATH, langsz);
2443     }
2444
2445     GetSystemDirectoryA(path, MAX_PATH);
2446     lstrcatA(path, "\\kernel32.dll");
2447
2448     get_version_info(path, &vercheck, &verchecksz, &langcheck, &langchecksz);
2449
2450     /* absolute path, has version information */
2451     versz = MAX_PATH;
2452     langsz = MAX_PATH;
2453     lstrcpyA(version, "version");
2454     lstrcpyA(lang, "lang");
2455     r = MsiGetFileVersionA(path, version, &versz, lang, &langsz);
2456     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2457     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2458     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2459     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2460     ok(!lstrcmpA(version, vercheck),
2461         "Expected %s, got %s\n", vercheck, version);
2462
2463     /* only check version */
2464     versz = MAX_PATH;
2465     lstrcpyA(version, "version");
2466     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2467     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2468     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2469     ok(!lstrcmpA(version, vercheck),
2470        "Expected %s, got %s\n", vercheck, version);
2471
2472     /* only check language */
2473     langsz = MAX_PATH;
2474     lstrcpyA(lang, "lang");
2475     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2476     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2477     ok(!lstrcmpA(lang, langcheck), "Expected %s, got %s\n", langcheck, lang);
2478     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2479
2480     /* check neither version nor language */
2481     r = MsiGetFileVersionA(path, NULL, NULL, NULL, NULL);
2482     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2483
2484     /* get pcchVersionBuf */
2485     versz = MAX_PATH;
2486     r = MsiGetFileVersionA(path, NULL, &versz, NULL, NULL);
2487     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2488     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2489
2490     /* get pcchLangBuf */
2491     langsz = MAX_PATH;
2492     r = MsiGetFileVersionA(path, NULL, NULL, NULL, &langsz);
2493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2494     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2495
2496     /* pcchVersionBuf not big enough */
2497     versz = 5;
2498     lstrcpyA(version, "version");
2499     r = MsiGetFileVersionA(path, version, &versz, NULL, NULL);
2500     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2501     ok(!strncmp(version, vercheck, 4),
2502        "Expected first 4 characters of %s, got %s\n", vercheck, version);
2503     ok(versz == verchecksz, "Expected %d, got %d\n", verchecksz, versz);
2504
2505     /* pcchLangBuf not big enough */
2506     langsz = 3;
2507     lstrcpyA(lang, "lang");
2508     r = MsiGetFileVersionA(path, NULL, NULL, lang, &langsz);
2509     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2510     ok(!strncmp(lang, langcheck, 2),
2511        "Expected first character of %s, got %s\n", langcheck, lang);
2512     ok(langsz == langchecksz, "Expected %d, got %d\n", langchecksz, langsz);
2513
2514     HeapFree(GetProcessHeap(), 0, vercheck);
2515     HeapFree(GetProcessHeap(), 0, langcheck);
2516 }
2517
2518 static void test_MsiGetProductInfo(void)
2519 {
2520     UINT r;
2521     LONG res;
2522     HKEY propkey, source;
2523     HKEY prodkey, localkey;
2524     CHAR prodcode[MAX_PATH];
2525     CHAR prod_squashed[MAX_PATH];
2526     CHAR packcode[MAX_PATH];
2527     CHAR pack_squashed[MAX_PATH];
2528     CHAR buf[MAX_PATH];
2529     CHAR keypath[MAX_PATH];
2530     LPSTR usersid;
2531     DWORD sz, val = 42;
2532
2533     create_test_guid(prodcode, prod_squashed);
2534     create_test_guid(packcode, pack_squashed);
2535     get_user_sid(&usersid);
2536
2537     /* NULL szProduct */
2538     sz = MAX_PATH;
2539     lstrcpyA(buf, "apple");
2540     r = MsiGetProductInfoA(NULL, INSTALLPROPERTY_HELPLINK, buf, &sz);
2541     ok(r == ERROR_INVALID_PARAMETER,
2542        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2543     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2544     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2545
2546     /* empty szProduct */
2547     sz = MAX_PATH;
2548     lstrcpyA(buf, "apple");
2549     r = MsiGetProductInfoA("", INSTALLPROPERTY_HELPLINK, buf, &sz);
2550     ok(r == ERROR_INVALID_PARAMETER,
2551        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2552     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2553     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2554
2555     /* garbage szProduct */
2556     sz = MAX_PATH;
2557     lstrcpyA(buf, "apple");
2558     r = MsiGetProductInfoA("garbage", INSTALLPROPERTY_HELPLINK, buf, &sz);
2559     ok(r == ERROR_INVALID_PARAMETER,
2560        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2561     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2562     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2563
2564     /* guid without brackets */
2565     sz = MAX_PATH;
2566     lstrcpyA(buf, "apple");
2567     r = MsiGetProductInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
2568                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2569     ok(r == ERROR_INVALID_PARAMETER,
2570        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2571     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2572     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2573
2574     /* guid with brackets */
2575     sz = MAX_PATH;
2576     lstrcpyA(buf, "apple");
2577     r = MsiGetProductInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
2578                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2579     ok(r == ERROR_UNKNOWN_PRODUCT,
2580        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2581     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2582     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2583
2584     /* same length as guid, but random */
2585     sz = MAX_PATH;
2586     lstrcpyA(buf, "apple");
2587     r = MsiGetProductInfoA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
2588                            INSTALLPROPERTY_HELPLINK, buf, &sz);
2589     ok(r == ERROR_INVALID_PARAMETER,
2590        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2591     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2592     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2593
2594     /* not installed, NULL szAttribute */
2595     sz = MAX_PATH;
2596     lstrcpyA(buf, "apple");
2597     r = MsiGetProductInfoA(prodcode, NULL, buf, &sz);
2598     ok(r == ERROR_INVALID_PARAMETER,
2599        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2600     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2601     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2602
2603     /* not installed, NULL lpValueBuf */
2604     sz = MAX_PATH;
2605     lstrcpyA(buf, "apple");
2606     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2607     ok(r == ERROR_UNKNOWN_PRODUCT,
2608        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2609     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2610     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2611
2612     /* not installed, NULL pcchValueBuf */
2613     sz = MAX_PATH;
2614     lstrcpyA(buf, "apple");
2615     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, NULL);
2616     ok(r == ERROR_INVALID_PARAMETER,
2617        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
2618     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2619     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2620
2621     /* created guid cannot possibly be an installed product code */
2622     sz = MAX_PATH;
2623     lstrcpyA(buf, "apple");
2624     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2625     ok(r == ERROR_UNKNOWN_PRODUCT,
2626        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2627     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2628     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2629
2630     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2631     lstrcatA(keypath, usersid);
2632     lstrcatA(keypath, "\\Installer\\Products\\");
2633     lstrcatA(keypath, prod_squashed);
2634
2635     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2637
2638     /* managed product code exists */
2639     sz = MAX_PATH;
2640     lstrcpyA(buf, "apple");
2641     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2642     ok(r == ERROR_UNKNOWN_PROPERTY,
2643        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2644     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2645     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2646
2647     RegDeleteKeyA(prodkey, "");
2648     RegCloseKey(prodkey);
2649
2650     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2651     lstrcatA(keypath, usersid);
2652     lstrcatA(keypath, "\\Products\\");
2653     lstrcatA(keypath, prod_squashed);
2654
2655     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2656     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2657
2658     /* local user product code exists */
2659     sz = MAX_PATH;
2660     lstrcpyA(buf, "apple");
2661     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2662     ok(r == ERROR_UNKNOWN_PRODUCT,
2663        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
2664     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2665     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2666
2667     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
2668     lstrcatA(keypath, usersid);
2669     lstrcatA(keypath, "\\Installer\\Products\\");
2670     lstrcatA(keypath, prod_squashed);
2671
2672     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2673     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2674
2675     /* both local and managed product code exist */
2676     sz = MAX_PATH;
2677     lstrcpyA(buf, "apple");
2678     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2679     ok(r == ERROR_UNKNOWN_PROPERTY,
2680        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2681     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
2682     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2683
2684     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2685     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2686
2687     /* InstallProperties key exists */
2688     sz = MAX_PATH;
2689     lstrcpyA(buf, "apple");
2690     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2691     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2692     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2693     ok(sz == 0, "Expected 0, got %d\n", sz);
2694
2695     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2696     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2697
2698     /* HelpLink value exists */
2699     sz = MAX_PATH;
2700     lstrcpyA(buf, "apple");
2701     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2702     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2703     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2704     ok(sz == 4, "Expected 4, got %d\n", sz);
2705
2706     /* pcchBuf is NULL */
2707     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, NULL);
2708     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2709
2710     /* lpValueBuf is NULL */
2711     sz = MAX_PATH;
2712     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, NULL, &sz);
2713     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2714     ok(sz == 4, "Expected 4, got %d\n", sz);
2715
2716     /* lpValueBuf is NULL, pcchValueBuf is too small */
2717     sz = 2;
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     lstrcpyA(buf, "apple");
2725     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2726     ok(!lstrcmpA(buf, "apple"), "Expected buf to remain unchanged, got \"%s\"\n", buf);
2727     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2728     ok(sz == 4, "Expected 4, got %d\n", sz);
2729
2730     /* lpValueBuf is NULL, pcchValueBuf is exactly 4 */
2731     sz = 4;
2732     lstrcpyA(buf, "apple");
2733     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2734     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2735     ok(!lstrcmpA(buf, "apple"),
2736        "Expected buf to remain unchanged, got \"%s\"\n", buf);
2737     ok(sz == 4, "Expected 4, got %d\n", sz);
2738
2739     res = RegSetValueExA(propkey, "IMadeThis", 0, REG_SZ, (LPBYTE)"random", 7);
2740     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2741
2742     /* random property not supported by MSI, value exists */
2743     sz = MAX_PATH;
2744     lstrcpyA(buf, "apple");
2745     r = MsiGetProductInfoA(prodcode, "IMadeThis", buf, &sz);
2746     ok(r == ERROR_UNKNOWN_PROPERTY,
2747        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2748     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2749     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2750
2751     RegDeleteValueA(propkey, "IMadeThis");
2752     RegDeleteValueA(propkey, "HelpLink");
2753     RegDeleteKeyA(propkey, "");
2754     RegDeleteKeyA(localkey, "");
2755     RegDeleteKeyA(prodkey, "");
2756     RegCloseKey(propkey);
2757     RegCloseKey(localkey);
2758     RegCloseKey(prodkey);
2759
2760     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
2761     lstrcatA(keypath, prod_squashed);
2762
2763     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
2764     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2765
2766     /* user product key exists */
2767     sz = MAX_PATH;
2768     lstrcpyA(buf, "apple");
2769     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2770     ok(r == ERROR_UNKNOWN_PROPERTY,
2771        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2772     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2773     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2774
2775     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2776     lstrcatA(keypath, usersid);
2777     lstrcatA(keypath, "\\Products\\");
2778     lstrcatA(keypath, prod_squashed);
2779
2780     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2781     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2782
2783     /* local user product key exists */
2784     sz = MAX_PATH;
2785     lstrcpyA(buf, "apple");
2786     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2787     ok(r == ERROR_UNKNOWN_PROPERTY,
2788        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2789     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2790     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2791
2792     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2793     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2794
2795     /* InstallProperties key exists */
2796     sz = MAX_PATH;
2797     lstrcpyA(buf, "apple");
2798     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2799     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2800     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2801     ok(sz == 0, "Expected 0, got %d\n", sz);
2802
2803     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2804     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2805
2806     /* HelpLink value exists */
2807     sz = MAX_PATH;
2808     lstrcpyA(buf, "apple");
2809     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2810     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2811     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2812     ok(sz == 4, "Expected 4, got %d\n", sz);
2813
2814     RegDeleteValueA(propkey, "HelpLink");
2815     RegDeleteKeyA(propkey, "");
2816     RegDeleteKeyA(localkey, "");
2817     RegDeleteKeyA(prodkey, "");
2818     RegCloseKey(propkey);
2819     RegCloseKey(localkey);
2820     RegCloseKey(prodkey);
2821
2822     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
2823     lstrcatA(keypath, prod_squashed);
2824
2825     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
2826     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2827
2828     /* classes product key exists */
2829     sz = MAX_PATH;
2830     lstrcpyA(buf, "apple");
2831     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2832     ok(r == ERROR_UNKNOWN_PROPERTY,
2833        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2834     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2835     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2836
2837     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2838     lstrcatA(keypath, usersid);
2839     lstrcatA(keypath, "\\Products\\");
2840     lstrcatA(keypath, prod_squashed);
2841
2842     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2843     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2844
2845     /* local user product key exists */
2846     sz = MAX_PATH;
2847     lstrcpyA(buf, "apple");
2848     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2849     ok(r == ERROR_UNKNOWN_PROPERTY,
2850        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2851     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2852     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2853
2854     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2855     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2856
2857     /* InstallProperties key exists */
2858     sz = MAX_PATH;
2859     lstrcpyA(buf, "apple");
2860     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2861     ok(r == ERROR_UNKNOWN_PROPERTY,
2862        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2863     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2864     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2865
2866     RegDeleteKeyA(propkey, "");
2867     RegDeleteKeyA(localkey, "");
2868     RegCloseKey(propkey);
2869     RegCloseKey(localkey);
2870
2871     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
2872     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
2873     lstrcatA(keypath, prod_squashed);
2874
2875     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
2876     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2877
2878     /* Local System product key exists */
2879     sz = MAX_PATH;
2880     lstrcpyA(buf, "apple");
2881     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2882     ok(r == ERROR_UNKNOWN_PROPERTY,
2883         "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
2884     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
2885     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
2886
2887     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
2888     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2889
2890     /* InstallProperties key exists */
2891     sz = MAX_PATH;
2892     lstrcpyA(buf, "apple");
2893     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2894     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2895     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
2896     ok(sz == 0, "Expected 0, got %d\n", sz);
2897
2898     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
2899     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2900
2901     /* HelpLink value exists */
2902     sz = MAX_PATH;
2903     lstrcpyA(buf, "apple");
2904     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2905     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2906     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
2907     ok(sz == 4, "Expected 4, got %d\n", sz);
2908
2909     res = RegSetValueExA(propkey, "HelpLink", 0, REG_DWORD,
2910                          (const BYTE *)&val, sizeof(DWORD));
2911     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2912
2913     /* HelpLink type is REG_DWORD */
2914     sz = MAX_PATH;
2915     lstrcpyA(buf, "apple");
2916     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPLINK, buf, &sz);
2917     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2918     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2919     ok(sz == 2, "Expected 2, got %d\n", sz);
2920
2921     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
2922     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2923
2924     /* DisplayName value exists */
2925     sz = MAX_PATH;
2926     lstrcpyA(buf, "apple");
2927     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2928     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2929     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
2930     ok(sz == 4, "Expected 4, got %d\n", sz);
2931
2932     res = RegSetValueExA(propkey, "DisplayName", 0, REG_DWORD,
2933                          (const BYTE *)&val, sizeof(DWORD));
2934     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2935
2936     /* DisplayName type is REG_DWORD */
2937     sz = MAX_PATH;
2938     lstrcpyA(buf, "apple");
2939     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
2940     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2941     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2942     ok(sz == 2, "Expected 2, got %d\n", sz);
2943
2944     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"1.1.1", 6);
2945     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2946
2947     /* DisplayVersion value exists */
2948     sz = MAX_PATH;
2949     lstrcpyA(buf, "apple");
2950     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2951     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2952     ok(!lstrcmpA(buf, "1.1.1"), "Expected \"1.1.1\", got \"%s\"\n", buf);
2953     ok(sz == 5, "Expected 5, got %d\n", sz);
2954
2955     res = RegSetValueExA(propkey, "DisplayVersion", 0,
2956                          REG_DWORD, (const BYTE *)&val, sizeof(DWORD));
2957     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2958
2959     /* DisplayVersion type is REG_DWORD */
2960     sz = MAX_PATH;
2961     lstrcpyA(buf, "apple");
2962     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
2963     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2964     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2965     ok(sz == 2, "Expected 2, got %d\n", sz);
2966
2967     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"tele", 5);
2968     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2969
2970     /* HelpTelephone value exists */
2971     sz = MAX_PATH;
2972     lstrcpyA(buf, "apple");
2973     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2974     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2975     ok(!lstrcmpA(buf, "tele"), "Expected \"tele\", got \"%s\"\n", buf);
2976     ok(sz == 4, "Expected 4, got %d\n", sz);
2977
2978     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_DWORD,
2979                          (const BYTE *)&val, sizeof(DWORD));
2980     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2981
2982     /* HelpTelephone type is REG_DWORD */
2983     sz = MAX_PATH;
2984     lstrcpyA(buf, "apple");
2985     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
2986     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2987     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
2988     ok(sz == 2, "Expected 2, got %d\n", sz);
2989
2990     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
2991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
2992
2993     /* InstallLocation value exists */
2994     sz = MAX_PATH;
2995     lstrcpyA(buf, "apple");
2996     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
2997     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2998     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
2999     ok(sz == 3, "Expected 3, got %d\n", sz);
3000
3001     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_DWORD,
3002                          (const BYTE *)&val, sizeof(DWORD));
3003     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3004
3005     /* InstallLocation type is REG_DWORD */
3006     sz = MAX_PATH;
3007     lstrcpyA(buf, "apple");
3008     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
3009     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3010     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3011     ok(sz == 2, "Expected 2, got %d\n", sz);
3012
3013     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
3014     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3015
3016     /* InstallSource value exists */
3017     sz = MAX_PATH;
3018     lstrcpyA(buf, "apple");
3019     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3020     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3021     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
3022     ok(sz == 6, "Expected 6, got %d\n", sz);
3023
3024     res = RegSetValueExA(propkey, "InstallSource", 0, REG_DWORD,
3025                          (const BYTE *)&val, sizeof(DWORD));
3026     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3027
3028     /* InstallSource type is REG_DWORD */
3029     sz = MAX_PATH;
3030     lstrcpyA(buf, "apple");
3031     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
3032     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3033     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3034     ok(sz == 2, "Expected 2, got %d\n", sz);
3035
3036     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
3037     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3038
3039     /* InstallDate value exists */
3040     sz = MAX_PATH;
3041     lstrcpyA(buf, "apple");
3042     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3044     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
3045     ok(sz == 4, "Expected 4, got %d\n", sz);
3046
3047     res = RegSetValueExA(propkey, "InstallDate", 0, REG_DWORD,
3048                          (const BYTE *)&val, sizeof(DWORD));
3049     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3050
3051     /* InstallDate type is REG_DWORD */
3052     sz = MAX_PATH;
3053     lstrcpyA(buf, "apple");
3054     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTALLDATE, buf, &sz);
3055     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3056     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3057     ok(sz == 2, "Expected 2, got %d\n", sz);
3058
3059     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
3060     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3061
3062     /* Publisher value exists */
3063     sz = MAX_PATH;
3064     lstrcpyA(buf, "apple");
3065     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3066     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3067     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
3068     ok(sz == 3, "Expected 3, got %d\n", sz);
3069
3070     res = RegSetValueExA(propkey, "Publisher", 0, REG_DWORD,
3071                          (const BYTE *)&val, sizeof(DWORD));
3072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3073
3074     /* Publisher type is REG_DWORD */
3075     sz = MAX_PATH;
3076     lstrcpyA(buf, "apple");
3077     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PUBLISHER, buf, &sz);
3078     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3079     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3080     ok(sz == 2, "Expected 2, got %d\n", sz);
3081
3082     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"pack", 5);
3083     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3084
3085     /* LocalPackage value exists */
3086     sz = MAX_PATH;
3087     lstrcpyA(buf, "apple");
3088     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3089     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3090     ok(!lstrcmpA(buf, "pack"), "Expected \"pack\", got \"%s\"\n", buf);
3091     ok(sz == 4, "Expected 4, got %d\n", sz);
3092
3093     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_DWORD,
3094                          (const BYTE *)&val, sizeof(DWORD));
3095     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3096
3097     /* LocalPackage type is REG_DWORD */
3098     sz = MAX_PATH;
3099     lstrcpyA(buf, "apple");
3100     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
3101     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3102     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3103     ok(sz == 2, "Expected 2, got %d\n", sz);
3104
3105     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
3106     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3107
3108     /* UrlInfoAbout value exists */
3109     sz = MAX_PATH;
3110     lstrcpyA(buf, "apple");
3111     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3112     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3113     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
3114     ok(sz == 5, "Expected 5, got %d\n", sz);
3115
3116     res = RegSetValueExA(propkey, "UrlInfoAbout", 0, REG_DWORD,
3117                          (const BYTE *)&val, sizeof(DWORD));
3118     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3119
3120     /* UrlInfoAbout type is REG_DWORD */
3121     sz = MAX_PATH;
3122     lstrcpyA(buf, "apple");
3123     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
3124     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3125     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3126     ok(sz == 2, "Expected 2, got %d\n", sz);
3127
3128     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_SZ, (LPBYTE)"info", 5);
3129     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3130
3131     /* UrlUpdateInfo value exists */
3132     sz = MAX_PATH;
3133     lstrcpyA(buf, "apple");
3134     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3135     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3136     ok(!lstrcmpA(buf, "info"), "Expected \"info\", got \"%s\"\n", buf);
3137     ok(sz == 4, "Expected 4, got %d\n", sz);
3138
3139     res = RegSetValueExA(propkey, "UrlUpdateInfo", 0, REG_DWORD,
3140                          (const BYTE *)&val, sizeof(DWORD));
3141     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3142
3143     /* UrlUpdateInfo type is REG_DWORD */
3144     sz = MAX_PATH;
3145     lstrcpyA(buf, "apple");
3146     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
3147     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3148     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3149     ok(sz == 2, "Expected 2, got %d\n", sz);
3150
3151     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"1", 2);
3152     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3153
3154     /* VersionMinor value exists */
3155     sz = MAX_PATH;
3156     lstrcpyA(buf, "apple");
3157     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3158     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3159     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3160     ok(sz == 1, "Expected 1, got %d\n", sz);
3161
3162     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_DWORD,
3163                          (const BYTE *)&val, sizeof(DWORD));
3164     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3165
3166     /* VersionMinor type is REG_DWORD */
3167     sz = MAX_PATH;
3168     lstrcpyA(buf, "apple");
3169     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
3170     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3171     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3172     ok(sz == 2, "Expected 2, got %d\n", sz);
3173
3174     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"1", 2);
3175     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3176
3177     /* VersionMajor value exists */
3178     sz = MAX_PATH;
3179     lstrcpyA(buf, "apple");
3180     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3181     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3182     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
3183     ok(sz == 1, "Expected 1, got %d\n", sz);
3184
3185     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_DWORD,
3186                          (const BYTE *)&val, sizeof(DWORD));
3187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3188
3189     /* VersionMajor type is REG_DWORD */
3190     sz = MAX_PATH;
3191     lstrcpyA(buf, "apple");
3192     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
3193     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3194     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3195     ok(sz == 2, "Expected 2, got %d\n", sz);
3196
3197     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
3198     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3199
3200     /* ProductID value exists */
3201     sz = MAX_PATH;
3202     lstrcpyA(buf, "apple");
3203     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3204     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3205     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
3206     ok(sz == 2, "Expected 2, got %d\n", sz);
3207
3208     res = RegSetValueExA(propkey, "ProductID", 0, REG_DWORD,
3209                          (const BYTE *)&val, sizeof(DWORD));
3210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3211
3212     /* ProductID type is REG_DWORD */
3213     sz = MAX_PATH;
3214     lstrcpyA(buf, "apple");
3215     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTID, buf, &sz);
3216     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3217     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3218     ok(sz == 2, "Expected 2, got %d\n", sz);
3219
3220     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
3221     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3222
3223     /* RegCompany value exists */
3224     sz = MAX_PATH;
3225     lstrcpyA(buf, "apple");
3226     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3227     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3228     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
3229     ok(sz == 4, "Expected 4, got %d\n", sz);
3230
3231     res = RegSetValueExA(propkey, "RegCompany", 0, REG_DWORD,
3232                          (const BYTE *)&val, sizeof(DWORD));
3233     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3234
3235     /* RegCompany type is REG_DWORD */
3236     sz = MAX_PATH;
3237     lstrcpyA(buf, "apple");
3238     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGCOMPANY, buf, &sz);
3239     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3240     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3241     ok(sz == 2, "Expected 2, got %d\n", sz);
3242
3243     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"own", 4);
3244     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3245
3246     /* RegOwner value exists */
3247     sz = MAX_PATH;
3248     lstrcpyA(buf, "apple");
3249     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3250     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3251     ok(!lstrcmpA(buf, "own"), "Expected \"own\", got \"%s\"\n", buf);
3252     ok(sz == 3, "Expected 3, got %d\n", sz);
3253
3254     res = RegSetValueExA(propkey, "RegOwner", 0, REG_DWORD,
3255                          (const BYTE *)&val, sizeof(DWORD));
3256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3257
3258     /* RegOwner type is REG_DWORD */
3259     sz = MAX_PATH;
3260     lstrcpyA(buf, "apple");
3261     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_REGOWNER, buf, &sz);
3262     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3263     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3264     ok(sz == 2, "Expected 2, got %d\n", sz);
3265
3266     res = RegSetValueExA(propkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3267     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3268
3269     /* InstanceType value exists */
3270     sz = MAX_PATH;
3271     lstrcpyA(buf, "apple");
3272     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3273     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3274     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3275     ok(sz == 0, "Expected 0, got %d\n", sz);
3276
3277     res = RegSetValueExA(propkey, "InstanceType", 0, REG_DWORD,
3278                          (const BYTE *)&val, sizeof(DWORD));
3279     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3280
3281     /* InstanceType type is REG_DWORD */
3282     sz = MAX_PATH;
3283     lstrcpyA(buf, "apple");
3284     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3285     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3286     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3287     ok(sz == 0, "Expected 0, got %d\n", sz);
3288
3289     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_SZ, (LPBYTE)"type", 5);
3290     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3291
3292     /* InstanceType value exists */
3293     sz = MAX_PATH;
3294     lstrcpyA(buf, "apple");
3295     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3296     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3297     ok(!lstrcmpA(buf, "type"), "Expected \"type\", got \"%s\"\n", buf);
3298     ok(sz == 4, "Expected 4, got %d\n", sz);
3299
3300     res = RegSetValueExA(prodkey, "InstanceType", 0, REG_DWORD,
3301                          (const BYTE *)&val, sizeof(DWORD));
3302     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3303
3304     /* InstanceType type is REG_DWORD */
3305     sz = MAX_PATH;
3306     lstrcpyA(buf, "apple");
3307     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_INSTANCETYPE, buf, &sz);
3308     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3309     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3310     ok(sz == 2, "Expected 2, got %d\n", sz);
3311
3312     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3313     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3314
3315     /* Transforms value exists */
3316     sz = MAX_PATH;
3317     lstrcpyA(buf, "apple");
3318     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3319     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3320     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3321     ok(sz == 0, "Expected 0, got %d\n", sz);
3322
3323     res = RegSetValueExA(propkey, "Transforms", 0, REG_DWORD,
3324                          (const BYTE *)&val, sizeof(DWORD));
3325     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3326
3327     /* Transforms type is REG_DWORD */
3328     sz = MAX_PATH;
3329     lstrcpyA(buf, "apple");
3330     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3331     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3332     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3333     ok(sz == 0, "Expected 0, got %d\n", sz);
3334
3335     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"tforms", 7);
3336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3337
3338     /* Transforms value exists */
3339     sz = MAX_PATH;
3340     lstrcpyA(buf, "apple");
3341     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3342     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3343     ok(!lstrcmpA(buf, "tforms"), "Expected \"tforms\", got \"%s\"\n", buf);
3344     ok(sz == 6, "Expected 6, got %d\n", sz);
3345
3346     res = RegSetValueExA(prodkey, "Transforms", 0, REG_DWORD,
3347                          (const BYTE *)&val, sizeof(DWORD));
3348     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3349
3350     /* Transforms type is REG_DWORD */
3351     sz = MAX_PATH;
3352     lstrcpyA(buf, "apple");
3353     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_TRANSFORMS, buf, &sz);
3354     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3355     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3356     ok(sz == 2, "Expected 2, got %d\n", sz);
3357
3358     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3359     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3360
3361     /* Language value exists */
3362     sz = MAX_PATH;
3363     lstrcpyA(buf, "apple");
3364     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3365     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3366     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3367     ok(sz == 0, "Expected 0, got %d\n", sz);
3368
3369     res = RegSetValueExA(propkey, "Language", 0, REG_DWORD,
3370                          (const BYTE *)&val, sizeof(DWORD));
3371     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3372
3373     /* Language type is REG_DWORD */
3374     sz = MAX_PATH;
3375     lstrcpyA(buf, "apple");
3376     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3377     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3378     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3379     ok(sz == 0, "Expected 0, got %d\n", sz);
3380
3381     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
3382     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3383
3384     /* Language value exists */
3385     sz = MAX_PATH;
3386     lstrcpyA(buf, "apple");
3387     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3388     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3389     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
3390     ok(sz == 4, "Expected 4, got %d\n", sz);
3391
3392     res = RegSetValueExA(prodkey, "Language", 0, REG_DWORD,
3393                          (const BYTE *)&val, sizeof(DWORD));
3394     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3395
3396     /* Language type is REG_DWORD */
3397     sz = MAX_PATH;
3398     lstrcpyA(buf, "apple");
3399     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_LANGUAGE, buf, &sz);
3400     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3401     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3402     ok(sz == 2, "Expected 2, got %d\n", sz);
3403
3404     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3405     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3406
3407     /* ProductName value exists */
3408     sz = MAX_PATH;
3409     lstrcpyA(buf, "apple");
3410     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3411     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3412     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3413     ok(sz == 0, "Expected 0, got %d\n", sz);
3414
3415     res = RegSetValueExA(propkey, "ProductName", 0, REG_DWORD,
3416                          (const BYTE *)&val, sizeof(DWORD));
3417     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3418
3419     /* ProductName type is REG_DWORD */
3420     sz = MAX_PATH;
3421     lstrcpyA(buf, "apple");
3422     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3423     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3424     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3425     ok(sz == 0, "Expected 0, got %d\n", sz);
3426
3427     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
3428     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3429
3430     /* ProductName value exists */
3431     sz = MAX_PATH;
3432     lstrcpyA(buf, "apple");
3433     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3434     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3435     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
3436     ok(sz == 4, "Expected 4, got %d\n", sz);
3437
3438     res = RegSetValueExA(prodkey, "ProductName", 0, REG_DWORD,
3439                          (const BYTE *)&val, sizeof(DWORD));
3440     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3441
3442     /* ProductName type is REG_DWORD */
3443     sz = MAX_PATH;
3444     lstrcpyA(buf, "apple");
3445     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
3446     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3447     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3448     ok(sz == 2, "Expected 2, got %d\n", sz);
3449
3450     res = RegSetValueExA(propkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3451     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3452
3453     /* Assignment value exists */
3454     sz = MAX_PATH;
3455     lstrcpyA(buf, "apple");
3456     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3457     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3458     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3459     ok(sz == 0, "Expected 0, got %d\n", sz);
3460
3461     res = RegSetValueExA(propkey, "Assignment", 0, REG_DWORD,
3462                          (const BYTE *)&val, sizeof(DWORD));
3463     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3464
3465     /* Assignment type is REG_DWORD */
3466     sz = MAX_PATH;
3467     lstrcpyA(buf, "apple");
3468     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3469     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3470     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3471     ok(sz == 0, "Expected 0, got %d\n", sz);
3472
3473     res = RegSetValueExA(prodkey, "Assignment", 0, REG_SZ, (LPBYTE)"at", 3);
3474     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3475
3476     /* Assignment value exists */
3477     sz = MAX_PATH;
3478     lstrcpyA(buf, "apple");
3479     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3480     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3481     ok(!lstrcmpA(buf, "at"), "Expected \"at\", got \"%s\"\n", buf);
3482     ok(sz == 2, "Expected 2, got %d\n", sz);
3483
3484     res = RegSetValueExA(prodkey, "Assignment", 0, REG_DWORD,
3485                          (const BYTE *)&val, sizeof(DWORD));
3486     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3487
3488     /* Assignment type is REG_DWORD */
3489     sz = MAX_PATH;
3490     lstrcpyA(buf, "apple");
3491     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
3492     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3493     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3494     ok(sz == 2, "Expected 2, got %d\n", sz);
3495
3496     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3497     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3498
3499     /* PackageCode value exists */
3500     sz = MAX_PATH;
3501     lstrcpyA(buf, "apple");
3502     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3503     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3504     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3505     ok(sz == 0, "Expected 0, got %d\n", sz);
3506
3507     res = RegSetValueExA(propkey, "PackageCode", 0, REG_DWORD,
3508                          (const BYTE *)&val, sizeof(DWORD));
3509     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3510
3511     /* PackageCode type is REG_DWORD */
3512     sz = MAX_PATH;
3513     lstrcpyA(buf, "apple");
3514     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3515     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3516     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3517     ok(sz == 0, "Expected 0, got %d\n", sz);
3518
3519     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
3520     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3521
3522     /* PackageCode value exists */
3523     sz = MAX_PATH;
3524     lstrcpyA(buf, "apple");
3525     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3526     ok(r == ERROR_BAD_CONFIGURATION,
3527        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
3528     ok(!lstrcmpA(buf, "code"), "Expected \"code\", got \"%s\"\n", buf);
3529     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3530
3531     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_DWORD,
3532                          (const BYTE *)&val, sizeof(DWORD));
3533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3534
3535     /* PackageCode type is REG_DWORD */
3536     sz = MAX_PATH;
3537     lstrcpyA(buf, "apple");
3538     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3539     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3540     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3541     ok(sz == 2, "Expected 2, got %d\n", sz);
3542
3543     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)pack_squashed, 33);
3544     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3545
3546     /* PackageCode value exists */
3547     sz = MAX_PATH;
3548     lstrcpyA(buf, "apple");
3549     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGECODE, buf, &sz);
3550     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3551     ok(!lstrcmpA(buf, packcode), "Expected \"%s\", got \"%s\"\n", packcode, buf);
3552     ok(sz == 38, "Expected 38, got %d\n", sz);
3553
3554     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3555     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3556
3557     /* Version value exists */
3558     sz = MAX_PATH;
3559     lstrcpyA(buf, "apple");
3560     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3561     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3562     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3563     ok(sz == 0, "Expected 0, got %d\n", sz);
3564
3565     res = RegSetValueExA(propkey, "Version", 0, REG_DWORD,
3566                          (const BYTE *)&val, sizeof(DWORD));
3567     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3568
3569     /* Version type is REG_DWORD */
3570     sz = MAX_PATH;
3571     lstrcpyA(buf, "apple");
3572     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3573     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3574     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3575     ok(sz == 0, "Expected 0, got %d\n", sz);
3576
3577     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
3578     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3579
3580     /* Version value exists */
3581     sz = MAX_PATH;
3582     lstrcpyA(buf, "apple");
3583     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3584     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3585     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
3586     ok(sz == 3, "Expected 3, got %d\n", sz);
3587
3588     res = RegSetValueExA(prodkey, "Version", 0, REG_DWORD,
3589                          (const BYTE *)&val, sizeof(DWORD));
3590     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3591
3592     /* Version type is REG_DWORD */
3593     sz = MAX_PATH;
3594     lstrcpyA(buf, "apple");
3595     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_VERSION, buf, &sz);
3596     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3597     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3598     ok(sz == 2, "Expected 2, got %d\n", sz);
3599
3600     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3602
3603     /* ProductIcon value exists */
3604     sz = MAX_PATH;
3605     lstrcpyA(buf, "apple");
3606     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3607     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3608     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3609     ok(sz == 0, "Expected 0, got %d\n", sz);
3610
3611     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_DWORD,
3612                          (const BYTE *)&val, sizeof(DWORD));
3613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3614
3615     /* ProductIcon type is REG_DWORD */
3616     sz = MAX_PATH;
3617     lstrcpyA(buf, "apple");
3618     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3619     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3620     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3621     ok(sz == 0, "Expected 0, got %d\n", sz);
3622
3623     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"ico", 4);
3624     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3625
3626     /* ProductIcon value exists */
3627     sz = MAX_PATH;
3628     lstrcpyA(buf, "apple");
3629     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3630     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3631     ok(!lstrcmpA(buf, "ico"), "Expected \"ico\", got \"%s\"\n", buf);
3632     ok(sz == 3, "Expected 3, got %d\n", sz);
3633
3634     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_DWORD,
3635                          (const BYTE *)&val, sizeof(DWORD));
3636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3637
3638     /* ProductIcon type is REG_DWORD */
3639     sz = MAX_PATH;
3640     lstrcpyA(buf, "apple");
3641     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PRODUCTICON, buf, &sz);
3642     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3643     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3644     ok(sz == 2, "Expected 2, got %d\n", sz);
3645
3646     res = RegCreateKeyA(prodkey, "SourceList", &source);
3647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3648
3649     res = RegSetValueExA(source, "PackageName", 0, REG_SZ, (LPBYTE)"packname", 9);
3650     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3651
3652     sz = MAX_PATH;
3653     lstrcpyA(buf, "apple");
3654     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3655     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3656     ok(!lstrcmpA(buf, "packname"), "Expected \"packname\", got \"%s\"\n", buf);
3657     ok(sz == 8, "Expected 8, got %d\n", sz);
3658
3659     res = RegSetValueExA(source, "PackageName", 0, REG_DWORD,
3660                          (const BYTE *)&val, sizeof(DWORD));
3661     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3662
3663     /* PackageName type is REG_DWORD */
3664     sz = MAX_PATH;
3665     lstrcpyA(buf, "apple");
3666     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_PACKAGENAME, buf, &sz);
3667     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3668     ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3669     ok(sz == 2, "Expected 2, got %d\n", sz);
3670
3671     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3672     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3673
3674     /* Authorized value exists */
3675     sz = MAX_PATH;
3676     lstrcpyA(buf, "apple");
3677     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3678     if (r != ERROR_UNKNOWN_PROPERTY)
3679     {
3680         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3681         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3682         ok(sz == 0, "Expected 0, got %d\n", sz);
3683     }
3684
3685     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_DWORD,
3686                          (const BYTE *)&val, sizeof(DWORD));
3687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3688
3689     /* AuthorizedLUAApp type is REG_DWORD */
3690     sz = MAX_PATH;
3691     lstrcpyA(buf, "apple");
3692     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3693     if (r != ERROR_UNKNOWN_PROPERTY)
3694     {
3695         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3696         ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3697         ok(sz == 0, "Expected 0, got %d\n", sz);
3698     }
3699
3700     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
3701     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3702
3703     /* Authorized value exists */
3704     sz = MAX_PATH;
3705     lstrcpyA(buf, "apple");
3706     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3707     if (r != ERROR_UNKNOWN_PROPERTY)
3708     {
3709         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3710         ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
3711         ok(sz == 4, "Expected 4, got %d\n", sz);
3712     }
3713
3714     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_DWORD,
3715                          (const BYTE *)&val, sizeof(DWORD));
3716     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3717
3718     /* AuthorizedLUAApp type is REG_DWORD */
3719     sz = MAX_PATH;
3720     lstrcpyA(buf, "apple");
3721     r = MsiGetProductInfoA(prodcode, INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
3722     if (r != ERROR_UNKNOWN_PROPERTY)
3723     {
3724         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3725         ok(!lstrcmpA(buf, "42"), "Expected \"42\", got \"%s\"\n", buf);
3726         ok(sz == 2, "Expected 2, got %d\n", sz);
3727     }
3728
3729     RegDeleteValueA(propkey, "HelpLink");
3730     RegDeleteValueA(propkey, "DisplayName");
3731     RegDeleteValueA(propkey, "DisplayVersion");
3732     RegDeleteValueA(propkey, "HelpTelephone");
3733     RegDeleteValueA(propkey, "InstallLocation");
3734     RegDeleteValueA(propkey, "InstallSource");
3735     RegDeleteValueA(propkey, "InstallDate");
3736     RegDeleteValueA(propkey, "Publisher");
3737     RegDeleteValueA(propkey, "LocalPackage");
3738     RegDeleteValueA(propkey, "UrlInfoAbout");
3739     RegDeleteValueA(propkey, "UrlUpdateInfo");
3740     RegDeleteValueA(propkey, "VersionMinor");
3741     RegDeleteValueA(propkey, "VersionMajor");
3742     RegDeleteValueA(propkey, "ProductID");
3743     RegDeleteValueA(propkey, "RegCompany");
3744     RegDeleteValueA(propkey, "RegOwner");
3745     RegDeleteValueA(propkey, "InstanceType");
3746     RegDeleteValueA(propkey, "Transforms");
3747     RegDeleteValueA(propkey, "Language");
3748     RegDeleteValueA(propkey, "ProductName");
3749     RegDeleteValueA(propkey, "Assignment");
3750     RegDeleteValueA(propkey, "PackageCode");
3751     RegDeleteValueA(propkey, "Version");
3752     RegDeleteValueA(propkey, "ProductIcon");
3753     RegDeleteValueA(propkey, "AuthorizedLUAApp");
3754     RegDeleteKeyA(propkey, "");
3755     RegDeleteKeyA(localkey, "");
3756     RegDeleteValueA(prodkey, "InstanceType");
3757     RegDeleteValueA(prodkey, "Transforms");
3758     RegDeleteValueA(prodkey, "Language");
3759     RegDeleteValueA(prodkey, "ProductName");
3760     RegDeleteValueA(prodkey, "Assignment");
3761     RegDeleteValueA(prodkey, "PackageCode");
3762     RegDeleteValueA(prodkey, "Version");
3763     RegDeleteValueA(prodkey, "ProductIcon");
3764     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
3765     RegDeleteValueA(source, "PackageName");
3766     RegDeleteKeyA(source, "");
3767     RegDeleteKeyA(prodkey, "");
3768     RegCloseKey(propkey);
3769     RegCloseKey(localkey);
3770     RegCloseKey(source);
3771     RegCloseKey(prodkey);
3772 }
3773
3774 static void test_MsiGetProductInfoEx(void)
3775 {
3776     UINT r;
3777     LONG res;
3778     HKEY propkey, userkey;
3779     HKEY prodkey, localkey;
3780     CHAR prodcode[MAX_PATH];
3781     CHAR prod_squashed[MAX_PATH];
3782     CHAR packcode[MAX_PATH];
3783     CHAR pack_squashed[MAX_PATH];
3784     CHAR buf[MAX_PATH];
3785     CHAR keypath[MAX_PATH];
3786     LPSTR usersid;
3787     DWORD sz;
3788
3789     if (!pMsiGetProductInfoExA)
3790     {
3791         skip("MsiGetProductInfoExA is not available\n");
3792         return;
3793     }
3794
3795     create_test_guid(prodcode, prod_squashed);
3796     create_test_guid(packcode, pack_squashed);
3797     get_user_sid(&usersid);
3798
3799     /* NULL szProductCode */
3800     sz = MAX_PATH;
3801     lstrcpyA(buf, "apple");
3802     r = pMsiGetProductInfoExA(NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3803                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3804     ok(r == ERROR_INVALID_PARAMETER,
3805        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3806     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3807     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3808
3809     /* empty szProductCode */
3810     sz = MAX_PATH;
3811     lstrcpyA(buf, "apple");
3812     r = pMsiGetProductInfoExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3813                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3814     ok(r == ERROR_INVALID_PARAMETER,
3815        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3816     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3817     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3818
3819     /* garbage szProductCode */
3820     sz = MAX_PATH;
3821     lstrcpyA(buf, "apple");
3822     r = pMsiGetProductInfoExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
3823                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3824     ok(r == ERROR_INVALID_PARAMETER,
3825        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3826     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3827     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3828
3829     /* guid without brackets */
3830     sz = MAX_PATH;
3831     lstrcpyA(buf, "apple");
3832     r = pMsiGetProductInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
3833                               MSIINSTALLCONTEXT_USERUNMANAGED,
3834                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3835     ok(r == ERROR_INVALID_PARAMETER,
3836        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3837     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3838     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3839
3840     /* guid with brackets */
3841     sz = MAX_PATH;
3842     lstrcpyA(buf, "apple");
3843     r = pMsiGetProductInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", usersid,
3844                               MSIINSTALLCONTEXT_USERUNMANAGED,
3845                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3846     ok(r == ERROR_UNKNOWN_PRODUCT,
3847        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3848     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3849     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3850
3851     /* szValue is non-NULL while pcchValue is NULL */
3852     lstrcpyA(buf, "apple");
3853     r = pMsiGetProductInfoExA(prodcode, usersid,
3854                               MSIINSTALLCONTEXT_USERUNMANAGED,
3855                               INSTALLPROPERTY_PRODUCTSTATE, buf, NULL);
3856     ok(r == ERROR_INVALID_PARAMETER,
3857        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3858     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3859
3860     /* dwContext is out of range */
3861     sz = MAX_PATH;
3862     lstrcpyA(buf, "apple");
3863     r = pMsiGetProductInfoExA(prodcode, usersid, 42,
3864                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3865     ok(r == ERROR_INVALID_PARAMETER,
3866        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3867     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3868     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3869
3870     /* szProperty is NULL */
3871     sz = MAX_PATH;
3872     lstrcpyA(buf, "apple");
3873     r = pMsiGetProductInfoExA(prodcode, usersid,
3874                               MSIINSTALLCONTEXT_USERUNMANAGED,
3875                               NULL, buf, &sz);
3876     ok(r == ERROR_INVALID_PARAMETER,
3877        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3878     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3879     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3880
3881     /* szProperty is empty */
3882     sz = MAX_PATH;
3883     lstrcpyA(buf, "apple");
3884     r = pMsiGetProductInfoExA(prodcode, usersid,
3885                               MSIINSTALLCONTEXT_USERUNMANAGED,
3886                               "", buf, &sz);
3887     ok(r == ERROR_INVALID_PARAMETER,
3888        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3889     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3890     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3891
3892     /* szProperty is not a valid property */
3893     sz = MAX_PATH;
3894     lstrcpyA(buf, "apple");
3895     r = pMsiGetProductInfoExA(prodcode, usersid,
3896                               MSIINSTALLCONTEXT_USERUNMANAGED,
3897                               "notvalid", buf, &sz);
3898     ok(r == ERROR_UNKNOWN_PRODUCT,
3899        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3900     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3901     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3902
3903     /* same length as guid, but random */
3904     sz = MAX_PATH;
3905     lstrcpyA(buf, "apple");
3906     r = pMsiGetProductInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", usersid,
3907                               MSIINSTALLCONTEXT_USERUNMANAGED,
3908                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3909     ok(r == ERROR_INVALID_PARAMETER,
3910        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3911     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3912     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3913
3914     /* MSIINSTALLCONTEXT_USERUNMANAGED */
3915
3916     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
3917     lstrcatA(keypath, usersid);
3918     lstrcatA(keypath, "\\Products\\");
3919     lstrcatA(keypath, prod_squashed);
3920
3921     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
3922     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3923
3924     /* local user product key exists */
3925     sz = MAX_PATH;
3926     lstrcpyA(buf, "apple");
3927     r = pMsiGetProductInfoExA(prodcode, usersid,
3928                               MSIINSTALLCONTEXT_USERUNMANAGED,
3929                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3930     ok(r == ERROR_UNKNOWN_PRODUCT,
3931        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3932     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3933     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3934
3935     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
3936     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3937
3938     /* InstallProperties key exists */
3939     sz = MAX_PATH;
3940     lstrcpyA(buf, "apple");
3941     r = pMsiGetProductInfoExA(prodcode, usersid,
3942                               MSIINSTALLCONTEXT_USERUNMANAGED,
3943                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3944     ok(r == ERROR_UNKNOWN_PRODUCT,
3945        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3946     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3947     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3948
3949     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3950     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3951
3952     /* LocalPackage value exists */
3953     sz = MAX_PATH;
3954     lstrcpyA(buf, "apple");
3955     r = pMsiGetProductInfoExA(prodcode, usersid,
3956                               MSIINSTALLCONTEXT_USERUNMANAGED,
3957                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
3958     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3959     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
3960     ok(sz == 1, "Expected 1, got %d\n", sz);
3961
3962     RegDeleteValueA(propkey, "LocalPackage");
3963
3964     /* LocalPackage value must exist */
3965     sz = MAX_PATH;
3966     lstrcpyA(buf, "apple");
3967     r = pMsiGetProductInfoExA(prodcode, usersid,
3968                               MSIINSTALLCONTEXT_USERUNMANAGED,
3969                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3970     ok(r == ERROR_UNKNOWN_PRODUCT,
3971        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
3972     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
3973     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
3974
3975     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
3976     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3977
3978     /* LocalPackage exists, but HelpLink does not exist */
3979     sz = MAX_PATH;
3980     lstrcpyA(buf, "apple");
3981     r = pMsiGetProductInfoExA(prodcode, usersid,
3982                               MSIINSTALLCONTEXT_USERUNMANAGED,
3983                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3984     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3985     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
3986     ok(sz == 0, "Expected 0, got %d\n", sz);
3987
3988     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
3989     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
3990
3991     /* HelpLink value exists */
3992     sz = MAX_PATH;
3993     lstrcpyA(buf, "apple");
3994     r = pMsiGetProductInfoExA(prodcode, usersid,
3995                               MSIINSTALLCONTEXT_USERUNMANAGED,
3996                               INSTALLPROPERTY_HELPLINK, buf, &sz);
3997     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3998     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
3999     ok(sz == 4, "Expected 4, got %d\n", sz);
4000
4001     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4002     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4003
4004     /* HelpTelephone value exists */
4005     sz = MAX_PATH;
4006     lstrcpyA(buf, "apple");
4007     r = pMsiGetProductInfoExA(prodcode, usersid,
4008                               MSIINSTALLCONTEXT_USERUNMANAGED,
4009                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4010     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4011     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4012     ok(sz == 5, "Expected 5, got %d\n", sz);
4013
4014     /* szValue and pcchValue are NULL */
4015     r = pMsiGetProductInfoExA(prodcode, usersid,
4016                               MSIINSTALLCONTEXT_USERUNMANAGED,
4017                               INSTALLPROPERTY_HELPTELEPHONE, NULL, NULL);
4018     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4019
4020     /* pcchValue is exactly 5 */
4021     sz = 5;
4022     lstrcpyA(buf, "apple");
4023     r = pMsiGetProductInfoExA(prodcode, usersid,
4024                               MSIINSTALLCONTEXT_USERUNMANAGED,
4025                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4026     ok(r == ERROR_MORE_DATA,
4027        "Expected ERROR_MORE_DATA, got %d\n", r);
4028     ok(sz == 10, "Expected 10, got %d\n", sz);
4029
4030     /* szValue is NULL, pcchValue is exactly 5 */
4031     sz = 5;
4032     r = pMsiGetProductInfoExA(prodcode, usersid,
4033                               MSIINSTALLCONTEXT_USERUNMANAGED,
4034                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4035     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4036     ok(sz == 10, "Expected 10, got %d\n", sz);
4037
4038     /* szValue is NULL, pcchValue is MAX_PATH */
4039     sz = MAX_PATH;
4040     r = pMsiGetProductInfoExA(prodcode, usersid,
4041                               MSIINSTALLCONTEXT_USERUNMANAGED,
4042                               INSTALLPROPERTY_HELPTELEPHONE, NULL, &sz);
4043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4044     ok(sz == 10, "Expected 10, got %d\n", sz);
4045
4046     /* pcchValue is exactly 0 */
4047     sz = 0;
4048     lstrcpyA(buf, "apple");
4049     r = pMsiGetProductInfoExA(prodcode, usersid,
4050                               MSIINSTALLCONTEXT_USERUNMANAGED,
4051                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4052     ok(r == ERROR_MORE_DATA,
4053        "Expected ERROR_MORE_DATA, got %d\n", r);
4054     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
4055     ok(sz == 10, "Expected 10, got %d\n", sz);
4056
4057     res = RegSetValueExA(propkey, "notvalid", 0, REG_SZ, (LPBYTE)"invalid", 8);
4058     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4059
4060     /* szProperty is not a valid property */
4061     sz = MAX_PATH;
4062     lstrcpyA(buf, "apple");
4063     r = pMsiGetProductInfoExA(prodcode, usersid,
4064                               MSIINSTALLCONTEXT_USERUNMANAGED,
4065                               "notvalid", buf, &sz);
4066     ok(r == ERROR_UNKNOWN_PROPERTY,
4067        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4068     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4069     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4070
4071     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4072     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4073
4074     /* InstallDate value exists */
4075     sz = MAX_PATH;
4076     lstrcpyA(buf, "apple");
4077     r = pMsiGetProductInfoExA(prodcode, usersid,
4078                               MSIINSTALLCONTEXT_USERUNMANAGED,
4079                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4080     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4081     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4082     ok(sz == 4, "Expected 4, got %d\n", sz);
4083
4084     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4085     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4086
4087     /* DisplayName value exists */
4088     sz = MAX_PATH;
4089     lstrcpyA(buf, "apple");
4090     r = pMsiGetProductInfoExA(prodcode, usersid,
4091                               MSIINSTALLCONTEXT_USERUNMANAGED,
4092                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4093     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4094     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4095     ok(sz == 4, "Expected 4, got %d\n", sz);
4096
4097     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4098     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4099
4100     /* InstallLocation value exists */
4101     sz = MAX_PATH;
4102     lstrcpyA(buf, "apple");
4103     r = pMsiGetProductInfoExA(prodcode, usersid,
4104                               MSIINSTALLCONTEXT_USERUNMANAGED,
4105                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4106     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4107     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4108     ok(sz == 3, "Expected 3, got %d\n", sz);
4109
4110     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4111     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4112
4113     /* InstallSource value exists */
4114     sz = MAX_PATH;
4115     lstrcpyA(buf, "apple");
4116     r = pMsiGetProductInfoExA(prodcode, usersid,
4117                               MSIINSTALLCONTEXT_USERUNMANAGED,
4118                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4119     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4120     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4121     ok(sz == 6, "Expected 6, got %d\n", sz);
4122
4123     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4124     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4125
4126     /* LocalPackage value exists */
4127     sz = MAX_PATH;
4128     lstrcpyA(buf, "apple");
4129     r = pMsiGetProductInfoExA(prodcode, usersid,
4130                               MSIINSTALLCONTEXT_USERUNMANAGED,
4131                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4132     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4133     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4134     ok(sz == 5, "Expected 5, got %d\n", sz);
4135
4136     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4137     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4138
4139     /* Publisher value exists */
4140     sz = MAX_PATH;
4141     lstrcpyA(buf, "apple");
4142     r = pMsiGetProductInfoExA(prodcode, usersid,
4143                               MSIINSTALLCONTEXT_USERUNMANAGED,
4144                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4146     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4147     ok(sz == 3, "Expected 3, got %d\n", sz);
4148
4149     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4151
4152     /* URLInfoAbout value exists */
4153     sz = MAX_PATH;
4154     lstrcpyA(buf, "apple");
4155     r = pMsiGetProductInfoExA(prodcode, usersid,
4156                               MSIINSTALLCONTEXT_USERUNMANAGED,
4157                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4158     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4159     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4160     ok(sz == 5, "Expected 5, got %d\n", sz);
4161
4162     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4163     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4164
4165     /* URLUpdateInfo value exists */
4166     sz = MAX_PATH;
4167     lstrcpyA(buf, "apple");
4168     r = pMsiGetProductInfoExA(prodcode, usersid,
4169                               MSIINSTALLCONTEXT_USERUNMANAGED,
4170                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4171     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4172     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
4173     ok(sz == 6, "Expected 6, got %d\n", sz);
4174
4175     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4176     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4177
4178     /* VersionMinor value exists */
4179     sz = MAX_PATH;
4180     lstrcpyA(buf, "apple");
4181     r = pMsiGetProductInfoExA(prodcode, usersid,
4182                               MSIINSTALLCONTEXT_USERUNMANAGED,
4183                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4184     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4185     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
4186     ok(sz == 1, "Expected 1, got %d\n", sz);
4187
4188     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4189     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4190
4191     /* VersionMajor value exists */
4192     sz = MAX_PATH;
4193     lstrcpyA(buf, "apple");
4194     r = pMsiGetProductInfoExA(prodcode, usersid,
4195                               MSIINSTALLCONTEXT_USERUNMANAGED,
4196                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4197     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4198     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
4199     ok(sz == 1, "Expected 1, got %d\n", sz);
4200
4201     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4203
4204     /* DisplayVersion value exists */
4205     sz = MAX_PATH;
4206     lstrcpyA(buf, "apple");
4207     r = pMsiGetProductInfoExA(prodcode, usersid,
4208                               MSIINSTALLCONTEXT_USERUNMANAGED,
4209                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4210     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4211     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
4212     ok(sz == 5, "Expected 5, got %d\n", sz);
4213
4214     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4215     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4216
4217     /* ProductID value exists */
4218     sz = MAX_PATH;
4219     lstrcpyA(buf, "apple");
4220     r = pMsiGetProductInfoExA(prodcode, usersid,
4221                               MSIINSTALLCONTEXT_USERUNMANAGED,
4222                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4223     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4224     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
4225     ok(sz == 2, "Expected 2, got %d\n", sz);
4226
4227     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4228     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4229
4230     /* RegCompany value exists */
4231     sz = MAX_PATH;
4232     lstrcpyA(buf, "apple");
4233     r = pMsiGetProductInfoExA(prodcode, usersid,
4234                               MSIINSTALLCONTEXT_USERUNMANAGED,
4235                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4236     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4237     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
4238     ok(sz == 4, "Expected 4, got %d\n", sz);
4239
4240     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4241     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4242
4243     /* RegOwner value exists */
4244     sz = MAX_PATH;
4245     lstrcpyA(buf, "apple");
4246     r = pMsiGetProductInfoExA(prodcode, usersid,
4247                               MSIINSTALLCONTEXT_USERUNMANAGED,
4248                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4249     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4250     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
4251     ok(sz == 5, "Expected 5, got %d\n", sz);
4252
4253     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4254     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4255
4256     /* Transforms value exists */
4257     sz = MAX_PATH;
4258     lstrcpyA(buf, "apple");
4259     r = pMsiGetProductInfoExA(prodcode, usersid,
4260                               MSIINSTALLCONTEXT_USERUNMANAGED,
4261                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4262     ok(r == ERROR_UNKNOWN_PRODUCT,
4263        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4264     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4265     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4266
4267     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4268     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4269
4270     /* Language value exists */
4271     sz = MAX_PATH;
4272     lstrcpyA(buf, "apple");
4273     r = pMsiGetProductInfoExA(prodcode, usersid,
4274                               MSIINSTALLCONTEXT_USERUNMANAGED,
4275                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4276     ok(r == ERROR_UNKNOWN_PRODUCT,
4277        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4278     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4279     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4280
4281     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4283
4284     /* ProductName value exists */
4285     sz = MAX_PATH;
4286     lstrcpyA(buf, "apple");
4287     r = pMsiGetProductInfoExA(prodcode, usersid,
4288                               MSIINSTALLCONTEXT_USERUNMANAGED,
4289                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4290     ok(r == ERROR_UNKNOWN_PRODUCT,
4291        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4292     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4293     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4294
4295     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4296     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4297
4298     /* FIXME */
4299
4300     /* AssignmentType value exists */
4301     sz = MAX_PATH;
4302     lstrcpyA(buf, "apple");
4303     r = pMsiGetProductInfoExA(prodcode, usersid,
4304                               MSIINSTALLCONTEXT_USERUNMANAGED,
4305                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4306     ok(r == ERROR_UNKNOWN_PRODUCT,
4307        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4308     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4309     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4310
4311     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4312     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4313
4314     /* PackageCode value exists */
4315     sz = MAX_PATH;
4316     lstrcpyA(buf, "apple");
4317     r = pMsiGetProductInfoExA(prodcode, usersid,
4318                               MSIINSTALLCONTEXT_USERUNMANAGED,
4319                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4320     ok(r == ERROR_UNKNOWN_PRODUCT,
4321        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4322     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4323     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4324
4325     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4326     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4327
4328     /* Version value exists */
4329     sz = MAX_PATH;
4330     lstrcpyA(buf, "apple");
4331     r = pMsiGetProductInfoExA(prodcode, usersid,
4332                               MSIINSTALLCONTEXT_USERUNMANAGED,
4333                               INSTALLPROPERTY_VERSION, buf, &sz);
4334     ok(r == ERROR_UNKNOWN_PRODUCT,
4335        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4336     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4337     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4338
4339     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4340     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4341
4342     /* ProductIcon value exists */
4343     sz = MAX_PATH;
4344     lstrcpyA(buf, "apple");
4345     r = pMsiGetProductInfoExA(prodcode, usersid,
4346                               MSIINSTALLCONTEXT_USERUNMANAGED,
4347                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4348     ok(r == ERROR_UNKNOWN_PRODUCT,
4349        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4350     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4351     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4352
4353     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4355
4356     /* PackageName value exists */
4357     sz = MAX_PATH;
4358     lstrcpyA(buf, "apple");
4359     r = pMsiGetProductInfoExA(prodcode, usersid,
4360                               MSIINSTALLCONTEXT_USERUNMANAGED,
4361                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4362     ok(r == ERROR_UNKNOWN_PRODUCT,
4363        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4364     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4365     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4366
4367     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4368     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4369
4370     /* AuthorizedLUAApp value exists */
4371     sz = MAX_PATH;
4372     lstrcpyA(buf, "apple");
4373     r = pMsiGetProductInfoExA(prodcode, usersid,
4374                               MSIINSTALLCONTEXT_USERUNMANAGED,
4375                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4376     ok(r == ERROR_UNKNOWN_PRODUCT,
4377        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4378     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4379     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4380
4381     RegDeleteValueA(propkey, "AuthorizedLUAApp");
4382     RegDeleteValueA(propkey, "PackageName");
4383     RegDeleteValueA(propkey, "ProductIcon");
4384     RegDeleteValueA(propkey, "Version");
4385     RegDeleteValueA(propkey, "PackageCode");
4386     RegDeleteValueA(propkey, "AssignmentType");
4387     RegDeleteValueA(propkey, "ProductName");
4388     RegDeleteValueA(propkey, "Language");
4389     RegDeleteValueA(propkey, "Transforms");
4390     RegDeleteValueA(propkey, "RegOwner");
4391     RegDeleteValueA(propkey, "RegCompany");
4392     RegDeleteValueA(propkey, "ProductID");
4393     RegDeleteValueA(propkey, "DisplayVersion");
4394     RegDeleteValueA(propkey, "VersionMajor");
4395     RegDeleteValueA(propkey, "VersionMinor");
4396     RegDeleteValueA(propkey, "URLUpdateInfo");
4397     RegDeleteValueA(propkey, "URLInfoAbout");
4398     RegDeleteValueA(propkey, "Publisher");
4399     RegDeleteValueA(propkey, "LocalPackage");
4400     RegDeleteValueA(propkey, "InstallSource");
4401     RegDeleteValueA(propkey, "InstallLocation");
4402     RegDeleteValueA(propkey, "DisplayName");
4403     RegDeleteValueA(propkey, "InstallDate");
4404     RegDeleteValueA(propkey, "HelpTelephone");
4405     RegDeleteValueA(propkey, "HelpLink");
4406     RegDeleteValueA(propkey, "LocalPackage");
4407     RegDeleteKeyA(propkey, "");
4408     RegCloseKey(propkey);
4409     RegDeleteKeyA(localkey, "");
4410     RegCloseKey(localkey);
4411
4412     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
4413     lstrcatA(keypath, usersid);
4414     lstrcatA(keypath, "\\Installer\\Products\\");
4415     lstrcatA(keypath, prod_squashed);
4416
4417     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
4418     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4419
4420     /* user product key exists */
4421     sz = MAX_PATH;
4422     lstrcpyA(buf, "apple");
4423     r = pMsiGetProductInfoExA(prodcode, usersid,
4424                               MSIINSTALLCONTEXT_USERUNMANAGED,
4425                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4426     ok(r == ERROR_UNKNOWN_PRODUCT,
4427        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4428     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4429     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4430
4431     RegDeleteKeyA(userkey, "");
4432     RegCloseKey(userkey);
4433
4434     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
4435     lstrcatA(keypath, prod_squashed);
4436
4437     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
4438     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4439
4440     sz = MAX_PATH;
4441     lstrcpyA(buf, "apple");
4442     r = pMsiGetProductInfoExA(prodcode, usersid,
4443                               MSIINSTALLCONTEXT_USERUNMANAGED,
4444                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4445     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4446     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
4447     ok(sz == 1, "Expected 1, got %d\n", sz);
4448
4449     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4450     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4451
4452     /* HelpLink value exists */
4453     sz = MAX_PATH;
4454     lstrcpyA(buf, "apple");
4455     r = pMsiGetProductInfoExA(prodcode, usersid,
4456                               MSIINSTALLCONTEXT_USERUNMANAGED,
4457                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4458     ok(r == ERROR_UNKNOWN_PROPERTY,
4459        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4460     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4461     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4462
4463     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4464     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4465
4466     /* HelpTelephone value exists */
4467     sz = MAX_PATH;
4468     lstrcpyA(buf, "apple");
4469     r = pMsiGetProductInfoExA(prodcode, usersid,
4470                               MSIINSTALLCONTEXT_USERUNMANAGED,
4471                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4472     ok(r == ERROR_UNKNOWN_PROPERTY,
4473        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4474     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4475     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4476
4477     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4478     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4479
4480     /* InstallDate value exists */
4481     sz = MAX_PATH;
4482     lstrcpyA(buf, "apple");
4483     r = pMsiGetProductInfoExA(prodcode, usersid,
4484                               MSIINSTALLCONTEXT_USERUNMANAGED,
4485                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4486     ok(r == ERROR_UNKNOWN_PROPERTY,
4487        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4488     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4489     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4490
4491     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4493
4494     /* DisplayName value exists */
4495     sz = MAX_PATH;
4496     lstrcpyA(buf, "apple");
4497     r = pMsiGetProductInfoExA(prodcode, usersid,
4498                               MSIINSTALLCONTEXT_USERUNMANAGED,
4499                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4500     ok(r == ERROR_UNKNOWN_PROPERTY,
4501        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4502     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4503     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4504
4505     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4506     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4507
4508     /* InstallLocation value exists */
4509     sz = MAX_PATH;
4510     lstrcpyA(buf, "apple");
4511     r = pMsiGetProductInfoExA(prodcode, usersid,
4512                               MSIINSTALLCONTEXT_USERUNMANAGED,
4513                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4514     ok(r == ERROR_UNKNOWN_PROPERTY,
4515        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4516     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4517     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4518
4519     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4520     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4521
4522     /* InstallSource value exists */
4523     sz = MAX_PATH;
4524     lstrcpyA(buf, "apple");
4525     r = pMsiGetProductInfoExA(prodcode, usersid,
4526                               MSIINSTALLCONTEXT_USERUNMANAGED,
4527                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4528     ok(r == ERROR_UNKNOWN_PROPERTY,
4529        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4530     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4531     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4532
4533     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4534     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4535
4536     /* LocalPackage value exists */
4537     sz = MAX_PATH;
4538     lstrcpyA(buf, "apple");
4539     r = pMsiGetProductInfoExA(prodcode, usersid,
4540                               MSIINSTALLCONTEXT_USERUNMANAGED,
4541                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4542     ok(r == ERROR_UNKNOWN_PROPERTY,
4543        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4544     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4545     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4546
4547     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4549
4550     /* Publisher value exists */
4551     sz = MAX_PATH;
4552     lstrcpyA(buf, "apple");
4553     r = pMsiGetProductInfoExA(prodcode, usersid,
4554                               MSIINSTALLCONTEXT_USERUNMANAGED,
4555                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4556     ok(r == ERROR_UNKNOWN_PROPERTY,
4557        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4558     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4559     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4560
4561     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4562     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4563
4564     /* URLInfoAbout value exists */
4565     sz = MAX_PATH;
4566     lstrcpyA(buf, "apple");
4567     r = pMsiGetProductInfoExA(prodcode, usersid,
4568                               MSIINSTALLCONTEXT_USERUNMANAGED,
4569                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4570     ok(r == ERROR_UNKNOWN_PROPERTY,
4571        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4572     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4573     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4574
4575     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4576     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4577
4578     /* URLUpdateInfo value exists */
4579     sz = MAX_PATH;
4580     lstrcpyA(buf, "apple");
4581     r = pMsiGetProductInfoExA(prodcode, usersid,
4582                               MSIINSTALLCONTEXT_USERUNMANAGED,
4583                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
4584     ok(r == ERROR_UNKNOWN_PROPERTY,
4585        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4586     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4587     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4588
4589     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
4590     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4591
4592     /* VersionMinor value exists */
4593     sz = MAX_PATH;
4594     lstrcpyA(buf, "apple");
4595     r = pMsiGetProductInfoExA(prodcode, usersid,
4596                               MSIINSTALLCONTEXT_USERUNMANAGED,
4597                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
4598     ok(r == ERROR_UNKNOWN_PROPERTY,
4599        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4600     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4601     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4602
4603     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
4604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4605
4606     /* VersionMajor value exists */
4607     sz = MAX_PATH;
4608     lstrcpyA(buf, "apple");
4609     r = pMsiGetProductInfoExA(prodcode, usersid,
4610                               MSIINSTALLCONTEXT_USERUNMANAGED,
4611                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
4612     ok(r == ERROR_UNKNOWN_PROPERTY,
4613        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4614     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4615     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4616
4617     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
4618     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4619
4620     /* DisplayVersion value exists */
4621     sz = MAX_PATH;
4622     lstrcpyA(buf, "apple");
4623     r = pMsiGetProductInfoExA(prodcode, usersid,
4624                               MSIINSTALLCONTEXT_USERUNMANAGED,
4625                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
4626     ok(r == ERROR_UNKNOWN_PROPERTY,
4627        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4628     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4629     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4630
4631     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
4632     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4633
4634     /* ProductID value exists */
4635     sz = MAX_PATH;
4636     lstrcpyA(buf, "apple");
4637     r = pMsiGetProductInfoExA(prodcode, usersid,
4638                               MSIINSTALLCONTEXT_USERUNMANAGED,
4639                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
4640     ok(r == ERROR_UNKNOWN_PROPERTY,
4641        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4642     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4643     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4644
4645     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
4646     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4647
4648     /* RegCompany value exists */
4649     sz = MAX_PATH;
4650     lstrcpyA(buf, "apple");
4651     r = pMsiGetProductInfoExA(prodcode, usersid,
4652                               MSIINSTALLCONTEXT_USERUNMANAGED,
4653                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
4654     ok(r == ERROR_UNKNOWN_PROPERTY,
4655        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4656     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4657     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4658
4659     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
4660     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4661
4662     /* RegOwner value exists */
4663     sz = MAX_PATH;
4664     lstrcpyA(buf, "apple");
4665     r = pMsiGetProductInfoExA(prodcode, usersid,
4666                               MSIINSTALLCONTEXT_USERUNMANAGED,
4667                               INSTALLPROPERTY_REGOWNER, buf, &sz);
4668     ok(r == ERROR_UNKNOWN_PROPERTY,
4669        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
4670     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4671     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4672
4673     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
4674     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4675
4676     /* Transforms value exists */
4677     sz = MAX_PATH;
4678     lstrcpyA(buf, "apple");
4679     r = pMsiGetProductInfoExA(prodcode, usersid,
4680                               MSIINSTALLCONTEXT_USERUNMANAGED,
4681                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
4682     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4683     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
4684     ok(sz == 5, "Expected 5, got %d\n", sz);
4685
4686     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
4687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4688
4689     /* Language value exists */
4690     sz = MAX_PATH;
4691     lstrcpyA(buf, "apple");
4692     r = pMsiGetProductInfoExA(prodcode, usersid,
4693                               MSIINSTALLCONTEXT_USERUNMANAGED,
4694                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
4695     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4696     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
4697     ok(sz == 4, "Expected 4, got %d\n", sz);
4698
4699     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
4700     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4701
4702     /* ProductName value exists */
4703     sz = MAX_PATH;
4704     lstrcpyA(buf, "apple");
4705     r = pMsiGetProductInfoExA(prodcode, usersid,
4706                               MSIINSTALLCONTEXT_USERUNMANAGED,
4707                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
4708     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4709     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4710     ok(sz == 4, "Expected 4, got %d\n", sz);
4711
4712     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
4713     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4714
4715     /* FIXME */
4716
4717     /* AssignmentType value exists */
4718     sz = MAX_PATH;
4719     lstrcpyA(buf, "apple");
4720     r = pMsiGetProductInfoExA(prodcode, usersid,
4721                               MSIINSTALLCONTEXT_USERUNMANAGED,
4722                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
4723     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4724     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
4725     ok(sz == 0, "Expected 0, got %d\n", sz);
4726
4727     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
4728     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4729
4730     /* FIXME */
4731
4732     /* PackageCode value exists */
4733     sz = MAX_PATH;
4734     lstrcpyA(buf, "apple");
4735     r = pMsiGetProductInfoExA(prodcode, usersid,
4736                               MSIINSTALLCONTEXT_USERUNMANAGED,
4737                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
4738     todo_wine
4739     {
4740         ok(r == ERROR_BAD_CONFIGURATION,
4741            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
4742         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4743         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4744     }
4745
4746     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
4747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4748
4749     /* Version value exists */
4750     sz = MAX_PATH;
4751     lstrcpyA(buf, "apple");
4752     r = pMsiGetProductInfoExA(prodcode, usersid,
4753                               MSIINSTALLCONTEXT_USERUNMANAGED,
4754                               INSTALLPROPERTY_VERSION, buf, &sz);
4755     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4756     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
4757     ok(sz == 3, "Expected 3, got %d\n", sz);
4758
4759     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
4760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4761
4762     /* ProductIcon value exists */
4763     sz = MAX_PATH;
4764     lstrcpyA(buf, "apple");
4765     r = pMsiGetProductInfoExA(prodcode, usersid,
4766                               MSIINSTALLCONTEXT_USERUNMANAGED,
4767                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
4768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4769     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
4770     ok(sz == 4, "Expected 4, got %d\n", sz);
4771
4772     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
4773     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4774
4775     /* PackageName value exists */
4776     sz = MAX_PATH;
4777     lstrcpyA(buf, "apple");
4778     r = pMsiGetProductInfoExA(prodcode, usersid,
4779                               MSIINSTALLCONTEXT_USERUNMANAGED,
4780                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
4781     todo_wine
4782     {
4783         ok(r == ERROR_UNKNOWN_PRODUCT,
4784            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4785         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4786         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4787     }
4788
4789     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
4790     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4791
4792     /* AuthorizedLUAApp value exists */
4793     sz = MAX_PATH;
4794     lstrcpyA(buf, "apple");
4795     r = pMsiGetProductInfoExA(prodcode, usersid,
4796                               MSIINSTALLCONTEXT_USERUNMANAGED,
4797                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
4798     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4799     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
4800     ok(sz == 4, "Expected 4, got %d\n", sz);
4801
4802     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
4803     RegDeleteValueA(prodkey, "PackageName");
4804     RegDeleteValueA(prodkey, "ProductIcon");
4805     RegDeleteValueA(prodkey, "Version");
4806     RegDeleteValueA(prodkey, "PackageCode");
4807     RegDeleteValueA(prodkey, "AssignmentType");
4808     RegDeleteValueA(prodkey, "ProductName");
4809     RegDeleteValueA(prodkey, "Language");
4810     RegDeleteValueA(prodkey, "Transforms");
4811     RegDeleteValueA(prodkey, "RegOwner");
4812     RegDeleteValueA(prodkey, "RegCompany");
4813     RegDeleteValueA(prodkey, "ProductID");
4814     RegDeleteValueA(prodkey, "DisplayVersion");
4815     RegDeleteValueA(prodkey, "VersionMajor");
4816     RegDeleteValueA(prodkey, "VersionMinor");
4817     RegDeleteValueA(prodkey, "URLUpdateInfo");
4818     RegDeleteValueA(prodkey, "URLInfoAbout");
4819     RegDeleteValueA(prodkey, "Publisher");
4820     RegDeleteValueA(prodkey, "LocalPackage");
4821     RegDeleteValueA(prodkey, "InstallSource");
4822     RegDeleteValueA(prodkey, "InstallLocation");
4823     RegDeleteValueA(prodkey, "DisplayName");
4824     RegDeleteValueA(prodkey, "InstallDate");
4825     RegDeleteValueA(prodkey, "HelpTelephone");
4826     RegDeleteValueA(prodkey, "HelpLink");
4827     RegDeleteValueA(prodkey, "LocalPackage");
4828     RegDeleteKeyA(prodkey, "");
4829     RegCloseKey(prodkey);
4830
4831     /* MSIINSTALLCONTEXT_USERMANAGED */
4832
4833     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
4834     lstrcatA(keypath, usersid);
4835     lstrcatA(keypath, "\\Products\\");
4836     lstrcatA(keypath, prod_squashed);
4837
4838     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
4839     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4840
4841     /* local user product key exists */
4842     sz = MAX_PATH;
4843     lstrcpyA(buf, "apple");
4844     r = pMsiGetProductInfoExA(prodcode, usersid,
4845                               MSIINSTALLCONTEXT_USERMANAGED,
4846                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4847     ok(r == ERROR_UNKNOWN_PRODUCT,
4848        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4849     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4850     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4851
4852     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
4853     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4854
4855     /* InstallProperties key exists */
4856     sz = MAX_PATH;
4857     lstrcpyA(buf, "apple");
4858     r = pMsiGetProductInfoExA(prodcode, usersid,
4859                               MSIINSTALLCONTEXT_USERMANAGED,
4860                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4861     ok(r == ERROR_UNKNOWN_PRODUCT,
4862        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
4863     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
4864     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
4865
4866     res = RegSetValueExA(propkey, "ManagedLocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4867     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4868
4869     /* ManagedLocalPackage value exists */
4870     sz = MAX_PATH;
4871     lstrcpyA(buf, "apple");
4872     r = pMsiGetProductInfoExA(prodcode, usersid,
4873                               MSIINSTALLCONTEXT_USERMANAGED,
4874                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
4875     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4876     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
4877     ok(sz == 1, "Expected 1, got %d\n", sz);
4878
4879     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
4880     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4881
4882     /* HelpLink value exists */
4883     sz = MAX_PATH;
4884     lstrcpyA(buf, "apple");
4885     r = pMsiGetProductInfoExA(prodcode, usersid,
4886                               MSIINSTALLCONTEXT_USERMANAGED,
4887                               INSTALLPROPERTY_HELPLINK, buf, &sz);
4888     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4889     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
4890     ok(sz == 4, "Expected 4, got %d\n", sz);
4891
4892     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
4893     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4894
4895     /* HelpTelephone value exists */
4896     sz = MAX_PATH;
4897     lstrcpyA(buf, "apple");
4898     r = pMsiGetProductInfoExA(prodcode, usersid,
4899                               MSIINSTALLCONTEXT_USERMANAGED,
4900                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
4901     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4902     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
4903     ok(sz == 5, "Expected 5, got %d\n", sz);
4904
4905     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
4906     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4907
4908     /* InstallDate value exists */
4909     sz = MAX_PATH;
4910     lstrcpyA(buf, "apple");
4911     r = pMsiGetProductInfoExA(prodcode, usersid,
4912                               MSIINSTALLCONTEXT_USERMANAGED,
4913                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
4914     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4915     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
4916     ok(sz == 4, "Expected 4, got %d\n", sz);
4917
4918     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
4919     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4920
4921     /* DisplayName value exists */
4922     sz = MAX_PATH;
4923     lstrcpyA(buf, "apple");
4924     r = pMsiGetProductInfoExA(prodcode, usersid,
4925                               MSIINSTALLCONTEXT_USERMANAGED,
4926                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
4927     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4928     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
4929     ok(sz == 4, "Expected 4, got %d\n", sz);
4930
4931     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
4932     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4933
4934     /* InstallLocation value exists */
4935     sz = MAX_PATH;
4936     lstrcpyA(buf, "apple");
4937     r = pMsiGetProductInfoExA(prodcode, usersid,
4938                               MSIINSTALLCONTEXT_USERMANAGED,
4939                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
4940     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4941     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
4942     ok(sz == 3, "Expected 3, got %d\n", sz);
4943
4944     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
4945     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4946
4947     /* InstallSource value exists */
4948     sz = MAX_PATH;
4949     lstrcpyA(buf, "apple");
4950     r = pMsiGetProductInfoExA(prodcode, usersid,
4951                               MSIINSTALLCONTEXT_USERMANAGED,
4952                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
4953     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4954     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
4955     ok(sz == 6, "Expected 6, got %d\n", sz);
4956
4957     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
4958     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4959
4960     /* LocalPackage value exists */
4961     sz = MAX_PATH;
4962     lstrcpyA(buf, "apple");
4963     r = pMsiGetProductInfoExA(prodcode, usersid,
4964                               MSIINSTALLCONTEXT_USERMANAGED,
4965                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
4966     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4967     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
4968     ok(sz == 5, "Expected 5, got %d\n", sz);
4969
4970     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
4971     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4972
4973     /* Publisher value exists */
4974     sz = MAX_PATH;
4975     lstrcpyA(buf, "apple");
4976     r = pMsiGetProductInfoExA(prodcode, usersid,
4977                               MSIINSTALLCONTEXT_USERMANAGED,
4978                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
4979     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4980     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
4981     ok(sz == 3, "Expected 3, got %d\n", sz);
4982
4983     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
4984     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4985
4986     /* URLInfoAbout value exists */
4987     sz = MAX_PATH;
4988     lstrcpyA(buf, "apple");
4989     r = pMsiGetProductInfoExA(prodcode, usersid,
4990                               MSIINSTALLCONTEXT_USERMANAGED,
4991                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
4992     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4993     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
4994     ok(sz == 5, "Expected 5, got %d\n", sz);
4995
4996     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
4997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
4998
4999     /* URLUpdateInfo value exists */
5000     sz = MAX_PATH;
5001     lstrcpyA(buf, "apple");
5002     r = pMsiGetProductInfoExA(prodcode, usersid,
5003                               MSIINSTALLCONTEXT_USERMANAGED,
5004                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5005     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5006     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5007     ok(sz == 6, "Expected 6, got %d\n", sz);
5008
5009     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5010     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5011
5012     /* VersionMinor value exists */
5013     sz = MAX_PATH;
5014     lstrcpyA(buf, "apple");
5015     r = pMsiGetProductInfoExA(prodcode, usersid,
5016                               MSIINSTALLCONTEXT_USERMANAGED,
5017                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5018     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5019     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5020     ok(sz == 1, "Expected 1, got %d\n", sz);
5021
5022     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5023     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5024
5025     /* VersionMajor value exists */
5026     sz = MAX_PATH;
5027     lstrcpyA(buf, "apple");
5028     r = pMsiGetProductInfoExA(prodcode, usersid,
5029                               MSIINSTALLCONTEXT_USERMANAGED,
5030                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5031     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5032     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5033     ok(sz == 1, "Expected 1, got %d\n", sz);
5034
5035     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5036     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5037
5038     /* DisplayVersion value exists */
5039     sz = MAX_PATH;
5040     lstrcpyA(buf, "apple");
5041     r = pMsiGetProductInfoExA(prodcode, usersid,
5042                               MSIINSTALLCONTEXT_USERMANAGED,
5043                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5044     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5045     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5046     ok(sz == 5, "Expected 5, got %d\n", sz);
5047
5048     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5049     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5050
5051     /* ProductID value exists */
5052     sz = MAX_PATH;
5053     lstrcpyA(buf, "apple");
5054     r = pMsiGetProductInfoExA(prodcode, usersid,
5055                               MSIINSTALLCONTEXT_USERMANAGED,
5056                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5057     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5058     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5059     ok(sz == 2, "Expected 2, got %d\n", sz);
5060
5061     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5062     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5063
5064     /* RegCompany value exists */
5065     sz = MAX_PATH;
5066     lstrcpyA(buf, "apple");
5067     r = pMsiGetProductInfoExA(prodcode, usersid,
5068                               MSIINSTALLCONTEXT_USERMANAGED,
5069                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5070     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5071     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5072     ok(sz == 4, "Expected 4, got %d\n", sz);
5073
5074     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5075     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5076
5077     /* RegOwner value exists */
5078     sz = MAX_PATH;
5079     lstrcpyA(buf, "apple");
5080     r = pMsiGetProductInfoExA(prodcode, usersid,
5081                               MSIINSTALLCONTEXT_USERMANAGED,
5082                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5083     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5084     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5085     ok(sz == 5, "Expected 5, got %d\n", sz);
5086
5087     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5088     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5089
5090     /* Transforms value exists */
5091     sz = MAX_PATH;
5092     lstrcpyA(buf, "apple");
5093     r = pMsiGetProductInfoExA(prodcode, usersid,
5094                               MSIINSTALLCONTEXT_USERMANAGED,
5095                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5096     ok(r == ERROR_UNKNOWN_PRODUCT,
5097        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5098     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5099     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5100
5101     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5102     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5103
5104     /* Language value exists */
5105     sz = MAX_PATH;
5106     lstrcpyA(buf, "apple");
5107     r = pMsiGetProductInfoExA(prodcode, usersid,
5108                               MSIINSTALLCONTEXT_USERMANAGED,
5109                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5110     ok(r == ERROR_UNKNOWN_PRODUCT,
5111        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5112     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5113     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5114
5115     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5116     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5117
5118     /* ProductName value exists */
5119     sz = MAX_PATH;
5120     lstrcpyA(buf, "apple");
5121     r = pMsiGetProductInfoExA(prodcode, usersid,
5122                               MSIINSTALLCONTEXT_USERMANAGED,
5123                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5124     ok(r == ERROR_UNKNOWN_PRODUCT,
5125        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5126     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5127     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5128
5129     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5130     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5131
5132     /* FIXME */
5133
5134     /* AssignmentType value exists */
5135     sz = MAX_PATH;
5136     lstrcpyA(buf, "apple");
5137     r = pMsiGetProductInfoExA(prodcode, usersid,
5138                               MSIINSTALLCONTEXT_USERMANAGED,
5139                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5140     ok(r == ERROR_UNKNOWN_PRODUCT,
5141        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5142     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5143     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5144
5145     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5146     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5147
5148     /* PackageCode value exists */
5149     sz = MAX_PATH;
5150     lstrcpyA(buf, "apple");
5151     r = pMsiGetProductInfoExA(prodcode, usersid,
5152                               MSIINSTALLCONTEXT_USERMANAGED,
5153                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5154     ok(r == ERROR_UNKNOWN_PRODUCT,
5155        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5156     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5157     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5158
5159     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5160     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5161
5162     /* Version value exists */
5163     sz = MAX_PATH;
5164     lstrcpyA(buf, "apple");
5165     r = pMsiGetProductInfoExA(prodcode, usersid,
5166                               MSIINSTALLCONTEXT_USERMANAGED,
5167                               INSTALLPROPERTY_VERSION, buf, &sz);
5168     ok(r == ERROR_UNKNOWN_PRODUCT,
5169        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5170     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5171     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5172
5173     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5174     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5175
5176     /* ProductIcon value exists */
5177     sz = MAX_PATH;
5178     lstrcpyA(buf, "apple");
5179     r = pMsiGetProductInfoExA(prodcode, usersid,
5180                               MSIINSTALLCONTEXT_USERMANAGED,
5181                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5182     ok(r == ERROR_UNKNOWN_PRODUCT,
5183        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5184     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5185     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5186
5187     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5188     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5189
5190     /* PackageName value exists */
5191     sz = MAX_PATH;
5192     lstrcpyA(buf, "apple");
5193     r = pMsiGetProductInfoExA(prodcode, usersid,
5194                               MSIINSTALLCONTEXT_USERMANAGED,
5195                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5196     ok(r == ERROR_UNKNOWN_PRODUCT,
5197        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5198     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5199     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5200
5201     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5202     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5203
5204     /* AuthorizedLUAApp value exists */
5205     sz = MAX_PATH;
5206     lstrcpyA(buf, "apple");
5207     r = pMsiGetProductInfoExA(prodcode, usersid,
5208                               MSIINSTALLCONTEXT_USERMANAGED,
5209                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5210     ok(r == ERROR_UNKNOWN_PRODUCT,
5211        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5212     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5213     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5214
5215     RegDeleteValueA(propkey, "AuthorizedLUAApp");
5216     RegDeleteValueA(propkey, "PackageName");
5217     RegDeleteValueA(propkey, "ProductIcon");
5218     RegDeleteValueA(propkey, "Version");
5219     RegDeleteValueA(propkey, "PackageCode");
5220     RegDeleteValueA(propkey, "AssignmentType");
5221     RegDeleteValueA(propkey, "ProductName");
5222     RegDeleteValueA(propkey, "Language");
5223     RegDeleteValueA(propkey, "Transforms");
5224     RegDeleteValueA(propkey, "RegOwner");
5225     RegDeleteValueA(propkey, "RegCompany");
5226     RegDeleteValueA(propkey, "ProductID");
5227     RegDeleteValueA(propkey, "DisplayVersion");
5228     RegDeleteValueA(propkey, "VersionMajor");
5229     RegDeleteValueA(propkey, "VersionMinor");
5230     RegDeleteValueA(propkey, "URLUpdateInfo");
5231     RegDeleteValueA(propkey, "URLInfoAbout");
5232     RegDeleteValueA(propkey, "Publisher");
5233     RegDeleteValueA(propkey, "LocalPackage");
5234     RegDeleteValueA(propkey, "InstallSource");
5235     RegDeleteValueA(propkey, "InstallLocation");
5236     RegDeleteValueA(propkey, "DisplayName");
5237     RegDeleteValueA(propkey, "InstallDate");
5238     RegDeleteValueA(propkey, "HelpTelephone");
5239     RegDeleteValueA(propkey, "HelpLink");
5240     RegDeleteValueA(propkey, "ManagedLocalPackage");
5241     RegDeleteKeyA(propkey, "");
5242     RegCloseKey(propkey);
5243     RegDeleteKeyA(localkey, "");
5244     RegCloseKey(localkey);
5245
5246     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5247     lstrcatA(keypath, usersid);
5248     lstrcatA(keypath, "\\Installer\\Products\\");
5249     lstrcatA(keypath, prod_squashed);
5250
5251     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5252     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5253
5254     /* user product key exists */
5255     sz = MAX_PATH;
5256     lstrcpyA(buf, "apple");
5257     r = pMsiGetProductInfoExA(prodcode, usersid,
5258                               MSIINSTALLCONTEXT_USERMANAGED,
5259                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5260     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5261     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
5262     ok(sz == 1, "Expected 1, got %d\n", sz);
5263
5264     RegDeleteKeyA(userkey, "");
5265     RegCloseKey(userkey);
5266
5267     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
5268     lstrcatA(keypath, prod_squashed);
5269
5270     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
5271     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5272
5273     /* current user product key exists */
5274     sz = MAX_PATH;
5275     lstrcpyA(buf, "apple");
5276     r = pMsiGetProductInfoExA(prodcode, usersid,
5277                               MSIINSTALLCONTEXT_USERMANAGED,
5278                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5279     ok(r == ERROR_UNKNOWN_PRODUCT,
5280        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5281     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5282     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5283
5284     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5285     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5286
5287     /* HelpLink value exists, user product key does not exist */
5288     sz = MAX_PATH;
5289     lstrcpyA(buf, "apple");
5290     r = pMsiGetProductInfoExA(prodcode, usersid,
5291                               MSIINSTALLCONTEXT_USERMANAGED,
5292                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5293     ok(r == ERROR_UNKNOWN_PRODUCT,
5294        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5295     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5296     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5297
5298     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
5299     lstrcatA(keypath, usersid);
5300     lstrcatA(keypath, "\\Installer\\Products\\");
5301     lstrcatA(keypath, prod_squashed);
5302
5303     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
5304     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5305
5306     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5308
5309     /* HelpLink value exists, user product key does exist */
5310     sz = MAX_PATH;
5311     lstrcpyA(buf, "apple");
5312     r = pMsiGetProductInfoExA(prodcode, usersid,
5313                               MSIINSTALLCONTEXT_USERMANAGED,
5314                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5315     ok(r == ERROR_UNKNOWN_PROPERTY,
5316        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5317     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5318     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5319
5320     res = RegSetValueExA(userkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5321     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5322
5323     /* HelpTelephone value exists */
5324     sz = MAX_PATH;
5325     lstrcpyA(buf, "apple");
5326     r = pMsiGetProductInfoExA(prodcode, usersid,
5327                               MSIINSTALLCONTEXT_USERMANAGED,
5328                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5329     ok(r == ERROR_UNKNOWN_PROPERTY,
5330        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5331     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5332     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5333
5334     res = RegSetValueExA(userkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5335     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5336
5337     /* InstallDate value exists */
5338     sz = MAX_PATH;
5339     lstrcpyA(buf, "apple");
5340     r = pMsiGetProductInfoExA(prodcode, usersid,
5341                               MSIINSTALLCONTEXT_USERMANAGED,
5342                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5343     ok(r == ERROR_UNKNOWN_PROPERTY,
5344        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5345     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5346     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5347
5348     res = RegSetValueExA(userkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5349     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5350
5351     /* DisplayName value exists */
5352     sz = MAX_PATH;
5353     lstrcpyA(buf, "apple");
5354     r = pMsiGetProductInfoExA(prodcode, usersid,
5355                               MSIINSTALLCONTEXT_USERMANAGED,
5356                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5357     ok(r == ERROR_UNKNOWN_PROPERTY,
5358        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5359     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5360     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5361
5362     res = RegSetValueExA(userkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5363     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5364
5365     /* InstallLocation value exists */
5366     sz = MAX_PATH;
5367     lstrcpyA(buf, "apple");
5368     r = pMsiGetProductInfoExA(prodcode, usersid,
5369                               MSIINSTALLCONTEXT_USERMANAGED,
5370                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5371     ok(r == ERROR_UNKNOWN_PROPERTY,
5372        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5373     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5374     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5375
5376     res = RegSetValueExA(userkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5377     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5378
5379     /* InstallSource value exists */
5380     sz = MAX_PATH;
5381     lstrcpyA(buf, "apple");
5382     r = pMsiGetProductInfoExA(prodcode, usersid,
5383                               MSIINSTALLCONTEXT_USERMANAGED,
5384                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5385     ok(r == ERROR_UNKNOWN_PROPERTY,
5386        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5387     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5388     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5389
5390     res = RegSetValueExA(userkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5391     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5392
5393     /* LocalPackage value exists */
5394     sz = MAX_PATH;
5395     lstrcpyA(buf, "apple");
5396     r = pMsiGetProductInfoExA(prodcode, usersid,
5397                               MSIINSTALLCONTEXT_USERMANAGED,
5398                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5399     ok(r == ERROR_UNKNOWN_PROPERTY,
5400        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5401     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5402     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5403
5404     res = RegSetValueExA(userkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5405     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5406
5407     /* Publisher value exists */
5408     sz = MAX_PATH;
5409     lstrcpyA(buf, "apple");
5410     r = pMsiGetProductInfoExA(prodcode, usersid,
5411                               MSIINSTALLCONTEXT_USERMANAGED,
5412                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5413     ok(r == ERROR_UNKNOWN_PROPERTY,
5414        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5415     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5416     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5417
5418     res = RegSetValueExA(userkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5419     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5420
5421     /* URLInfoAbout value exists */
5422     sz = MAX_PATH;
5423     lstrcpyA(buf, "apple");
5424     r = pMsiGetProductInfoExA(prodcode, usersid,
5425                               MSIINSTALLCONTEXT_USERMANAGED,
5426                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5427     ok(r == ERROR_UNKNOWN_PROPERTY,
5428        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5429     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5430     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5431
5432     res = RegSetValueExA(userkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5433     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5434
5435     /* URLUpdateInfo value exists */
5436     sz = MAX_PATH;
5437     lstrcpyA(buf, "apple");
5438     r = pMsiGetProductInfoExA(prodcode, usersid,
5439                               MSIINSTALLCONTEXT_USERMANAGED,
5440                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5441     ok(r == ERROR_UNKNOWN_PROPERTY,
5442        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5443     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5444     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5445
5446     res = RegSetValueExA(userkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5447     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5448
5449     /* VersionMinor value exists */
5450     sz = MAX_PATH;
5451     lstrcpyA(buf, "apple");
5452     r = pMsiGetProductInfoExA(prodcode, usersid,
5453                               MSIINSTALLCONTEXT_USERMANAGED,
5454                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5455     ok(r == ERROR_UNKNOWN_PROPERTY,
5456        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5457     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5458     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5459
5460     res = RegSetValueExA(userkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5461     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5462
5463     /* VersionMajor value exists */
5464     sz = MAX_PATH;
5465     lstrcpyA(buf, "apple");
5466     r = pMsiGetProductInfoExA(prodcode, usersid,
5467                               MSIINSTALLCONTEXT_USERMANAGED,
5468                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5469     ok(r == ERROR_UNKNOWN_PROPERTY,
5470        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5471     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5472     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5473
5474     res = RegSetValueExA(userkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5475     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5476
5477     /* DisplayVersion value exists */
5478     sz = MAX_PATH;
5479     lstrcpyA(buf, "apple");
5480     r = pMsiGetProductInfoExA(prodcode, usersid,
5481                               MSIINSTALLCONTEXT_USERMANAGED,
5482                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5483     ok(r == ERROR_UNKNOWN_PROPERTY,
5484        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5485     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5486     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5487
5488     res = RegSetValueExA(userkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5489     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5490
5491     /* ProductID value exists */
5492     sz = MAX_PATH;
5493     lstrcpyA(buf, "apple");
5494     r = pMsiGetProductInfoExA(prodcode, usersid,
5495                               MSIINSTALLCONTEXT_USERMANAGED,
5496                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5497     ok(r == ERROR_UNKNOWN_PROPERTY,
5498        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5499     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5500     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5501
5502     res = RegSetValueExA(userkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5503     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5504
5505     /* RegCompany value exists */
5506     sz = MAX_PATH;
5507     lstrcpyA(buf, "apple");
5508     r = pMsiGetProductInfoExA(prodcode, usersid,
5509                               MSIINSTALLCONTEXT_USERMANAGED,
5510                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5511     ok(r == ERROR_UNKNOWN_PROPERTY,
5512        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5513     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5514     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5515
5516     res = RegSetValueExA(userkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5517     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5518
5519     /* RegOwner value exists */
5520     sz = MAX_PATH;
5521     lstrcpyA(buf, "apple");
5522     r = pMsiGetProductInfoExA(prodcode, usersid,
5523                               MSIINSTALLCONTEXT_USERMANAGED,
5524                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5525     ok(r == ERROR_UNKNOWN_PROPERTY,
5526        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
5527     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5528     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5529
5530     res = RegSetValueExA(userkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5531     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5532
5533     /* Transforms value exists */
5534     sz = MAX_PATH;
5535     lstrcpyA(buf, "apple");
5536     r = pMsiGetProductInfoExA(prodcode, usersid,
5537                               MSIINSTALLCONTEXT_USERMANAGED,
5538                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5539     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5540     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
5541     ok(sz == 5, "Expected 5, got %d\n", sz);
5542
5543     res = RegSetValueExA(userkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5544     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5545
5546     /* Language value exists */
5547     sz = MAX_PATH;
5548     lstrcpyA(buf, "apple");
5549     r = pMsiGetProductInfoExA(prodcode, usersid,
5550                               MSIINSTALLCONTEXT_USERMANAGED,
5551                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5552     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5553     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
5554     ok(sz == 4, "Expected 4, got %d\n", sz);
5555
5556     res = RegSetValueExA(userkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5557     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5558
5559     /* ProductName value exists */
5560     sz = MAX_PATH;
5561     lstrcpyA(buf, "apple");
5562     r = pMsiGetProductInfoExA(prodcode, usersid,
5563                               MSIINSTALLCONTEXT_USERMANAGED,
5564                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5565     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5566     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5567     ok(sz == 4, "Expected 4, got %d\n", sz);
5568
5569     res = RegSetValueExA(userkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5570     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5571
5572     /* FIXME */
5573
5574     /* AssignmentType value exists */
5575     sz = MAX_PATH;
5576     lstrcpyA(buf, "apple");
5577     r = pMsiGetProductInfoExA(prodcode, usersid,
5578                               MSIINSTALLCONTEXT_USERMANAGED,
5579                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
5580     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5581     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
5582     ok(sz == 0, "Expected 0, got %d\n", sz);
5583
5584     res = RegSetValueExA(userkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
5585     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5586
5587     /* FIXME */
5588
5589     /* PackageCode value exists */
5590     sz = MAX_PATH;
5591     lstrcpyA(buf, "apple");
5592     r = pMsiGetProductInfoExA(prodcode, usersid,
5593                               MSIINSTALLCONTEXT_USERMANAGED,
5594                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
5595     todo_wine
5596     {
5597         ok(r == ERROR_BAD_CONFIGURATION,
5598            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
5599         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5600         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5601     }
5602
5603     res = RegSetValueExA(userkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
5604     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5605
5606     /* Version value exists */
5607     sz = MAX_PATH;
5608     lstrcpyA(buf, "apple");
5609     r = pMsiGetProductInfoExA(prodcode, usersid,
5610                               MSIINSTALLCONTEXT_USERMANAGED,
5611                               INSTALLPROPERTY_VERSION, buf, &sz);
5612     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5613     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
5614     ok(sz == 3, "Expected 3, got %d\n", sz);
5615
5616     res = RegSetValueExA(userkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
5617     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5618
5619     /* ProductIcon value exists */
5620     sz = MAX_PATH;
5621     lstrcpyA(buf, "apple");
5622     r = pMsiGetProductInfoExA(prodcode, usersid,
5623                               MSIINSTALLCONTEXT_USERMANAGED,
5624                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
5625     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5626     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
5627     ok(sz == 4, "Expected 4, got %d\n", sz);
5628
5629     res = RegSetValueExA(userkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
5630     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5631
5632     /* PackageName value exists */
5633     sz = MAX_PATH;
5634     lstrcpyA(buf, "apple");
5635     r = pMsiGetProductInfoExA(prodcode, usersid,
5636                               MSIINSTALLCONTEXT_USERMANAGED,
5637                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
5638     todo_wine
5639     {
5640         ok(r == ERROR_UNKNOWN_PRODUCT,
5641            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5642         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5643         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5644     }
5645
5646     res = RegSetValueExA(userkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
5647     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5648
5649     /* AuthorizedLUAApp value exists */
5650     sz = MAX_PATH;
5651     lstrcpyA(buf, "apple");
5652     r = pMsiGetProductInfoExA(prodcode, usersid,
5653                               MSIINSTALLCONTEXT_USERMANAGED,
5654                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
5655     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5656     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
5657     ok(sz == 4, "Expected 4, got %d\n", sz);
5658
5659     RegDeleteValueA(userkey, "AuthorizedLUAApp");
5660     RegDeleteValueA(userkey, "PackageName");
5661     RegDeleteValueA(userkey, "ProductIcon");
5662     RegDeleteValueA(userkey, "Version");
5663     RegDeleteValueA(userkey, "PackageCode");
5664     RegDeleteValueA(userkey, "AssignmentType");
5665     RegDeleteValueA(userkey, "ProductName");
5666     RegDeleteValueA(userkey, "Language");
5667     RegDeleteValueA(userkey, "Transforms");
5668     RegDeleteValueA(userkey, "RegOwner");
5669     RegDeleteValueA(userkey, "RegCompany");
5670     RegDeleteValueA(userkey, "ProductID");
5671     RegDeleteValueA(userkey, "DisplayVersion");
5672     RegDeleteValueA(userkey, "VersionMajor");
5673     RegDeleteValueA(userkey, "VersionMinor");
5674     RegDeleteValueA(userkey, "URLUpdateInfo");
5675     RegDeleteValueA(userkey, "URLInfoAbout");
5676     RegDeleteValueA(userkey, "Publisher");
5677     RegDeleteValueA(userkey, "LocalPackage");
5678     RegDeleteValueA(userkey, "InstallSource");
5679     RegDeleteValueA(userkey, "InstallLocation");
5680     RegDeleteValueA(userkey, "DisplayName");
5681     RegDeleteValueA(userkey, "InstallDate");
5682     RegDeleteValueA(userkey, "HelpTelephone");
5683     RegDeleteValueA(userkey, "HelpLink");
5684     RegDeleteKeyA(userkey, "");
5685     RegCloseKey(userkey);
5686     RegDeleteKeyA(prodkey, "");
5687     RegCloseKey(prodkey);
5688
5689     /* MSIINSTALLCONTEXT_MACHINE */
5690
5691     /* szUserSid is non-NULL */
5692     sz = MAX_PATH;
5693     lstrcpyA(buf, "apple");
5694     r = pMsiGetProductInfoExA(prodcode, usersid,
5695                               MSIINSTALLCONTEXT_MACHINE,
5696                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5697     ok(r == ERROR_INVALID_PARAMETER,
5698        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
5699     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5700     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5701
5702     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
5703     lstrcatA(keypath, prod_squashed);
5704
5705     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
5706     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5707
5708     /* local system product key exists */
5709     sz = MAX_PATH;
5710     lstrcpyA(buf, "apple");
5711     r = pMsiGetProductInfoExA(prodcode, NULL,
5712                               MSIINSTALLCONTEXT_MACHINE,
5713                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5714     ok(r == ERROR_UNKNOWN_PRODUCT,
5715        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5716     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5717     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5718
5719     res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
5720     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5721
5722     /* InstallProperties key exists */
5723     sz = MAX_PATH;
5724     lstrcpyA(buf, "apple");
5725     r = pMsiGetProductInfoExA(prodcode, NULL,
5726                               MSIINSTALLCONTEXT_MACHINE,
5727                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5728     ok(r == ERROR_UNKNOWN_PRODUCT,
5729        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5730     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5731     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5732
5733     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5734     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5735
5736     /* LocalPackage value exists */
5737     sz = MAX_PATH;
5738     lstrcpyA(buf, "apple");
5739     r = pMsiGetProductInfoExA(prodcode, NULL,
5740                               MSIINSTALLCONTEXT_MACHINE,
5741                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
5742     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5743     ok(!lstrcmpA(buf, "5"), "Expected \"5\", got \"%s\"\n", buf);
5744     ok(sz == 1, "Expected 1, got %d\n", sz);
5745
5746     res = RegSetValueExA(propkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
5747     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5748
5749     /* HelpLink value exists */
5750     sz = MAX_PATH;
5751     lstrcpyA(buf, "apple");
5752     r = pMsiGetProductInfoExA(prodcode, NULL,
5753                               MSIINSTALLCONTEXT_MACHINE,
5754                               INSTALLPROPERTY_HELPLINK, buf, &sz);
5755     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5756     ok(!lstrcmpA(buf, "link"), "Expected \"link\", got \"%s\"\n", buf);
5757     ok(sz == 4, "Expected 4, got %d\n", sz);
5758
5759     res = RegSetValueExA(propkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
5760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5761
5762     /* HelpTelephone value exists */
5763     sz = MAX_PATH;
5764     lstrcpyA(buf, "apple");
5765     r = pMsiGetProductInfoExA(prodcode, NULL,
5766                               MSIINSTALLCONTEXT_MACHINE,
5767                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
5768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5769     ok(!lstrcmpA(buf, "phone"), "Expected \"phone\", got \"%s\"\n", buf);
5770     ok(sz == 5, "Expected 5, got %d\n", sz);
5771
5772     res = RegSetValueExA(propkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
5773     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5774
5775     /* InstallDate value exists */
5776     sz = MAX_PATH;
5777     lstrcpyA(buf, "apple");
5778     r = pMsiGetProductInfoExA(prodcode, NULL,
5779                               MSIINSTALLCONTEXT_MACHINE,
5780                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
5781     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5782     ok(!lstrcmpA(buf, "date"), "Expected \"date\", got \"%s\"\n", buf);
5783     ok(sz == 4, "Expected 4, got %d\n", sz);
5784
5785     res = RegSetValueExA(propkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
5786     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5787
5788     /* DisplayName value exists */
5789     sz = MAX_PATH;
5790     lstrcpyA(buf, "apple");
5791     r = pMsiGetProductInfoExA(prodcode, NULL,
5792                               MSIINSTALLCONTEXT_MACHINE,
5793                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
5794     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5795     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
5796     ok(sz == 4, "Expected 4, got %d\n", sz);
5797
5798     res = RegSetValueExA(propkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
5799     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5800
5801     /* InstallLocation value exists */
5802     sz = MAX_PATH;
5803     lstrcpyA(buf, "apple");
5804     r = pMsiGetProductInfoExA(prodcode, NULL,
5805                               MSIINSTALLCONTEXT_MACHINE,
5806                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
5807     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5808     ok(!lstrcmpA(buf, "loc"), "Expected \"loc\", got \"%s\"\n", buf);
5809     ok(sz == 3, "Expected 3, got %d\n", sz);
5810
5811     res = RegSetValueExA(propkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
5812     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5813
5814     /* InstallSource value exists */
5815     sz = MAX_PATH;
5816     lstrcpyA(buf, "apple");
5817     r = pMsiGetProductInfoExA(prodcode, NULL,
5818                               MSIINSTALLCONTEXT_MACHINE,
5819                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
5820     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5821     ok(!lstrcmpA(buf, "source"), "Expected \"source\", got \"%s\"\n", buf);
5822     ok(sz == 6, "Expected 6, got %d\n", sz);
5823
5824     res = RegSetValueExA(propkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
5825     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5826
5827     /* LocalPackage value exists */
5828     sz = MAX_PATH;
5829     lstrcpyA(buf, "apple");
5830     r = pMsiGetProductInfoExA(prodcode, NULL,
5831                               MSIINSTALLCONTEXT_MACHINE,
5832                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
5833     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5834     ok(!lstrcmpA(buf, "local"), "Expected \"local\", got \"%s\"\n", buf);
5835     ok(sz == 5, "Expected 5, got %d\n", sz);
5836
5837     res = RegSetValueExA(propkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
5838     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5839
5840     /* Publisher value exists */
5841     sz = MAX_PATH;
5842     lstrcpyA(buf, "apple");
5843     r = pMsiGetProductInfoExA(prodcode, NULL,
5844                               MSIINSTALLCONTEXT_MACHINE,
5845                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
5846     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5847     ok(!lstrcmpA(buf, "pub"), "Expected \"pub\", got \"%s\"\n", buf);
5848     ok(sz == 3, "Expected 3, got %d\n", sz);
5849
5850     res = RegSetValueExA(propkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
5851     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5852
5853     /* URLInfoAbout value exists */
5854     sz = MAX_PATH;
5855     lstrcpyA(buf, "apple");
5856     r = pMsiGetProductInfoExA(prodcode, NULL,
5857                               MSIINSTALLCONTEXT_MACHINE,
5858                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
5859     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5860     ok(!lstrcmpA(buf, "about"), "Expected \"about\", got \"%s\"\n", buf);
5861     ok(sz == 5, "Expected 5, got %d\n", sz);
5862
5863     res = RegSetValueExA(propkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
5864     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5865
5866     /* URLUpdateInfo value exists */
5867     sz = MAX_PATH;
5868     lstrcpyA(buf, "apple");
5869     r = pMsiGetProductInfoExA(prodcode, NULL,
5870                               MSIINSTALLCONTEXT_MACHINE,
5871                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
5872     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5873     ok(!lstrcmpA(buf, "update"), "Expected \"update\", got \"%s\"\n", buf);
5874     ok(sz == 6, "Expected 6, got %d\n", sz);
5875
5876     res = RegSetValueExA(propkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
5877     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5878
5879     /* VersionMinor value exists */
5880     sz = MAX_PATH;
5881     lstrcpyA(buf, "apple");
5882     r = pMsiGetProductInfoExA(prodcode, NULL,
5883                               MSIINSTALLCONTEXT_MACHINE,
5884                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
5885     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5886     ok(!lstrcmpA(buf, "2"), "Expected \"2\", got \"%s\"\n", buf);
5887     ok(sz == 1, "Expected 1, got %d\n", sz);
5888
5889     res = RegSetValueExA(propkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
5890     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5891
5892     /* VersionMajor value exists */
5893     sz = MAX_PATH;
5894     lstrcpyA(buf, "apple");
5895     r = pMsiGetProductInfoExA(prodcode, NULL,
5896                               MSIINSTALLCONTEXT_MACHINE,
5897                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
5898     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5899     ok(!lstrcmpA(buf, "3"), "Expected \"3\", got \"%s\"\n", buf);
5900     ok(sz == 1, "Expected 1, got %d\n", sz);
5901
5902     res = RegSetValueExA(propkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
5903     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5904
5905     /* DisplayVersion value exists */
5906     sz = MAX_PATH;
5907     lstrcpyA(buf, "apple");
5908     r = pMsiGetProductInfoExA(prodcode, NULL,
5909                               MSIINSTALLCONTEXT_MACHINE,
5910                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
5911     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5912     ok(!lstrcmpA(buf, "3.2.1"), "Expected \"3.2.1\", got \"%s\"\n", buf);
5913     ok(sz == 5, "Expected 5, got %d\n", sz);
5914
5915     res = RegSetValueExA(propkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
5916     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5917
5918     /* ProductID value exists */
5919     sz = MAX_PATH;
5920     lstrcpyA(buf, "apple");
5921     r = pMsiGetProductInfoExA(prodcode, NULL,
5922                               MSIINSTALLCONTEXT_MACHINE,
5923                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
5924     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5925     ok(!lstrcmpA(buf, "id"), "Expected \"id\", got \"%s\"\n", buf);
5926     ok(sz == 2, "Expected 2, got %d\n", sz);
5927
5928     res = RegSetValueExA(propkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
5929     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5930
5931     /* RegCompany value exists */
5932     sz = MAX_PATH;
5933     lstrcpyA(buf, "apple");
5934     r = pMsiGetProductInfoExA(prodcode, NULL,
5935                               MSIINSTALLCONTEXT_MACHINE,
5936                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
5937     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5938     ok(!lstrcmpA(buf, "comp"), "Expected \"comp\", got \"%s\"\n", buf);
5939     ok(sz == 4, "Expected 4, got %d\n", sz);
5940
5941     res = RegSetValueExA(propkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
5942     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5943
5944     /* RegOwner value exists */
5945     sz = MAX_PATH;
5946     lstrcpyA(buf, "apple");
5947     r = pMsiGetProductInfoExA(prodcode, NULL,
5948                               MSIINSTALLCONTEXT_MACHINE,
5949                               INSTALLPROPERTY_REGOWNER, buf, &sz);
5950     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
5951     ok(!lstrcmpA(buf, "owner"), "Expected \"owner\", got \"%s\"\n", buf);
5952     ok(sz == 5, "Expected 5, got %d\n", sz);
5953
5954     res = RegSetValueExA(propkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
5955     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5956
5957     /* Transforms value exists */
5958     sz = MAX_PATH;
5959     lstrcpyA(buf, "apple");
5960     r = pMsiGetProductInfoExA(prodcode, NULL,
5961                               MSIINSTALLCONTEXT_MACHINE,
5962                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
5963     ok(r == ERROR_UNKNOWN_PRODUCT,
5964        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5965     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5966     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5967
5968     res = RegSetValueExA(propkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
5969     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5970
5971     /* Language value exists */
5972     sz = MAX_PATH;
5973     lstrcpyA(buf, "apple");
5974     r = pMsiGetProductInfoExA(prodcode, NULL,
5975                               MSIINSTALLCONTEXT_MACHINE,
5976                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
5977     ok(r == ERROR_UNKNOWN_PRODUCT,
5978        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5979     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5980     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5981
5982     res = RegSetValueExA(propkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
5983     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5984
5985     /* ProductName value exists */
5986     sz = MAX_PATH;
5987     lstrcpyA(buf, "apple");
5988     r = pMsiGetProductInfoExA(prodcode, NULL,
5989                               MSIINSTALLCONTEXT_MACHINE,
5990                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
5991     ok(r == ERROR_UNKNOWN_PRODUCT,
5992        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
5993     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
5994     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
5995
5996     res = RegSetValueExA(propkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
5997     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
5998
5999     /* FIXME */
6000
6001     /* AssignmentType value exists */
6002     sz = MAX_PATH;
6003     lstrcpyA(buf, "apple");
6004     r = pMsiGetProductInfoExA(prodcode, NULL,
6005                               MSIINSTALLCONTEXT_MACHINE,
6006                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6007     ok(r == ERROR_UNKNOWN_PRODUCT,
6008        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6009     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6010     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6011
6012     res = RegSetValueExA(propkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6013     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6014
6015     /* PackageCode value exists */
6016     sz = MAX_PATH;
6017     lstrcpyA(buf, "apple");
6018     r = pMsiGetProductInfoExA(prodcode, NULL,
6019                               MSIINSTALLCONTEXT_MACHINE,
6020                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6021     ok(r == ERROR_UNKNOWN_PRODUCT,
6022        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6023     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6024     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6025
6026     res = RegSetValueExA(propkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6027     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6028
6029     /* Version value exists */
6030     sz = MAX_PATH;
6031     lstrcpyA(buf, "apple");
6032     r = pMsiGetProductInfoExA(prodcode, NULL,
6033                               MSIINSTALLCONTEXT_MACHINE,
6034                               INSTALLPROPERTY_VERSION, buf, &sz);
6035     ok(r == ERROR_UNKNOWN_PRODUCT,
6036        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6037     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6038     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6039
6040     res = RegSetValueExA(propkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6041     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6042
6043     /* ProductIcon value exists */
6044     sz = MAX_PATH;
6045     lstrcpyA(buf, "apple");
6046     r = pMsiGetProductInfoExA(prodcode, NULL,
6047                               MSIINSTALLCONTEXT_MACHINE,
6048                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6049     ok(r == ERROR_UNKNOWN_PRODUCT,
6050        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6051     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6052     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6053
6054     res = RegSetValueExA(propkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6055     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6056
6057     /* PackageName value exists */
6058     sz = MAX_PATH;
6059     lstrcpyA(buf, "apple");
6060     r = pMsiGetProductInfoExA(prodcode, NULL,
6061                               MSIINSTALLCONTEXT_MACHINE,
6062                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6063     ok(r == ERROR_UNKNOWN_PRODUCT,
6064        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6065     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6066     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6067
6068     res = RegSetValueExA(propkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6069     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6070
6071     /* AuthorizedLUAApp value exists */
6072     sz = MAX_PATH;
6073     lstrcpyA(buf, "apple");
6074     r = pMsiGetProductInfoExA(prodcode, NULL,
6075                               MSIINSTALLCONTEXT_MACHINE,
6076                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6077     ok(r == ERROR_UNKNOWN_PRODUCT,
6078        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6079     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6080     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6081
6082     RegDeleteValueA(propkey, "AuthorizedLUAApp");
6083     RegDeleteValueA(propkey, "PackageName");
6084     RegDeleteValueA(propkey, "ProductIcon");
6085     RegDeleteValueA(propkey, "Version");
6086     RegDeleteValueA(propkey, "PackageCode");
6087     RegDeleteValueA(propkey, "AssignmentType");
6088     RegDeleteValueA(propkey, "ProductName");
6089     RegDeleteValueA(propkey, "Language");
6090     RegDeleteValueA(propkey, "Transforms");
6091     RegDeleteValueA(propkey, "RegOwner");
6092     RegDeleteValueA(propkey, "RegCompany");
6093     RegDeleteValueA(propkey, "ProductID");
6094     RegDeleteValueA(propkey, "DisplayVersion");
6095     RegDeleteValueA(propkey, "VersionMajor");
6096     RegDeleteValueA(propkey, "VersionMinor");
6097     RegDeleteValueA(propkey, "URLUpdateInfo");
6098     RegDeleteValueA(propkey, "URLInfoAbout");
6099     RegDeleteValueA(propkey, "Publisher");
6100     RegDeleteValueA(propkey, "LocalPackage");
6101     RegDeleteValueA(propkey, "InstallSource");
6102     RegDeleteValueA(propkey, "InstallLocation");
6103     RegDeleteValueA(propkey, "DisplayName");
6104     RegDeleteValueA(propkey, "InstallDate");
6105     RegDeleteValueA(propkey, "HelpTelephone");
6106     RegDeleteValueA(propkey, "HelpLink");
6107     RegDeleteValueA(propkey, "LocalPackage");
6108     RegDeleteKeyA(propkey, "");
6109     RegCloseKey(propkey);
6110     RegDeleteKeyA(localkey, "");
6111     RegCloseKey(localkey);
6112
6113     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6114     lstrcatA(keypath, prod_squashed);
6115
6116     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6117     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6118
6119     /* local classes product key exists */
6120     sz = MAX_PATH;
6121     lstrcpyA(buf, "apple");
6122     r = pMsiGetProductInfoExA(prodcode, NULL,
6123                               MSIINSTALLCONTEXT_MACHINE,
6124                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
6125     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6126     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
6127     ok(sz == 1, "Expected 1, got %d\n", sz);
6128
6129     res = RegSetValueExA(prodkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
6130     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6131
6132     /* HelpLink value exists */
6133     sz = MAX_PATH;
6134     lstrcpyA(buf, "apple");
6135     r = pMsiGetProductInfoExA(prodcode, NULL,
6136                               MSIINSTALLCONTEXT_MACHINE,
6137                               INSTALLPROPERTY_HELPLINK, buf, &sz);
6138     ok(r == ERROR_UNKNOWN_PROPERTY,
6139        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6140     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6141     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6142
6143     res = RegSetValueExA(prodkey, "HelpTelephone", 0, REG_SZ, (LPBYTE)"phone", 6);
6144     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6145
6146     /* HelpTelephone value exists */
6147     sz = MAX_PATH;
6148     lstrcpyA(buf, "apple");
6149     r = pMsiGetProductInfoExA(prodcode, NULL,
6150                               MSIINSTALLCONTEXT_MACHINE,
6151                               INSTALLPROPERTY_HELPTELEPHONE, buf, &sz);
6152     ok(r == ERROR_UNKNOWN_PROPERTY,
6153        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6154     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6155     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6156
6157     res = RegSetValueExA(prodkey, "InstallDate", 0, REG_SZ, (LPBYTE)"date", 5);
6158     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6159
6160     /* InstallDate value exists */
6161     sz = MAX_PATH;
6162     lstrcpyA(buf, "apple");
6163     r = pMsiGetProductInfoExA(prodcode, NULL,
6164                               MSIINSTALLCONTEXT_MACHINE,
6165                               INSTALLPROPERTY_INSTALLDATE, buf, &sz);
6166     ok(r == ERROR_UNKNOWN_PROPERTY,
6167        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6168     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6169     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6170
6171     res = RegSetValueExA(prodkey, "DisplayName", 0, REG_SZ, (LPBYTE)"name", 5);
6172     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6173
6174     /* DisplayName value exists */
6175     sz = MAX_PATH;
6176     lstrcpyA(buf, "apple");
6177     r = pMsiGetProductInfoExA(prodcode, NULL,
6178                               MSIINSTALLCONTEXT_MACHINE,
6179                               INSTALLPROPERTY_INSTALLEDPRODUCTNAME, buf, &sz);
6180     ok(r == ERROR_UNKNOWN_PROPERTY,
6181        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6182     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6183     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6184
6185     res = RegSetValueExA(prodkey, "InstallLocation", 0, REG_SZ, (LPBYTE)"loc", 4);
6186     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6187
6188     /* InstallLocation value exists */
6189     sz = MAX_PATH;
6190     lstrcpyA(buf, "apple");
6191     r = pMsiGetProductInfoExA(prodcode, NULL,
6192                               MSIINSTALLCONTEXT_MACHINE,
6193                               INSTALLPROPERTY_INSTALLLOCATION, buf, &sz);
6194     ok(r == ERROR_UNKNOWN_PROPERTY,
6195        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6196     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6197     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6198
6199     res = RegSetValueExA(prodkey, "InstallSource", 0, REG_SZ, (LPBYTE)"source", 7);
6200     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6201
6202     /* InstallSource value exists */
6203     sz = MAX_PATH;
6204     lstrcpyA(buf, "apple");
6205     r = pMsiGetProductInfoExA(prodcode, NULL,
6206                               MSIINSTALLCONTEXT_MACHINE,
6207                               INSTALLPROPERTY_INSTALLSOURCE, buf, &sz);
6208     ok(r == ERROR_UNKNOWN_PROPERTY,
6209        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6210     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6211     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6212
6213     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (LPBYTE)"local", 6);
6214     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6215
6216     /* LocalPackage value exists */
6217     sz = MAX_PATH;
6218     lstrcpyA(buf, "apple");
6219     r = pMsiGetProductInfoExA(prodcode, NULL,
6220                               MSIINSTALLCONTEXT_MACHINE,
6221                               INSTALLPROPERTY_LOCALPACKAGE, buf, &sz);
6222     ok(r == ERROR_UNKNOWN_PROPERTY,
6223        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6224     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6225     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6226
6227     res = RegSetValueExA(prodkey, "Publisher", 0, REG_SZ, (LPBYTE)"pub", 4);
6228     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6229
6230     /* Publisher value exists */
6231     sz = MAX_PATH;
6232     lstrcpyA(buf, "apple");
6233     r = pMsiGetProductInfoExA(prodcode, NULL,
6234                               MSIINSTALLCONTEXT_MACHINE,
6235                               INSTALLPROPERTY_PUBLISHER, buf, &sz);
6236     ok(r == ERROR_UNKNOWN_PROPERTY,
6237        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6238     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6239     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6240
6241     res = RegSetValueExA(prodkey, "URLInfoAbout", 0, REG_SZ, (LPBYTE)"about", 6);
6242     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6243
6244     /* URLInfoAbout value exists */
6245     sz = MAX_PATH;
6246     lstrcpyA(buf, "apple");
6247     r = pMsiGetProductInfoExA(prodcode, NULL,
6248                               MSIINSTALLCONTEXT_MACHINE,
6249                               INSTALLPROPERTY_URLINFOABOUT, buf, &sz);
6250     ok(r == ERROR_UNKNOWN_PROPERTY,
6251        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6252     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6253     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6254
6255     res = RegSetValueExA(prodkey, "URLUpdateInfo", 0, REG_SZ, (LPBYTE)"update", 7);
6256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6257
6258     /* URLUpdateInfo value exists */
6259     sz = MAX_PATH;
6260     lstrcpyA(buf, "apple");
6261     r = pMsiGetProductInfoExA(prodcode, NULL,
6262                               MSIINSTALLCONTEXT_MACHINE,
6263                               INSTALLPROPERTY_URLUPDATEINFO, buf, &sz);
6264     ok(r == ERROR_UNKNOWN_PROPERTY,
6265        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6266     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6267     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6268
6269     res = RegSetValueExA(prodkey, "VersionMinor", 0, REG_SZ, (LPBYTE)"2", 2);
6270     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6271
6272     /* VersionMinor value exists */
6273     sz = MAX_PATH;
6274     lstrcpyA(buf, "apple");
6275     r = pMsiGetProductInfoExA(prodcode, NULL,
6276                               MSIINSTALLCONTEXT_MACHINE,
6277                               INSTALLPROPERTY_VERSIONMINOR, buf, &sz);
6278     ok(r == ERROR_UNKNOWN_PROPERTY,
6279        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6280     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6281     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6282
6283     res = RegSetValueExA(prodkey, "VersionMajor", 0, REG_SZ, (LPBYTE)"3", 2);
6284     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6285
6286     /* VersionMajor value exists */
6287     sz = MAX_PATH;
6288     lstrcpyA(buf, "apple");
6289     r = pMsiGetProductInfoExA(prodcode, NULL,
6290                               MSIINSTALLCONTEXT_MACHINE,
6291                               INSTALLPROPERTY_VERSIONMAJOR, buf, &sz);
6292     ok(r == ERROR_UNKNOWN_PROPERTY,
6293        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6294     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6295     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6296
6297     res = RegSetValueExA(prodkey, "DisplayVersion", 0, REG_SZ, (LPBYTE)"3.2.1", 6);
6298     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6299
6300     /* DisplayVersion value exists */
6301     sz = MAX_PATH;
6302     lstrcpyA(buf, "apple");
6303     r = pMsiGetProductInfoExA(prodcode, NULL,
6304                               MSIINSTALLCONTEXT_MACHINE,
6305                               INSTALLPROPERTY_VERSIONSTRING, buf, &sz);
6306     ok(r == ERROR_UNKNOWN_PROPERTY,
6307        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6308     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6309     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6310
6311     res = RegSetValueExA(prodkey, "ProductID", 0, REG_SZ, (LPBYTE)"id", 3);
6312     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6313
6314     /* ProductID value exists */
6315     sz = MAX_PATH;
6316     lstrcpyA(buf, "apple");
6317     r = pMsiGetProductInfoExA(prodcode, NULL,
6318                               MSIINSTALLCONTEXT_MACHINE,
6319                               INSTALLPROPERTY_PRODUCTID, buf, &sz);
6320     ok(r == ERROR_UNKNOWN_PROPERTY,
6321        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6322     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6323     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6324
6325     res = RegSetValueExA(prodkey, "RegCompany", 0, REG_SZ, (LPBYTE)"comp", 5);
6326     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6327
6328     /* RegCompany value exists */
6329     sz = MAX_PATH;
6330     lstrcpyA(buf, "apple");
6331     r = pMsiGetProductInfoExA(prodcode, NULL,
6332                               MSIINSTALLCONTEXT_MACHINE,
6333                               INSTALLPROPERTY_REGCOMPANY, buf, &sz);
6334     ok(r == ERROR_UNKNOWN_PROPERTY,
6335        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6336     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6337     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6338
6339     res = RegSetValueExA(prodkey, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6340     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6341
6342     /* RegOwner value exists */
6343     sz = MAX_PATH;
6344     lstrcpyA(buf, "apple");
6345     r = pMsiGetProductInfoExA(prodcode, NULL,
6346                               MSIINSTALLCONTEXT_MACHINE,
6347                               INSTALLPROPERTY_REGOWNER, buf, &sz);
6348     ok(r == ERROR_UNKNOWN_PROPERTY,
6349        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
6350     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6351     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6352
6353     res = RegSetValueExA(prodkey, "Transforms", 0, REG_SZ, (LPBYTE)"trans", 6);
6354     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6355
6356     /* Transforms value exists */
6357     sz = MAX_PATH;
6358     lstrcpyA(buf, "apple");
6359     r = pMsiGetProductInfoExA(prodcode, NULL,
6360                               MSIINSTALLCONTEXT_MACHINE,
6361                               INSTALLPROPERTY_TRANSFORMS, buf, &sz);
6362     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6363     ok(!lstrcmpA(buf, "trans"), "Expected \"trans\", got \"%s\"\n", buf);
6364     ok(sz == 5, "Expected 5, got %d\n", sz);
6365
6366     res = RegSetValueExA(prodkey, "Language", 0, REG_SZ, (LPBYTE)"lang", 5);
6367     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6368
6369     /* Language value exists */
6370     sz = MAX_PATH;
6371     lstrcpyA(buf, "apple");
6372     r = pMsiGetProductInfoExA(prodcode, NULL,
6373                               MSIINSTALLCONTEXT_MACHINE,
6374                               INSTALLPROPERTY_LANGUAGE, buf, &sz);
6375     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6376     ok(!lstrcmpA(buf, "lang"), "Expected \"lang\", got \"%s\"\n", buf);
6377     ok(sz == 4, "Expected 4, got %d\n", sz);
6378
6379     res = RegSetValueExA(prodkey, "ProductName", 0, REG_SZ, (LPBYTE)"name", 5);
6380     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6381
6382     /* ProductName value exists */
6383     sz = MAX_PATH;
6384     lstrcpyA(buf, "apple");
6385     r = pMsiGetProductInfoExA(prodcode, NULL,
6386                               MSIINSTALLCONTEXT_MACHINE,
6387                               INSTALLPROPERTY_PRODUCTNAME, buf, &sz);
6388     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6389     ok(!lstrcmpA(buf, "name"), "Expected \"name\", got \"%s\"\n", buf);
6390     ok(sz == 4, "Expected 4, got %d\n", sz);
6391
6392     res = RegSetValueExA(prodkey, "AssignmentType", 0, REG_SZ, (LPBYTE)"type", 5);
6393     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6394
6395     /* FIXME */
6396
6397     /* AssignmentType value exists */
6398     sz = MAX_PATH;
6399     lstrcpyA(buf, "apple");
6400     r = pMsiGetProductInfoExA(prodcode, NULL,
6401                               MSIINSTALLCONTEXT_MACHINE,
6402                               INSTALLPROPERTY_ASSIGNMENTTYPE, buf, &sz);
6403     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6404     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
6405     ok(sz == 0, "Expected 0, got %d\n", sz);
6406
6407     res = RegSetValueExA(prodkey, "PackageCode", 0, REG_SZ, (LPBYTE)"code", 5);
6408     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6409
6410     /* FIXME */
6411
6412     /* PackageCode value exists */
6413     sz = MAX_PATH;
6414     lstrcpyA(buf, "apple");
6415     r = pMsiGetProductInfoExA(prodcode, NULL,
6416                               MSIINSTALLCONTEXT_MACHINE,
6417                               INSTALLPROPERTY_PACKAGECODE, buf, &sz);
6418     todo_wine
6419     {
6420         ok(r == ERROR_BAD_CONFIGURATION,
6421            "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
6422         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6423         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6424     }
6425
6426     res = RegSetValueExA(prodkey, "Version", 0, REG_SZ, (LPBYTE)"ver", 4);
6427     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6428
6429     /* Version value exists */
6430     sz = MAX_PATH;
6431     lstrcpyA(buf, "apple");
6432     r = pMsiGetProductInfoExA(prodcode, NULL,
6433                               MSIINSTALLCONTEXT_MACHINE,
6434                               INSTALLPROPERTY_VERSION, buf, &sz);
6435     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6436     ok(!lstrcmpA(buf, "ver"), "Expected \"ver\", got \"%s\"\n", buf);
6437     ok(sz == 3, "Expected 3, got %d\n", sz);
6438
6439     res = RegSetValueExA(prodkey, "ProductIcon", 0, REG_SZ, (LPBYTE)"icon", 5);
6440     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6441
6442     /* ProductIcon value exists */
6443     sz = MAX_PATH;
6444     lstrcpyA(buf, "apple");
6445     r = pMsiGetProductInfoExA(prodcode, NULL,
6446                               MSIINSTALLCONTEXT_MACHINE,
6447                               INSTALLPROPERTY_PRODUCTICON, buf, &sz);
6448     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6449     ok(!lstrcmpA(buf, "icon"), "Expected \"icon\", got \"%s\"\n", buf);
6450     ok(sz == 4, "Expected 4, got %d\n", sz);
6451
6452     res = RegSetValueExA(prodkey, "PackageName", 0, REG_SZ, (LPBYTE)"name", 5);
6453     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6454
6455     /* PackageName value exists */
6456     sz = MAX_PATH;
6457     lstrcpyA(buf, "apple");
6458     r = pMsiGetProductInfoExA(prodcode, NULL,
6459                               MSIINSTALLCONTEXT_MACHINE,
6460                               INSTALLPROPERTY_PACKAGENAME, buf, &sz);
6461     todo_wine
6462     {
6463         ok(r == ERROR_UNKNOWN_PRODUCT,
6464            "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
6465         ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
6466         ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
6467     }
6468
6469     res = RegSetValueExA(prodkey, "AuthorizedLUAApp", 0, REG_SZ, (LPBYTE)"auth", 5);
6470     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6471
6472     /* AuthorizedLUAApp value exists */
6473     sz = MAX_PATH;
6474     lstrcpyA(buf, "apple");
6475     r = pMsiGetProductInfoExA(prodcode, NULL,
6476                               MSIINSTALLCONTEXT_MACHINE,
6477                               INSTALLPROPERTY_AUTHORIZED_LUA_APP, buf, &sz);
6478     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
6479     ok(!lstrcmpA(buf, "auth"), "Expected \"auth\", got \"%s\"\n", buf);
6480     ok(sz == 4, "Expected 4, got %d\n", sz);
6481
6482     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
6483     RegDeleteValueA(prodkey, "PackageName");
6484     RegDeleteValueA(prodkey, "ProductIcon");
6485     RegDeleteValueA(prodkey, "Version");
6486     RegDeleteValueA(prodkey, "PackageCode");
6487     RegDeleteValueA(prodkey, "AssignmentType");
6488     RegDeleteValueA(prodkey, "ProductName");
6489     RegDeleteValueA(prodkey, "Language");
6490     RegDeleteValueA(prodkey, "Transforms");
6491     RegDeleteValueA(prodkey, "RegOwner");
6492     RegDeleteValueA(prodkey, "RegCompany");
6493     RegDeleteValueA(prodkey, "ProductID");
6494     RegDeleteValueA(prodkey, "DisplayVersion");
6495     RegDeleteValueA(prodkey, "VersionMajor");
6496     RegDeleteValueA(prodkey, "VersionMinor");
6497     RegDeleteValueA(prodkey, "URLUpdateInfo");
6498     RegDeleteValueA(prodkey, "URLInfoAbout");
6499     RegDeleteValueA(prodkey, "Publisher");
6500     RegDeleteValueA(prodkey, "LocalPackage");
6501     RegDeleteValueA(prodkey, "InstallSource");
6502     RegDeleteValueA(prodkey, "InstallLocation");
6503     RegDeleteValueA(prodkey, "DisplayName");
6504     RegDeleteValueA(prodkey, "InstallDate");
6505     RegDeleteValueA(prodkey, "HelpTelephone");
6506     RegDeleteValueA(prodkey, "HelpLink");
6507     RegDeleteKeyA(prodkey, "");
6508     RegCloseKey(prodkey);
6509 }
6510
6511 #define INIT_USERINFO() \
6512     lstrcpyA(user, "apple"); \
6513     lstrcpyA(org, "orange"); \
6514     lstrcpyA(serial, "banana"); \
6515     usersz = orgsz = serialsz = MAX_PATH;
6516
6517 static void test_MsiGetUserInfo(void)
6518 {
6519     USERINFOSTATE state;
6520     CHAR user[MAX_PATH];
6521     CHAR org[MAX_PATH];
6522     CHAR serial[MAX_PATH];
6523     DWORD usersz, orgsz, serialsz;
6524     CHAR keypath[MAX_PATH * 2];
6525     CHAR prodcode[MAX_PATH];
6526     CHAR prod_squashed[MAX_PATH];
6527     HKEY prodkey, userprod, props;
6528     LPSTR usersid;
6529     LONG res;
6530
6531     create_test_guid(prodcode, prod_squashed);
6532     get_user_sid(&usersid);
6533
6534     /* NULL szProduct */
6535     INIT_USERINFO();
6536     state = MsiGetUserInfoA(NULL, user, &usersz, org, &orgsz, serial, &serialsz);
6537     ok(state == USERINFOSTATE_INVALIDARG,
6538        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6539     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6540     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6541     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6542     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6543     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6544     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6545
6546     /* empty szProductCode */
6547     INIT_USERINFO();
6548     state = MsiGetUserInfoA("", user, &usersz, org, &orgsz, serial, &serialsz);
6549     ok(state == USERINFOSTATE_INVALIDARG,
6550        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6551     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6552     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6553     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6554     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6555     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6556     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6557
6558     /* garbage szProductCode */
6559     INIT_USERINFO();
6560     state = MsiGetUserInfoA("garbage", user, &usersz, org, &orgsz, serial, &serialsz);
6561     ok(state == USERINFOSTATE_INVALIDARG,
6562        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6563     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6564     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6565     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6566     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6567     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6568     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6569
6570     /* guid without brackets */
6571     INIT_USERINFO();
6572     state = MsiGetUserInfoA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
6573                             user, &usersz, org, &orgsz, serial, &serialsz);
6574     ok(state == USERINFOSTATE_INVALIDARG,
6575        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6576     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6577     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6578     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6579     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6580     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6581     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6582
6583     /* guid with brackets */
6584     INIT_USERINFO();
6585     state = MsiGetUserInfoA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
6586                             user, &usersz, org, &orgsz, serial, &serialsz);
6587     ok(state == USERINFOSTATE_UNKNOWN,
6588        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6589     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6590     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6591     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6592     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6593     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6594     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6595
6596     /* NULL lpUserNameBuf */
6597     INIT_USERINFO();
6598     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6599     ok(state == USERINFOSTATE_UNKNOWN,
6600        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6601     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6602     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6603     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6604     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6605     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6606
6607     /* NULL pcchUserNameBuf */
6608     INIT_USERINFO();
6609     state = MsiGetUserInfoA(prodcode, user, NULL, org, &orgsz, serial, &serialsz);
6610     ok(state == USERINFOSTATE_INVALIDARG,
6611        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6612     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6613     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6614     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6615     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6616     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6617
6618     /* both lpUserNameBuf and pcchUserNameBuf NULL */
6619     INIT_USERINFO();
6620     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6621     ok(state == USERINFOSTATE_UNKNOWN,
6622        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6623     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6624     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6625     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6626     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6627
6628     /* NULL lpOrgNameBuf */
6629     INIT_USERINFO();
6630     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, &orgsz, serial, &serialsz);
6631     ok(state == USERINFOSTATE_UNKNOWN,
6632        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6633     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6634     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6635     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6636     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6637     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6638
6639     /* NULL pcchOrgNameBuf */
6640     INIT_USERINFO();
6641     state = MsiGetUserInfoA(prodcode, user, &usersz, org, NULL, serial, &serialsz);
6642     ok(state == USERINFOSTATE_INVALIDARG,
6643        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6644     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6645     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6646     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6647     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6648     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6649
6650     /* both lpOrgNameBuf and pcchOrgNameBuf NULL */
6651     INIT_USERINFO();
6652     state = MsiGetUserInfoA(prodcode, user, &usersz, NULL, NULL, serial, &serialsz);
6653     ok(state == USERINFOSTATE_UNKNOWN,
6654        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6655     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6656     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6657     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6658     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6659
6660     /* NULL lpSerialBuf */
6661     INIT_USERINFO();
6662     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, &serialsz);
6663     ok(state == USERINFOSTATE_UNKNOWN,
6664        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6665     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6666     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6667     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6668     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6669     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6670
6671     /* NULL pcchSerialBuf */
6672     INIT_USERINFO();
6673     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, NULL);
6674     ok(state == USERINFOSTATE_INVALIDARG,
6675        "Expected USERINFOSTATE_INVALIDARG, got %d\n", state);
6676     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6677     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6678     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6679     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6680     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6681
6682     /* both lpSerialBuf and pcchSerialBuf NULL */
6683     INIT_USERINFO();
6684     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, NULL, NULL);
6685     ok(state == USERINFOSTATE_UNKNOWN,
6686        "Expected USERINFOSTATE_UNKNOWN, got %d\n", state);
6687     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6688     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6689     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6690     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6691
6692     /* MSIINSTALLCONTEXT_USERMANAGED */
6693
6694     /* create local system product key */
6695     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
6696     lstrcatA(keypath, usersid);
6697     lstrcatA(keypath, "\\Installer\\Products\\");
6698     lstrcatA(keypath, prod_squashed);
6699
6700     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6701     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6702
6703     /* managed product key exists */
6704     INIT_USERINFO();
6705     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6706     ok(state == USERINFOSTATE_ABSENT,
6707        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6708     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6709     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6710     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6711     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6712     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6713     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6714
6715     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6716     lstrcatA(keypath, "Installer\\UserData\\");
6717     lstrcatA(keypath, usersid);
6718     lstrcatA(keypath, "\\Products\\");
6719     lstrcatA(keypath, prod_squashed);
6720
6721     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6722     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6723
6724     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6725     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6726
6727     /* InstallProperties key exists */
6728     INIT_USERINFO();
6729     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6730     ok(state == USERINFOSTATE_ABSENT,
6731        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6732     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6733     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6734     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6735     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6736     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6737     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6738
6739     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6740     INIT_USERINFO();
6741     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6742     ok(state == USERINFOSTATE_ABSENT,
6743        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6744     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6745     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6746     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6747     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6748
6749     /* RegOwner, RegCompany don't exist, out params are NULL */
6750     INIT_USERINFO();
6751     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6752     ok(state == USERINFOSTATE_ABSENT,
6753        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6754     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6755     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6756
6757     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6758     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6759
6760     /* RegOwner value exists */
6761     INIT_USERINFO();
6762     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6763     ok(state == USERINFOSTATE_ABSENT,
6764        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6765     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6766     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6767     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6768     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6769     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6770     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6771
6772     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6773     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6774
6775     /* RegCompany value exists */
6776     INIT_USERINFO();
6777     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6778     ok(state == USERINFOSTATE_ABSENT,
6779        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6780     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6781     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6782     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6783     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6784     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6785     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6786
6787     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6788     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6789
6790     /* ProductID value exists */
6791     INIT_USERINFO();
6792     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6793     ok(state == USERINFOSTATE_PRESENT,
6794        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6795     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6796     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6797     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6798     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6799     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6800     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6801
6802     /* pcchUserNameBuf is too small */
6803     INIT_USERINFO();
6804     usersz = 0;
6805     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6806     ok(state == USERINFOSTATE_MOREDATA,
6807        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6808     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6809     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6810     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6811     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6812     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6813     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6814
6815     /* pcchUserNameBuf has no room for NULL terminator */
6816     INIT_USERINFO();
6817     usersz = 5;
6818     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6819     ok(state == USERINFOSTATE_MOREDATA,
6820        "Expected USERINFOSTATE_MOREDATA, got %d\n", state);
6821     todo_wine
6822     {
6823         ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6824     }
6825     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6826     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6827     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6828     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6829     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6830
6831     /* pcchUserNameBuf is too small, lpUserNameBuf is NULL */
6832     INIT_USERINFO();
6833     usersz = 0;
6834     state = MsiGetUserInfoA(prodcode, NULL, &usersz, org, &orgsz, serial, &serialsz);
6835     ok(state == USERINFOSTATE_PRESENT,
6836        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6837     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6838     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6839     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6840     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6841     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6842     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6843
6844     RegDeleteValueA(props, "ProductID");
6845     RegDeleteValueA(props, "RegCompany");
6846     RegDeleteValueA(props, "RegOwner");
6847     RegDeleteKeyA(props, "");
6848     RegCloseKey(props);
6849     RegDeleteKeyA(userprod, "");
6850     RegCloseKey(userprod);
6851     RegDeleteKeyA(prodkey, "");
6852     RegCloseKey(prodkey);
6853
6854     /* MSIINSTALLCONTEXT_USERUNMANAGED */
6855
6856     /* create local system product key */
6857     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
6858     lstrcatA(keypath, prod_squashed);
6859
6860     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
6861     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6862
6863     /* product key exists */
6864     INIT_USERINFO();
6865     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6866     ok(state == USERINFOSTATE_ABSENT,
6867        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6868     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6869     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6870     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6871     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6872     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6873     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6874
6875     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6876     lstrcatA(keypath, "Installer\\UserData\\");
6877     lstrcatA(keypath, usersid);
6878     lstrcatA(keypath, "\\Products\\");
6879     lstrcatA(keypath, prod_squashed);
6880
6881     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6882     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6883
6884     res = RegCreateKeyA(userprod, "InstallProperties", &props);
6885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6886
6887     /* InstallProperties key exists */
6888     INIT_USERINFO();
6889     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6890     ok(state == USERINFOSTATE_ABSENT,
6891        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6892     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6893     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6894     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6895     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
6896     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6897     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6898
6899     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
6900     INIT_USERINFO();
6901     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
6902     ok(state == USERINFOSTATE_ABSENT,
6903        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6904     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6905     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6906     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6907     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6908
6909     /* RegOwner, RegCompany don't exist, out params are NULL */
6910     INIT_USERINFO();
6911     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
6912     ok(state == USERINFOSTATE_ABSENT,
6913        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6914     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6915     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6916
6917     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
6918     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6919
6920     /* RegOwner value exists */
6921     INIT_USERINFO();
6922     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6923     ok(state == USERINFOSTATE_ABSENT,
6924        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6925     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6926     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
6927     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6928     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6929     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
6930     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6931
6932     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
6933     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6934
6935     /* RegCompany value exists */
6936     INIT_USERINFO();
6937     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6938     ok(state == USERINFOSTATE_ABSENT,
6939        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6940     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6941     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6942     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6943     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6944     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6945     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
6946
6947     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
6948     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6949
6950     /* ProductID value exists */
6951     INIT_USERINFO();
6952     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6953     ok(state == USERINFOSTATE_PRESENT,
6954        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
6955     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
6956     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
6957     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
6958     ok(usersz == 5, "Expected 5, got %d\n", usersz);
6959     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
6960     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
6961
6962     RegDeleteValueA(props, "ProductID");
6963     RegDeleteValueA(props, "RegCompany");
6964     RegDeleteValueA(props, "RegOwner");
6965     RegDeleteKeyA(props, "");
6966     RegCloseKey(props);
6967     RegDeleteKeyA(userprod, "");
6968     RegCloseKey(userprod);
6969     RegDeleteKeyA(prodkey, "");
6970     RegCloseKey(prodkey);
6971
6972     /* MSIINSTALLCONTEXT_MACHINE */
6973
6974     /* create local system product key */
6975     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
6976     lstrcatA(keypath, prod_squashed);
6977
6978     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
6979     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
6980
6981     /* product key exists */
6982     INIT_USERINFO();
6983     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
6984     ok(state == USERINFOSTATE_ABSENT,
6985        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
6986     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
6987     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
6988     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
6989     ok(usersz == MAX_PATH, "Expected MAX_PATH, got %d\n", usersz);
6990     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
6991     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
6992
6993     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
6994     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18");
6995     lstrcatA(keypath, "\\Products\\");
6996     lstrcatA(keypath, prod_squashed);
6997
6998     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
6999     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7000
7001     res = RegCreateKeyA(userprod, "InstallProperties", &props);
7002     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7003
7004     /* InstallProperties key exists */
7005     INIT_USERINFO();
7006     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7007     ok(state == USERINFOSTATE_ABSENT,
7008        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7009     ok(!lstrcmpA(user, "apple"), "Expected user to be unchanged, got \"%s\"\n", user);
7010     ok(!lstrcmpA(org, "orange"), "Expected org to be unchanged, got \"%s\"\n", org);
7011     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7012     ok(usersz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", usersz);
7013     ok(orgsz == MAX_PATH, "Expected MAX_PATH, got %d\n", orgsz);
7014     ok(serialsz == MAX_PATH, "Expected MAX_PATH, got %d\n", serialsz);
7015
7016     /* RegOwner doesn't exist, lpUserNameBuf and pcchUserNameBuf are NULL */
7017     INIT_USERINFO();
7018     state = MsiGetUserInfoA(prodcode, NULL, NULL, org, &orgsz, serial, &serialsz);
7019     ok(state == USERINFOSTATE_ABSENT,
7020        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7021     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7022     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7023     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7024     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7025
7026     /* RegOwner, RegCompany don't exist, out params are NULL */
7027     INIT_USERINFO();
7028     state = MsiGetUserInfoA(prodcode, NULL, NULL, NULL, NULL, serial, &serialsz);
7029     ok(state == USERINFOSTATE_ABSENT,
7030        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7031     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7032     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7033
7034     res = RegSetValueExA(props, "RegOwner", 0, REG_SZ, (LPBYTE)"owner", 6);
7035     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7036
7037     /* RegOwner value exists */
7038     INIT_USERINFO();
7039     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7040     ok(state == USERINFOSTATE_ABSENT,
7041        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7042     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7043     ok(!lstrcmpA(org, ""), "Expected empty string, got \"%s\"\n", org);
7044     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7045     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7046     ok(orgsz == 0, "Expected 0, got %d\n", orgsz);
7047     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7048
7049     res = RegSetValueExA(props, "RegCompany", 0, REG_SZ, (LPBYTE)"company", 8);
7050     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7051
7052     /* RegCompany value exists */
7053     INIT_USERINFO();
7054     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7055     ok(state == USERINFOSTATE_ABSENT,
7056        "Expected USERINFOSTATE_ABSENT, got %d\n", state);
7057     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7058     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7059     ok(!lstrcmpA(serial, "banana"), "Expected serial to be unchanged, got \"%s\"\n", serial);
7060     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7061     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7062     ok(serialsz == MAX_PATH - 1, "Expected MAX_PATH - 1, got %d\n", serialsz);
7063
7064     res = RegSetValueExA(props, "ProductID", 0, REG_SZ, (LPBYTE)"ID", 3);
7065     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7066
7067     /* ProductID value exists */
7068     INIT_USERINFO();
7069     state = MsiGetUserInfoA(prodcode, user, &usersz, org, &orgsz, serial, &serialsz);
7070     ok(state == USERINFOSTATE_PRESENT,
7071        "Expected USERINFOSTATE_PRESENT, got %d\n", state);
7072     ok(!lstrcmpA(user, "owner"), "Expected \"owner\", got \"%s\"\n", user);
7073     ok(!lstrcmpA(org, "company"), "Expected \"company\", got \"%s\"\n", org);
7074     ok(!lstrcmpA(serial, "ID"), "Expected \"ID\", got \"%s\"\n", serial);
7075     ok(usersz == 5, "Expected 5, got %d\n", usersz);
7076     ok(orgsz == 7, "Expected 7, got %d\n", orgsz);
7077     ok(serialsz == 2, "Expected 2, got %d\n", serialsz);
7078
7079     RegDeleteValueA(props, "ProductID");
7080     RegDeleteValueA(props, "RegCompany");
7081     RegDeleteValueA(props, "RegOwner");
7082     RegDeleteKeyA(props, "");
7083     RegCloseKey(props);
7084     RegDeleteKeyA(userprod, "");
7085     RegCloseKey(userprod);
7086     RegDeleteKeyA(prodkey, "");
7087     RegCloseKey(prodkey);
7088 }
7089
7090 static void test_MsiOpenProduct(void)
7091 {
7092     MSIHANDLE hprod, hdb;
7093     CHAR val[MAX_PATH];
7094     CHAR path[MAX_PATH];
7095     CHAR keypath[MAX_PATH*2];
7096     CHAR prodcode[MAX_PATH];
7097     CHAR prod_squashed[MAX_PATH];
7098     HKEY prodkey, userkey, props;
7099     LPSTR usersid;
7100     DWORD size;
7101     LONG res;
7102     UINT r;
7103
7104     GetCurrentDirectoryA(MAX_PATH, path);
7105     lstrcatA(path, "\\");
7106
7107     create_test_guid(prodcode, prod_squashed);
7108     get_user_sid(&usersid);
7109
7110     hdb = create_package_db(prodcode);
7111     MsiCloseHandle(hdb);
7112
7113     /* NULL szProduct */
7114     hprod = 0xdeadbeef;
7115     r = MsiOpenProductA(NULL, &hprod);
7116     ok(r == ERROR_INVALID_PARAMETER,
7117        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7118     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7119
7120     /* empty szProduct */
7121     hprod = 0xdeadbeef;
7122     r = MsiOpenProductA("", &hprod);
7123     ok(r == ERROR_INVALID_PARAMETER,
7124        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7125     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7126
7127     /* garbage szProduct */
7128     hprod = 0xdeadbeef;
7129     r = MsiOpenProductA("garbage", &hprod);
7130     ok(r == ERROR_INVALID_PARAMETER,
7131        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7132     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7133
7134     /* guid without brackets */
7135     hprod = 0xdeadbeef;
7136     r = MsiOpenProductA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", &hprod);
7137     ok(r == ERROR_INVALID_PARAMETER,
7138        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7139     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7140
7141     /* guid with brackets */
7142     hprod = 0xdeadbeef;
7143     r = MsiOpenProductA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", &hprod);
7144     ok(r == ERROR_UNKNOWN_PRODUCT,
7145        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7146     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7147
7148     /* same length as guid, but random */
7149     hprod = 0xdeadbeef;
7150     r = MsiOpenProductA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", &hprod);
7151     ok(r == ERROR_INVALID_PARAMETER,
7152        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7153     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7154
7155     /* hProduct is NULL */
7156     hprod = 0xdeadbeef;
7157     r = MsiOpenProductA(prodcode, NULL);
7158     ok(r == ERROR_INVALID_PARAMETER,
7159        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7160     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7161
7162     /* MSIINSTALLCONTEXT_USERMANAGED */
7163
7164     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7165     lstrcatA(keypath, "Installer\\Managed\\");
7166     lstrcatA(keypath, usersid);
7167     lstrcatA(keypath, "\\Installer\\Products\\");
7168     lstrcatA(keypath, prod_squashed);
7169
7170     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7171     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7172
7173     /* managed product key exists */
7174     hprod = 0xdeadbeef;
7175     r = MsiOpenProductA(prodcode, &hprod);
7176     ok(r == ERROR_UNKNOWN_PRODUCT,
7177        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7178     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7179
7180     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7181     lstrcatA(keypath, "Installer\\UserData\\");
7182     lstrcatA(keypath, usersid);
7183     lstrcatA(keypath, "\\Products\\");
7184     lstrcatA(keypath, prod_squashed);
7185
7186     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7187     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7188
7189     /* user product key exists */
7190     hprod = 0xdeadbeef;
7191     r = MsiOpenProductA(prodcode, &hprod);
7192     ok(r == ERROR_UNKNOWN_PRODUCT,
7193        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7194     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7195
7196     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7197     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7198
7199     /* InstallProperties key exists */
7200     hprod = 0xdeadbeef;
7201     r = MsiOpenProductA(prodcode, &hprod);
7202     ok(r == ERROR_UNKNOWN_PRODUCT,
7203        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7204     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7205
7206     lstrcpyA(val, path);
7207     lstrcatA(val, "\\winetest.msi");
7208     res = RegSetValueExA(props, "ManagedLocalPackage", 0, REG_SZ,
7209                          (const BYTE *)val, lstrlenA(val) + 1);
7210     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7211
7212     /* ManagedLocalPackage value exists */
7213     hprod = 0xdeadbeef;
7214     r = MsiOpenProductA(prodcode, &hprod);
7215     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7216     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7217
7218     size = MAX_PATH;
7219     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7220     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7221     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7222     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7223
7224     MsiCloseHandle(hprod);
7225
7226     RegDeleteValueA(props, "ManagedLocalPackage");
7227     RegDeleteKeyA(props, "");
7228     RegCloseKey(props);
7229     RegDeleteKeyA(userkey, "");
7230     RegCloseKey(userkey);
7231     RegDeleteKeyA(prodkey, "");
7232     RegCloseKey(prodkey);
7233
7234     /* MSIINSTALLCONTEXT_USERUNMANAGED */
7235
7236     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
7237     lstrcatA(keypath, prod_squashed);
7238
7239     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
7240     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7241
7242     /* unmanaged product key exists */
7243     hprod = 0xdeadbeef;
7244     r = MsiOpenProductA(prodcode, &hprod);
7245     ok(r == ERROR_UNKNOWN_PRODUCT,
7246        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7247     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7248
7249     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7250     lstrcatA(keypath, "Installer\\UserData\\");
7251     lstrcatA(keypath, usersid);
7252     lstrcatA(keypath, "\\Products\\");
7253     lstrcatA(keypath, prod_squashed);
7254
7255     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7256     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7257
7258     /* user product key exists */
7259     hprod = 0xdeadbeef;
7260     r = MsiOpenProductA(prodcode, &hprod);
7261     ok(r == ERROR_UNKNOWN_PRODUCT,
7262        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7263     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7264
7265     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7266     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7267
7268     /* InstallProperties key exists */
7269     hprod = 0xdeadbeef;
7270     r = MsiOpenProductA(prodcode, &hprod);
7271     ok(r == ERROR_UNKNOWN_PRODUCT,
7272        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7273     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7274
7275     lstrcpyA(val, path);
7276     lstrcatA(val, "\\winetest.msi");
7277     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7278                          (const BYTE *)val, lstrlenA(val) + 1);
7279     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7280
7281     /* LocalPackage value exists */
7282     hprod = 0xdeadbeef;
7283     r = MsiOpenProductA(prodcode, &hprod);
7284     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7285     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7286
7287     size = MAX_PATH;
7288     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7289     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7290     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7291     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7292
7293     MsiCloseHandle(hprod);
7294
7295     RegDeleteValueA(props, "LocalPackage");
7296     RegDeleteKeyA(props, "");
7297     RegCloseKey(props);
7298     RegDeleteKeyA(userkey, "");
7299     RegCloseKey(userkey);
7300     RegDeleteKeyA(prodkey, "");
7301     RegCloseKey(prodkey);
7302
7303     /* MSIINSTALLCONTEXT_MACHINE */
7304
7305     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
7306     lstrcatA(keypath, prod_squashed);
7307
7308     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7309     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7310
7311     /* managed product key exists */
7312     hprod = 0xdeadbeef;
7313     r = MsiOpenProductA(prodcode, &hprod);
7314     ok(r == ERROR_UNKNOWN_PRODUCT,
7315        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7316     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7317
7318     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
7319     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
7320     lstrcatA(keypath, prod_squashed);
7321
7322     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
7323     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7324
7325     /* user product key exists */
7326     hprod = 0xdeadbeef;
7327     r = MsiOpenProductA(prodcode, &hprod);
7328     ok(r == ERROR_UNKNOWN_PRODUCT,
7329        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7330     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7331
7332     res = RegCreateKeyA(userkey, "InstallProperties", &props);
7333     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7334
7335     /* InstallProperties key exists */
7336     hprod = 0xdeadbeef;
7337     r = MsiOpenProductA(prodcode, &hprod);
7338     ok(r == ERROR_UNKNOWN_PRODUCT,
7339        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7340     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7341
7342     lstrcpyA(val, path);
7343     lstrcatA(val, "\\winetest.msi");
7344     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7345                          (const BYTE *)val, lstrlenA(val) + 1);
7346     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7347
7348     /* LocalPackage value exists */
7349     hprod = 0xdeadbeef;
7350     r = MsiOpenProductA(prodcode, &hprod);
7351     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7352     ok(hprod != 0 && hprod != 0xdeadbeef, "Expected a valid product handle\n");
7353
7354     size = MAX_PATH;
7355     r = MsiGetPropertyA(hprod, "ProductCode", val, &size);
7356     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7357     ok(!lstrcmpA(val, prodcode), "Expected \"%s\", got \"%s\"\n", prodcode, val);
7358     ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
7359
7360     MsiCloseHandle(hprod);
7361
7362     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7363                          (const BYTE *)"winetest.msi", 13);
7364     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7365
7366     /* LocalPackage has just the package name */
7367     hprod = 0xdeadbeef;
7368     r = MsiOpenProductA(prodcode, &hprod);
7369     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
7370        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
7371     if (r == ERROR_SUCCESS)
7372         MsiCloseHandle(hprod);
7373     else
7374         ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7375
7376     lstrcpyA(val, path);
7377     lstrcatA(val, "\\winetest.msi");
7378     res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
7379                          (const BYTE *)val, lstrlenA(val) + 1);
7380     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7381
7382     DeleteFileA(msifile);
7383
7384     /* local package does not exist */
7385     hprod = 0xdeadbeef;
7386     r = MsiOpenProductA(prodcode, &hprod);
7387     ok(r == ERROR_UNKNOWN_PRODUCT,
7388        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
7389     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
7390
7391     RegDeleteValueA(props, "LocalPackage");
7392     RegDeleteKeyA(props, "");
7393     RegCloseKey(props);
7394     RegDeleteKeyA(userkey, "");
7395     RegCloseKey(userkey);
7396     RegDeleteKeyA(prodkey, "");
7397     RegCloseKey(prodkey);
7398
7399     DeleteFileA(msifile);
7400 }
7401
7402 static void test_MsiEnumPatchesEx(void)
7403 {
7404     CHAR keypath[MAX_PATH], patch[MAX_PATH];
7405     CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
7406     CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
7407     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
7408     HKEY prodkey, patches, udprod, udpatch;
7409     HKEY userkey, hpatch;
7410     MSIINSTALLCONTEXT context;
7411     DWORD size, data;
7412     LPSTR usersid;
7413     LONG res;
7414     UINT r;
7415
7416     if (!pMsiEnumPatchesExA)
7417     {
7418         win_skip("MsiEnumPatchesExA not implemented\n");
7419         return;
7420     }
7421
7422     create_test_guid(prodcode, prod_squashed);
7423     create_test_guid(patch, patch_squashed);
7424     get_user_sid(&usersid);
7425
7426     /* empty szProductCode */
7427     lstrcpyA(patchcode, "apple");
7428     lstrcpyA(targetprod, "banana");
7429     context = 0xdeadbeef;
7430     lstrcpyA(targetsid, "kiwi");
7431     size = MAX_PATH;
7432     r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7433                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
7434                            targetsid, &size);
7435     ok(r == ERROR_INVALID_PARAMETER,
7436        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7437     ok(!lstrcmpA(patchcode, "apple"),
7438        "Expected patchcode to be unchanged, got %s\n", patchcode);
7439     ok(!lstrcmpA(targetprod, "banana"),
7440        "Expected targetprod to be unchanged, got %s\n", targetprod);
7441     ok(context == 0xdeadbeef,
7442        "Expected context to be unchanged, got %d\n", context);
7443     ok(!lstrcmpA(targetsid, "kiwi"),
7444        "Expected targetsid to be unchanged, got %s\n", targetsid);
7445     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7446
7447     /* garbage szProductCode */
7448     lstrcpyA(patchcode, "apple");
7449     lstrcpyA(targetprod, "banana");
7450     context = 0xdeadbeef;
7451     lstrcpyA(targetsid, "kiwi");
7452     size = MAX_PATH;
7453     r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7454                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
7455                            targetsid, &size);
7456     ok(r == ERROR_INVALID_PARAMETER,
7457        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7458     ok(!lstrcmpA(patchcode, "apple"),
7459        "Expected patchcode to be unchanged, got %s\n", patchcode);
7460     ok(!lstrcmpA(targetprod, "banana"),
7461        "Expected targetprod to be unchanged, got %s\n", targetprod);
7462     ok(context == 0xdeadbeef,
7463        "Expected context to be unchanged, got %d\n", context);
7464     ok(!lstrcmpA(targetsid, "kiwi"),
7465        "Expected targetsid to be unchanged, got %s\n", targetsid);
7466     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7467
7468     /* guid without brackets */
7469     lstrcpyA(patchcode, "apple");
7470     lstrcpyA(targetprod, "banana");
7471     context = 0xdeadbeef;
7472     lstrcpyA(targetsid, "kiwi");
7473     size = MAX_PATH;
7474     r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
7475                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7476                            0, patchcode, targetprod, &context,
7477                            targetsid, &size);
7478     ok(r == ERROR_INVALID_PARAMETER,
7479        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7480     ok(!lstrcmpA(patchcode, "apple"),
7481        "Expected patchcode to be unchanged, got %s\n", patchcode);
7482     ok(!lstrcmpA(targetprod, "banana"),
7483        "Expected targetprod to be unchanged, got %s\n", targetprod);
7484     ok(context == 0xdeadbeef,
7485        "Expected context to be unchanged, got %d\n", context);
7486     ok(!lstrcmpA(targetsid, "kiwi"),
7487        "Expected targetsid to be unchanged, got %s\n", targetsid);
7488     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7489
7490     /* guid with brackets */
7491     lstrcpyA(patchcode, "apple");
7492     lstrcpyA(targetprod, "banana");
7493     context = 0xdeadbeef;
7494     lstrcpyA(targetsid, "kiwi");
7495     size = MAX_PATH;
7496     r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
7497                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7498                            0, patchcode, targetprod, &context,
7499                            targetsid, &size);
7500     ok(r == ERROR_NO_MORE_ITEMS,
7501        "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7502     ok(!lstrcmpA(patchcode, "apple"),
7503        "Expected patchcode to be unchanged, got %s\n", patchcode);
7504     ok(!lstrcmpA(targetprod, "banana"),
7505        "Expected targetprod to be unchanged, got %s\n", targetprod);
7506     ok(context == 0xdeadbeef,
7507        "Expected context to be unchanged, got %d\n", context);
7508     ok(!lstrcmpA(targetsid, "kiwi"),
7509        "Expected targetsid to be unchanged, got %s\n", targetsid);
7510     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7511
7512     /* szUserSid is S-1-5-18 */
7513     lstrcpyA(patchcode, "apple");
7514     lstrcpyA(targetprod, "banana");
7515     context = 0xdeadbeef;
7516     lstrcpyA(targetsid, "kiwi");
7517     size = MAX_PATH;
7518     r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
7519                            MSIINSTALLCONTEXT_USERUNMANAGED, MSIPATCHSTATE_ALL,
7520                            0, patchcode, targetprod, &context,
7521                            targetsid, &size);
7522     ok(r == ERROR_INVALID_PARAMETER,
7523        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7524     ok(!lstrcmpA(patchcode, "apple"),
7525        "Expected patchcode to be unchanged, got %s\n", patchcode);
7526     ok(!lstrcmpA(targetprod, "banana"),
7527        "Expected targetprod to be unchanged, got %s\n", targetprod);
7528     ok(context == 0xdeadbeef,
7529        "Expected context to be unchanged, got %d\n", context);
7530     ok(!lstrcmpA(targetsid, "kiwi"),
7531        "Expected targetsid to be unchanged, got %s\n", targetsid);
7532     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7533
7534     /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
7535     lstrcpyA(patchcode, "apple");
7536     lstrcpyA(targetprod, "banana");
7537     context = 0xdeadbeef;
7538     lstrcpyA(targetsid, "kiwi");
7539     size = MAX_PATH;
7540     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
7541                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7542                            &context, targetsid, &size);
7543     ok(r == ERROR_INVALID_PARAMETER,
7544        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7545     ok(!lstrcmpA(patchcode, "apple"),
7546        "Expected patchcode to be unchanged, got %s\n", patchcode);
7547     ok(!lstrcmpA(targetprod, "banana"),
7548        "Expected targetprod to be unchanged, got %s\n", targetprod);
7549     ok(context == 0xdeadbeef,
7550        "Expected context to be unchanged, got %d\n", context);
7551     ok(!lstrcmpA(targetsid, "kiwi"),
7552        "Expected targetsid to be unchanged, got %s\n", targetsid);
7553     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7554
7555     /* dwContext is out of bounds */
7556     lstrcpyA(patchcode, "apple");
7557     lstrcpyA(targetprod, "banana");
7558     context = 0xdeadbeef;
7559     lstrcpyA(targetsid, "kiwi");
7560     size = MAX_PATH;
7561     r = pMsiEnumPatchesExA(prodcode, usersid, 0,
7562                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7563                            &context, targetsid, &size);
7564     ok(r == ERROR_INVALID_PARAMETER,
7565        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7566     ok(!lstrcmpA(patchcode, "apple"),
7567        "Expected patchcode to be unchanged, got %s\n", patchcode);
7568     ok(!lstrcmpA(targetprod, "banana"),
7569        "Expected targetprod to be unchanged, got %s\n", targetprod);
7570     ok(context == 0xdeadbeef,
7571        "Expected context to be unchanged, got %d\n", context);
7572     ok(!lstrcmpA(targetsid, "kiwi"),
7573        "Expected targetsid to be unchanged, got %s\n", targetsid);
7574     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7575
7576     /* dwContext is out of bounds */
7577     lstrcpyA(patchcode, "apple");
7578     lstrcpyA(targetprod, "banana");
7579     context = 0xdeadbeef;
7580     lstrcpyA(targetsid, "kiwi");
7581     size = MAX_PATH;
7582     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
7583                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7584                            &context, targetsid, &size);
7585     ok(r == ERROR_INVALID_PARAMETER,
7586        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7587     ok(!lstrcmpA(patchcode, "apple"),
7588        "Expected patchcode to be unchanged, got %s\n", patchcode);
7589     ok(!lstrcmpA(targetprod, "banana"),
7590        "Expected targetprod to be unchanged, got %s\n", targetprod);
7591     ok(context == 0xdeadbeef,
7592        "Expected context to be unchanged, got %d\n", context);
7593     ok(!lstrcmpA(targetsid, "kiwi"),
7594        "Expected targetsid to be unchanged, got %s\n", targetsid);
7595     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7596
7597     /* dwFilter is out of bounds */
7598     lstrcpyA(patchcode, "apple");
7599     lstrcpyA(targetprod, "banana");
7600     context = 0xdeadbeef;
7601     lstrcpyA(targetsid, "kiwi");
7602     size = MAX_PATH;
7603     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7604                            MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
7605                            &context, targetsid, &size);
7606     ok(r == ERROR_INVALID_PARAMETER,
7607        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7608     ok(!lstrcmpA(patchcode, "apple"),
7609        "Expected patchcode to be unchanged, got %s\n", patchcode);
7610     ok(!lstrcmpA(targetprod, "banana"),
7611        "Expected targetprod to be unchanged, got %s\n", targetprod);
7612     ok(context == 0xdeadbeef,
7613        "Expected context to be unchanged, got %d\n", context);
7614     ok(!lstrcmpA(targetsid, "kiwi"),
7615        "Expected targetsid to be unchanged, got %s\n", targetsid);
7616     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7617
7618     /* dwFilter is out of bounds */
7619     lstrcpyA(patchcode, "apple");
7620     lstrcpyA(targetprod, "banana");
7621     context = 0xdeadbeef;
7622     lstrcpyA(targetsid, "kiwi");
7623     size = MAX_PATH;
7624     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7625                            MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
7626                            &context, targetsid, &size);
7627     ok(r == ERROR_INVALID_PARAMETER,
7628        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7629     ok(!lstrcmpA(patchcode, "apple"),
7630        "Expected patchcode to be unchanged, got %s\n", patchcode);
7631     ok(!lstrcmpA(targetprod, "banana"),
7632        "Expected targetprod to be unchanged, got %s\n", targetprod);
7633     ok(context == 0xdeadbeef,
7634        "Expected context to be unchanged, got %d\n", context);
7635     ok(!lstrcmpA(targetsid, "kiwi"),
7636        "Expected targetsid to be unchanged, got %s\n", targetsid);
7637     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7638
7639     /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
7640     lstrcpyA(patchcode, "apple");
7641     lstrcpyA(targetprod, "banana");
7642     context = 0xdeadbeef;
7643     lstrcpyA(targetsid, "kiwi");
7644     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
7645                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
7646                            &context, targetsid, NULL);
7647     ok(r == ERROR_INVALID_PARAMETER,
7648        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7649     ok(!lstrcmpA(patchcode, "apple"),
7650        "Expected patchcode to be unchanged, got %s\n", patchcode);
7651     ok(!lstrcmpA(targetprod, "banana"),
7652        "Expected targetprod to be unchanged, got %s\n", targetprod);
7653     ok(context == 0xdeadbeef,
7654        "Expected context to be unchanged, got %d\n", context);
7655     ok(!lstrcmpA(targetsid, "kiwi"),
7656        "Expected targetsid to be unchanged, got %s\n", targetsid);
7657
7658     /* MSIINSTALLCONTEXT_USERMANAGED */
7659
7660     /* MSIPATCHSTATE_APPLIED */
7661
7662     lstrcpyA(patchcode, "apple");
7663     lstrcpyA(targetprod, "banana");
7664     context = 0xdeadbeef;
7665     lstrcpyA(targetsid, "kiwi");
7666     size = MAX_PATH;
7667     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7668                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7669                            &context, targetsid, &size);
7670     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7671     ok(!lstrcmpA(patchcode, "apple"),
7672        "Expected patchcode to be unchanged, got %s\n", patchcode);
7673     ok(!lstrcmpA(targetprod, "banana"),
7674        "Expected targetprod to be unchanged, got %s\n", targetprod);
7675     ok(context == 0xdeadbeef,
7676        "Expected context to be unchanged, got %d\n", context);
7677     ok(!lstrcmpA(targetsid, "kiwi"),
7678        "Expected targetsid to be unchanged, got %s\n", targetsid);
7679     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7680
7681     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
7682     lstrcatA(keypath, usersid);
7683     lstrcatA(keypath, "\\Installer\\Products\\");
7684     lstrcatA(keypath, prod_squashed);
7685
7686     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
7687     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7688
7689     /* managed product key exists */
7690     lstrcpyA(patchcode, "apple");
7691     lstrcpyA(targetprod, "banana");
7692     context = 0xdeadbeef;
7693     lstrcpyA(targetsid, "kiwi");
7694     size = MAX_PATH;
7695     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7696                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7697                            &context, targetsid, &size);
7698     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7699     ok(!lstrcmpA(patchcode, "apple"),
7700        "Expected patchcode to be unchanged, got %s\n", patchcode);
7701     ok(!lstrcmpA(targetprod, "banana"),
7702        "Expected targetprod to be unchanged, got %s\n", targetprod);
7703     ok(context == 0xdeadbeef,
7704        "Expected context to be unchanged, got %d\n", context);
7705     ok(!lstrcmpA(targetsid, "kiwi"),
7706        "Expected targetsid to be unchanged, got %s\n", targetsid);
7707     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7708
7709     res = RegCreateKeyA(prodkey, "Patches", &patches);
7710     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7711
7712     /* patches key exists */
7713     lstrcpyA(patchcode, "apple");
7714     lstrcpyA(targetprod, "banana");
7715     context = 0xdeadbeef;
7716     lstrcpyA(targetsid, "kiwi");
7717     size = MAX_PATH;
7718     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7719                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7720                            &context, targetsid, &size);
7721     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7722     ok(!lstrcmpA(patchcode, "apple"),
7723        "Expected patchcode to be unchanged, got %s\n", patchcode);
7724     ok(!lstrcmpA(targetprod, "banana"),
7725        "Expected targetprod to be unchanged, got %s\n", targetprod);
7726     ok(context == 0xdeadbeef,
7727        "Expected context to be unchanged, got %d\n", context);
7728     ok(!lstrcmpA(targetsid, "kiwi"),
7729        "Expected targetsid to be unchanged, got %s\n", targetsid);
7730     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7731
7732     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
7733                          (const BYTE *)patch_squashed,
7734                          lstrlenA(patch_squashed) + 1);
7735     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7736
7737     /* Patches value exists, is not REG_MULTI_SZ */
7738     lstrcpyA(patchcode, "apple");
7739     lstrcpyA(targetprod, "banana");
7740     context = 0xdeadbeef;
7741     lstrcpyA(targetsid, "kiwi");
7742     size = MAX_PATH;
7743     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7744                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7745                            &context, targetsid, &size);
7746     ok(r == ERROR_BAD_CONFIGURATION,
7747        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7748     ok(!lstrcmpA(patchcode, "apple"),
7749        "Expected patchcode to be unchanged, got %s\n", patchcode);
7750     ok(!lstrcmpA(targetprod, "banana"),
7751        "Expected targetprod to be unchanged, got %s\n", targetprod);
7752     ok(context == 0xdeadbeef,
7753        "Expected context to be unchanged, got %d\n", context);
7754     ok(!lstrcmpA(targetsid, "kiwi"),
7755        "Expected targetsid to be unchanged, got %s\n", targetsid);
7756     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7757
7758     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7759                          (const BYTE *)"a\0b\0c\0\0", 7);
7760     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7761
7762     /* Patches value exists, is not a squashed guid */
7763     lstrcpyA(patchcode, "apple");
7764     lstrcpyA(targetprod, "banana");
7765     context = 0xdeadbeef;
7766     lstrcpyA(targetsid, "kiwi");
7767     size = MAX_PATH;
7768     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
7769                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7770                            &context, targetsid, &size);
7771     ok(r == ERROR_BAD_CONFIGURATION,
7772        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
7773     ok(!lstrcmpA(patchcode, "apple"),
7774        "Expected patchcode to be unchanged, got %s\n", patchcode);
7775     ok(!lstrcmpA(targetprod, "banana"),
7776        "Expected targetprod to be unchanged, got %s\n", targetprod);
7777     ok(context == 0xdeadbeef,
7778        "Expected context to be unchanged, got %d\n", context);
7779     ok(!lstrcmpA(targetsid, "kiwi"),
7780        "Expected targetsid to be unchanged, got %s\n", targetsid);
7781     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7782
7783     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
7784     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
7785                          (const BYTE *)patch_squashed,
7786                          lstrlenA(patch_squashed) + 2);
7787     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7788
7789     /* Patches value exists */
7790     lstrcpyA(patchcode, "apple");
7791     lstrcpyA(targetprod, "banana");
7792     context = 0xdeadbeef;
7793     lstrcpyA(targetsid, "kiwi");
7794     size = MAX_PATH;
7795     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7796                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7797                            &context, targetsid, &size);
7798     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7799     ok(!lstrcmpA(patchcode, "apple"),
7800        "Expected patchcode to be unchanged, got %s\n", patchcode);
7801     ok(!lstrcmpA(targetprod, "banana"),
7802        "Expected targetprod to be unchanged, got %s\n", targetprod);
7803     ok(context == 0xdeadbeef,
7804        "Expected context to be unchanged, got %d\n", context);
7805     ok(!lstrcmpA(targetsid, "kiwi"),
7806        "Expected targetsid to be unchanged, got %s\n", targetsid);
7807     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7808
7809     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
7810                          (const BYTE *)"whatever", 9);
7811     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
7812
7813     /* patch squashed value exists */
7814     lstrcpyA(patchcode, "apple");
7815     lstrcpyA(targetprod, "banana");
7816     context = 0xdeadbeef;
7817     lstrcpyA(targetsid, "kiwi");
7818     size = MAX_PATH;
7819     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7820                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7821                            &context, targetsid, &size);
7822     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7823     ok(!lstrcmpA(patchcode, patch),
7824        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7825     ok(!lstrcmpA(targetprod, prodcode),
7826        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7827     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7828        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7829     ok(!lstrcmpA(targetsid, usersid),
7830        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7831     ok(size == lstrlenA(usersid),
7832        "Expected %d, got %d\n", lstrlenA(usersid), size);
7833
7834     /* increase the index */
7835     lstrcpyA(patchcode, "apple");
7836     lstrcpyA(targetprod, "banana");
7837     context = 0xdeadbeef;
7838     lstrcpyA(targetsid, "kiwi");
7839     size = MAX_PATH;
7840     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7841                            MSIPATCHSTATE_APPLIED, 1, patchcode, targetprod,
7842                            &context, targetsid, &size);
7843     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
7844     ok(!lstrcmpA(patchcode, "apple"),
7845        "Expected patchcode to be unchanged, got %s\n", patchcode);
7846     ok(!lstrcmpA(targetprod, "banana"),
7847        "Expected targetprod to be unchanged, got %s\n", targetprod);
7848     ok(context == 0xdeadbeef,
7849        "Expected context to be unchanged, got %d\n", context);
7850     ok(!lstrcmpA(targetsid, "kiwi"),
7851        "Expected targetsid to be unchanged, got %s\n", targetsid);
7852     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7853
7854     /* increase again */
7855     lstrcpyA(patchcode, "apple");
7856     lstrcpyA(targetprod, "banana");
7857     context = 0xdeadbeef;
7858     lstrcpyA(targetsid, "kiwi");
7859     size = MAX_PATH;
7860     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7861                            MSIPATCHSTATE_APPLIED, 2, patchcode, targetprod,
7862                            &context, targetsid, &size);
7863     ok(r == ERROR_INVALID_PARAMETER,
7864        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
7865     ok(!lstrcmpA(patchcode, "apple"),
7866        "Expected patchcode to be unchanged, got %s\n", patchcode);
7867     ok(!lstrcmpA(targetprod, "banana"),
7868        "Expected targetprod to be unchanged, got %s\n", targetprod);
7869     ok(context == 0xdeadbeef,
7870        "Expected context to be unchanged, got %d\n", context);
7871     ok(!lstrcmpA(targetsid, "kiwi"),
7872        "Expected targetsid to be unchanged, got %s\n", targetsid);
7873     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
7874
7875     /* szPatchCode is NULL */
7876     lstrcpyA(targetprod, "banana");
7877     context = 0xdeadbeef;
7878     lstrcpyA(targetsid, "kiwi");
7879     size = MAX_PATH;
7880     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7881                            MSIPATCHSTATE_APPLIED, 0, NULL, targetprod,
7882                            &context, targetsid, &size);
7883     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7884     ok(!lstrcmpA(targetprod, prodcode),
7885        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7886     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7887        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7888     ok(!lstrcmpA(targetsid, usersid),
7889        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7890     ok(size == lstrlenA(usersid),
7891        "Expected %d, got %d\n", lstrlenA(usersid), size);
7892
7893     /* szTargetProductCode is NULL */
7894     lstrcpyA(patchcode, "apple");
7895     context = 0xdeadbeef;
7896     lstrcpyA(targetsid, "kiwi");
7897     size = MAX_PATH;
7898     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7899                            MSIPATCHSTATE_APPLIED, 0, patchcode, NULL,
7900                            &context, targetsid, &size);
7901     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7902     ok(!lstrcmpA(patchcode, patch),
7903        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7904     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7905        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7906     ok(!lstrcmpA(targetsid, usersid),
7907        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7908     ok(size == lstrlenA(usersid),
7909        "Expected %d, got %d\n", lstrlenA(usersid), size);
7910
7911     /* pdwTargetProductContext is NULL */
7912     lstrcpyA(patchcode, "apple");
7913     lstrcpyA(targetprod, "banana");
7914     lstrcpyA(targetsid, "kiwi");
7915     size = MAX_PATH;
7916     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7917                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7918                            NULL, targetsid, &size);
7919     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7920     ok(!lstrcmpA(patchcode, patch),
7921        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7922     ok(!lstrcmpA(targetprod, prodcode),
7923        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7924     ok(!lstrcmpA(targetsid, usersid),
7925        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7926     ok(size == lstrlenA(usersid),
7927        "Expected %d, got %d\n", lstrlenA(usersid), size);
7928
7929     /* szTargetUserSid is NULL */
7930     lstrcpyA(patchcode, "apple");
7931     lstrcpyA(targetprod, "banana");
7932     context = 0xdeadbeef;
7933     size = MAX_PATH;
7934     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7935                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7936                            &context, NULL, &size);
7937     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7938     ok(!lstrcmpA(patchcode, patch),
7939        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7940     ok(!lstrcmpA(targetprod, prodcode),
7941        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7942     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7943        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7944     ok(size == lstrlenA(usersid) * sizeof(WCHAR),
7945        "Got %d\n", size);
7946
7947     /* pcchTargetUserSid is exactly the length of szTargetUserSid */
7948     lstrcpyA(patchcode, "apple");
7949     lstrcpyA(targetprod, "banana");
7950     context = 0xdeadbeef;
7951     lstrcpyA(targetsid, "kiwi");
7952     size = lstrlenA(usersid);
7953     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7954                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7955                            &context, targetsid, &size);
7956     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
7957     ok(!lstrcmpA(patchcode, patch),
7958        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7959     ok(!lstrcmpA(targetprod, prodcode),
7960        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7961     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7962        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7963     ok(!strncmp(targetsid, usersid, lstrlenA(usersid) - 1),
7964        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7965     ok(size == lstrlenA(usersid) * sizeof(WCHAR),
7966        "Got %d\n", size);
7967
7968     /* pcchTargetUserSid has enough room for NULL terminator */
7969     lstrcpyA(patchcode, "apple");
7970     lstrcpyA(targetprod, "banana");
7971     context = 0xdeadbeef;
7972     lstrcpyA(targetsid, "kiwi");
7973     size = lstrlenA(usersid) + 1;
7974     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7975                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7976                            &context, targetsid, &size);
7977     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7978     ok(!lstrcmpA(patchcode, patch),
7979        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7980     ok(!lstrcmpA(targetprod, prodcode),
7981        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
7982     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
7983        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
7984     ok(!lstrcmpA(targetsid, usersid),
7985        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
7986     ok(size == lstrlenA(usersid),
7987        "Expected %d, got %d\n", lstrlenA(usersid), size);
7988
7989     /* both szTargetuserSid and pcchTargetUserSid are NULL */
7990     lstrcpyA(patchcode, "apple");
7991     lstrcpyA(targetprod, "banana");
7992     context = 0xdeadbeef;
7993     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
7994                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
7995                            &context, NULL, NULL);
7996     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
7997     ok(!lstrcmpA(patchcode, patch),
7998        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
7999     ok(!lstrcmpA(targetprod, prodcode),
8000        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8001     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8002        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8003
8004     /* MSIPATCHSTATE_SUPERSEDED */
8005
8006     lstrcpyA(patchcode, "apple");
8007     lstrcpyA(targetprod, "banana");
8008     context = 0xdeadbeef;
8009     lstrcpyA(targetsid, "kiwi");
8010     size = MAX_PATH;
8011     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8012                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8013                            &context, targetsid, &size);
8014     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8015     ok(!lstrcmpA(patchcode, "apple"),
8016        "Expected patchcode to be unchanged, got %s\n", patchcode);
8017     ok(!lstrcmpA(targetprod, "banana"),
8018        "Expected targetprod to be unchanged, got %s\n", targetprod);
8019     ok(context == 0xdeadbeef,
8020        "Expected context to be unchanged, got %d\n", context);
8021     ok(!lstrcmpA(targetsid, "kiwi"),
8022        "Expected targetsid to be unchanged, got %s\n", targetsid);
8023     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8024
8025     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8026     lstrcatA(keypath, usersid);
8027     lstrcatA(keypath, "\\Products\\");
8028     lstrcatA(keypath, prod_squashed);
8029
8030     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8031     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8032
8033     /* UserData product key exists */
8034     lstrcpyA(patchcode, "apple");
8035     lstrcpyA(targetprod, "banana");
8036     context = 0xdeadbeef;
8037     lstrcpyA(targetsid, "kiwi");
8038     size = MAX_PATH;
8039     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8040                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8041                            &context, targetsid, &size);
8042     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8043     ok(!lstrcmpA(patchcode, "apple"),
8044        "Expected patchcode to be unchanged, got %s\n", patchcode);
8045     ok(!lstrcmpA(targetprod, "banana"),
8046        "Expected targetprod to be unchanged, got %s\n", targetprod);
8047     ok(context == 0xdeadbeef,
8048        "Expected context to be unchanged, got %d\n", context);
8049     ok(!lstrcmpA(targetsid, "kiwi"),
8050        "Expected targetsid to be unchanged, got %s\n", targetsid);
8051     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8052
8053     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8054     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8055
8056     /* UserData patches key exists */
8057     lstrcpyA(patchcode, "apple");
8058     lstrcpyA(targetprod, "banana");
8059     context = 0xdeadbeef;
8060     lstrcpyA(targetsid, "kiwi");
8061     size = MAX_PATH;
8062     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8063                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8064                            &context, targetsid, &size);
8065     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8066     ok(!lstrcmpA(patchcode, "apple"),
8067        "Expected patchcode to be unchanged, got %s\n", patchcode);
8068     ok(!lstrcmpA(targetprod, "banana"),
8069        "Expected targetprod to be unchanged, got %s\n", targetprod);
8070     ok(context == 0xdeadbeef,
8071        "Expected context to be unchanged, got %d\n", context);
8072     ok(!lstrcmpA(targetsid, "kiwi"),
8073        "Expected targetsid to be unchanged, got %s\n", targetsid);
8074     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8075
8076     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8077     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8078
8079     /* specific UserData patch key exists */
8080     lstrcpyA(patchcode, "apple");
8081     lstrcpyA(targetprod, "banana");
8082     context = 0xdeadbeef;
8083     lstrcpyA(targetsid, "kiwi");
8084     size = MAX_PATH;
8085     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8086                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8087                            &context, targetsid, &size);
8088     ok(r == ERROR_BAD_CONFIGURATION,
8089        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8090     ok(!lstrcmpA(patchcode, "apple"),
8091        "Expected patchcode to be unchanged, got %s\n", patchcode);
8092     ok(!lstrcmpA(targetprod, "banana"),
8093        "Expected targetprod to be unchanged, got %s\n", targetprod);
8094     ok(context == 0xdeadbeef,
8095        "Expected context to be unchanged, got %d\n", context);
8096     ok(!lstrcmpA(targetsid, "kiwi"),
8097        "Expected targetsid to be unchanged, got %s\n", targetsid);
8098     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8099
8100     data = MSIPATCHSTATE_SUPERSEDED;
8101     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8102                          (const BYTE *)&data, sizeof(DWORD));
8103     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8104
8105     /* State value exists */
8106     lstrcpyA(patchcode, "apple");
8107     lstrcpyA(targetprod, "banana");
8108     context = 0xdeadbeef;
8109     lstrcpyA(targetsid, "kiwi");
8110     size = MAX_PATH;
8111     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8112                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8113                            &context, targetsid, &size);
8114     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8115     ok(!lstrcmpA(patchcode, patch),
8116        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8117     ok(!lstrcmpA(targetprod, prodcode),
8118        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8119     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8120        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8121     ok(!lstrcmpA(targetsid, usersid),
8122        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8123     ok(size == lstrlenA(usersid),
8124        "Expected %d, got %d\n", lstrlenA(usersid), size);
8125
8126     /* MSIPATCHSTATE_OBSOLETED */
8127
8128     lstrcpyA(patchcode, "apple");
8129     lstrcpyA(targetprod, "banana");
8130     context = 0xdeadbeef;
8131     lstrcpyA(targetsid, "kiwi");
8132     size = MAX_PATH;
8133     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8134                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8135                            &context, targetsid, &size);
8136     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8137     ok(!lstrcmpA(patchcode, "apple"),
8138        "Expected patchcode to be unchanged, got %s\n", patchcode);
8139     ok(!lstrcmpA(targetprod, "banana"),
8140        "Expected targetprod to be unchanged, got %s\n", targetprod);
8141     ok(context == 0xdeadbeef,
8142        "Expected context to be unchanged, got %d\n", context);
8143     ok(!lstrcmpA(targetsid, "kiwi"),
8144        "Expected targetsid to be unchanged, got %s\n", targetsid);
8145     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8146
8147     data = MSIPATCHSTATE_OBSOLETED;
8148     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8149                          (const BYTE *)&data, sizeof(DWORD));
8150     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8151
8152     /* State value is obsoleted */
8153     lstrcpyA(patchcode, "apple");
8154     lstrcpyA(targetprod, "banana");
8155     context = 0xdeadbeef;
8156     lstrcpyA(targetsid, "kiwi");
8157     size = MAX_PATH;
8158     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8159                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8160                            &context, targetsid, &size);
8161     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8162     ok(!lstrcmpA(patchcode, patch),
8163        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8164     ok(!lstrcmpA(targetprod, prodcode),
8165        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8166     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8167        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8168     ok(!lstrcmpA(targetsid, usersid),
8169        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8170     ok(size == lstrlenA(usersid),
8171        "Expected %d, got %d\n", lstrlenA(usersid), size);
8172
8173     /* MSIPATCHSTATE_REGISTERED */
8174     /* FIXME */
8175
8176     /* MSIPATCHSTATE_ALL */
8177
8178     /* 1st */
8179     lstrcpyA(patchcode, "apple");
8180     lstrcpyA(targetprod, "banana");
8181     context = 0xdeadbeef;
8182     lstrcpyA(targetsid, "kiwi");
8183     size = MAX_PATH;
8184     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8185                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8186                            &context, targetsid, &size);
8187     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8188     ok(!lstrcmpA(patchcode, patch),
8189        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8190     ok(!lstrcmpA(targetprod, prodcode),
8191        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8192     ok(context == MSIINSTALLCONTEXT_USERMANAGED,
8193        "Expected MSIINSTALLCONTEXT_USERMANAGED, got %d\n", context);
8194     ok(!lstrcmpA(targetsid, usersid),
8195        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8196     ok(size == lstrlenA(usersid),
8197        "Expected %d, got %d\n", lstrlenA(usersid), size);
8198
8199     /* same patch in multiple places, only one is enumerated */
8200     lstrcpyA(patchcode, "apple");
8201     lstrcpyA(targetprod, "banana");
8202     context = 0xdeadbeef;
8203     lstrcpyA(targetsid, "kiwi");
8204     size = MAX_PATH;
8205     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
8206                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8207                            &context, targetsid, &size);
8208     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8209     ok(!lstrcmpA(patchcode, "apple"),
8210        "Expected patchcode to be unchanged, got %s\n", patchcode);
8211     ok(!lstrcmpA(targetprod, "banana"),
8212        "Expected targetprod to be unchanged, got %s\n", targetprod);
8213     ok(context == 0xdeadbeef,
8214        "Expected context to be unchanged, got %d\n", context);
8215     ok(!lstrcmpA(targetsid, "kiwi"),
8216        "Expected targetsid to be unchanged, got %s\n", targetsid);
8217     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8218
8219     RegDeleteValueA(hpatch, "State");
8220     RegDeleteKeyA(hpatch, "");
8221     RegCloseKey(hpatch);
8222     RegDeleteKeyA(udpatch, "");
8223     RegCloseKey(udpatch);
8224     RegDeleteKeyA(udprod, "");
8225     RegCloseKey(udprod);
8226     RegDeleteValueA(patches, "Patches");
8227     RegDeleteKeyA(patches, "");
8228     RegCloseKey(patches);
8229     RegDeleteKeyA(prodkey, "");
8230     RegCloseKey(prodkey);
8231
8232     /* MSIINSTALLCONTEXT_USERUNMANAGED */
8233
8234     /* MSIPATCHSTATE_APPLIED */
8235
8236     lstrcpyA(patchcode, "apple");
8237     lstrcpyA(targetprod, "banana");
8238     context = 0xdeadbeef;
8239     lstrcpyA(targetsid, "kiwi");
8240     size = MAX_PATH;
8241     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8242                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8243                            &context, targetsid, &size);
8244     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8245     ok(!lstrcmpA(patchcode, "apple"),
8246        "Expected patchcode to be unchanged, got %s\n", patchcode);
8247     ok(!lstrcmpA(targetprod, "banana"),
8248        "Expected targetprod to be unchanged, got %s\n", targetprod);
8249     ok(context == 0xdeadbeef,
8250        "Expected context to be unchanged, got %d\n", context);
8251     ok(!lstrcmpA(targetsid, "kiwi"),
8252        "Expected targetsid to be unchanged, got %s\n", targetsid);
8253     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8254
8255     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
8256     lstrcatA(keypath, prod_squashed);
8257
8258     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
8259     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8260
8261     /* current user product key exists */
8262     lstrcpyA(patchcode, "apple");
8263     lstrcpyA(targetprod, "banana");
8264     context = 0xdeadbeef;
8265     lstrcpyA(targetsid, "kiwi");
8266     size = MAX_PATH;
8267     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8268                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8269                            &context, targetsid, &size);
8270     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8271     ok(!lstrcmpA(patchcode, "apple"),
8272        "Expected patchcode to be unchanged, got %s\n", patchcode);
8273     ok(!lstrcmpA(targetprod, "banana"),
8274        "Expected targetprod to be unchanged, got %s\n", targetprod);
8275     ok(context == 0xdeadbeef,
8276        "Expected context to be unchanged, got %d\n", context);
8277     ok(!lstrcmpA(targetsid, "kiwi"),
8278        "Expected targetsid to be unchanged, got %s\n", targetsid);
8279     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8280
8281     res = RegCreateKeyA(prodkey, "Patches", &patches);
8282     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8283
8284     /* Patches key exists */
8285     lstrcpyA(patchcode, "apple");
8286     lstrcpyA(targetprod, "banana");
8287     context = 0xdeadbeef;
8288     lstrcpyA(targetsid, "kiwi");
8289     size = MAX_PATH;
8290     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8291                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8292                            &context, targetsid, &size);
8293     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8294     ok(!lstrcmpA(patchcode, "apple"),
8295        "Expected patchcode to be unchanged, got %s\n", patchcode);
8296     ok(!lstrcmpA(targetprod, "banana"),
8297        "Expected targetprod to be unchanged, got %s\n", targetprod);
8298     ok(context == 0xdeadbeef,
8299        "Expected context to be unchanged, got %d\n", context);
8300     ok(!lstrcmpA(targetsid, "kiwi"),
8301        "Expected targetsid to be unchanged, got %s\n", targetsid);
8302     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8303
8304     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8305                          (const BYTE *)patch_squashed,
8306                          lstrlenA(patch_squashed) + 1);
8307     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8308
8309     /* Patches value exists, is not REG_MULTI_SZ */
8310     lstrcpyA(patchcode, "apple");
8311     lstrcpyA(targetprod, "banana");
8312     context = 0xdeadbeef;
8313     lstrcpyA(targetsid, "kiwi");
8314     size = MAX_PATH;
8315     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8316                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8317                            &context, targetsid, &size);
8318     ok(r == ERROR_BAD_CONFIGURATION,
8319        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8320     ok(!lstrcmpA(patchcode, "apple"),
8321        "Expected patchcode to be unchanged, got %s\n", patchcode);
8322     ok(!lstrcmpA(targetprod, "banana"),
8323        "Expected targetprod to be unchanged, got %s\n", targetprod);
8324     ok(context == 0xdeadbeef,
8325        "Expected context to be unchanged, got %d\n", context);
8326     ok(!lstrcmpA(targetsid, "kiwi"),
8327        "Expected targetsid to be unchanged, got %s\n", targetsid);
8328     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8329
8330     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8331                          (const BYTE *)"a\0b\0c\0\0", 7);
8332     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8333
8334     /* Patches value exists, is not a squashed guid */
8335     lstrcpyA(patchcode, "apple");
8336     lstrcpyA(targetprod, "banana");
8337     context = 0xdeadbeef;
8338     lstrcpyA(targetsid, "kiwi");
8339     size = MAX_PATH;
8340     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8341                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8342                            &context, targetsid, &size);
8343     ok(r == ERROR_BAD_CONFIGURATION,
8344        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8345     ok(!lstrcmpA(patchcode, "apple"),
8346        "Expected patchcode to be unchanged, got %s\n", patchcode);
8347     ok(!lstrcmpA(targetprod, "banana"),
8348        "Expected targetprod to be unchanged, got %s\n", targetprod);
8349     ok(context == 0xdeadbeef,
8350        "Expected context to be unchanged, got %d\n", context);
8351     ok(!lstrcmpA(targetsid, "kiwi"),
8352        "Expected targetsid to be unchanged, got %s\n", targetsid);
8353     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8354
8355     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8356                          (const BYTE *)patch_squashed,
8357                          lstrlenA(patch_squashed) + 1);
8358     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8359
8360     /* Patches value exists */
8361     lstrcpyA(patchcode, "apple");
8362     lstrcpyA(targetprod, "banana");
8363     context = 0xdeadbeef;
8364     lstrcpyA(targetsid, "kiwi");
8365     size = MAX_PATH;
8366     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8367                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8368                            &context, targetsid, &size);
8369     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8370     ok(!lstrcmpA(patchcode, "apple"),
8371        "Expected patchcode to be unchanged, got %s\n", patchcode);
8372     ok(!lstrcmpA(targetprod, "banana"),
8373        "Expected targetprod to be unchanged, got %s\n", targetprod);
8374     ok(context == 0xdeadbeef,
8375        "Expected context to be unchanged, got %d\n", context);
8376     ok(!lstrcmpA(targetsid, "kiwi"),
8377        "Expected targetsid to be unchanged, got %s\n", targetsid);
8378     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8379
8380     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8381                          (const BYTE *)"whatever", 9);
8382     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8383
8384     /* patch code value exists */
8385     lstrcpyA(patchcode, "apple");
8386     lstrcpyA(targetprod, "banana");
8387     context = 0xdeadbeef;
8388     lstrcpyA(targetsid, "kiwi");
8389     size = MAX_PATH;
8390     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8391                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8392                            &context, targetsid, &size);
8393     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8394     ok(!lstrcmpA(patchcode, "apple"),
8395        "Expected patchcode to be unchanged, got %s\n", patchcode);
8396     ok(!lstrcmpA(targetprod, "banana"),
8397        "Expected targetprod to be unchanged, got %s\n", targetprod);
8398     ok(context == 0xdeadbeef,
8399        "Expected context to be unchanged, got %d\n", context);
8400     ok(!lstrcmpA(targetsid, "kiwi"),
8401        "Expected targetsid to be unchanged, got %s\n", targetsid);
8402     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8403
8404     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8405     lstrcatA(keypath, usersid);
8406     lstrcatA(keypath, "\\Patches\\");
8407     lstrcatA(keypath, patch_squashed);
8408
8409     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
8410     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8411
8412     /* userdata patch key exists */
8413     lstrcpyA(patchcode, "apple");
8414     lstrcpyA(targetprod, "banana");
8415     context = 0xdeadbeef;
8416     lstrcpyA(targetsid, "kiwi");
8417     size = MAX_PATH;
8418     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8419                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8420                            &context, targetsid, &size);
8421     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8422     ok(!lstrcmpA(patchcode, patch),
8423        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8424     ok(!lstrcmpA(targetprod, prodcode),
8425        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8426     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8427        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8428     ok(!lstrcmpA(targetsid, usersid),
8429        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8430     ok(size == lstrlenA(usersid),
8431        "Expected %d, got %d\n", lstrlenA(usersid), size);
8432
8433     /* MSIPATCHSTATE_SUPERSEDED */
8434
8435     lstrcpyA(patchcode, "apple");
8436     lstrcpyA(targetprod, "banana");
8437     context = 0xdeadbeef;
8438     lstrcpyA(targetsid, "kiwi");
8439     size = MAX_PATH;
8440     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8441                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8442                            &context, targetsid, &size);
8443     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8444     ok(!lstrcmpA(patchcode, "apple"),
8445        "Expected patchcode to be unchanged, got %s\n", patchcode);
8446     ok(!lstrcmpA(targetprod, "banana"),
8447        "Expected targetprod to be unchanged, got %s\n", targetprod);
8448     ok(context == 0xdeadbeef,
8449        "Expected context to be unchanged, got %d\n", context);
8450     ok(!lstrcmpA(targetsid, "kiwi"),
8451        "Expected targetsid to be unchanged, got %s\n", targetsid);
8452     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8453
8454     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
8455     lstrcatA(keypath, usersid);
8456     lstrcatA(keypath, "\\Products\\");
8457     lstrcatA(keypath, prod_squashed);
8458
8459     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8460     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8461
8462     /* UserData product key exists */
8463     lstrcpyA(patchcode, "apple");
8464     lstrcpyA(targetprod, "banana");
8465     context = 0xdeadbeef;
8466     lstrcpyA(targetsid, "kiwi");
8467     size = MAX_PATH;
8468     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8469                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8470                            &context, targetsid, &size);
8471     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8472     ok(!lstrcmpA(patchcode, "apple"),
8473        "Expected patchcode to be unchanged, got %s\n", patchcode);
8474     ok(!lstrcmpA(targetprod, "banana"),
8475        "Expected targetprod to be unchanged, got %s\n", targetprod);
8476     ok(context == 0xdeadbeef,
8477        "Expected context to be unchanged, got %d\n", context);
8478     ok(!lstrcmpA(targetsid, "kiwi"),
8479        "Expected targetsid to be unchanged, got %s\n", targetsid);
8480     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8481
8482     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8483     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8484
8485     /* UserData patches key exists */
8486     lstrcpyA(patchcode, "apple");
8487     lstrcpyA(targetprod, "banana");
8488     context = 0xdeadbeef;
8489     lstrcpyA(targetsid, "kiwi");
8490     size = MAX_PATH;
8491     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8492                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8493                            &context, targetsid, &size);
8494     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8495     ok(!lstrcmpA(patchcode, "apple"),
8496        "Expected patchcode to be unchanged, got %s\n", patchcode);
8497     ok(!lstrcmpA(targetprod, "banana"),
8498        "Expected targetprod to be unchanged, got %s\n", targetprod);
8499     ok(context == 0xdeadbeef,
8500        "Expected context to be unchanged, got %d\n", context);
8501     ok(!lstrcmpA(targetsid, "kiwi"),
8502        "Expected targetsid to be unchanged, got %s\n", targetsid);
8503     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8504
8505     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8506     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8507
8508     /* specific UserData patch key exists */
8509     lstrcpyA(patchcode, "apple");
8510     lstrcpyA(targetprod, "banana");
8511     context = 0xdeadbeef;
8512     lstrcpyA(targetsid, "kiwi");
8513     size = MAX_PATH;
8514     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8515                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8516                            &context, targetsid, &size);
8517     ok(r == ERROR_BAD_CONFIGURATION,
8518        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8519     ok(!lstrcmpA(patchcode, "apple"),
8520        "Expected patchcode to be unchanged, got %s\n", patchcode);
8521     ok(!lstrcmpA(targetprod, "banana"),
8522        "Expected targetprod to be unchanged, got %s\n", targetprod);
8523     ok(context == 0xdeadbeef,
8524        "Expected context to be unchanged, got %d\n", context);
8525     ok(!lstrcmpA(targetsid, "kiwi"),
8526        "Expected targetsid to be unchanged, got %s\n", targetsid);
8527     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8528
8529     data = MSIPATCHSTATE_SUPERSEDED;
8530     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8531                          (const BYTE *)&data, sizeof(DWORD));
8532     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8533
8534     /* State value exists */
8535     lstrcpyA(patchcode, "apple");
8536     lstrcpyA(targetprod, "banana");
8537     context = 0xdeadbeef;
8538     lstrcpyA(targetsid, "kiwi");
8539     size = MAX_PATH;
8540     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8541                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8542                            &context, targetsid, &size);
8543     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8544     ok(!lstrcmpA(patchcode, patch),
8545        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8546     ok(!lstrcmpA(targetprod, prodcode),
8547        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8548     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8549        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8550     ok(!lstrcmpA(targetsid, usersid),
8551        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8552     ok(size == lstrlenA(usersid),
8553        "Expected %d, got %d\n", lstrlenA(usersid), size);
8554
8555     /* MSIPATCHSTATE_OBSOLETED */
8556
8557     lstrcpyA(patchcode, "apple");
8558     lstrcpyA(targetprod, "banana");
8559     context = 0xdeadbeef;
8560     lstrcpyA(targetsid, "kiwi");
8561     size = MAX_PATH;
8562     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8563                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8564                            &context, targetsid, &size);
8565     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8566     ok(!lstrcmpA(patchcode, "apple"),
8567        "Expected patchcode to be unchanged, got %s\n", patchcode);
8568     ok(!lstrcmpA(targetprod, "banana"),
8569        "Expected targetprod to be unchanged, got %s\n", targetprod);
8570     ok(context == 0xdeadbeef,
8571        "Expected context to be unchanged, got %d\n", context);
8572     ok(!lstrcmpA(targetsid, "kiwi"),
8573        "Expected targetsid to be unchanged, got %s\n", targetsid);
8574     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8575
8576     data = MSIPATCHSTATE_OBSOLETED;
8577     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8578                          (const BYTE *)&data, sizeof(DWORD));
8579     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8580
8581     /* State value is obsoleted */
8582     lstrcpyA(patchcode, "apple");
8583     lstrcpyA(targetprod, "banana");
8584     context = 0xdeadbeef;
8585     lstrcpyA(targetsid, "kiwi");
8586     size = MAX_PATH;
8587     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8588                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8589                            &context, targetsid, &size);
8590     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8591     ok(!lstrcmpA(patchcode, patch),
8592        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8593     ok(!lstrcmpA(targetprod, prodcode),
8594        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8595     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8596        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8597     ok(!lstrcmpA(targetsid, usersid),
8598        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8599     ok(size == lstrlenA(usersid),
8600        "Expected %d, got %d\n", lstrlenA(usersid), size);
8601
8602     /* MSIPATCHSTATE_REGISTERED */
8603     /* FIXME */
8604
8605     /* MSIPATCHSTATE_ALL */
8606
8607     /* 1st */
8608     lstrcpyA(patchcode, "apple");
8609     lstrcpyA(targetprod, "banana");
8610     context = 0xdeadbeef;
8611     lstrcpyA(targetsid, "kiwi");
8612     size = MAX_PATH;
8613     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8614                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
8615                            &context, targetsid, &size);
8616     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8617     ok(!lstrcmpA(patchcode, patch),
8618        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8619     ok(!lstrcmpA(targetprod, prodcode),
8620        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8621     ok(context == MSIINSTALLCONTEXT_USERUNMANAGED,
8622        "Expected MSIINSTALLCONTEXT_USERUNMANAGED, got %d\n", context);
8623     ok(!lstrcmpA(targetsid, usersid),
8624        "Expected \"%s\", got \"%s\"\n", usersid, targetsid);
8625     ok(size == lstrlenA(usersid),
8626        "Expected %d, got %d\n", lstrlenA(usersid), size);
8627
8628     /* same patch in multiple places, only one is enumerated */
8629     lstrcpyA(patchcode, "apple");
8630     lstrcpyA(targetprod, "banana");
8631     context = 0xdeadbeef;
8632     lstrcpyA(targetsid, "kiwi");
8633     size = MAX_PATH;
8634     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
8635                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
8636                            &context, targetsid, &size);
8637     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8638     ok(!lstrcmpA(patchcode, "apple"),
8639        "Expected patchcode to be unchanged, got %s\n", patchcode);
8640     ok(!lstrcmpA(targetprod, "banana"),
8641        "Expected targetprod to be unchanged, got %s\n", targetprod);
8642     ok(context == 0xdeadbeef,
8643        "Expected context to be unchanged, got %d\n", context);
8644     ok(!lstrcmpA(targetsid, "kiwi"),
8645        "Expected targetsid to be unchanged, got %s\n", targetsid);
8646     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8647
8648     RegDeleteValueA(hpatch, "State");
8649     RegDeleteKeyA(hpatch, "");
8650     RegCloseKey(hpatch);
8651     RegDeleteKeyA(udpatch, "");
8652     RegCloseKey(udpatch);
8653     RegDeleteKeyA(userkey, "");
8654     RegCloseKey(userkey);
8655     RegDeleteValueA(patches, patch_squashed);
8656     RegDeleteValueA(patches, "Patches");
8657     RegDeleteKeyA(patches, "");
8658     RegCloseKey(patches);
8659     RegDeleteKeyA(prodkey, "");
8660     RegCloseKey(prodkey);
8661
8662     /* MSIINSTALLCONTEXT_MACHINE */
8663
8664     /* MSIPATCHSTATE_APPLIED */
8665
8666     lstrcpyA(patchcode, "apple");
8667     lstrcpyA(targetprod, "banana");
8668     context = 0xdeadbeef;
8669     lstrcpyA(targetsid, "kiwi");
8670     size = MAX_PATH;
8671     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8672                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8673                            &context, targetsid, &size);
8674     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8675     ok(!lstrcmpA(patchcode, "apple"),
8676        "Expected patchcode to be unchanged, got %s\n", patchcode);
8677     ok(!lstrcmpA(targetprod, "banana"),
8678        "Expected targetprod to be unchanged, got %s\n", targetprod);
8679     ok(context == 0xdeadbeef,
8680        "Expected context to be unchanged, got %d\n", context);
8681     ok(!lstrcmpA(targetsid, "kiwi"),
8682        "Expected targetsid to be unchanged, got %s\n", targetsid);
8683     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8684
8685     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
8686     lstrcatA(keypath, prod_squashed);
8687
8688     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
8689     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8690
8691     /* local product key exists */
8692     lstrcpyA(patchcode, "apple");
8693     lstrcpyA(targetprod, "banana");
8694     context = 0xdeadbeef;
8695     lstrcpyA(targetsid, "kiwi");
8696     size = MAX_PATH;
8697     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8698                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8699                            &context, targetsid, &size);
8700     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8701     ok(!lstrcmpA(patchcode, "apple"),
8702        "Expected patchcode to be unchanged, got %s\n", patchcode);
8703     ok(!lstrcmpA(targetprod, "banana"),
8704        "Expected targetprod to be unchanged, got %s\n", targetprod);
8705     ok(context == 0xdeadbeef,
8706        "Expected context to be unchanged, got %d\n", context);
8707     ok(!lstrcmpA(targetsid, "kiwi"),
8708        "Expected targetsid to be unchanged, got %s\n", targetsid);
8709     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8710
8711     res = RegCreateKeyA(prodkey, "Patches", &patches);
8712     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8713
8714     /* Patches key exists */
8715     lstrcpyA(patchcode, "apple");
8716     lstrcpyA(targetprod, "banana");
8717     context = 0xdeadbeef;
8718     lstrcpyA(targetsid, "kiwi");
8719     size = MAX_PATH;
8720     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8721                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8722                            &context, targetsid, &size);
8723     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8724     ok(!lstrcmpA(patchcode, "apple"),
8725        "Expected patchcode to be unchanged, got %s\n", patchcode);
8726     ok(!lstrcmpA(targetprod, "banana"),
8727        "Expected targetprod to be unchanged, got %s\n", targetprod);
8728     ok(context == 0xdeadbeef,
8729        "Expected context to be unchanged, got %d\n", context);
8730     ok(!lstrcmpA(targetsid, "kiwi"),
8731        "Expected targetsid to be unchanged, got %s\n", targetsid);
8732     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8733
8734     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
8735                          (const BYTE *)patch_squashed,
8736                          lstrlenA(patch_squashed) + 1);
8737     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8738
8739     /* Patches value exists, is not REG_MULTI_SZ */
8740     lstrcpyA(patchcode, "apple");
8741     lstrcpyA(targetprod, "banana");
8742     context = 0xdeadbeef;
8743     lstrcpyA(targetsid, "kiwi");
8744     size = MAX_PATH;
8745     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8746                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8747                            &context, targetsid, &size);
8748     ok(r == ERROR_BAD_CONFIGURATION,
8749        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8750     ok(!lstrcmpA(patchcode, "apple"),
8751        "Expected patchcode to be unchanged, got %s\n", patchcode);
8752     ok(!lstrcmpA(targetprod, "banana"),
8753        "Expected targetprod to be unchanged, got %s\n", targetprod);
8754     ok(context == 0xdeadbeef,
8755        "Expected context to be unchanged, got %d\n", context);
8756     ok(!lstrcmpA(targetsid, "kiwi"),
8757        "Expected targetsid to be unchanged, got %s\n", targetsid);
8758     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8759
8760     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8761                          (const BYTE *)"a\0b\0c\0\0", 7);
8762     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8763
8764     /* Patches value exists, is not a squashed guid */
8765     lstrcpyA(patchcode, "apple");
8766     lstrcpyA(targetprod, "banana");
8767     context = 0xdeadbeef;
8768     lstrcpyA(targetsid, "kiwi");
8769     size = MAX_PATH;
8770     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8771                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8772                            &context, targetsid, &size);
8773     ok(r == ERROR_BAD_CONFIGURATION,
8774        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
8775     ok(!lstrcmpA(patchcode, "apple"),
8776        "Expected patchcode to be unchanged, got %s\n", patchcode);
8777     ok(!lstrcmpA(targetprod, "banana"),
8778        "Expected targetprod to be unchanged, got %s\n", targetprod);
8779     ok(context == 0xdeadbeef,
8780        "Expected context to be unchanged, got %d\n", context);
8781     ok(!lstrcmpA(targetsid, "kiwi"),
8782        "Expected targetsid to be unchanged, got %s\n", targetsid);
8783     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8784
8785     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
8786     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
8787                          (const BYTE *)patch_squashed,
8788                          lstrlenA(patch_squashed) + 2);
8789     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8790
8791     /* Patches value exists */
8792     lstrcpyA(patchcode, "apple");
8793     lstrcpyA(targetprod, "banana");
8794     context = 0xdeadbeef;
8795     lstrcpyA(targetsid, "kiwi");
8796     size = MAX_PATH;
8797     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8798                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8799                            &context, targetsid, &size);
8800     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8801     ok(!lstrcmpA(patchcode, "apple"),
8802        "Expected patchcode to be unchanged, got %s\n", patchcode);
8803     ok(!lstrcmpA(targetprod, "banana"),
8804        "Expected targetprod to be unchanged, got %s\n", targetprod);
8805     ok(context == 0xdeadbeef,
8806        "Expected context to be unchanged, got %d\n", context);
8807     ok(!lstrcmpA(targetsid, "kiwi"),
8808        "Expected targetsid to be unchanged, got %s\n", targetsid);
8809     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8810
8811     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
8812                          (const BYTE *)"whatever", 9);
8813     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8814
8815     /* patch code value exists */
8816     lstrcpyA(patchcode, "apple");
8817     lstrcpyA(targetprod, "banana");
8818     context = 0xdeadbeef;
8819     lstrcpyA(targetsid, "kiwi");
8820     size = MAX_PATH;
8821     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8822                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8823                            &context, targetsid, &size);
8824     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8825     ok(!lstrcmpA(patchcode, patch),
8826        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8827     ok(!lstrcmpA(targetprod, prodcode),
8828        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8829     ok(context == MSIINSTALLCONTEXT_MACHINE,
8830        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8831     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8832     ok(size == 0, "Expected 0, got %d\n", size);
8833
8834     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
8835     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
8836     lstrcatA(keypath, prod_squashed);
8837
8838     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
8839     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8840
8841     /* local UserData product key exists */
8842     lstrcpyA(patchcode, "apple");
8843     lstrcpyA(targetprod, "banana");
8844     context = 0xdeadbeef;
8845     lstrcpyA(targetsid, "kiwi");
8846     size = MAX_PATH;
8847     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8848                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8849                            &context, targetsid, &size);
8850     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8851     ok(!lstrcmpA(patchcode, patch),
8852        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8853     ok(!lstrcmpA(targetprod, prodcode),
8854        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8855     ok(context == MSIINSTALLCONTEXT_MACHINE,
8856        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8857     ok(!lstrcmpA(targetsid, ""),
8858        "Expected \"\", got \"%s\"\n", targetsid);
8859     ok(size == 0, "Expected 0, got %d\n", size);
8860
8861     res = RegCreateKeyA(udprod, "Patches", &udpatch);
8862     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8863
8864     /* local UserData Patches key exists */
8865     lstrcpyA(patchcode, "apple");
8866     lstrcpyA(targetprod, "banana");
8867     context = 0xdeadbeef;
8868     lstrcpyA(targetsid, "kiwi");
8869     size = MAX_PATH;
8870     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8871                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8872                            &context, targetsid, &size);
8873     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8874     ok(!lstrcmpA(patchcode, patch),
8875        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8876     ok(!lstrcmpA(targetprod, prodcode),
8877        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8878     ok(context == MSIINSTALLCONTEXT_MACHINE,
8879        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8880     ok(!lstrcmpA(targetsid, ""),
8881        "Expected \"\", got \"%s\"\n", targetsid);
8882     ok(size == 0, "Expected 0, got %d\n", size);
8883
8884     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
8885     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8886
8887     /* local UserData Product patch key exists */
8888     lstrcpyA(patchcode, "apple");
8889     lstrcpyA(targetprod, "banana");
8890     context = 0xdeadbeef;
8891     lstrcpyA(targetsid, "kiwi");
8892     size = MAX_PATH;
8893     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8894                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8895                            &context, targetsid, &size);
8896     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8897     ok(!lstrcmpA(patchcode, "apple"),
8898        "Expected patchcode to be unchanged, got %s\n", patchcode);
8899     ok(!lstrcmpA(targetprod, "banana"),
8900        "Expected targetprod to be unchanged, got %s\n", targetprod);
8901     ok(context == 0xdeadbeef,
8902        "Expected context to be unchanged, got %d\n", context);
8903     ok(!lstrcmpA(targetsid, "kiwi"),
8904        "Expected targetsid to be unchanged, got %s\n", targetsid);
8905     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8906
8907     data = MSIPATCHSTATE_APPLIED;
8908     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8909                          (const BYTE *)&data, sizeof(DWORD));
8910     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8911
8912     /* State value exists */
8913     lstrcpyA(patchcode, "apple");
8914     lstrcpyA(targetprod, "banana");
8915     context = 0xdeadbeef;
8916     lstrcpyA(targetsid, "kiwi");
8917     size = MAX_PATH;
8918     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8919                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
8920                            &context, targetsid, &size);
8921     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8922     ok(!lstrcmpA(patchcode, patch),
8923        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8924     ok(!lstrcmpA(targetprod, prodcode),
8925        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8926     ok(context == MSIINSTALLCONTEXT_MACHINE,
8927        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8928     ok(!lstrcmpA(targetsid, ""),
8929        "Expected \"\", got \"%s\"\n", targetsid);
8930     ok(size == 0, "Expected 0, got %d\n", size);
8931
8932     /* MSIPATCHSTATE_SUPERSEDED */
8933
8934     lstrcpyA(patchcode, "apple");
8935     lstrcpyA(targetprod, "banana");
8936     context = 0xdeadbeef;
8937     lstrcpyA(targetsid, "kiwi");
8938     size = MAX_PATH;
8939     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8940                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8941                            &context, targetsid, &size);
8942     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8943     ok(!lstrcmpA(patchcode, "apple"),
8944        "Expected patchcode to be unchanged, got %s\n", patchcode);
8945     ok(!lstrcmpA(targetprod, "banana"),
8946        "Expected targetprod to be unchanged, got %s\n", targetprod);
8947     ok(context == 0xdeadbeef,
8948        "Expected context to be unchanged, got %d\n", context);
8949     ok(!lstrcmpA(targetsid, "kiwi"),
8950        "Expected targetsid to be unchanged, got %s\n", targetsid);
8951     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8952
8953     data = MSIPATCHSTATE_SUPERSEDED;
8954     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
8955                          (const BYTE *)&data, sizeof(DWORD));
8956     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
8957
8958     /* State value is MSIPATCHSTATE_SUPERSEDED */
8959     lstrcpyA(patchcode, "apple");
8960     lstrcpyA(targetprod, "banana");
8961     context = 0xdeadbeef;
8962     lstrcpyA(targetsid, "kiwi");
8963     size = MAX_PATH;
8964     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8965                            MSIPATCHSTATE_SUPERSEDED, 0, patchcode, targetprod,
8966                            &context, targetsid, &size);
8967     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
8968     ok(!lstrcmpA(patchcode, patch),
8969        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
8970     ok(!lstrcmpA(targetprod, prodcode),
8971        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
8972     ok(context == MSIINSTALLCONTEXT_MACHINE,
8973        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
8974     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
8975     ok(size == 0, "Expected 0, got %d\n", size);
8976
8977     /* MSIPATCHSTATE_OBSOLETED */
8978
8979     lstrcpyA(patchcode, "apple");
8980     lstrcpyA(targetprod, "banana");
8981     context = 0xdeadbeef;
8982     lstrcpyA(targetsid, "kiwi");
8983     size = MAX_PATH;
8984     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
8985                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
8986                            &context, targetsid, &size);
8987     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
8988     ok(!lstrcmpA(patchcode, "apple"),
8989        "Expected patchcode to be unchanged, got %s\n", patchcode);
8990     ok(!lstrcmpA(targetprod, "banana"),
8991        "Expected targetprod to be unchanged, got %s\n", targetprod);
8992     ok(context == 0xdeadbeef,
8993        "Expected context to be unchanged, got %d\n", context);
8994     ok(!lstrcmpA(targetsid, "kiwi"),
8995        "Expected targetsid to be unchanged, got %s\n", targetsid);
8996     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
8997
8998     data = MSIPATCHSTATE_OBSOLETED;
8999     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9000                          (const BYTE *)&data, sizeof(DWORD));
9001     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9002
9003     /* State value is obsoleted */
9004     lstrcpyA(patchcode, "apple");
9005     lstrcpyA(targetprod, "banana");
9006     context = 0xdeadbeef;
9007     lstrcpyA(targetsid, "kiwi");
9008     size = MAX_PATH;
9009     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9010                            MSIPATCHSTATE_OBSOLETED, 0, patchcode, targetprod,
9011                            &context, targetsid, &size);
9012     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9013     ok(!lstrcmpA(patchcode, patch),
9014        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9015     ok(!lstrcmpA(targetprod, prodcode),
9016        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9017     ok(context == MSIINSTALLCONTEXT_MACHINE,
9018        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9019     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9020     ok(size == 0, "Expected 0, got %d\n", size);
9021
9022     /* MSIPATCHSTATE_REGISTERED */
9023     /* FIXME */
9024
9025     /* MSIPATCHSTATE_ALL */
9026
9027     /* 1st */
9028     lstrcpyA(patchcode, "apple");
9029     lstrcpyA(targetprod, "banana");
9030     context = 0xdeadbeef;
9031     lstrcpyA(targetsid, "kiwi");
9032     size = MAX_PATH;
9033     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9034                            MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
9035                            &context, targetsid, &size);
9036     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9037     ok(!lstrcmpA(patchcode, patch),
9038        "Expected \"%s\", got \"%s\"\n", patch, patchcode);
9039     ok(!lstrcmpA(targetprod, prodcode),
9040        "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
9041     ok(context == MSIINSTALLCONTEXT_MACHINE,
9042        "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
9043     ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
9044     ok(size == 0, "Expected 0, got %d\n", size);
9045
9046     /* same patch in multiple places, only one is enumerated */
9047     lstrcpyA(patchcode, "apple");
9048     lstrcpyA(targetprod, "banana");
9049     context = 0xdeadbeef;
9050     lstrcpyA(targetsid, "kiwi");
9051     size = MAX_PATH;
9052     r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
9053                            MSIPATCHSTATE_ALL, 1, patchcode, targetprod,
9054                            &context, targetsid, &size);
9055     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9056     ok(!lstrcmpA(patchcode, "apple"),
9057        "Expected patchcode to be unchanged, got %s\n", patchcode);
9058     ok(!lstrcmpA(targetprod, "banana"),
9059        "Expected targetprod to be unchanged, got %s\n", targetprod);
9060     ok(context == 0xdeadbeef,
9061        "Expected context to be unchanged, got %d\n", context);
9062     ok(!lstrcmpA(targetsid, "kiwi"),
9063        "Expected targetsid to be unchanged, got %s\n", targetsid);
9064     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9065
9066     RegDeleteValueA(patches, patch_squashed);
9067     RegDeleteValueA(patches, "Patches");
9068     RegDeleteKeyA(patches, "");
9069     RegCloseKey(patches);
9070     RegDeleteValueA(hpatch, "State");
9071     RegDeleteKeyA(hpatch, "");
9072     RegCloseKey(hpatch);
9073     RegDeleteKeyA(udpatch, "");
9074     RegCloseKey(udpatch);
9075     RegDeleteKeyA(udprod, "");
9076     RegCloseKey(udprod);
9077     RegDeleteKeyA(prodkey, "");
9078     RegCloseKey(prodkey);
9079 }
9080
9081 static void test_MsiEnumPatches(void)
9082 {
9083     CHAR keypath[MAX_PATH], patch[MAX_PATH];
9084     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9085     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9086     CHAR transforms[MAX_PATH];
9087     HKEY prodkey, patches, udprod;
9088     HKEY userkey, hpatch, udpatch;
9089     DWORD size, data;
9090     LPSTR usersid;
9091     LONG res;
9092     UINT r;
9093
9094     create_test_guid(prodcode, prod_squashed);
9095     create_test_guid(patchcode, patch_squashed);
9096     get_user_sid(&usersid);
9097
9098     /* NULL szProduct */
9099     size = MAX_PATH;
9100     lstrcpyA(patch, "apple");
9101     lstrcpyA(transforms, "banana");
9102     r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
9103     ok(r == ERROR_INVALID_PARAMETER,
9104        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9105     ok(!lstrcmpA(patch, "apple"),
9106        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9107     ok(!lstrcmpA(transforms, "banana"),
9108        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9109     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9110
9111     /* empty szProduct */
9112     size = MAX_PATH;
9113     lstrcpyA(patch, "apple");
9114     lstrcpyA(transforms, "banana");
9115     r = MsiEnumPatchesA("", 0, patch, transforms, &size);
9116     ok(r == ERROR_INVALID_PARAMETER,
9117        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9118     ok(!lstrcmpA(patch, "apple"),
9119        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9120     ok(!lstrcmpA(transforms, "banana"),
9121        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9122     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9123
9124     /* garbage szProduct */
9125     size = MAX_PATH;
9126     lstrcpyA(patch, "apple");
9127     lstrcpyA(transforms, "banana");
9128     r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
9129     ok(r == ERROR_INVALID_PARAMETER,
9130        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9131     ok(!lstrcmpA(patch, "apple"),
9132        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9133     ok(!lstrcmpA(transforms, "banana"),
9134        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9135     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9136
9137     /* guid without brackets */
9138     size = MAX_PATH;
9139     lstrcpyA(patch, "apple");
9140     lstrcpyA(transforms, "banana");
9141     r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
9142                         transforms, &size);
9143     ok(r == ERROR_INVALID_PARAMETER,
9144        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9145     ok(!lstrcmpA(patch, "apple"),
9146        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9147     ok(!lstrcmpA(transforms, "banana"),
9148        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9149     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9150
9151     /* guid with brackets */
9152     size = MAX_PATH;
9153     lstrcpyA(patch, "apple");
9154     lstrcpyA(transforms, "banana");
9155     r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
9156                         transforms, &size);
9157     ok(r == ERROR_UNKNOWN_PRODUCT,
9158        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9159     ok(!lstrcmpA(patch, "apple"),
9160        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9161     ok(!lstrcmpA(transforms, "banana"),
9162        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9163     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9164
9165     /* same length as guid, but random */
9166     size = MAX_PATH;
9167     lstrcpyA(patch, "apple");
9168     lstrcpyA(transforms, "banana");
9169     r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
9170                         transforms, &size);
9171     ok(r == ERROR_INVALID_PARAMETER,
9172        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9173     ok(!lstrcmpA(patch, "apple"),
9174        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9175     ok(!lstrcmpA(transforms, "banana"),
9176        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9177     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9178
9179     /* MSIINSTALLCONTEXT_USERMANAGED */
9180
9181     size = MAX_PATH;
9182     lstrcpyA(patch, "apple");
9183     lstrcpyA(transforms, "banana");
9184     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9185     ok(r == ERROR_UNKNOWN_PRODUCT,
9186        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9187     ok(!lstrcmpA(patch, "apple"),
9188        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9189     ok(!lstrcmpA(transforms, "banana"),
9190        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9191     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9192
9193     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
9194     lstrcatA(keypath, usersid);
9195     lstrcatA(keypath, "\\Installer\\Products\\");
9196     lstrcatA(keypath, prod_squashed);
9197
9198     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9199     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9200
9201     /* managed product key exists */
9202     size = MAX_PATH;
9203     lstrcpyA(patch, "apple");
9204     lstrcpyA(transforms, "banana");
9205     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9206     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9207     ok(!lstrcmpA(patch, "apple"),
9208        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9209     ok(!lstrcmpA(transforms, "banana"),
9210        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9211     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9212
9213     res = RegCreateKeyA(prodkey, "Patches", &patches);
9214     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9215
9216     /* patches key exists */
9217     size = MAX_PATH;
9218     lstrcpyA(patch, "apple");
9219     lstrcpyA(transforms, "banana");
9220     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9221     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9222     ok(!lstrcmpA(patch, "apple"),
9223        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9224     ok(!lstrcmpA(transforms, "banana"),
9225        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9226     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9227
9228     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9229                          (const BYTE *)patch_squashed,
9230                          lstrlenA(patch_squashed) + 1);
9231     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9232
9233     /* Patches value exists, is not REG_MULTI_SZ */
9234     size = MAX_PATH;
9235     lstrcpyA(patch, "apple");
9236     lstrcpyA(transforms, "banana");
9237     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9238     ok(r == ERROR_BAD_CONFIGURATION,
9239        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9240     ok(!lstrcmpA(patch, "apple"),
9241        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9242     ok(!lstrcmpA(transforms, "banana"),
9243        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9244     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9245
9246     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9247                          (const BYTE *)"a\0b\0c\0\0", 7);
9248     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9249
9250     /* Patches value exists, is not a squashed guid */
9251     size = MAX_PATH;
9252     lstrcpyA(patch, "apple");
9253     lstrcpyA(transforms, "banana");
9254     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9255     ok(r == ERROR_BAD_CONFIGURATION,
9256        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9257     ok(!lstrcmpA(patch, "apple"),
9258        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9259     ok(!lstrcmpA(transforms, "banana"),
9260        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9261     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9262
9263     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9264     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9265                          (const BYTE *)patch_squashed,
9266                          lstrlenA(patch_squashed) + 2);
9267     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9268
9269     /* Patches value exists */
9270     size = MAX_PATH;
9271     lstrcpyA(patch, "apple");
9272     lstrcpyA(transforms, "banana");
9273     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9274     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9275     ok(!lstrcmpA(patch, "apple"),
9276        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9277     ok(!lstrcmpA(transforms, "banana"),
9278        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9279     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9280
9281     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9282                          (const BYTE *)"whatever", 9);
9283     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9284
9285     /* patch squashed value exists */
9286     size = MAX_PATH;
9287     lstrcpyA(patch, "apple");
9288     lstrcpyA(transforms, "banana");
9289     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9290     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9291     ok(!lstrcmpA(patch, patchcode),
9292        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9293     ok(!lstrcmpA(transforms, "whatever"),
9294        "Expected \"whatever\", got \"%s\"\n", transforms);
9295     ok(size == 8, "Expected 8, got %d\n", size);
9296
9297     /* lpPatchBuf is NULL */
9298     size = MAX_PATH;
9299     lstrcpyA(transforms, "banana");
9300     r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
9301     ok(r == ERROR_INVALID_PARAMETER,
9302        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9303     ok(!lstrcmpA(transforms, "banana"),
9304        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9305     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9306
9307     /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
9308     size = MAX_PATH;
9309     lstrcpyA(patch, "apple");
9310     r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
9311     ok(r == ERROR_INVALID_PARAMETER,
9312        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9313     ok(!lstrcmpA(patch, "apple"),
9314        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9315     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9316
9317     /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
9318     lstrcpyA(patch, "apple");
9319     lstrcpyA(transforms, "banana");
9320     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
9321     ok(r == ERROR_INVALID_PARAMETER,
9322        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9323     ok(!lstrcmpA(patch, "apple"),
9324        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9325     ok(!lstrcmpA(transforms, "banana"),
9326        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9327
9328     /* pcchTransformsBuf is too small */
9329     size = 6;
9330     lstrcpyA(patch, "apple");
9331     lstrcpyA(transforms, "banana");
9332     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9333     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
9334     ok(!lstrcmpA(patch, patchcode),
9335        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9336     ok(!lstrcmpA(transforms, "whate"),
9337        "Expected \"whate\", got \"%s\"\n", transforms);
9338     ok(size == 16, "Expected 16, got %d\n", size);
9339
9340     /* increase the index */
9341     size = MAX_PATH;
9342     lstrcpyA(patch, "apple");
9343     lstrcpyA(transforms, "banana");
9344     r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
9345     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9346     ok(!lstrcmpA(patch, "apple"),
9347        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9348     ok(!lstrcmpA(transforms, "banana"),
9349        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9350     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9351
9352     /* increase again */
9353     size = MAX_PATH;
9354     lstrcpyA(patch, "apple");
9355     lstrcpyA(transforms, "banana");
9356     r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
9357     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9358     ok(!lstrcmpA(patch, "apple"),
9359        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9360     ok(!lstrcmpA(transforms, "banana"),
9361        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9362     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9363
9364     RegDeleteValueA(patches, "Patches");
9365     RegDeleteKeyA(patches, "");
9366     RegCloseKey(patches);
9367     RegDeleteKeyA(prodkey, "");
9368     RegCloseKey(prodkey);
9369
9370     /* MSIINSTALLCONTEXT_USERUNMANAGED */
9371
9372     size = MAX_PATH;
9373     lstrcpyA(patch, "apple");
9374     lstrcpyA(transforms, "banana");
9375     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9376     ok(r == ERROR_UNKNOWN_PRODUCT,
9377        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9378     ok(!lstrcmpA(patch, "apple"),
9379        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9380     ok(!lstrcmpA(transforms, "banana"),
9381        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9382     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9383
9384     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
9385     lstrcatA(keypath, prod_squashed);
9386
9387     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
9388     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9389
9390     /* current user product key exists */
9391     size = MAX_PATH;
9392     lstrcpyA(patch, "apple");
9393     lstrcpyA(transforms, "banana");
9394     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9395     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9396     ok(!lstrcmpA(patch, "apple"),
9397        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9398     ok(!lstrcmpA(transforms, "banana"),
9399        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9400     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9401
9402     res = RegCreateKeyA(prodkey, "Patches", &patches);
9403     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9404
9405     /* Patches key exists */
9406     size = MAX_PATH;
9407     lstrcpyA(patch, "apple");
9408     lstrcpyA(transforms, "banana");
9409     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9410     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9411     ok(!lstrcmpA(patch, "apple"),
9412        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9413     ok(!lstrcmpA(transforms, "banana"),
9414        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9415     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9416
9417     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9418                          (const BYTE *)patch_squashed,
9419                          lstrlenA(patch_squashed) + 1);
9420     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9421
9422     /* Patches value exists, is not REG_MULTI_SZ */
9423     size = MAX_PATH;
9424     lstrcpyA(patch, "apple");
9425     lstrcpyA(transforms, "banana");
9426     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9427     ok(r == ERROR_BAD_CONFIGURATION,
9428        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9429     ok(!lstrcmpA(patch, "apple"),
9430        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9431     ok(!lstrcmpA(transforms, "banana"),
9432        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9433     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9434
9435     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9436                          (const BYTE *)"a\0b\0c\0\0", 7);
9437     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9438
9439     /* Patches value exists, is not a squashed guid */
9440     size = MAX_PATH;
9441     lstrcpyA(patch, "apple");
9442     lstrcpyA(transforms, "banana");
9443     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9444     ok(r == ERROR_BAD_CONFIGURATION,
9445        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9446     ok(!lstrcmpA(patch, "apple"),
9447        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9448     ok(!lstrcmpA(transforms, "banana"),
9449        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9450     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9451
9452     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9453     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9454                          (const BYTE *)patch_squashed,
9455                          lstrlenA(patch_squashed) + 2);
9456     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9457
9458     /* Patches value exists */
9459     size = MAX_PATH;
9460     lstrcpyA(patch, "apple");
9461     lstrcpyA(transforms, "banana");
9462     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9463     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9464     ok(!lstrcmpA(patch, "apple"),
9465        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9466     ok(!lstrcmpA(transforms, "banana"),
9467        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9468     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9469
9470     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9471                          (const BYTE *)"whatever", 9);
9472     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9473
9474     /* patch code value exists */
9475     size = MAX_PATH;
9476     lstrcpyA(patch, "apple");
9477     lstrcpyA(transforms, "banana");
9478     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9479     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9480     ok(!lstrcmpA(patch, "apple"),
9481        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9482     ok(!lstrcmpA(transforms, "banana"),
9483        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9484     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9485
9486     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9487     lstrcatA(keypath, usersid);
9488     lstrcatA(keypath, "\\Patches\\");
9489     lstrcatA(keypath, patch_squashed);
9490
9491     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
9492     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9493
9494     /* userdata patch key exists */
9495     size = MAX_PATH;
9496     lstrcpyA(patch, "apple");
9497     lstrcpyA(transforms, "banana");
9498     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9499     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9500     ok(!lstrcmpA(patch, patchcode),
9501        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9502     ok(!lstrcmpA(transforms, "whatever"),
9503        "Expected \"whatever\", got \"%s\"\n", transforms);
9504     ok(size == 8, "Expected 8, got %d\n", size);
9505
9506     RegDeleteKeyA(userkey, "");
9507     RegCloseKey(userkey);
9508     RegDeleteValueA(patches, patch_squashed);
9509     RegDeleteValueA(patches, "Patches");
9510     RegDeleteKeyA(patches, "");
9511     RegCloseKey(patches);
9512     RegDeleteKeyA(prodkey, "");
9513     RegCloseKey(prodkey);
9514
9515     /* MSIINSTALLCONTEXT_MACHINE */
9516
9517     size = MAX_PATH;
9518     lstrcpyA(patch, "apple");
9519     lstrcpyA(transforms, "banana");
9520     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9521     ok(r == ERROR_UNKNOWN_PRODUCT,
9522        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9523     ok(!lstrcmpA(patch, "apple"),
9524        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9525     ok(!lstrcmpA(transforms, "banana"),
9526        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9527     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9528
9529     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
9530     lstrcatA(keypath, prod_squashed);
9531
9532     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
9533     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9534
9535     /* local product key exists */
9536     size = MAX_PATH;
9537     lstrcpyA(patch, "apple");
9538     lstrcpyA(transforms, "banana");
9539     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9540     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9541     ok(!lstrcmpA(patch, "apple"),
9542        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9543     ok(!lstrcmpA(transforms, "banana"),
9544        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9545     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9546
9547     res = RegCreateKeyA(prodkey, "Patches", &patches);
9548     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9549
9550     /* Patches key exists */
9551     size = MAX_PATH;
9552     lstrcpyA(patch, "apple");
9553     lstrcpyA(transforms, "banana");
9554     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9555     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9556     ok(!lstrcmpA(patch, "apple"),
9557        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9558     ok(!lstrcmpA(transforms, "banana"),
9559        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9560     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9561
9562     res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
9563                          (const BYTE *)patch_squashed,
9564                          lstrlenA(patch_squashed) + 1);
9565     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9566
9567     /* Patches value exists, is not REG_MULTI_SZ */
9568     size = MAX_PATH;
9569     lstrcpyA(patch, "apple");
9570     lstrcpyA(transforms, "banana");
9571     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9572     ok(r == ERROR_BAD_CONFIGURATION,
9573        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9574     ok(!lstrcmpA(patch, "apple"),
9575        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9576     ok(!lstrcmpA(transforms, "banana"),
9577        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9578     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9579
9580     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9581                          (const BYTE *)"a\0b\0c\0\0", 7);
9582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9583
9584     /* Patches value exists, is not a squashed guid */
9585     size = MAX_PATH;
9586     lstrcpyA(patch, "apple");
9587     lstrcpyA(transforms, "banana");
9588     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9589     ok(r == ERROR_BAD_CONFIGURATION,
9590        "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
9591     ok(!lstrcmpA(patch, "apple"),
9592        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9593     ok(!lstrcmpA(transforms, "banana"),
9594        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9595     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9596
9597     patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
9598     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
9599                          (const BYTE *)patch_squashed,
9600                          lstrlenA(patch_squashed) + 2);
9601     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9602
9603     /* Patches value exists */
9604     size = MAX_PATH;
9605     lstrcpyA(patch, "apple");
9606     lstrcpyA(transforms, "banana");
9607     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9608     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9609     ok(!lstrcmpA(patch, "apple"),
9610        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9611     ok(!lstrcmpA(transforms, "banana"),
9612        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9613     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9614
9615     res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
9616                          (const BYTE *)"whatever", 9);
9617     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9618
9619     /* patch code value exists */
9620     size = MAX_PATH;
9621     lstrcpyA(patch, "apple");
9622     lstrcpyA(transforms, "banana");
9623     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9624     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9625     ok(!lstrcmpA(patch, patchcode),
9626        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9627     ok(!lstrcmpA(transforms, "whatever"),
9628        "Expected \"whatever\", got \"%s\"\n", transforms);
9629     ok(size == 8, "Expected 8, got %d\n", size);
9630
9631     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
9632     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
9633     lstrcatA(keypath, prod_squashed);
9634
9635     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9636     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9637
9638     /* local UserData product key exists */
9639     size = MAX_PATH;
9640     lstrcpyA(patch, "apple");
9641     lstrcpyA(transforms, "banana");
9642     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9643     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9644     ok(!lstrcmpA(patch, patchcode),
9645        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9646     ok(!lstrcmpA(transforms, "whatever"),
9647        "Expected \"whatever\", got \"%s\"\n", transforms);
9648     ok(size == 8, "Expected 8, got %d\n", size);
9649
9650     res = RegCreateKeyA(udprod, "Patches", &udpatch);
9651     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9652
9653     /* local UserData Patches key exists */
9654     size = MAX_PATH;
9655     lstrcpyA(patch, "apple");
9656     lstrcpyA(transforms, "banana");
9657     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9658     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9659     ok(!lstrcmpA(patch, patchcode),
9660        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9661     ok(!lstrcmpA(transforms, "whatever"),
9662        "Expected \"whatever\", got \"%s\"\n", transforms);
9663     ok(size == 8, "Expected 8, got %d\n", size);
9664
9665     res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
9666     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9667
9668     /* local UserData Product patch key exists */
9669     size = MAX_PATH;
9670     lstrcpyA(patch, "apple");
9671     lstrcpyA(transforms, "banana");
9672     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9673     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
9674     ok(!lstrcmpA(patch, "apple"),
9675        "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
9676     ok(!lstrcmpA(transforms, "banana"),
9677        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
9678     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9679
9680     data = MSIPATCHSTATE_APPLIED;
9681     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
9682                          (const BYTE *)&data, sizeof(DWORD));
9683     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9684
9685     /* State value exists */
9686     size = MAX_PATH;
9687     lstrcpyA(patch, "apple");
9688     lstrcpyA(transforms, "banana");
9689     r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
9690     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
9691     ok(!lstrcmpA(patch, patchcode),
9692        "Expected \"%s\", got \"%s\"\n", patchcode, patch);
9693     ok(!lstrcmpA(transforms, "whatever"),
9694        "Expected \"whatever\", got \"%s\"\n", transforms);
9695     ok(size == 8, "Expected 8, got %d\n", size);
9696
9697     RegDeleteValueA(patches, patch_squashed);
9698     RegDeleteValueA(patches, "Patches");
9699     RegDeleteKeyA(patches, "");
9700     RegCloseKey(patches);
9701     RegDeleteValueA(hpatch, "State");
9702     RegDeleteKeyA(hpatch, "");
9703     RegCloseKey(hpatch);
9704     RegDeleteKeyA(udpatch, "");
9705     RegCloseKey(udpatch);
9706     RegDeleteKeyA(udprod, "");
9707     RegCloseKey(udprod);
9708     RegDeleteKeyA(prodkey, "");
9709     RegCloseKey(prodkey);
9710 }
9711
9712 static void test_MsiGetPatchInfoEx(void)
9713 {
9714     CHAR keypath[MAX_PATH], val[MAX_PATH];
9715     CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
9716     CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
9717     HKEY prodkey, patches, udprod, props;
9718     HKEY hpatch, udpatch, prodpatches;
9719     LPSTR usersid;
9720     DWORD size;
9721     LONG res;
9722     UINT r;
9723
9724     if (!pMsiGetPatchInfoExA)
9725     {
9726         win_skip("MsiGetPatchInfoEx not implemented\n");
9727         return;
9728     }
9729
9730     create_test_guid(prodcode, prod_squashed);
9731     create_test_guid(patchcode, patch_squashed);
9732     get_user_sid(&usersid);
9733
9734     /* NULL szPatchCode */
9735     lstrcpyA(val, "apple");
9736     size = MAX_PATH;
9737     r = pMsiGetPatchInfoExA(NULL, prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9738                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9739     ok(r == ERROR_INVALID_PARAMETER,
9740        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9741     ok(!lstrcmpA(val, "apple"),
9742        "Expected val to be unchanged, got \"%s\"\n", val);
9743     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9744
9745     /* empty szPatchCode */
9746     size = MAX_PATH;
9747     lstrcpyA(val, "apple");
9748     r = pMsiGetPatchInfoExA("", prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9749                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9750     ok(r == ERROR_INVALID_PARAMETER,
9751        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9752     ok(!lstrcmpA(val, "apple"),
9753        "Expected val to be unchanged, got \"%s\"\n", val);
9754     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9755
9756     /* garbage szPatchCode */
9757     size = MAX_PATH;
9758     lstrcpyA(val, "apple");
9759     r = pMsiGetPatchInfoExA("garbage", prodcode, NULL,
9760                             MSIINSTALLCONTEXT_USERMANAGED,
9761                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9762     ok(r == ERROR_INVALID_PARAMETER,
9763        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9764     ok(!lstrcmpA(val, "apple"),
9765        "Expected val to be unchanged, got \"%s\"\n", val);
9766     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9767
9768     /* guid without brackets */
9769     size = MAX_PATH;
9770     lstrcpyA(val, "apple");
9771     r = pMsiGetPatchInfoExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", prodcode,
9772                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9773                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9774     ok(r == ERROR_INVALID_PARAMETER,
9775        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9776     ok(!lstrcmpA(val, "apple"),
9777        "Expected val to be unchanged, got \"%s\"\n", val);
9778     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9779
9780     /* guid with brackets */
9781     size = MAX_PATH;
9782     lstrcpyA(val, "apple");
9783     r = pMsiGetPatchInfoExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", prodcode,
9784                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9785                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9786     ok(r == ERROR_UNKNOWN_PRODUCT,
9787        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9788     ok(!lstrcmpA(val, "apple"),
9789        "Expected val to be unchanged, got \"%s\"\n", val);
9790     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9791
9792     /* same length as guid, but random */
9793     size = MAX_PATH;
9794     lstrcpyA(val, "apple");
9795     r = pMsiGetPatchInfoExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", prodcode,
9796                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9797                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9798     ok(r == ERROR_INVALID_PARAMETER,
9799        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9800     ok(!lstrcmpA(val, "apple"),
9801        "Expected val to be unchanged, got \"%s\"\n", val);
9802     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9803
9804     /* NULL szProductCode */
9805     lstrcpyA(val, "apple");
9806     size = MAX_PATH;
9807     r = pMsiGetPatchInfoExA(patchcode, NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED,
9808                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9809     ok(r == ERROR_INVALID_PARAMETER,
9810        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9811     ok(!lstrcmpA(val, "apple"),
9812        "Expected val to be unchanged, got \"%s\"\n", val);
9813     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9814
9815     /* empty szProductCode */
9816     size = MAX_PATH;
9817     lstrcpyA(val, "apple");
9818     r = pMsiGetPatchInfoExA(patchcode, "", NULL, MSIINSTALLCONTEXT_USERMANAGED,
9819                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9820     ok(r == ERROR_INVALID_PARAMETER,
9821        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9822     ok(!lstrcmpA(val, "apple"),
9823        "Expected val to be unchanged, got \"%s\"\n", val);
9824     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9825
9826     /* garbage szProductCode */
9827     size = MAX_PATH;
9828     lstrcpyA(val, "apple");
9829     r = pMsiGetPatchInfoExA(patchcode, "garbage", NULL,
9830                             MSIINSTALLCONTEXT_USERMANAGED,
9831                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9832     ok(r == ERROR_INVALID_PARAMETER,
9833        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9834     ok(!lstrcmpA(val, "apple"),
9835        "Expected val to be unchanged, got \"%s\"\n", val);
9836     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9837
9838     /* guid without brackets */
9839     size = MAX_PATH;
9840     lstrcpyA(val, "apple");
9841     r = pMsiGetPatchInfoExA(patchcode, "6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
9842                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9843                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9844     ok(r == ERROR_INVALID_PARAMETER,
9845        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9846     ok(!lstrcmpA(val, "apple"),
9847        "Expected val to be unchanged, got \"%s\"\n", val);
9848     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9849
9850     /* guid with brackets */
9851     size = MAX_PATH;
9852     lstrcpyA(val, "apple");
9853     r = pMsiGetPatchInfoExA(patchcode, "{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
9854                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9855                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9856     ok(r == ERROR_UNKNOWN_PRODUCT,
9857        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9858     ok(!lstrcmpA(val, "apple"),
9859        "Expected val to be unchanged, got \"%s\"\n", val);
9860     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9861
9862     /* same length as guid, but random */
9863     size = MAX_PATH;
9864     lstrcpyA(val, "apple");
9865     r = pMsiGetPatchInfoExA(patchcode, "A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
9866                             NULL, MSIINSTALLCONTEXT_USERMANAGED,
9867                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9868     ok(r == ERROR_INVALID_PARAMETER,
9869        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9870     ok(!lstrcmpA(val, "apple"),
9871        "Expected val to be unchanged, got \"%s\"\n", val);
9872     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9873
9874     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERMANAGED */
9875     size = MAX_PATH;
9876     lstrcpyA(val, "apple");
9877     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9878                             MSIINSTALLCONTEXT_USERMANAGED,
9879                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9880     ok(r == ERROR_INVALID_PARAMETER,
9881        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9882     ok(!lstrcmpA(val, "apple"),
9883        "Expected val to be unchanged, got \"%s\"\n", val);
9884     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9885
9886     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_USERUNMANAGED */
9887     size = MAX_PATH;
9888     lstrcpyA(val, "apple");
9889     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9890                             MSIINSTALLCONTEXT_USERUNMANAGED,
9891                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9892     ok(r == ERROR_INVALID_PARAMETER,
9893        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9894     ok(!lstrcmpA(val, "apple"),
9895        "Expected val to be unchanged, got \"%s\"\n", val);
9896     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9897
9898     /* szUserSid cannot be S-1-5-18 for MSIINSTALLCONTEXT_MACHINE */
9899     size = MAX_PATH;
9900     lstrcpyA(val, "apple");
9901     r = pMsiGetPatchInfoExA(patchcode, prodcode, "S-1-5-18",
9902                             MSIINSTALLCONTEXT_MACHINE,
9903                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9904     ok(r == ERROR_INVALID_PARAMETER,
9905        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9906     ok(!lstrcmpA(val, "apple"),
9907        "Expected val to be unchanged, got \"%s\"\n", val);
9908     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9909
9910     /* szUserSid must be NULL for MSIINSTALLCONTEXT_MACHINE */
9911     size = MAX_PATH;
9912     lstrcpyA(val, "apple");
9913     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9914                             MSIINSTALLCONTEXT_MACHINE,
9915                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9916     ok(r == ERROR_INVALID_PARAMETER,
9917        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9918     ok(!lstrcmpA(val, "apple"),
9919        "Expected val to be unchanged, got \"%s\"\n", val);
9920     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9921
9922     /* dwContext is out of range */
9923     size = MAX_PATH;
9924     lstrcpyA(val, "apple");
9925     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9926                             MSIINSTALLCONTEXT_NONE,
9927                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9928     ok(r == ERROR_INVALID_PARAMETER,
9929        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9930     ok(!lstrcmpA(val, "apple"),
9931        "Expected val to be unchanged, got \"%s\"\n", val);
9932     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9933
9934     /* dwContext is out of range */
9935     size = MAX_PATH;
9936     lstrcpyA(val, "apple");
9937     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9938                             MSIINSTALLCONTEXT_ALL,
9939                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9940     ok(r == ERROR_INVALID_PARAMETER,
9941        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9942     ok(!lstrcmpA(val, "apple"),
9943        "Expected val to be unchanged, got \"%s\"\n", val);
9944     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9945
9946     /* dwContext is invalid */
9947     size = MAX_PATH;
9948     lstrcpyA(val, "apple");
9949     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid, 3,
9950                            INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9951     ok(r == ERROR_INVALID_PARAMETER,
9952        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
9953     ok(!lstrcmpA(val, "apple"),
9954        "Expected val to be unchanged, got \"%s\"\n", val);
9955     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9956
9957     /* MSIINSTALLCONTEXT_USERMANAGED */
9958
9959     size = MAX_PATH;
9960     lstrcpyA(val, "apple");
9961     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9962                             MSIINSTALLCONTEXT_USERMANAGED,
9963                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9964     ok(r == ERROR_UNKNOWN_PRODUCT,
9965        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9966     ok(!lstrcmpA(val, "apple"),
9967        "Expected val to be unchanged, got \"%s\"\n", val);
9968     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9969
9970     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
9971     lstrcatA(keypath, usersid);
9972     lstrcatA(keypath, "\\Products\\");
9973     lstrcatA(keypath, prod_squashed);
9974
9975     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
9976     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9977
9978     /* local UserData product key exists */
9979     size = MAX_PATH;
9980     lstrcpyA(val, "apple");
9981     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9982                             MSIINSTALLCONTEXT_USERMANAGED,
9983                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9984     ok(r == ERROR_UNKNOWN_PRODUCT,
9985        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
9986     ok(!lstrcmpA(val, "apple"),
9987        "Expected val to be unchanged, got \"%s\"\n", val);
9988     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
9989
9990     res = RegCreateKeyA(udprod, "InstallProperties", &props);
9991     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
9992
9993     /* InstallProperties key exists */
9994     size = MAX_PATH;
9995     lstrcpyA(val, "apple");
9996     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
9997                             MSIINSTALLCONTEXT_USERMANAGED,
9998                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
9999     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10000     ok(!lstrcmpA(val, "apple"),
10001        "Expected val to be unchanged, got \"%s\"\n", val);
10002     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10003
10004     res = RegCreateKeyA(udprod, "Patches", &patches);
10005     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10006
10007     /* Patches key exists */
10008     size = MAX_PATH;
10009     lstrcpyA(val, "apple");
10010     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10011                             MSIINSTALLCONTEXT_USERMANAGED,
10012                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10013     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10014     ok(!lstrcmpA(val, "apple"),
10015        "Expected val to be unchanged, got \"%s\"\n", val);
10016     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10017
10018     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10019     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10020
10021     /* Patches key exists */
10022     size = MAX_PATH;
10023     lstrcpyA(val, "apple");
10024     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10025                             MSIINSTALLCONTEXT_USERMANAGED,
10026                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10027     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10028     ok(!lstrcmpA(val, "apple"),
10029        "Expected val to be unchanged, got \"%s\"\n", val);
10030     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10031
10032     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
10033     lstrcatA(keypath, usersid);
10034     lstrcatA(keypath, "\\Installer\\Products\\");
10035     lstrcatA(keypath, prod_squashed);
10036
10037     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10038     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10039
10040     /* managed product key exists */
10041     size = MAX_PATH;
10042     lstrcpyA(val, "apple");
10043     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10044                             MSIINSTALLCONTEXT_USERMANAGED,
10045                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10046     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10047     ok(!lstrcmpA(val, "apple"),
10048        "Expected val to be unchanged, got \"%s\"\n", val);
10049     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10050
10051     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10052     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10053
10054     /* Patches key exists */
10055     size = MAX_PATH;
10056     lstrcpyA(val, "apple");
10057     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10058                             MSIINSTALLCONTEXT_USERMANAGED,
10059                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10060     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10061     ok(!lstrcmpA(val, "apple"),
10062        "Expected val to be unchanged, got \"%s\"\n", val);
10063     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10064
10065     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10066                          (const BYTE *)"transforms", 11);
10067     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10068
10069     /* specific patch value exists */
10070     size = MAX_PATH;
10071     lstrcpyA(val, "apple");
10072     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10073                             MSIINSTALLCONTEXT_USERMANAGED,
10074                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10075     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10076     ok(!lstrcmpA(val, "apple"),
10077        "Expected val to be unchanged, got \"%s\"\n", val);
10078     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10079
10080     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10081     lstrcatA(keypath, usersid);
10082     lstrcatA(keypath, "\\Patches\\");
10083     lstrcatA(keypath, patch_squashed);
10084
10085     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10086     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10087
10088     /* UserData Patches key exists */
10089     size = MAX_PATH;
10090     lstrcpyA(val, "apple");
10091     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10092                             MSIINSTALLCONTEXT_USERMANAGED,
10093                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10094     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10095     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10096     ok(size == 0, "Expected 0, got %d\n", size);
10097
10098     res = RegSetValueExA(udpatch, "ManagedLocalPackage", 0, REG_SZ,
10099                          (const BYTE *)"pack", 5);
10100     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10101
10102     /* ManagedLocalPatch value exists */
10103     size = MAX_PATH;
10104     lstrcpyA(val, "apple");
10105     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10106                             MSIINSTALLCONTEXT_USERMANAGED,
10107                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10108     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10109     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10110     ok(size == 4, "Expected 4, got %d\n", size);
10111
10112     size = MAX_PATH;
10113     lstrcpyA(val, "apple");
10114     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10115                             MSIINSTALLCONTEXT_USERMANAGED,
10116                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10117     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10118     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10119     ok(size == 10, "Expected 10, got %d\n", size);
10120
10121     res = RegSetValueExA(hpatch, "Installed", 0, REG_SZ,
10122                          (const BYTE *)"mydate", 7);
10123     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10124
10125     /* Installed value exists */
10126     size = MAX_PATH;
10127     lstrcpyA(val, "apple");
10128     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10129                             MSIINSTALLCONTEXT_USERMANAGED,
10130                             INSTALLPROPERTY_INSTALLDATE, val, &size);
10131     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10132     ok(!lstrcmpA(val, "mydate"), "Expected \"mydate\", got \"%s\"\n", val);
10133     ok(size == 6, "Expected 6, got %d\n", size);
10134
10135     res = RegSetValueExA(hpatch, "Uninstallable", 0, REG_SZ,
10136                          (const BYTE *)"yes", 4);
10137     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10138
10139     /* Uninstallable value exists */
10140     size = MAX_PATH;
10141     lstrcpyA(val, "apple");
10142     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10143                             MSIINSTALLCONTEXT_USERMANAGED,
10144                             INSTALLPROPERTY_UNINSTALLABLE, val, &size);
10145     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10146     ok(!lstrcmpA(val, "yes"), "Expected \"yes\", got \"%s\"\n", val);
10147     ok(size == 3, "Expected 3, got %d\n", size);
10148
10149     res = RegSetValueExA(hpatch, "State", 0, REG_SZ,
10150                          (const BYTE *)"good", 5);
10151     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10152
10153     /* State value exists */
10154     size = MAX_PATH;
10155     lstrcpyA(val, "apple");
10156     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10157                             MSIINSTALLCONTEXT_USERMANAGED,
10158                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10159     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10160     ok(!lstrcmpA(val, "good"), "Expected \"good\", got \"%s\"\n", val);
10161     ok(size == 4, "Expected 4, got %d\n", size);
10162
10163     size = 1;
10164     res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
10165                          (const BYTE *)&size, sizeof(DWORD));
10166     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10167
10168     /* State value exists */
10169     size = MAX_PATH;
10170     lstrcpyA(val, "apple");
10171     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10172                             MSIINSTALLCONTEXT_USERMANAGED,
10173                             INSTALLPROPERTY_PATCHSTATE, val, &size);
10174     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10175     todo_wine ok(!lstrcmpA(val, "1"), "Expected \"1\", got \"%s\"\n", val);
10176     ok(size == 1, "Expected 1, got %d\n", size);
10177
10178     res = RegSetValueExA(hpatch, "DisplayName", 0, REG_SZ,
10179                          (const BYTE *)"display", 8);
10180     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10181
10182     /* DisplayName value exists */
10183     size = MAX_PATH;
10184     lstrcpyA(val, "apple");
10185     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10186                             MSIINSTALLCONTEXT_USERMANAGED,
10187                             INSTALLPROPERTY_DISPLAYNAME, val, &size);
10188     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10189     ok(!lstrcmpA(val, "display"), "Expected \"display\", got \"%s\"\n", val);
10190     ok(size == 7, "Expected 7, got %d\n", size);
10191
10192     res = RegSetValueExA(hpatch, "MoreInfoURL", 0, REG_SZ,
10193                          (const BYTE *)"moreinfo", 9);
10194     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10195
10196     /* MoreInfoURL value exists */
10197     size = MAX_PATH;
10198     lstrcpyA(val, "apple");
10199     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10200                             MSIINSTALLCONTEXT_USERMANAGED,
10201                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10202     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10203     ok(!lstrcmpA(val, "moreinfo"), "Expected \"moreinfo\", got \"%s\"\n", val);
10204     ok(size == 8, "Expected 8, got %d\n", size);
10205
10206     /* szProperty is invalid */
10207     size = MAX_PATH;
10208     lstrcpyA(val, "apple");
10209     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10210                             MSIINSTALLCONTEXT_USERMANAGED,
10211                             "IDontExist", val, &size);
10212     ok(r == ERROR_UNKNOWN_PROPERTY,
10213        "Expected ERROR_UNKNOWN_PROPERTY, got %d\n", r);
10214     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10215     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10216
10217     /* lpValue is NULL, while pcchValue is non-NULL */
10218     size = MAX_PATH;
10219     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10220                             MSIINSTALLCONTEXT_USERMANAGED,
10221                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10222     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10223     ok(size == 16, "Expected 16, got %d\n", size);
10224
10225     /* pcchValue is NULL, while lpValue is non-NULL */
10226     lstrcpyA(val, "apple");
10227     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10228                             MSIINSTALLCONTEXT_USERMANAGED,
10229                             INSTALLPROPERTY_MOREINFOURL, val, NULL);
10230     ok(r == ERROR_INVALID_PARAMETER,
10231        "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10232     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10233
10234     /* both lpValue and pcchValue are NULL */
10235     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10236                             MSIINSTALLCONTEXT_USERMANAGED,
10237                             INSTALLPROPERTY_MOREINFOURL, NULL, NULL);
10238     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10239
10240     /* pcchValue doesn't have enough room for NULL terminator */
10241     size = 8;
10242     lstrcpyA(val, "apple");
10243     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10244                             MSIINSTALLCONTEXT_USERMANAGED,
10245                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10246     ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
10247     ok(!lstrcmpA(val, "moreinf"),
10248        "Expected \"moreinf\", got \"%s\"\n", val);
10249     ok(size == 16, "Expected 16, got %d\n", size);
10250
10251     /* pcchValue has exactly enough room for NULL terminator */
10252     size = 9;
10253     lstrcpyA(val, "apple");
10254     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10255                             MSIINSTALLCONTEXT_USERMANAGED,
10256                             INSTALLPROPERTY_MOREINFOURL, val, &size);
10257     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10258     ok(!lstrcmpA(val, "moreinfo"),
10259        "Expected \"moreinfo\", got \"%s\"\n", val);
10260     ok(size == 8, "Expected 8, got %d\n", size);
10261
10262     /* pcchValue is too small, lpValue is NULL */
10263     size = 0;
10264     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10265                             MSIINSTALLCONTEXT_USERMANAGED,
10266                             INSTALLPROPERTY_MOREINFOURL, NULL, &size);
10267     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10268     ok(size == 16, "Expected 16, got %d\n", size);
10269
10270     RegDeleteValueA(prodpatches, patch_squashed);
10271     RegDeleteKeyA(prodpatches, "");
10272     RegCloseKey(prodpatches);
10273     RegDeleteKeyA(prodkey, "");
10274     RegCloseKey(prodkey);
10275
10276     /* UserData is sufficient for all properties
10277      * except INSTALLPROPERTY_TRANSFORMS
10278      */
10279     size = MAX_PATH;
10280     lstrcpyA(val, "apple");
10281     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10282                             MSIINSTALLCONTEXT_USERMANAGED,
10283                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10284     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10285     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10286     ok(size == 4, "Expected 4, got %d\n", size);
10287
10288     /* UserData is sufficient for all properties
10289      * except INSTALLPROPERTY_TRANSFORMS
10290      */
10291     size = MAX_PATH;
10292     lstrcpyA(val, "apple");
10293     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10294                             MSIINSTALLCONTEXT_USERMANAGED,
10295                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10296     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10297     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10298     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10299
10300     RegDeleteValueA(hpatch, "MoreInfoURL");
10301     RegDeleteValueA(hpatch, "Display");
10302     RegDeleteValueA(hpatch, "State");
10303     RegDeleteValueA(hpatch, "Uninstallable");
10304     RegDeleteValueA(hpatch, "Installed");
10305     RegDeleteValueA(udpatch, "ManagedLocalPackage");
10306     RegDeleteKeyA(udpatch, "");
10307     RegCloseKey(udpatch);
10308     RegDeleteKeyA(hpatch, "");
10309     RegCloseKey(hpatch);
10310     RegDeleteKeyA(patches, "");
10311     RegCloseKey(patches);
10312     RegDeleteKeyA(props, "");
10313     RegCloseKey(props);
10314     RegDeleteKeyA(udprod, "");
10315     RegCloseKey(udprod);
10316
10317     /* MSIINSTALLCONTEXT_USERUNMANAGED */
10318
10319     size = MAX_PATH;
10320     lstrcpyA(val, "apple");
10321     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10322                             MSIINSTALLCONTEXT_USERUNMANAGED,
10323                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10324     ok(r == ERROR_UNKNOWN_PRODUCT,
10325        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10326     ok(!lstrcmpA(val, "apple"),
10327        "Expected val to be unchanged, got \"%s\"\n", val);
10328     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10329
10330     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10331     lstrcatA(keypath, usersid);
10332     lstrcatA(keypath, "\\Products\\");
10333     lstrcatA(keypath, prod_squashed);
10334
10335     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10336     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10337
10338     /* local UserData product key exists */
10339     size = MAX_PATH;
10340     lstrcpyA(val, "apple");
10341     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10342                             MSIINSTALLCONTEXT_USERUNMANAGED,
10343                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10344     ok(r == ERROR_UNKNOWN_PRODUCT,
10345        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10346     ok(!lstrcmpA(val, "apple"),
10347        "Expected val to be unchanged, got \"%s\"\n", val);
10348     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10349
10350     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10351     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10352
10353     /* InstallProperties key exists */
10354     size = MAX_PATH;
10355     lstrcpyA(val, "apple");
10356     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10357                             MSIINSTALLCONTEXT_USERUNMANAGED,
10358                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10359     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10360     ok(!lstrcmpA(val, "apple"),
10361        "Expected val to be unchanged, got \"%s\"\n", val);
10362     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10363
10364     res = RegCreateKeyA(udprod, "Patches", &patches);
10365     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10366
10367     /* Patches key exists */
10368     size = MAX_PATH;
10369     lstrcpyA(val, "apple");
10370     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10371                             MSIINSTALLCONTEXT_USERUNMANAGED,
10372                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10373     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10374     ok(!lstrcmpA(val, "apple"),
10375        "Expected val to be unchanged, got \"%s\"\n", val);
10376     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10377
10378     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10379     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10380
10381     /* Patches key exists */
10382     size = MAX_PATH;
10383     lstrcpyA(val, "apple");
10384     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10385                             MSIINSTALLCONTEXT_USERUNMANAGED,
10386                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10387     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10388     ok(!lstrcmpA(val, "apple"),
10389        "Expected val to be unchanged, got \"%s\"\n", val);
10390     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10391
10392     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
10393     lstrcatA(keypath, prod_squashed);
10394
10395     res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
10396     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10397
10398     /* current user product key exists */
10399     size = MAX_PATH;
10400     lstrcpyA(val, "apple");
10401     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10402                             MSIINSTALLCONTEXT_USERUNMANAGED,
10403                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10404     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10405     ok(!lstrcmpA(val, "apple"),
10406        "Expected val to be unchanged, got \"%s\"\n", val);
10407     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10408
10409     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10410     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10411
10412     /* Patches key exists */
10413     size = MAX_PATH;
10414     lstrcpyA(val, "apple");
10415     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10416                             MSIINSTALLCONTEXT_USERUNMANAGED,
10417                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10418     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10419     ok(!lstrcmpA(val, "apple"),
10420        "Expected val to be unchanged, got \"%s\"\n", val);
10421     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10422
10423     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10424                          (const BYTE *)"transforms", 11);
10425     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10426
10427     /* specific patch value exists */
10428     size = MAX_PATH;
10429     lstrcpyA(val, "apple");
10430     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10431                             MSIINSTALLCONTEXT_USERUNMANAGED,
10432                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10433     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10434     ok(!lstrcmpA(val, "apple"),
10435        "Expected val to be unchanged, got \"%s\"\n", val);
10436     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10437
10438     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
10439     lstrcatA(keypath, usersid);
10440     lstrcatA(keypath, "\\Patches\\");
10441     lstrcatA(keypath, patch_squashed);
10442
10443     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10444     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10445
10446     /* UserData Patches key exists */
10447     size = MAX_PATH;
10448     lstrcpyA(val, "apple");
10449     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10450                             MSIINSTALLCONTEXT_USERUNMANAGED,
10451                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10452     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10453     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10454     ok(size == 0, "Expected 0, got %d\n", size);
10455
10456     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10457                          (const BYTE *)"pack", 5);
10458     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10459
10460     /* LocalPatch value exists */
10461     size = MAX_PATH;
10462     lstrcpyA(val, "apple");
10463     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10464                             MSIINSTALLCONTEXT_USERUNMANAGED,
10465                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10466     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10467     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10468     ok(size == 4, "Expected 4, got %d\n", size);
10469
10470     size = MAX_PATH;
10471     lstrcpyA(val, "apple");
10472     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10473                             MSIINSTALLCONTEXT_USERUNMANAGED,
10474                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10475     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10476     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10477     ok(size == 10, "Expected 10, got %d\n", size);
10478
10479     RegDeleteValueA(prodpatches, patch_squashed);
10480     RegDeleteKeyA(prodpatches, "");
10481     RegCloseKey(prodpatches);
10482     RegDeleteKeyA(prodkey, "");
10483     RegCloseKey(prodkey);
10484
10485     /* UserData is sufficient for all properties
10486      * except INSTALLPROPERTY_TRANSFORMS
10487      */
10488     size = MAX_PATH;
10489     lstrcpyA(val, "apple");
10490     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10491                             MSIINSTALLCONTEXT_USERUNMANAGED,
10492                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10493     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10494     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10495     ok(size == 4, "Expected 4, got %d\n", size);
10496
10497     /* UserData is sufficient for all properties
10498      * except INSTALLPROPERTY_TRANSFORMS
10499      */
10500     size = MAX_PATH;
10501     lstrcpyA(val, "apple");
10502     r = pMsiGetPatchInfoExA(patchcode, prodcode, usersid,
10503                             MSIINSTALLCONTEXT_USERUNMANAGED,
10504                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10505     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10506     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10507     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10508
10509     RegDeleteValueA(udpatch, "LocalPackage");
10510     RegDeleteKeyA(udpatch, "");
10511     RegCloseKey(udpatch);
10512     RegDeleteKeyA(hpatch, "");
10513     RegCloseKey(hpatch);
10514     RegDeleteKeyA(patches, "");
10515     RegCloseKey(patches);
10516     RegDeleteKeyA(props, "");
10517     RegCloseKey(props);
10518     RegDeleteKeyA(udprod, "");
10519     RegCloseKey(udprod);
10520
10521     /* MSIINSTALLCONTEXT_MACHINE */
10522
10523     size = MAX_PATH;
10524     lstrcpyA(val, "apple");
10525     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10526                             MSIINSTALLCONTEXT_MACHINE,
10527                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10528     ok(r == ERROR_UNKNOWN_PRODUCT,
10529        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10530     ok(!lstrcmpA(val, "apple"),
10531        "Expected val to be unchanged, got \"%s\"\n", val);
10532     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10533
10534     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10535     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
10536     lstrcatA(keypath, prod_squashed);
10537
10538     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
10539     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10540
10541     /* local UserData product key exists */
10542     size = MAX_PATH;
10543     lstrcpyA(val, "apple");
10544     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10545                             MSIINSTALLCONTEXT_MACHINE,
10546                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10547     ok(r == ERROR_UNKNOWN_PRODUCT,
10548        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
10549     ok(!lstrcmpA(val, "apple"),
10550        "Expected val to be unchanged, got \"%s\"\n", val);
10551     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10552
10553     res = RegCreateKeyA(udprod, "InstallProperties", &props);
10554     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10555
10556     /* InstallProperties key exists */
10557     size = MAX_PATH;
10558     lstrcpyA(val, "apple");
10559     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10560                             MSIINSTALLCONTEXT_MACHINE,
10561                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10562     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10563     ok(!lstrcmpA(val, "apple"),
10564        "Expected val to be unchanged, got \"%s\"\n", val);
10565     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10566
10567     res = RegCreateKeyA(udprod, "Patches", &patches);
10568     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10569
10570     /* Patches key exists */
10571     size = MAX_PATH;
10572     lstrcpyA(val, "apple");
10573     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10574                             MSIINSTALLCONTEXT_MACHINE,
10575                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10576     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10577     ok(!lstrcmpA(val, "apple"),
10578        "Expected val to be unchanged, got \"%s\"\n", val);
10579     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10580
10581     res = RegCreateKeyA(patches, patch_squashed, &hpatch);
10582     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10583
10584     /* Patches key exists */
10585     size = MAX_PATH;
10586     lstrcpyA(val, "apple");
10587     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10588                             MSIINSTALLCONTEXT_MACHINE,
10589                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10590     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10591     ok(!lstrcmpA(val, "apple"),
10592        "Expected val to be unchanged, got \"%s\"\n", val);
10593     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10594
10595     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10596     lstrcatA(keypath, prod_squashed);
10597
10598     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
10599     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10600
10601     /* local product key exists */
10602     size = MAX_PATH;
10603     lstrcpyA(val, "apple");
10604     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10605                             MSIINSTALLCONTEXT_MACHINE,
10606                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10607     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10608     ok(!lstrcmpA(val, "apple"),
10609        "Expected val to be unchanged, got \"%s\"\n", val);
10610     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10611
10612     res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
10613     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10614
10615     /* Patches key exists */
10616     size = MAX_PATH;
10617     lstrcpyA(val, "apple");
10618     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10619                             MSIINSTALLCONTEXT_MACHINE,
10620                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10621     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10622     ok(!lstrcmpA(val, "apple"),
10623        "Expected val to be unchanged, got \"%s\"\n", val);
10624     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10625
10626     res = RegSetValueExA(prodpatches, patch_squashed, 0, REG_SZ,
10627                          (const BYTE *)"transforms", 11);
10628     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10629
10630     /* specific patch value exists */
10631     size = MAX_PATH;
10632     lstrcpyA(val, "apple");
10633     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10634                             MSIINSTALLCONTEXT_MACHINE,
10635                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10636     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10637     ok(!lstrcmpA(val, "apple"),
10638        "Expected val to be unchanged, got \"%s\"\n", val);
10639     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
10640
10641     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
10642     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
10643     lstrcatA(keypath, patch_squashed);
10644
10645     res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
10646     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10647
10648     /* UserData Patches key exists */
10649     size = MAX_PATH;
10650     lstrcpyA(val, "apple");
10651     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10652                             MSIINSTALLCONTEXT_MACHINE,
10653                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10654     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10655     ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
10656     ok(size == 0, "Expected 0, got %d\n", size);
10657
10658     res = RegSetValueExA(udpatch, "LocalPackage", 0, REG_SZ,
10659                          (const BYTE *)"pack", 5);
10660     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
10661
10662     /* LocalPatch value exists */
10663     size = MAX_PATH;
10664     lstrcpyA(val, "apple");
10665     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10666                             MSIINSTALLCONTEXT_MACHINE,
10667                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10668     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10669     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10670     ok(size == 4, "Expected 4, got %d\n", size);
10671
10672     size = MAX_PATH;
10673     lstrcpyA(val, "apple");
10674     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10675                             MSIINSTALLCONTEXT_MACHINE,
10676                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10677     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10678     ok(!lstrcmpA(val, "transforms"), "Expected \"transforms\", got \"%s\"\n", val);
10679     ok(size == 10, "Expected 10, got %d\n", size);
10680
10681     RegDeleteValueA(prodpatches, patch_squashed);
10682     RegDeleteKeyA(prodpatches, "");
10683     RegCloseKey(prodpatches);
10684     RegDeleteKeyA(prodkey, "");
10685     RegCloseKey(prodkey);
10686
10687     /* UserData is sufficient for all properties
10688      * except INSTALLPROPERTY_TRANSFORMS
10689      */
10690     size = MAX_PATH;
10691     lstrcpyA(val, "apple");
10692     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10693                             MSIINSTALLCONTEXT_MACHINE,
10694                             INSTALLPROPERTY_LOCALPACKAGE, val, &size);
10695     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10696     ok(!lstrcmpA(val, "pack"), "Expected \"pack\", got \"%s\"\n", val);
10697     ok(size == 4, "Expected 4, got %d\n", size);
10698
10699     /* UserData is sufficient for all properties
10700      * except INSTALLPROPERTY_TRANSFORMS
10701      */
10702     size = MAX_PATH;
10703     lstrcpyA(val, "apple");
10704     r = pMsiGetPatchInfoExA(patchcode, prodcode, NULL,
10705                             MSIINSTALLCONTEXT_MACHINE,
10706                             INSTALLPROPERTY_TRANSFORMS, val, &size);
10707     ok(r == ERROR_UNKNOWN_PATCH, "Expected ERROR_UNKNOWN_PATCH, got %d\n", r);
10708     ok(!lstrcmpA(val, "apple"), "Expected \"apple\", got \"%s\"\n", val);
10709     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
10710
10711     RegDeleteValueA(udpatch, "LocalPackage");
10712     RegDeleteKeyA(udpatch, "");
10713     RegCloseKey(udpatch);
10714     RegDeleteKeyA(hpatch, "");
10715     RegCloseKey(hpatch);
10716     RegDeleteKeyA(patches, "");
10717     RegCloseKey(patches);
10718     RegDeleteKeyA(props, "");
10719     RegCloseKey(props);
10720     RegDeleteKeyA(udprod, "");
10721     RegCloseKey(udprod);
10722 }
10723
10724 START_TEST(msi)
10725 {
10726     init_functionpointers();
10727
10728     test_usefeature();
10729     test_null();
10730     test_getcomponentpath();
10731     test_MsiGetFileHash();
10732
10733     if (!pConvertSidToStringSidA)
10734         skip("ConvertSidToStringSidA not implemented\n");
10735     else
10736     {
10737         /* These tests rely on get_user_sid that needs ConvertSidToStringSidA */
10738         test_MsiQueryProductState();
10739         test_MsiQueryFeatureState();
10740         test_MsiQueryComponentState();
10741         test_MsiGetComponentPath();
10742         test_MsiGetProductCode();
10743         test_MsiEnumClients();
10744         test_MsiGetProductInfo();
10745         test_MsiGetProductInfoEx();
10746         test_MsiGetUserInfo();
10747         test_MsiOpenProduct();
10748         test_MsiEnumPatchesEx();
10749         test_MsiEnumPatches();
10750         test_MsiGetPatchInfoEx();
10751     }
10752
10753     test_MsiGetFileVersion();
10754 }